headroom-cms 0.1.10 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -6
- package/admin/.well-known/headroom.json +9 -0
- package/admin/assets/{AdminsPage-BIWASote.js → AdminsPage-DUMTsCEp.js} +1 -1
- package/admin/assets/{AllContentPage-1gXe2OC7.js → AllContentPage-D5ey5AOV.js} +1 -1
- package/admin/assets/{ApiKeysPage-BBW4ATBx.js → ApiKeysPage-CzUOSoz_.js} +1 -1
- package/admin/assets/{AuditPage-B5GGFWGG.js → AuditPage-CYAg4dbI.js} +1 -1
- package/admin/assets/BackupsPage-04_oMy3v.js +1 -0
- package/admin/assets/{BlockEditor-ClskiZoX.js → BlockEditor-s0CRZsjy.js} +3 -3
- package/admin/assets/BlockTypeEditPage-D1OFIlJZ.js +1 -0
- package/admin/assets/{BlockTypesPage-D8Me6OeX.js → BlockTypesPage-cJNR25fN.js} +1 -1
- package/admin/assets/{BulkActionBar--35xjnOP.js → BulkActionBar-BWysX7Wo.js} +1 -1
- package/admin/assets/CollectionEditPage-DRmCA_73.js +1 -0
- package/admin/assets/{CollectionsPage-BQmGXpvW.js → CollectionsPage-CeQB5e9u.js} +1 -1
- package/admin/assets/{ContentCreatePage-DlgxamOe.js → ContentCreatePage-Cq8Pi8EF.js} +1 -1
- package/admin/assets/ContentEditPage-CEJ7I3WH.js +1 -0
- package/admin/assets/{ContentField-D04Uo1Ov.js → ContentField-BZT4OUfI.js} +1 -1
- package/admin/assets/ContentListPage-BCEQrYVs.js +1 -0
- package/admin/assets/{CustomBlockPreview-Cs9bFDh4.js → CustomBlockPreview-Kc6bb3oq.js} +1 -1
- package/admin/assets/FieldRenderer-CT-DgCbC.js +2 -0
- package/admin/assets/FileTypeIcon-CNHtffHC.js +1 -0
- package/admin/assets/FloatingComposerController-D4uLQfUX-0_Y8mkGU.js +1 -0
- package/admin/assets/IconPicker-BpPlHJO0.js +3 -0
- package/admin/assets/{LoginPage-Bi7TBzK4.js → LoginPage-Dya8sF_P.js} +1 -1
- package/admin/assets/MediaField-C3qFf3g5.js +1 -0
- package/admin/assets/MediaPage-BNxc0wLq.js +1 -0
- package/admin/assets/{Pagination-CuHwUPHi.js → Pagination-Dx8h11Rn.js} +1 -1
- package/admin/assets/{RelationshipPicker-Dv7GaLcU.js → RelationshipPicker-C2MTxrhl.js} +1 -1
- package/admin/assets/{SiteSettingsPage-nBT7NzkA.js → SiteSettingsPage-BDZaUBmf.js} +1 -1
- package/admin/assets/{SiteUserEditPage-DroUTii9.js → SiteUserEditPage-MfzhPW7v.js} +1 -1
- package/admin/assets/{SiteUsersPage-iVXPCBPe.js → SiteUsersPage-CrYugXpx.js} +1 -1
- package/admin/assets/{SitesPage-BefZeWuJ.js → SitesPage-Cl8V3Hb7.js} +1 -1
- package/admin/assets/SubmissionDetailPage-BnVlsGb-.js +1 -0
- package/admin/assets/SubmissionEditPage-B0Kq52fb.js +1 -0
- package/admin/assets/SubmissionListPage-K665VwMp.js +1 -0
- package/admin/assets/{TagInput-d-Hw1fkL.js → TagInput-C6tcB5Xw.js} +1 -1
- package/admin/assets/{TagsPage-BZzDvcKa.js → TagsPage-BONR6bSu.js} +1 -1
- package/admin/assets/{UsersPage-CnQAOOGF.js → UsersPage-C2iCy0UR.js} +1 -1
- package/admin/assets/{WebhookEditPage-KeS8hmdW.js → WebhookEditPage-DjZFxT72.js} +1 -1
- package/admin/assets/{WebhooksPage-CASjmlPN.js → WebhooksPage-g_a224a4.js} +1 -1
- package/admin/assets/{card-CZTHR2Qa.js → card-DlfsF8lU.js} +1 -1
- package/admin/assets/{checkbox-DEgzM8H9.js → checkbox-BX8EcGFf.js} +1 -1
- package/admin/assets/{command-CdzYw11U.js → command-DaTsImUa.js} +1 -1
- package/admin/assets/{contentStatus-CkPi9Dh6.js → contentStatus-WXGfd7vX.js} +1 -1
- package/admin/assets/format-BRcflvs9.js +1 -0
- package/admin/assets/index-9sbb3-yI.css +1 -0
- package/admin/assets/{index-BA3y7HJs.js → index-DC1UyCW2.js} +10 -10
- package/admin/assets/listCellValue-CBqXAwce.js +1 -0
- package/admin/assets/media-url-DdCoIedP.js +1 -0
- package/admin/assets/{popover-BFw_h3j6.js → popover-BA-47SRI.js} +1 -1
- package/admin/assets/{select-dX9e6VDt.js → select-waaVyoQ5.js} +1 -1
- package/admin/assets/serializeToText-CjHhyvXp.js +2 -0
- package/admin/assets/{table-Dk7eeOt2.js → table-Br-QgtTL.js} +1 -1
- package/admin/assets/{textarea-CpDSUg2s.js → textarea-BILv1DQB.js} +1 -1
- package/admin/assets/useAdminResolver-CbDzGoDp.js +1 -0
- package/admin/assets/useContent-Bp4f9qe0.js +1 -0
- package/admin/assets/{useContentSearch-_bwacEth.js → useContentSearch-DbiA8aG-.js} +1 -1
- package/admin/assets/{usePageTitle-DYvuJQp6.js → usePageTitle-DOEFrHbj.js} +1 -1
- package/admin/assets/{useSiteUsers-CKtC_8Jc.js → useSiteUsers-BFYAbJNT.js} +1 -1
- package/admin/assets/{useTags-ybsMbCst.js → useTags-DJlXwDyc.js} +1 -1
- package/admin/assets/{useWebhooks-BAB-3sLa.js → useWebhooks-BkpJKNLN.js} +1 -1
- package/admin/favicon-16x16.png +0 -0
- package/admin/favicon-32x32.png +0 -0
- package/admin/icons/icon-180x180.png +0 -0
- package/admin/icons/icon-192x192.png +0 -0
- package/admin/icons/icon-512x512.png +0 -0
- package/admin/icons/maskable-icon-512x512.png +0 -0
- package/admin/index.html +2 -2
- package/admin/sw.js +1 -1
- package/admin/workbox-362996ec.js +1 -0
- package/dist/admin-site.d.ts +4 -2
- package/dist/admin-site.d.ts.map +1 -1
- package/dist/admin-site.js +49 -6
- package/dist/admin-site.js.map +1 -1
- package/dist/api.d.ts +2 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +57 -5
- package/dist/api.js.map +1 -1
- package/dist/backup.d.ts +29 -0
- package/dist/backup.d.ts.map +1 -0
- package/dist/backup.js +95 -0
- package/dist/backup.js.map +1 -0
- package/dist/cdn-api.d.ts +25 -0
- package/dist/cdn-api.d.ts.map +1 -0
- package/dist/{cdn.js → cdn-api.js} +27 -158
- package/dist/cdn-api.js.map +1 -0
- package/dist/cdn-media.d.ts +26 -0
- package/dist/cdn-media.d.ts.map +1 -0
- package/dist/cdn-media.js +202 -0
- package/dist/cdn-media.js.map +1 -0
- package/dist/image.d.ts +8 -1
- package/dist/image.d.ts.map +1 -1
- package/dist/image.js +26 -6
- package/dist/image.js.map +1 -1
- package/dist/index.d.ts +18 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +52 -10
- package/dist/index.js.map +1 -1
- package/dist/storage.d.ts +1 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +21 -0
- package/dist/storage.js.map +1 -1
- package/dist/webhooks.d.ts +4 -3
- package/dist/webhooks.d.ts.map +1 -1
- package/dist/webhooks.js +22 -35
- package/dist/webhooks.js.map +1 -1
- package/lambda/api/bootstrap +0 -0
- package/lambda/backup-worker/bootstrap +0 -0
- package/lambda/image-lambda/index.mjs +30 -6
- package/lambda/image-lambda/node_modules/.package-lock.json +3 -3
- package/lambda/image-lambda/node_modules/semver/README.md +19 -4
- package/lambda/image-lambda/node_modules/semver/bin/semver.js +14 -10
- package/lambda/image-lambda/node_modules/semver/classes/range.js +7 -0
- package/lambda/image-lambda/node_modules/semver/functions/truncate.js +48 -0
- package/lambda/image-lambda/node_modules/semver/index.js +2 -0
- package/lambda/image-lambda/node_modules/semver/internal/re.js +1 -1
- package/lambda/image-lambda/node_modules/semver/package.json +3 -3
- package/lambda/image-lambda/node_modules/semver/range.bnf +5 -4
- package/lambda/image-lambda/node_modules/semver/ranges/subset.js +2 -2
- package/lambda/webhook-worker/bootstrap +0 -0
- package/package.json +1 -1
- package/src/admin-site.ts +53 -8
- package/src/api.ts +58 -5
- package/src/backup.ts +114 -0
- package/src/{cdn.ts → cdn-api.ts} +28 -183
- package/src/cdn-media.ts +250 -0
- package/src/image.ts +30 -6
- package/src/index.ts +71 -12
- package/src/sst-env.d.ts +4 -0
- package/src/storage.ts +22 -0
- package/src/webhooks.ts +22 -39
- package/admin/assets/BlockTypeEditPage-CY0gCPei.js +0 -1
- package/admin/assets/CollectionEditPage-y8t0ZO89.js +0 -1
- package/admin/assets/ContentEditPage-WkSbCnnG.js +0 -1
- package/admin/assets/ContentListPage-BDMx7pWb.js +0 -1
- package/admin/assets/FieldRenderer-wE-mtqZB.js +0 -2
- package/admin/assets/FilterBar-kFcOLffg.js +0 -1
- package/admin/assets/FloatingComposerController-D4uLQfUX-C0Lhbmda.js +0 -1
- package/admin/assets/IconPicker-BrgSAsa_.js +0 -3
- package/admin/assets/MediaField-B-Cz8TlK.js +0 -1
- package/admin/assets/MediaPage-C84p9d1U.js +0 -1
- package/admin/assets/SubmissionDetailPage-ktmzzOE1.js +0 -1
- package/admin/assets/SubmissionEditPage-C-ykTI2t.js +0 -1
- package/admin/assets/SubmissionListPage-DA-8deUy.js +0 -1
- package/admin/assets/format-C88SDH8g.js +0 -1
- package/admin/assets/index-c7UygSvP.css +0 -1
- package/admin/assets/media-url-DIg_vSyf.js +0 -1
- package/admin/assets/serializeToText-Zin3gYPm.js +0 -2
- package/admin/assets/useAdminResolver-Bljb4XGQ.js +0 -1
- package/admin/assets/useContent-CW0tm0FY.js +0 -1
- package/admin/assets/useMedia-Cu5N4rY8.js +0 -1
- package/admin/workbox-7d58179f.js +0 -1
- package/dist/cdn.d.ts +0 -27
- package/dist/cdn.d.ts.map +0 -1
- package/dist/cdn.js.map +0 -1
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Media CDN Infrastructure
|
|
3
|
+
*
|
|
4
|
+
* CloudFront distribution for the public media surface — `/media/*` and
|
|
5
|
+
* `/img/*` only. No edge auth (`/media/*` is OAC-public, `/img/*` is HMAC
|
|
6
|
+
* signed at the Sharp Lambda). The default behavior targets the S3 origin
|
|
7
|
+
* with no rewrite, so unmatched paths return AccessDenied from S3 — defense
|
|
8
|
+
* in depth.
|
|
9
|
+
*/
|
|
10
|
+
export function createMediaCdn(name, args) {
|
|
11
|
+
const { image, contentBucket } = args;
|
|
12
|
+
// =========================================================================
|
|
13
|
+
// CloudFront Function: Media Rewrite
|
|
14
|
+
// =========================================================================
|
|
15
|
+
const mediaRewriteFunction = new aws.cloudfront.Function(`${name}MediaRewrite`, {
|
|
16
|
+
name: $interpolate `${$app.name}-${$app.stage}-media-rewrite`,
|
|
17
|
+
runtime: "cloudfront-js-2.0",
|
|
18
|
+
publish: true,
|
|
19
|
+
code: `
|
|
20
|
+
function handler(event) {
|
|
21
|
+
var request = event.request;
|
|
22
|
+
var uri = request.uri;
|
|
23
|
+
|
|
24
|
+
// Rewrite /media/{site}/{mediaId}/{file} → /sites/{site}/media/{mediaId}/{file}
|
|
25
|
+
var parts = uri.split('/');
|
|
26
|
+
// parts: ['', 'media', '{site}', '{mediaId}', '{file}']
|
|
27
|
+
if (parts.length >= 5 && parts[1] === 'media') {
|
|
28
|
+
var site = parts[2];
|
|
29
|
+
var mediaId = parts[3];
|
|
30
|
+
var rest = parts.slice(4).join('/');
|
|
31
|
+
request.uri = '/sites/' + site + '/media/' + mediaId + '/' + rest;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return request;
|
|
35
|
+
}
|
|
36
|
+
`,
|
|
37
|
+
});
|
|
38
|
+
// =========================================================================
|
|
39
|
+
// Cache Policies
|
|
40
|
+
// =========================================================================
|
|
41
|
+
const imageCachePolicy = new aws.cloudfront.CachePolicy(`${name}ImageCachePolicy`, {
|
|
42
|
+
name: $interpolate `${$app.name}-${$app.stage}-image-cache`,
|
|
43
|
+
comment: "Cache policy for transformed images (immutable)",
|
|
44
|
+
defaultTtl: 31536000,
|
|
45
|
+
maxTtl: 31536000,
|
|
46
|
+
minTtl: 31536000,
|
|
47
|
+
parametersInCacheKeyAndForwardedToOrigin: {
|
|
48
|
+
cookiesConfig: { cookieBehavior: "none" },
|
|
49
|
+
headersConfig: { headerBehavior: "none" },
|
|
50
|
+
queryStringsConfig: {
|
|
51
|
+
queryStringBehavior: "whitelist",
|
|
52
|
+
queryStrings: {
|
|
53
|
+
items: ["w", "h", "fit", "format", "q", "sig"],
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
enableAcceptEncodingBrotli: true,
|
|
57
|
+
enableAcceptEncodingGzip: true,
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
const mediaCachePolicy = new aws.cloudfront.CachePolicy(`${name}MediaCachePolicy`, {
|
|
61
|
+
name: $interpolate `${$app.name}-${$app.stage}-media-cache`,
|
|
62
|
+
comment: "Cache policy for original media files (immutable)",
|
|
63
|
+
defaultTtl: 31536000,
|
|
64
|
+
maxTtl: 31536000,
|
|
65
|
+
minTtl: 31536000,
|
|
66
|
+
parametersInCacheKeyAndForwardedToOrigin: {
|
|
67
|
+
cookiesConfig: { cookieBehavior: "none" },
|
|
68
|
+
headersConfig: { headerBehavior: "none" },
|
|
69
|
+
queryStringsConfig: { queryStringBehavior: "none" },
|
|
70
|
+
enableAcceptEncodingBrotli: true,
|
|
71
|
+
enableAcceptEncodingGzip: true,
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
// =========================================================================
|
|
75
|
+
// Origin Access Controls (OAC)
|
|
76
|
+
// =========================================================================
|
|
77
|
+
const mediaOAC = new aws.cloudfront.OriginAccessControl(`${name}MediaOAC`, {
|
|
78
|
+
name: $interpolate `${$app.name}-${$app.stage}-media-oac`,
|
|
79
|
+
description: "OAC for S3 media origin",
|
|
80
|
+
originAccessControlOriginType: "s3",
|
|
81
|
+
signingBehavior: "always",
|
|
82
|
+
signingProtocol: "sigv4",
|
|
83
|
+
});
|
|
84
|
+
const imageOAC = new aws.cloudfront.OriginAccessControl(`${name}ImageOAC`, {
|
|
85
|
+
name: $interpolate `${$app.name}-${$app.stage}-image-oac`,
|
|
86
|
+
description: "OAC for image transform Lambda origin",
|
|
87
|
+
originAccessControlOriginType: "lambda",
|
|
88
|
+
signingBehavior: "always",
|
|
89
|
+
signingProtocol: "sigv4",
|
|
90
|
+
});
|
|
91
|
+
// =========================================================================
|
|
92
|
+
// CloudFront Distribution
|
|
93
|
+
// =========================================================================
|
|
94
|
+
const imageLambdaDomain = image.imageLambda.url.apply((url) => {
|
|
95
|
+
const parsed = new URL(url);
|
|
96
|
+
return parsed.hostname;
|
|
97
|
+
});
|
|
98
|
+
const s3RegionalDomain = $interpolate `${contentBucket.name}.s3.${aws.getRegionOutput().name}.amazonaws.com`;
|
|
99
|
+
const priceClass = args.priceClass ?? "PriceClass_100";
|
|
100
|
+
// Build aliases and certificate config for custom domain
|
|
101
|
+
const aliases = args.domain ? [args.domain.name] : undefined;
|
|
102
|
+
const viewerCertificate = args.domain
|
|
103
|
+
? {
|
|
104
|
+
acmCertificateArn: args.domain.certificateArn,
|
|
105
|
+
sslSupportMethod: "sni-only",
|
|
106
|
+
minimumProtocolVersion: "TLSv1.2_2021",
|
|
107
|
+
}
|
|
108
|
+
: {
|
|
109
|
+
cloudfrontDefaultCertificate: true,
|
|
110
|
+
};
|
|
111
|
+
// Fresh resource ID `${name}MediaDistribution` (parallel to
|
|
112
|
+
// `${name}ApiDistribution` in cdn-api.ts) — same blue/green rationale.
|
|
113
|
+
const distribution = new aws.cloudfront.Distribution(`${name}MediaDistribution`, {
|
|
114
|
+
enabled: true,
|
|
115
|
+
comment: $interpolate `Headroom CMS Media - ${$app.stage}`,
|
|
116
|
+
httpVersion: "http2and3",
|
|
117
|
+
priceClass,
|
|
118
|
+
aliases,
|
|
119
|
+
origins: [
|
|
120
|
+
{
|
|
121
|
+
originId: "media-s3",
|
|
122
|
+
domainName: s3RegionalDomain,
|
|
123
|
+
originAccessControlId: mediaOAC.id,
|
|
124
|
+
s3OriginConfig: {
|
|
125
|
+
originAccessIdentity: "",
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
originId: "image-lambda",
|
|
130
|
+
domainName: imageLambdaDomain,
|
|
131
|
+
originAccessControlId: imageOAC.id,
|
|
132
|
+
customOriginConfig: {
|
|
133
|
+
httpPort: 80,
|
|
134
|
+
httpsPort: 443,
|
|
135
|
+
originProtocolPolicy: "https-only",
|
|
136
|
+
originSslProtocols: ["TLSv1.2"],
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
// Default behavior: target media-s3 with mediaCachePolicy and NO
|
|
141
|
+
// viewer-request rewrite. Anything not under /media/* or /img/* hits
|
|
142
|
+
// S3 with the original URI and returns 403 AccessDenied — defense in
|
|
143
|
+
// depth so a typo can't accidentally rewrite to a real S3 key.
|
|
144
|
+
defaultCacheBehavior: {
|
|
145
|
+
targetOriginId: "media-s3",
|
|
146
|
+
viewerProtocolPolicy: "redirect-to-https",
|
|
147
|
+
allowedMethods: ["GET", "HEAD", "OPTIONS"],
|
|
148
|
+
cachedMethods: ["GET", "HEAD", "OPTIONS"],
|
|
149
|
+
compress: true,
|
|
150
|
+
cachePolicyId: mediaCachePolicy.id,
|
|
151
|
+
},
|
|
152
|
+
orderedCacheBehaviors: [
|
|
153
|
+
// Media originals: served directly from S3 via OAC. Explicit (not
|
|
154
|
+
// implicit-via-default) so the rewrite never runs on unrelated paths.
|
|
155
|
+
{
|
|
156
|
+
pathPattern: "/media/*",
|
|
157
|
+
targetOriginId: "media-s3",
|
|
158
|
+
viewerProtocolPolicy: "redirect-to-https",
|
|
159
|
+
allowedMethods: ["GET", "HEAD", "OPTIONS"],
|
|
160
|
+
cachedMethods: ["GET", "HEAD", "OPTIONS"],
|
|
161
|
+
compress: true,
|
|
162
|
+
cachePolicyId: mediaCachePolicy.id,
|
|
163
|
+
functionAssociations: [
|
|
164
|
+
{
|
|
165
|
+
eventType: "viewer-request",
|
|
166
|
+
functionArn: mediaRewriteFunction.arn,
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
},
|
|
170
|
+
// Image transforms: served via Sharp Lambda
|
|
171
|
+
{
|
|
172
|
+
pathPattern: "/img/*",
|
|
173
|
+
targetOriginId: "image-lambda",
|
|
174
|
+
viewerProtocolPolicy: "redirect-to-https",
|
|
175
|
+
allowedMethods: ["GET", "HEAD", "OPTIONS"],
|
|
176
|
+
cachedMethods: ["GET", "HEAD", "OPTIONS"],
|
|
177
|
+
compress: true,
|
|
178
|
+
cachePolicyId: imageCachePolicy.id,
|
|
179
|
+
},
|
|
180
|
+
],
|
|
181
|
+
restrictions: {
|
|
182
|
+
geoRestriction: { restrictionType: "none" },
|
|
183
|
+
},
|
|
184
|
+
viewerCertificate,
|
|
185
|
+
});
|
|
186
|
+
// Allow CloudFront to invoke the image Lambda via OAC.
|
|
187
|
+
// CRITICAL: sourceArn must reference the MEDIA distribution's ARN. Pointing
|
|
188
|
+
// it at the API CDN ARN would silently break image transforms in a way
|
|
189
|
+
// that's hard to spot from logs. (Single most-important consistency point
|
|
190
|
+
// per the design doc.)
|
|
191
|
+
new aws.lambda.Permission(`${name}ImageLambdaCFPermission`, {
|
|
192
|
+
action: "lambda:InvokeFunctionUrl",
|
|
193
|
+
function: image.imageLambda.name,
|
|
194
|
+
principal: "cloudfront.amazonaws.com",
|
|
195
|
+
sourceArn: distribution.arn,
|
|
196
|
+
});
|
|
197
|
+
const url = args.domain
|
|
198
|
+
? $interpolate `https://${args.domain.name}`
|
|
199
|
+
: $interpolate `https://${distribution.domainName}`;
|
|
200
|
+
return { distribution, url };
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=cdn-media.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdn-media.js","sourceRoot":"","sources":["../src/cdn-media.ts"],"names":[],"mappings":"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"}
|
package/dist/image.d.ts
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Sharp-based image transformation Lambda with HMAC-signed URLs.
|
|
5
5
|
* Supports dev mode (Node.js source) and package mode (pre-bundled handler).
|
|
6
|
+
*
|
|
7
|
+
* The signing key is per-site: the Lambda derives it from a master KDF
|
|
8
|
+
* input (HMAC-SHA256(master, site)) so leaking one site's key cannot be
|
|
9
|
+
* used to forge URLs for another site. The OLD master is an opt-in
|
|
10
|
+
* fallback for smooth rotation — the Sharp Lambda accepts either, the Go
|
|
11
|
+
* API only signs with the primary.
|
|
6
12
|
*/
|
|
7
13
|
import type { StorageResources } from "./storage.js";
|
|
8
14
|
export interface ImageArgs {
|
|
@@ -14,7 +20,8 @@ export interface ImageArgs {
|
|
|
14
20
|
};
|
|
15
21
|
}
|
|
16
22
|
export declare function createImage(name: string, args: ImageArgs): {
|
|
17
|
-
|
|
23
|
+
imageSigningMasterSecret: sst.Secret;
|
|
24
|
+
imageSigningMasterSecretOld: sst.Secret;
|
|
18
25
|
imageLambda: sst.aws.Function;
|
|
19
26
|
};
|
|
20
27
|
export type ImageResources = ReturnType<typeof createImage>;
|
package/dist/image.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../src/image.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../src/image.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,MAAM,WAAW,SAAS;IACxB,aAAa,EAAE,gBAAgB,CAAC,eAAe,CAAC,CAAC;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE;QACJ,qEAAqE;QACrE,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS;;;;EA6DxD;AAED,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC"}
|
package/dist/image.js
CHANGED
|
@@ -3,10 +3,20 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Sharp-based image transformation Lambda with HMAC-signed URLs.
|
|
5
5
|
* Supports dev mode (Node.js source) and package mode (pre-bundled handler).
|
|
6
|
+
*
|
|
7
|
+
* The signing key is per-site: the Lambda derives it from a master KDF
|
|
8
|
+
* input (HMAC-SHA256(master, site)) so leaking one site's key cannot be
|
|
9
|
+
* used to forge URLs for another site. The OLD master is an opt-in
|
|
10
|
+
* fallback for smooth rotation — the Sharp Lambda accepts either, the Go
|
|
11
|
+
* API only signs with the primary.
|
|
6
12
|
*/
|
|
7
13
|
import path from "path";
|
|
8
14
|
export function createImage(name, args) {
|
|
9
|
-
const
|
|
15
|
+
const imageSigningMasterSecret = new sst.Secret(`${name}ImageSigningMasterSecret`);
|
|
16
|
+
// Optional fallback master used during rotation. SST treats unset
|
|
17
|
+
// secrets as empty strings, which the Lambda's deriveSiteSecret turns
|
|
18
|
+
// into a null per-site key — disabling the fallback path entirely.
|
|
19
|
+
const imageSigningMasterSecretOld = new sst.Secret(`${name}ImageSigningMasterSecretOld`);
|
|
10
20
|
let imageLambda;
|
|
11
21
|
if (args.dev) {
|
|
12
22
|
imageLambda = new sst.aws.Function(`${name}ImageLambda`, {
|
|
@@ -23,9 +33,14 @@ export function createImage(name, args) {
|
|
|
23
33
|
},
|
|
24
34
|
environment: {
|
|
25
35
|
CONTENT_BUCKET: args.contentBucket.name,
|
|
26
|
-
|
|
36
|
+
IMAGE_SIGNING_MASTER_SECRET: imageSigningMasterSecret.value,
|
|
37
|
+
IMAGE_SIGNING_MASTER_SECRET_OLD: imageSigningMasterSecretOld.value,
|
|
27
38
|
},
|
|
28
|
-
link: [
|
|
39
|
+
link: [
|
|
40
|
+
args.contentBucket,
|
|
41
|
+
imageSigningMasterSecret,
|
|
42
|
+
imageSigningMasterSecretOld,
|
|
43
|
+
],
|
|
29
44
|
});
|
|
30
45
|
}
|
|
31
46
|
else {
|
|
@@ -41,11 +56,16 @@ export function createImage(name, args) {
|
|
|
41
56
|
},
|
|
42
57
|
environment: {
|
|
43
58
|
CONTENT_BUCKET: args.contentBucket.name,
|
|
44
|
-
|
|
59
|
+
IMAGE_SIGNING_MASTER_SECRET: imageSigningMasterSecret.value,
|
|
60
|
+
IMAGE_SIGNING_MASTER_SECRET_OLD: imageSigningMasterSecretOld.value,
|
|
45
61
|
},
|
|
46
|
-
link: [
|
|
62
|
+
link: [
|
|
63
|
+
args.contentBucket,
|
|
64
|
+
imageSigningMasterSecret,
|
|
65
|
+
imageSigningMasterSecretOld,
|
|
66
|
+
],
|
|
47
67
|
});
|
|
48
68
|
}
|
|
49
|
-
return {
|
|
69
|
+
return { imageSigningMasterSecret, imageSigningMasterSecretOld, imageLambda };
|
|
50
70
|
}
|
|
51
71
|
//# sourceMappingURL=image.js.map
|
package/dist/image.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image.js","sourceRoot":"","sources":["../src/image.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"image.js","sourceRoot":"","sources":["../src/image.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,IAAI,MAAM,MAAM,CAAC;AAYxB,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,IAAe;IACvD,MAAM,wBAAwB,GAAG,IAAI,GAAG,CAAC,MAAM,CAC7C,GAAG,IAAI,0BAA0B,CAClC,CAAC;IACF,kEAAkE;IAClE,sEAAsE;IACtE,mEAAmE;IACnE,MAAM,2BAA2B,GAAG,IAAI,GAAG,CAAC,MAAM,CAChD,GAAG,IAAI,6BAA6B,CACrC,CAAC;IAEF,IAAI,WAA6B,CAAC;IAClC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACb,WAAW,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,IAAI,aAAa,EAAE;YACvD,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO;YACzB,OAAO,EAAE,YAAY;YACrB,YAAY,EAAE,OAAO;YACrB,OAAO,EAAE,YAAY;YACrB,MAAM,EAAE,SAAS;YACjB,GAAG,EAAE;gBACH,aAAa,EAAE,KAAK;aACrB;YACD,MAAM,EAAE;gBACN,OAAO,EAAE,CAAC,OAAO,CAAC;aACnB;YACD,WAAW,EAAE;gBACX,cAAc,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI;gBACvC,2BAA2B,EAAE,wBAAwB,CAAC,KAAK;gBAC3D,+BAA+B,EAAE,2BAA2B,CAAC,KAAK;aACnE;YACD,IAAI,EAAE;gBACJ,IAAI,CAAC,aAAa;gBAClB,wBAAwB;gBACxB,2BAA2B;aAC5B;SACF,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,WAAW,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,IAAI,aAAa,EAAE;YACvD,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,qBAAqB,CAAC;YACtD,OAAO,EAAE,eAAe;YACxB,OAAO,EAAE,YAAY;YACrB,YAAY,EAAE,OAAO;YACrB,OAAO,EAAE,YAAY;YACrB,MAAM,EAAE,SAAS;YACjB,GAAG,EAAE;gBACH,aAAa,EAAE,KAAK;aACrB;YACD,WAAW,EAAE;gBACX,cAAc,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI;gBACvC,2BAA2B,EAAE,wBAAwB,CAAC,KAAK;gBAC3D,+BAA+B,EAAE,2BAA2B,CAAC,KAAK;aACnE;YACD,IAAI,EAAE;gBACJ,IAAI,CAAC,aAAa;gBAClB,wBAAwB;gBACxB,2BAA2B;aAC5B;SACF,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,wBAAwB,EAAE,2BAA2B,EAAE,WAAW,EAAE,CAAC;AAChF,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,9 +7,11 @@
|
|
|
7
7
|
export type { StorageResources } from "./storage.js";
|
|
8
8
|
export type { AuthResources } from "./auth.js";
|
|
9
9
|
export type { WebhookResources } from "./webhooks.js";
|
|
10
|
+
export type { BackupResources } from "./backup.js";
|
|
10
11
|
export type { ImageResources } from "./image.js";
|
|
11
12
|
export type { ApiResources } from "./api.js";
|
|
12
|
-
export type {
|
|
13
|
+
export type { ApiCdnResources } from "./cdn-api.js";
|
|
14
|
+
export type { MediaCdnResources } from "./cdn-media.js";
|
|
13
15
|
export type { SchedulerResources } from "./scheduler.js";
|
|
14
16
|
export type { CollaborationResources } from "./collaboration.js";
|
|
15
17
|
export type { AdminSiteResources } from "./admin-site.js";
|
|
@@ -21,7 +23,7 @@ export interface HeadroomCMSArgs {
|
|
|
21
23
|
*/
|
|
22
24
|
senderEmail: string;
|
|
23
25
|
/**
|
|
24
|
-
* Custom domain for the CDN (
|
|
26
|
+
* Custom domain for the API CDN (`/v1/*` and `/health`).
|
|
25
27
|
* If not provided, uses the default CloudFront domain.
|
|
26
28
|
*/
|
|
27
29
|
domain?: {
|
|
@@ -29,6 +31,16 @@ export interface HeadroomCMSArgs {
|
|
|
29
31
|
/** ACM certificate ARN (must be in us-east-1 for CloudFront) */
|
|
30
32
|
certificateArn: string;
|
|
31
33
|
};
|
|
34
|
+
/**
|
|
35
|
+
* Custom domain for the media CDN (S3 + image-Lambda origin, serves
|
|
36
|
+
* `/media/*` and `/img/*`). If not provided, uses the default CloudFront
|
|
37
|
+
* domain. The certificate must be in us-east-1, same as `domain`.
|
|
38
|
+
*/
|
|
39
|
+
mediaDomain?: {
|
|
40
|
+
name: string;
|
|
41
|
+
/** ACM certificate ARN (must be in us-east-1 for CloudFront) */
|
|
42
|
+
certificateArn: string;
|
|
43
|
+
};
|
|
32
44
|
/**
|
|
33
45
|
* Custom domain for the admin UI.
|
|
34
46
|
* If not provided, uses the default CloudFront domain.
|
|
@@ -67,6 +79,8 @@ export interface HeadroomCMSArgs {
|
|
|
67
79
|
apiHandler: string;
|
|
68
80
|
/** Go source path for webhook worker, e.g. "packages/webhook-worker" */
|
|
69
81
|
webhookWorkerHandler: string;
|
|
82
|
+
/** Go source path for backup worker, e.g. "packages/backup-worker" */
|
|
83
|
+
backupWorkerHandler: string;
|
|
70
84
|
/** SST handler for custom message function, e.g. "packages/functions/custom-message.handler" */
|
|
71
85
|
customMessageHandler: string;
|
|
72
86
|
/** SST handler for image Lambda, e.g. "packages/image-lambda/index.handler" */
|
|
@@ -89,7 +103,8 @@ export interface HeadroomCMSArgs {
|
|
|
89
103
|
}
|
|
90
104
|
export declare class HeadroomCMS {
|
|
91
105
|
readonly apiUrl: $util.Output<string>;
|
|
92
|
-
readonly
|
|
106
|
+
readonly apiCdnUrl: $util.Output<string>;
|
|
107
|
+
readonly mediaCdnUrl: $util.Output<string>;
|
|
93
108
|
readonly adminUrl: $util.Output<string>;
|
|
94
109
|
readonly userPoolId: $util.Output<string>;
|
|
95
110
|
readonly userPoolClientId: $util.Output<string>;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -9,9 +9,11 @@ import path from "path";
|
|
|
9
9
|
import { createStorage } from "./storage.js";
|
|
10
10
|
import { createAuth } from "./auth.js";
|
|
11
11
|
import { createWebhooks } from "./webhooks.js";
|
|
12
|
+
import { createBackup } from "./backup.js";
|
|
12
13
|
import { createImage } from "./image.js";
|
|
13
14
|
import { createApi } from "./api.js";
|
|
14
|
-
import {
|
|
15
|
+
import { createApiCdn } from "./cdn-api.js";
|
|
16
|
+
import { createMediaCdn } from "./cdn-media.js";
|
|
15
17
|
import { createScheduler } from "./scheduler.js";
|
|
16
18
|
import { createCollabTable, createCollabHandler } from "./collaboration.js";
|
|
17
19
|
import { createAdminSite } from "./admin-site.js";
|
|
@@ -41,7 +43,8 @@ function resolvePkgRoot() {
|
|
|
41
43
|
}
|
|
42
44
|
export class HeadroomCMS {
|
|
43
45
|
apiUrl;
|
|
44
|
-
|
|
46
|
+
apiCdnUrl;
|
|
47
|
+
mediaCdnUrl;
|
|
45
48
|
adminUrl;
|
|
46
49
|
userPoolId;
|
|
47
50
|
userPoolClientId;
|
|
@@ -61,7 +64,7 @@ export class HeadroomCMS {
|
|
|
61
64
|
? { handler: args.dev.customMessageHandler }
|
|
62
65
|
: undefined,
|
|
63
66
|
});
|
|
64
|
-
// 3. Webhooks (DynamoDB tables,
|
|
67
|
+
// 3. Webhooks (DynamoDB tables, DLQ, worker Lambda)
|
|
65
68
|
const webhooks = createWebhooks(name, {
|
|
66
69
|
sites: storage.sites,
|
|
67
70
|
pkgRoot,
|
|
@@ -69,6 +72,17 @@ export class HeadroomCMS {
|
|
|
69
72
|
? { handler: args.dev.webhookWorkerHandler }
|
|
70
73
|
: undefined,
|
|
71
74
|
});
|
|
75
|
+
// 3b. Backup worker Lambda (export + restore). Needs access to every
|
|
76
|
+
// site-scoped table plus the content + backup buckets. Created after
|
|
77
|
+
// webhooks so it can link the webhooks table for backup payloads.
|
|
78
|
+
const backup = createBackup(name, {
|
|
79
|
+
storage,
|
|
80
|
+
webhooks,
|
|
81
|
+
pkgRoot,
|
|
82
|
+
dev: args.dev
|
|
83
|
+
? { handler: args.dev.backupWorkerHandler }
|
|
84
|
+
: undefined,
|
|
85
|
+
});
|
|
72
86
|
// 4. Image Lambda (Sharp transform with HMAC-signed URLs)
|
|
73
87
|
const image = createImage(name, {
|
|
74
88
|
contentBucket: storage.contentBucket,
|
|
@@ -85,6 +99,7 @@ export class HeadroomCMS {
|
|
|
85
99
|
storage,
|
|
86
100
|
auth,
|
|
87
101
|
webhooks,
|
|
102
|
+
backup,
|
|
88
103
|
image,
|
|
89
104
|
collab: collabTable,
|
|
90
105
|
senderEmail: args.senderEmail,
|
|
@@ -117,20 +132,26 @@ export class HeadroomCMS {
|
|
|
117
132
|
? { handler: args.dev.schedulerHandler }
|
|
118
133
|
: undefined,
|
|
119
134
|
});
|
|
120
|
-
//
|
|
121
|
-
const
|
|
135
|
+
// 8a. API CDN (CloudFront distribution + edge auth, /v1/* and /health)
|
|
136
|
+
const apiCdn = createApiCdn(name, {
|
|
122
137
|
api,
|
|
123
|
-
image,
|
|
124
|
-
contentBucket: storage.contentBucket,
|
|
125
138
|
kvs: storage.kvs,
|
|
126
139
|
priceClass: args.priceClass,
|
|
127
140
|
apiCacheTtl: args.apiCacheTtl,
|
|
128
141
|
domain: args.domain,
|
|
129
142
|
});
|
|
143
|
+
// 8b. Media CDN (CloudFront distribution, /media/* and /img/* only)
|
|
144
|
+
const mediaCdn = createMediaCdn(name, {
|
|
145
|
+
image,
|
|
146
|
+
contentBucket: storage.contentBucket,
|
|
147
|
+
priceClass: args.priceClass,
|
|
148
|
+
domain: args.mediaDomain,
|
|
149
|
+
});
|
|
130
150
|
// 9. Admin UI (static site)
|
|
131
151
|
const admin = createAdminSite(name, {
|
|
132
152
|
api,
|
|
133
|
-
|
|
153
|
+
apiCdn,
|
|
154
|
+
mediaCdn,
|
|
134
155
|
auth,
|
|
135
156
|
collab,
|
|
136
157
|
pkgRoot,
|
|
@@ -142,18 +163,39 @@ export class HeadroomCMS {
|
|
|
142
163
|
});
|
|
143
164
|
// Expose outputs
|
|
144
165
|
this.apiUrl = api.api.url;
|
|
145
|
-
this.
|
|
166
|
+
this.apiCdnUrl = apiCdn.url;
|
|
167
|
+
this.mediaCdnUrl = mediaCdn.url;
|
|
146
168
|
this.adminUrl = admin.url;
|
|
147
169
|
this.userPoolId = auth.userPool.id;
|
|
148
170
|
this.userPoolClientId = auth.userPoolClient.id;
|
|
149
171
|
this.collabWsUrl = collab.wsUrl;
|
|
150
172
|
this.outputs = {
|
|
151
173
|
api: api.api.url,
|
|
152
|
-
|
|
174
|
+
apiCdn: apiCdn.url,
|
|
175
|
+
mediaCdn: mediaCdn.url,
|
|
153
176
|
admin: admin.url,
|
|
154
177
|
userPoolId: auth.userPool.id,
|
|
155
178
|
userPoolClientId: auth.userPoolClient.id,
|
|
156
179
|
collabWs: collab.wsUrl,
|
|
180
|
+
// DynamoDB table names (with Pulumi-generated random suffixes baked
|
|
181
|
+
// in). Exposed so consumers — notably the Phase 6 E2E test harness —
|
|
182
|
+
// can discover real table names rather than guess them from the
|
|
183
|
+
// `<app>-<stage>-<Name>` template (which omits the random suffix).
|
|
184
|
+
// Per CLAUDE.md, `.sst/outputs.json` IS the supported interface for
|
|
185
|
+
// post-deploy discovery.
|
|
186
|
+
sitesTable: storage.sites.name,
|
|
187
|
+
contentTable: storage.content.name,
|
|
188
|
+
draftContentTable: storage.draftContent.name,
|
|
189
|
+
blocksTable: storage.blocks.name,
|
|
190
|
+
mediaTable: storage.media.name,
|
|
191
|
+
collectionsTable: storage.collections.name,
|
|
192
|
+
blockTypesTable: storage.blockTypes.name,
|
|
193
|
+
adminAuditTable: storage.adminAudit.name,
|
|
194
|
+
relationshipsTable: storage.relationships.name,
|
|
195
|
+
siteUsersTable: storage.siteUsers.name,
|
|
196
|
+
webhooksTable: webhooks.webhooks.name,
|
|
197
|
+
contentBucket: storage.contentBucket.name,
|
|
198
|
+
backupBucket: storage.backupBucket.name,
|
|
157
199
|
};
|
|
158
200
|
}
|
|
159
201
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/storage.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export declare function createStorage(name: string): {
|
|
|
16
16
|
relationships: sst.aws.Dynamo;
|
|
17
17
|
siteUsers: sst.aws.Dynamo;
|
|
18
18
|
contentBucket: sst.aws.Bucket;
|
|
19
|
+
backupBucket: sst.aws.Bucket;
|
|
19
20
|
collabStateBucket: sst.aws.Bucket;
|
|
20
21
|
kvs: aws.cloudfront.KeyValueStore;
|
|
21
22
|
internalSecret: sst.Secret;
|
package/dist/storage.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM;;;;;;;;;;;;;;;;EA0MzC;AAED,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC"}
|
package/dist/storage.js
CHANGED
|
@@ -36,14 +36,22 @@ export function createStorage(name) {
|
|
|
36
36
|
fields: {
|
|
37
37
|
pk: "string",
|
|
38
38
|
sk: "string",
|
|
39
|
+
siteHost: "string",
|
|
39
40
|
},
|
|
40
41
|
primaryIndex: { hashKey: "pk", rangeKey: "sk" },
|
|
42
|
+
globalIndexes: {
|
|
43
|
+
bySite: { hashKey: "siteHost", rangeKey: "sk" },
|
|
44
|
+
},
|
|
41
45
|
});
|
|
42
46
|
const blocks = new sst.aws.Dynamo(`${name}Blocks`, {
|
|
43
47
|
fields: {
|
|
44
48
|
pk: "string",
|
|
49
|
+
siteHost: "string",
|
|
45
50
|
},
|
|
46
51
|
primaryIndex: { hashKey: "pk" },
|
|
52
|
+
globalIndexes: {
|
|
53
|
+
bySite: { hashKey: "siteHost", rangeKey: "pk" },
|
|
54
|
+
},
|
|
47
55
|
});
|
|
48
56
|
const media = new sst.aws.Dynamo(`${name}Media`, {
|
|
49
57
|
fields: {
|
|
@@ -85,10 +93,12 @@ export function createStorage(name) {
|
|
|
85
93
|
sk: "string",
|
|
86
94
|
targetPk: "string",
|
|
87
95
|
targetSk: "string",
|
|
96
|
+
siteHost: "string",
|
|
88
97
|
},
|
|
89
98
|
primaryIndex: { hashKey: "pk", rangeKey: "sk" },
|
|
90
99
|
globalIndexes: {
|
|
91
100
|
byTarget: { hashKey: "targetPk", rangeKey: "targetSk" },
|
|
101
|
+
bySite: { hashKey: "siteHost", rangeKey: "sk" },
|
|
92
102
|
},
|
|
93
103
|
});
|
|
94
104
|
const siteUsers = new sst.aws.Dynamo(`${name}SiteUsers`, {
|
|
@@ -96,13 +106,23 @@ export function createStorage(name) {
|
|
|
96
106
|
pk: "string",
|
|
97
107
|
sk: "string",
|
|
98
108
|
userId: "string",
|
|
109
|
+
siteHost: "string",
|
|
99
110
|
},
|
|
100
111
|
primaryIndex: { hashKey: "pk", rangeKey: "sk" },
|
|
101
112
|
globalIndexes: {
|
|
102
113
|
byUserId: { hashKey: "userId", rangeKey: "sk" },
|
|
114
|
+
bySite: { hashKey: "siteHost", rangeKey: "sk" },
|
|
103
115
|
},
|
|
104
116
|
ttl: "expiresAt",
|
|
105
117
|
});
|
|
118
|
+
// Backup bucket: archives of full site exports written by the backup worker.
|
|
119
|
+
// Layout: backups/{host}/{timestamp}.tar.gz + backups/{host}/latest.json.
|
|
120
|
+
// Versioning disabled — archives are immutable by convention (a new timestamp
|
|
121
|
+
// is a new object). No CloudFront origin — admin endpoints serve presigned
|
|
122
|
+
// URLs directly off S3.
|
|
123
|
+
const backupBucket = new sst.aws.Bucket(`${name}BackupBucket`, {
|
|
124
|
+
versioning: false,
|
|
125
|
+
});
|
|
106
126
|
const contentBucket = new sst.aws.Bucket(`${name}ContentBucket`, {
|
|
107
127
|
versioning: true,
|
|
108
128
|
access: "cloudfront",
|
|
@@ -166,6 +186,7 @@ export function createStorage(name) {
|
|
|
166
186
|
relationships,
|
|
167
187
|
siteUsers,
|
|
168
188
|
contentBucket,
|
|
189
|
+
backupBucket,
|
|
169
190
|
collabStateBucket,
|
|
170
191
|
kvs,
|
|
171
192
|
internalSecret,
|
package/dist/storage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,OAAO,EAAE;QAC/C,MAAM,EAAE;YACN,EAAE,EAAE,QAAQ;YACZ,EAAE,EAAE,QAAQ;SACb;QACD,YAAY,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;KAChD,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,SAAS,EAAE;QACnD,MAAM,EAAE;YACN,EAAE,EAAE,QAAQ;YACZ,EAAE,EAAE,QAAQ;YACZ,KAAK,EAAE,QAAQ;YACf,KAAK,EAAE,QAAQ;YACf,aAAa,EAAE,QAAQ;YACvB,eAAe,EAAE,QAAQ;YACzB,OAAO,EAAE,QAAQ;YACjB,cAAc,EAAE,QAAQ;YACxB,cAAc,EAAE,QAAQ;SACzB;QACD,YAAY,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC/C,aAAa,EAAE;YACb,eAAe,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE;YACxD,aAAa,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,eAAe,EAAE;YAC3D,iBAAiB,EAAE,EAAE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,SAAS,EAAE;YACtE,eAAe,EAAE,EAAE,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,gBAAgB,EAAE;SAC3E;KACF,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,cAAc,EAAE;QAC7D,MAAM,EAAE;YACN,EAAE,EAAE,QAAQ;YACZ,EAAE,EAAE,QAAQ;
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
|