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
package/dist/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,IAAI,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
package/dist/backup.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backup Infrastructure
|
|
3
|
+
*
|
|
4
|
+
* A single Go Lambda that handles both backup export and restore import.
|
|
5
|
+
* The API service invokes it synchronously via lambda:InvokeFunction for the
|
|
6
|
+
* "scheduled" entry point this will gain a daily EventBridge cron (Phase 4).
|
|
7
|
+
*
|
|
8
|
+
* The Lambda links every site-scoped table plus the content + backup buckets.
|
|
9
|
+
* Deliberately NOT linked: Collab, collabStateBucket, SchedulerLock,
|
|
10
|
+
* WebhookDeliveries — these are transient / operational and excluded from
|
|
11
|
+
* backup payloads (see steering doc "What's in scope vs. out of scope").
|
|
12
|
+
*/
|
|
13
|
+
import type { StorageResources } from "./storage.js";
|
|
14
|
+
import type { WebhookResources } from "./webhooks.js";
|
|
15
|
+
export interface BackupArgs {
|
|
16
|
+
storage: StorageResources;
|
|
17
|
+
webhooks: WebhookResources;
|
|
18
|
+
pkgRoot: string;
|
|
19
|
+
dev?: {
|
|
20
|
+
/** Go source path, e.g. "packages/backup-worker" */
|
|
21
|
+
handler: string;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export declare function createBackup(name: string, args: BackupArgs): {
|
|
25
|
+
backupWorker: sst.aws.Function;
|
|
26
|
+
backupCron: sst.aws.Cron;
|
|
27
|
+
};
|
|
28
|
+
export type BackupResources = ReturnType<typeof createBackup>;
|
|
29
|
+
//# sourceMappingURL=backup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backup.d.ts","sourceRoot":"","sources":["../src/backup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE;QACJ,oDAAoD;QACpD,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU;;;EAoF1D;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC"}
|
package/dist/backup.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backup Infrastructure
|
|
3
|
+
*
|
|
4
|
+
* A single Go Lambda that handles both backup export and restore import.
|
|
5
|
+
* The API service invokes it synchronously via lambda:InvokeFunction for the
|
|
6
|
+
* "scheduled" entry point this will gain a daily EventBridge cron (Phase 4).
|
|
7
|
+
*
|
|
8
|
+
* The Lambda links every site-scoped table plus the content + backup buckets.
|
|
9
|
+
* Deliberately NOT linked: Collab, collabStateBucket, SchedulerLock,
|
|
10
|
+
* WebhookDeliveries — these are transient / operational and excluded from
|
|
11
|
+
* backup payloads (see steering doc "What's in scope vs. out of scope").
|
|
12
|
+
*/
|
|
13
|
+
import path from "path";
|
|
14
|
+
export function createBackup(name, args) {
|
|
15
|
+
const { storage, webhooks } = args;
|
|
16
|
+
const workerConfig = args.dev
|
|
17
|
+
? {
|
|
18
|
+
handler: args.dev.handler,
|
|
19
|
+
runtime: "go",
|
|
20
|
+
}
|
|
21
|
+
: {
|
|
22
|
+
bundle: path.join(args.pkgRoot, "lambda/backup-worker"),
|
|
23
|
+
handler: "bootstrap",
|
|
24
|
+
runtime: "provided.al2023",
|
|
25
|
+
architecture: "arm64",
|
|
26
|
+
};
|
|
27
|
+
const backupWorker = new sst.aws.Function(`${name}BackupWorker`, {
|
|
28
|
+
...workerConfig,
|
|
29
|
+
// 15-minute Lambda budget. Large sites with many media files may bump up
|
|
30
|
+
// against this; see Deferred "Step Functions for very large sites" for
|
|
31
|
+
// the escape hatch.
|
|
32
|
+
timeout: "15 minutes",
|
|
33
|
+
// Higher than default — the worker holds tar/gzip pipes, an in-memory
|
|
34
|
+
// 25-row BatchWriteItem buffer, and parallel S3 GetObject buffers.
|
|
35
|
+
memory: "1024 MB",
|
|
36
|
+
environment: {
|
|
37
|
+
SITES_TABLE: storage.sites.name,
|
|
38
|
+
CONTENT_TABLE: storage.content.name,
|
|
39
|
+
DRAFT_CONTENT_TABLE: storage.draftContent.name,
|
|
40
|
+
BLOCKS_TABLE: storage.blocks.name,
|
|
41
|
+
MEDIA_TABLE: storage.media.name,
|
|
42
|
+
COLLECTIONS_TABLE: storage.collections.name,
|
|
43
|
+
BLOCK_TYPES_TABLE: storage.blockTypes.name,
|
|
44
|
+
ADMIN_AUDIT_TABLE: storage.adminAudit.name,
|
|
45
|
+
RELATIONSHIPS_TABLE: storage.relationships.name,
|
|
46
|
+
SITE_USERS_TABLE: storage.siteUsers.name,
|
|
47
|
+
WEBHOOKS_TABLE: webhooks.webhooks.name,
|
|
48
|
+
CONTENT_BUCKET: storage.contentBucket.name,
|
|
49
|
+
BACKUP_BUCKET: storage.backupBucket.name,
|
|
50
|
+
KVS_ARN: storage.kvs.arn,
|
|
51
|
+
AWS_REGION_NAME: aws.getRegionOutput().name,
|
|
52
|
+
},
|
|
53
|
+
link: [
|
|
54
|
+
storage.sites,
|
|
55
|
+
storage.content,
|
|
56
|
+
storage.draftContent,
|
|
57
|
+
storage.blocks,
|
|
58
|
+
storage.media,
|
|
59
|
+
storage.collections,
|
|
60
|
+
storage.blockTypes,
|
|
61
|
+
storage.adminAudit,
|
|
62
|
+
storage.relationships,
|
|
63
|
+
storage.siteUsers,
|
|
64
|
+
webhooks.webhooks,
|
|
65
|
+
storage.contentBucket,
|
|
66
|
+
storage.backupBucket,
|
|
67
|
+
],
|
|
68
|
+
permissions: [
|
|
69
|
+
{
|
|
70
|
+
// CloudFront KVS resync on restore: re-publish API key hashes so the
|
|
71
|
+
// edge function recognizes them. Fail-loud per steering §2.1 step 18.
|
|
72
|
+
actions: [
|
|
73
|
+
"cloudfront-keyvaluestore:DescribeKeyValueStore",
|
|
74
|
+
"cloudfront-keyvaluestore:PutKey",
|
|
75
|
+
"cloudfront-keyvaluestore:DeleteKey",
|
|
76
|
+
"cloudfront-keyvaluestore:GetKey",
|
|
77
|
+
],
|
|
78
|
+
resources: [storage.kvs.arn],
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
});
|
|
82
|
+
// Phase 4 — daily EventBridge cron that invokes the worker with a
|
|
83
|
+
// "scheduled" event. The handler scans the Sites table, runs backup +
|
|
84
|
+
// retention cleanup for every site with backupSchedule.enabled. 02:00
|
|
85
|
+
// UTC is a low-traffic window for most public sites; tune in the
|
|
86
|
+
// steering doc if needed. Cost is one Lambda invocation per day per
|
|
87
|
+
// stack, regardless of site count.
|
|
88
|
+
const backupCron = new sst.aws.Cron(`${name}BackupSchedule`, {
|
|
89
|
+
schedule: "cron(0 2 * * ? *)",
|
|
90
|
+
function: backupWorker.arn,
|
|
91
|
+
event: { type: "scheduled" },
|
|
92
|
+
});
|
|
93
|
+
return { backupWorker, backupCron };
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=backup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backup.js","sourceRoot":"","sources":["../src/backup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,IAAI,MAAM,MAAM,CAAC;AAcxB,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,IAAgB;IACzD,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IAEnC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG;QAC3B,CAAC,CAAC;YACE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO;YACzB,OAAO,EAAE,IAAa;SACvB;QACH,CAAC,CAAC;YACE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,sBAAsB,CAAC;YACvD,OAAO,EAAE,WAAW;YACpB,OAAO,EAAE,iBAA0B;YACnC,YAAY,EAAE,OAAgB;SAC/B,CAAC;IAEN,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,IAAI,cAAc,EAAE;QAC/D,GAAG,YAAY;QACf,yEAAyE;QACzE,uEAAuE;QACvE,oBAAoB;QACpB,OAAO,EAAE,YAAY;QACrB,sEAAsE;QACtE,mEAAmE;QACnE,MAAM,EAAE,SAAS;QACjB,WAAW,EAAE;YACX,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI;YAC/B,aAAa,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI;YACnC,mBAAmB,EAAE,OAAO,CAAC,YAAY,CAAC,IAAI;YAC9C,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI;YACjC,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI;YAC/B,iBAAiB,EAAE,OAAO,CAAC,WAAW,CAAC,IAAI;YAC3C,iBAAiB,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI;YAC1C,iBAAiB,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI;YAC1C,mBAAmB,EAAE,OAAO,CAAC,aAAa,CAAC,IAAI;YAC/C,gBAAgB,EAAE,OAAO,CAAC,SAAS,CAAC,IAAI;YACxC,cAAc,EAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI;YACtC,cAAc,EAAE,OAAO,CAAC,aAAa,CAAC,IAAI;YAC1C,aAAa,EAAE,OAAO,CAAC,YAAY,CAAC,IAAI;YACxC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG;YACxB,eAAe,EAAE,GAAG,CAAC,eAAe,EAAE,CAAC,IAAI;SAC5C;QACD,IAAI,EAAE;YACJ,OAAO,CAAC,KAAK;YACb,OAAO,CAAC,OAAO;YACf,OAAO,CAAC,YAAY;YACpB,OAAO,CAAC,MAAM;YACd,OAAO,CAAC,KAAK;YACb,OAAO,CAAC,WAAW;YACnB,OAAO,CAAC,UAAU;YAClB,OAAO,CAAC,UAAU;YAClB,OAAO,CAAC,aAAa;YACrB,OAAO,CAAC,SAAS;YACjB,QAAQ,CAAC,QAAQ;YACjB,OAAO,CAAC,aAAa;YACrB,OAAO,CAAC,YAAY;SACrB;QACD,WAAW,EAAE;YACX;gBACE,qEAAqE;gBACrE,sEAAsE;gBACtE,OAAO,EAAE;oBACP,gDAAgD;oBAChD,iCAAiC;oBACjC,oCAAoC;oBACpC,iCAAiC;iBAClC;gBACD,SAAS,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;aAC7B;SACF;KACF,CAAC,CAAC;IAEH,kEAAkE;IAClE,sEAAsE;IACtE,sEAAsE;IACtE,iEAAiE;IACjE,oEAAoE;IACpE,mCAAmC;IACnC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,gBAAgB,EAAE;QAC3D,QAAQ,EAAE,mBAAmB;QAC7B,QAAQ,EAAE,YAAY,CAAC,GAAG;QAC1B,KAAK,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;KAC7B,CAAC,CAAC;IAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API CDN Infrastructure
|
|
3
|
+
*
|
|
4
|
+
* CloudFront distribution for the Headroom API only — `/v1/*` and `/health`.
|
|
5
|
+
* Edge-auth function + KVS association live here. No `/media/*` or `/img/*`
|
|
6
|
+
* behaviors; those are served by the separate media CDN (see cdn-media.ts).
|
|
7
|
+
*/
|
|
8
|
+
import type { StorageResources } from "./storage.js";
|
|
9
|
+
import type { ApiResources } from "./api.js";
|
|
10
|
+
export interface ApiCdnArgs {
|
|
11
|
+
api: ApiResources;
|
|
12
|
+
kvs: StorageResources["kvs"];
|
|
13
|
+
priceClass?: "PriceClass_100" | "PriceClass_200" | "PriceClass_All";
|
|
14
|
+
apiCacheTtl?: number;
|
|
15
|
+
domain?: {
|
|
16
|
+
name: string;
|
|
17
|
+
certificateArn: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export declare function createApiCdn(name: string, args: ApiCdnArgs): {
|
|
21
|
+
distribution: aws.cloudfront.Distribution;
|
|
22
|
+
url: PulumiOutput<string>;
|
|
23
|
+
};
|
|
24
|
+
export type ApiCdnResources = ReturnType<typeof createApiCdn>;
|
|
25
|
+
//# sourceMappingURL=cdn-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdn-api.d.ts","sourceRoot":"","sources":["../src/cdn-api.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,YAAY,CAAC;IAClB,GAAG,EAAE,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAC7B,UAAU,CAAC,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU;;;EAkb1D;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CDN Infrastructure
|
|
2
|
+
* API CDN Infrastructure
|
|
3
3
|
*
|
|
4
|
-
* CloudFront distribution
|
|
5
|
-
*
|
|
4
|
+
* CloudFront distribution for the Headroom API only — `/v1/*` and `/health`.
|
|
5
|
+
* Edge-auth function + KVS association live here. No `/media/*` or `/img/*`
|
|
6
|
+
* behaviors; those are served by the separate media CDN (see cdn-media.ts).
|
|
6
7
|
*/
|
|
7
|
-
export function
|
|
8
|
-
const { api,
|
|
8
|
+
export function createApiCdn(name, args) {
|
|
9
|
+
const { api, kvs } = args;
|
|
9
10
|
const apiCacheTtl = args.apiCacheTtl ?? 3600;
|
|
10
11
|
// Extract KVS UUID from ARN (cf.kvs() needs the UUID, not the name)
|
|
11
12
|
const kvsUuid = kvs.arn.apply((arn) => arn.split("/").pop());
|
|
@@ -87,32 +88,6 @@ export function createCdn(name, args) {
|
|
|
87
88
|
return request;
|
|
88
89
|
}
|
|
89
90
|
`,
|
|
90
|
-
});
|
|
91
|
-
// =========================================================================
|
|
92
|
-
// CloudFront Function: Media Rewrite
|
|
93
|
-
// =========================================================================
|
|
94
|
-
const mediaRewriteFunction = new aws.cloudfront.Function(`${name}MediaRewrite`, {
|
|
95
|
-
name: $interpolate `${$app.name}-${$app.stage}-media-rewrite`,
|
|
96
|
-
runtime: "cloudfront-js-2.0",
|
|
97
|
-
publish: true,
|
|
98
|
-
code: `
|
|
99
|
-
function handler(event) {
|
|
100
|
-
var request = event.request;
|
|
101
|
-
var uri = request.uri;
|
|
102
|
-
|
|
103
|
-
// Rewrite /media/{site}/{mediaId}/{file} → /sites/{site}/media/{mediaId}/{file}
|
|
104
|
-
var parts = uri.split('/');
|
|
105
|
-
// parts: ['', 'media', '{site}', '{mediaId}', '{file}']
|
|
106
|
-
if (parts.length >= 5 && parts[1] === 'media') {
|
|
107
|
-
var site = parts[2];
|
|
108
|
-
var mediaId = parts[3];
|
|
109
|
-
var rest = parts.slice(4).join('/');
|
|
110
|
-
request.uri = '/sites/' + site + '/media/' + mediaId + '/' + rest;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return request;
|
|
114
|
-
}
|
|
115
|
-
`,
|
|
116
91
|
});
|
|
117
92
|
// =========================================================================
|
|
118
93
|
// Cache Policies
|
|
@@ -144,53 +119,14 @@ export function createCdn(name, args) {
|
|
|
144
119
|
enableAcceptEncodingGzip: true,
|
|
145
120
|
},
|
|
146
121
|
});
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
headersConfig: { headerBehavior: "none" },
|
|
156
|
-
queryStringsConfig: {
|
|
157
|
-
queryStringBehavior: "whitelist",
|
|
158
|
-
queryStrings: {
|
|
159
|
-
items: ["w", "h", "fit", "format", "q", "sig"],
|
|
160
|
-
},
|
|
161
|
-
},
|
|
162
|
-
enableAcceptEncodingBrotli: true,
|
|
163
|
-
enableAcceptEncodingGzip: true,
|
|
164
|
-
},
|
|
165
|
-
});
|
|
166
|
-
const mediaCachePolicy = new aws.cloudfront.CachePolicy(`${name}MediaCachePolicy`, {
|
|
167
|
-
name: $interpolate `${$app.name}-${$app.stage}-media-cache`,
|
|
168
|
-
comment: "Cache policy for original media files (immutable)",
|
|
169
|
-
defaultTtl: 31536000,
|
|
170
|
-
maxTtl: 31536000,
|
|
171
|
-
minTtl: 31536000,
|
|
172
|
-
parametersInCacheKeyAndForwardedToOrigin: {
|
|
173
|
-
cookiesConfig: { cookieBehavior: "none" },
|
|
174
|
-
headersConfig: { headerBehavior: "none" },
|
|
175
|
-
queryStringsConfig: { queryStringBehavior: "none" },
|
|
176
|
-
enableAcceptEncodingBrotli: true,
|
|
177
|
-
enableAcceptEncodingGzip: true,
|
|
178
|
-
},
|
|
179
|
-
});
|
|
180
|
-
const versionCachePolicy = new aws.cloudfront.CachePolicy(`${name}VersionCachePolicy`, {
|
|
181
|
-
name: $interpolate `${$app.name}-${$app.stage}-version-cache`,
|
|
182
|
-
comment: "Short-TTL cache for /version to absorb client polling",
|
|
183
|
-
minTtl: 0,
|
|
184
|
-
defaultTtl: 2,
|
|
185
|
-
maxTtl: 2,
|
|
186
|
-
parametersInCacheKeyAndForwardedToOrigin: {
|
|
187
|
-
cookiesConfig: { cookieBehavior: "none" },
|
|
188
|
-
headersConfig: { headerBehavior: "none" },
|
|
189
|
-
queryStringsConfig: { queryStringBehavior: "none" },
|
|
190
|
-
enableAcceptEncodingBrotli: true,
|
|
191
|
-
enableAcceptEncodingGzip: true,
|
|
192
|
-
},
|
|
193
|
-
});
|
|
122
|
+
// NOTE: the old `versionCachePolicy` (custom 2-second TTL) was deleted
|
|
123
|
+
// when /version began returning the per-site image signing secret.
|
|
124
|
+
// CloudFront custom cache policies do not honor `Cache-Control: private`
|
|
125
|
+
// from the origin — the explicit TTLs would win and the response (with
|
|
126
|
+
// the secret) would be edge-cached for 2s. We now use the AWS-managed
|
|
127
|
+
// `CachingDisabled` policy below for /v1/*/version, so the origin's
|
|
128
|
+
// `Cache-Control: private, max-age=2` is what reaches the browser
|
|
129
|
+
// (short-window in-browser cache) while the edge bypasses caching.
|
|
194
130
|
// =========================================================================
|
|
195
131
|
// Origin Request Policy
|
|
196
132
|
// =========================================================================
|
|
@@ -225,34 +161,12 @@ export function createCdn(name, args) {
|
|
|
225
161
|
// authenticated behaviors below.
|
|
226
162
|
const cachingDisabledPolicyId = "4135ea2d-6df8-44a3-9df3-4b5a84be39ad";
|
|
227
163
|
// =========================================================================
|
|
228
|
-
// Origin Access Controls (OAC)
|
|
229
|
-
// =========================================================================
|
|
230
|
-
const mediaOAC = new aws.cloudfront.OriginAccessControl(`${name}MediaOAC`, {
|
|
231
|
-
name: $interpolate `${$app.name}-${$app.stage}-media-oac`,
|
|
232
|
-
description: "OAC for S3 media origin",
|
|
233
|
-
originAccessControlOriginType: "s3",
|
|
234
|
-
signingBehavior: "always",
|
|
235
|
-
signingProtocol: "sigv4",
|
|
236
|
-
});
|
|
237
|
-
const imageOAC = new aws.cloudfront.OriginAccessControl(`${name}ImageOAC`, {
|
|
238
|
-
name: $interpolate `${$app.name}-${$app.stage}-image-oac`,
|
|
239
|
-
description: "OAC for image transform Lambda origin",
|
|
240
|
-
originAccessControlOriginType: "lambda",
|
|
241
|
-
signingBehavior: "always",
|
|
242
|
-
signingProtocol: "sigv4",
|
|
243
|
-
});
|
|
244
|
-
// =========================================================================
|
|
245
164
|
// CloudFront Distribution
|
|
246
165
|
// =========================================================================
|
|
247
166
|
const originDomain = api.api.url.apply((url) => {
|
|
248
167
|
const parsed = new URL(url);
|
|
249
168
|
return parsed.hostname;
|
|
250
169
|
});
|
|
251
|
-
const imageLambdaDomain = image.imageLambda.url.apply((url) => {
|
|
252
|
-
const parsed = new URL(url);
|
|
253
|
-
return parsed.hostname;
|
|
254
|
-
});
|
|
255
|
-
const s3RegionalDomain = $interpolate `${contentBucket.name}.s3.${aws.getRegionOutput().name}.amazonaws.com`;
|
|
256
170
|
const priceClass = args.priceClass ?? "PriceClass_100";
|
|
257
171
|
// Build aliases and certificate config for custom domain
|
|
258
172
|
const aliases = args.domain ? [args.domain.name] : undefined;
|
|
@@ -282,25 +196,6 @@ export function createCdn(name, args) {
|
|
|
282
196
|
originSslProtocols: ["TLSv1.2"],
|
|
283
197
|
},
|
|
284
198
|
},
|
|
285
|
-
{
|
|
286
|
-
originId: "media-s3",
|
|
287
|
-
domainName: s3RegionalDomain,
|
|
288
|
-
originAccessControlId: mediaOAC.id,
|
|
289
|
-
s3OriginConfig: {
|
|
290
|
-
originAccessIdentity: "",
|
|
291
|
-
},
|
|
292
|
-
},
|
|
293
|
-
{
|
|
294
|
-
originId: "image-lambda",
|
|
295
|
-
domainName: imageLambdaDomain,
|
|
296
|
-
originAccessControlId: imageOAC.id,
|
|
297
|
-
customOriginConfig: {
|
|
298
|
-
httpPort: 80,
|
|
299
|
-
httpsPort: 443,
|
|
300
|
-
originProtocolPolicy: "https-only",
|
|
301
|
-
originSslProtocols: ["TLSv1.2"],
|
|
302
|
-
},
|
|
303
|
-
},
|
|
304
199
|
],
|
|
305
200
|
defaultCacheBehavior: {
|
|
306
201
|
targetOriginId: "api",
|
|
@@ -375,10 +270,17 @@ export function createCdn(name, args) {
|
|
|
375
270
|
},
|
|
376
271
|
],
|
|
377
272
|
},
|
|
378
|
-
// Version endpoint:
|
|
379
|
-
//
|
|
380
|
-
//
|
|
381
|
-
//
|
|
273
|
+
// Version endpoint: caching DISABLED at the edge. /version now
|
|
274
|
+
// carries a per-site image signing secret in the body, so the
|
|
275
|
+
// shared edge cache must not hold it. The origin sets
|
|
276
|
+
// `Cache-Control: private, max-age=2` so browsers may still cache
|
|
277
|
+
// for the 2-second window — that absorbs single-flight contention
|
|
278
|
+
// from the same client without exposing the secret to any other
|
|
279
|
+
// viewer.
|
|
280
|
+
//
|
|
281
|
+
// Tradeoff: origin Lambda invocations on /version are now one per
|
|
282
|
+
// client poll instead of one per 2-second edge window. The SDK
|
|
283
|
+
// polls every 10s by default, so the impact is bounded.
|
|
382
284
|
//
|
|
383
285
|
// NOTE: pathPattern "/v1/*/version" matches exact "/version" only.
|
|
384
286
|
// CloudFront's `*` wildcard does not span path segments, so any
|
|
@@ -390,7 +292,7 @@ export function createCdn(name, args) {
|
|
|
390
292
|
allowedMethods: ["GET", "HEAD", "OPTIONS"],
|
|
391
293
|
cachedMethods: ["GET", "HEAD", "OPTIONS"],
|
|
392
294
|
compress: true,
|
|
393
|
-
cachePolicyId:
|
|
295
|
+
cachePolicyId: cachingDisabledPolicyId,
|
|
394
296
|
originRequestPolicyId: originRequestPolicy.id,
|
|
395
297
|
functionAssociations: [
|
|
396
298
|
{
|
|
@@ -484,32 +386,6 @@ export function createCdn(name, args) {
|
|
|
484
386
|
},
|
|
485
387
|
],
|
|
486
388
|
},
|
|
487
|
-
// Media originals: served directly from S3 via OAC
|
|
488
|
-
{
|
|
489
|
-
pathPattern: "/media/*",
|
|
490
|
-
targetOriginId: "media-s3",
|
|
491
|
-
viewerProtocolPolicy: "redirect-to-https",
|
|
492
|
-
allowedMethods: ["GET", "HEAD", "OPTIONS"],
|
|
493
|
-
cachedMethods: ["GET", "HEAD", "OPTIONS"],
|
|
494
|
-
compress: true,
|
|
495
|
-
cachePolicyId: mediaCachePolicy.id,
|
|
496
|
-
functionAssociations: [
|
|
497
|
-
{
|
|
498
|
-
eventType: "viewer-request",
|
|
499
|
-
functionArn: mediaRewriteFunction.arn,
|
|
500
|
-
},
|
|
501
|
-
],
|
|
502
|
-
},
|
|
503
|
-
// Image transforms: served via Sharp Lambda
|
|
504
|
-
{
|
|
505
|
-
pathPattern: "/img/*",
|
|
506
|
-
targetOriginId: "image-lambda",
|
|
507
|
-
viewerProtocolPolicy: "redirect-to-https",
|
|
508
|
-
allowedMethods: ["GET", "HEAD", "OPTIONS"],
|
|
509
|
-
cachedMethods: ["GET", "HEAD", "OPTIONS"],
|
|
510
|
-
compress: true,
|
|
511
|
-
cachePolicyId: imageCachePolicy.id,
|
|
512
|
-
},
|
|
513
389
|
// Health endpoint: no caching, no auth
|
|
514
390
|
{
|
|
515
391
|
pathPattern: "/health",
|
|
@@ -527,16 +403,9 @@ export function createCdn(name, args) {
|
|
|
527
403
|
},
|
|
528
404
|
viewerCertificate,
|
|
529
405
|
});
|
|
530
|
-
// Allow CloudFront to invoke the image Lambda via OAC
|
|
531
|
-
new aws.lambda.Permission(`${name}ImageLambdaCFPermission`, {
|
|
532
|
-
action: "lambda:InvokeFunctionUrl",
|
|
533
|
-
function: image.imageLambda.name,
|
|
534
|
-
principal: "cloudfront.amazonaws.com",
|
|
535
|
-
sourceArn: distribution.arn,
|
|
536
|
-
});
|
|
537
406
|
const url = args.domain
|
|
538
407
|
? $interpolate `https://${args.domain.name}`
|
|
539
408
|
: $interpolate `https://${distribution.domainName}`;
|
|
540
409
|
return { distribution, url };
|
|
541
410
|
}
|
|
542
|
-
//# sourceMappingURL=cdn.js.map
|
|
411
|
+
//# sourceMappingURL=cdn-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdn-api.js","sourceRoot":"","sources":["../src/cdn-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
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
|
+
import type { StorageResources } from "./storage.js";
|
|
11
|
+
import type { ImageResources } from "./image.js";
|
|
12
|
+
export interface MediaCdnArgs {
|
|
13
|
+
image: ImageResources;
|
|
14
|
+
contentBucket: StorageResources["contentBucket"];
|
|
15
|
+
priceClass?: "PriceClass_100" | "PriceClass_200" | "PriceClass_All";
|
|
16
|
+
domain?: {
|
|
17
|
+
name: string;
|
|
18
|
+
certificateArn: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export declare function createMediaCdn(name: string, args: MediaCdnArgs): {
|
|
22
|
+
distribution: aws.cloudfront.Distribution;
|
|
23
|
+
url: PulumiOutput<string>;
|
|
24
|
+
};
|
|
25
|
+
export type MediaCdnResources = ReturnType<typeof createMediaCdn>;
|
|
26
|
+
//# sourceMappingURL=cdn-media.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdn-media.d.ts","sourceRoot":"","sources":["../src/cdn-media.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,cAAc,CAAC;IACtB,aAAa,EAAE,gBAAgB,CAAC,eAAe,CAAC,CAAC;IACjD,UAAU,CAAC,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;IACpE,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY;;;EAgO9D;AAED,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC"}
|