@setzkasten-cms/astro-admin 1.4.6 → 1.5.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.
Files changed (166) hide show
  1. package/dist/api-routes/_auth-guard.d.ts +27 -3
  2. package/dist/api-routes/_auth-guard.js +5 -2
  3. package/dist/api-routes/_dev-session-secret.d.ts +8 -0
  4. package/dist/api-routes/_dev-session-secret.js +8 -0
  5. package/dist/api-routes/_github-token.js +1 -1
  6. package/dist/api-routes/_role-resolver.js +6 -3
  7. package/dist/api-routes/_session-secret.d.ts +19 -0
  8. package/dist/api-routes/_session-secret.js +7 -0
  9. package/dist/api-routes/_session-signing.d.ts +45 -0
  10. package/dist/api-routes/_session-signing.js +8 -0
  11. package/dist/api-routes/_webhook-dispatcher.js +4 -4
  12. package/dist/api-routes/asset-proxy.js +1 -1
  13. package/dist/api-routes/auth-callback.js +12 -5
  14. package/dist/api-routes/auth-logout.d.ts +4 -4
  15. package/dist/api-routes/auth-logout.js +8 -2
  16. package/dist/api-routes/auth-session.d.ts +6 -0
  17. package/dist/api-routes/auth-session.js +19 -19
  18. package/dist/api-routes/auth-setzkasten-login.js +14 -7
  19. package/dist/api-routes/catalog-add.js +59 -17
  20. package/dist/api-routes/catalog-export.js +14 -4
  21. package/dist/api-routes/config.d.ts +10 -3
  22. package/dist/api-routes/config.js +26 -4
  23. package/dist/api-routes/deploy-hook.js +8 -8
  24. package/dist/api-routes/editors.d.ts +1 -1
  25. package/dist/api-routes/editors.js +5 -2
  26. package/dist/api-routes/github-proxy.js +30 -8
  27. package/dist/api-routes/global-config.js +6 -3
  28. package/dist/api-routes/history-rollback.js +31 -14
  29. package/dist/api-routes/history-version.js +8 -6
  30. package/dist/api-routes/history.js +5 -2
  31. package/dist/api-routes/icons-local.js +1 -1
  32. package/dist/api-routes/init-add-section.js +113 -47
  33. package/dist/api-routes/init-apply.js +56 -42
  34. package/dist/api-routes/init-migrate.js +43 -36
  35. package/dist/api-routes/init-scan-page.d.ts +1 -1
  36. package/dist/api-routes/init-scan-page.js +59 -13
  37. package/dist/api-routes/init-scan.js +22 -7
  38. package/dist/api-routes/migrate-to-multi.js +5 -2
  39. package/dist/api-routes/pages.js +15 -4
  40. package/dist/api-routes/section-add.js +68 -16
  41. package/dist/api-routes/section-commit-pending.js +70 -22
  42. package/dist/api-routes/section-delete.js +49 -14
  43. package/dist/api-routes/section-duplicate.js +65 -16
  44. package/dist/api-routes/section-prepare-copy.js +15 -2
  45. package/dist/api-routes/section-prepare.js +25 -4
  46. package/dist/api-routes/setup-github-app-bounce.js +15 -1
  47. package/dist/api-routes/setup-github-app-branches.js +9 -6
  48. package/dist/api-routes/setup-github-app-callback.js +24 -1
  49. package/dist/api-routes/setup-github-app-credentials.d.ts +27 -0
  50. package/dist/api-routes/setup-github-app-credentials.js +43 -0
  51. package/dist/api-routes/setup-github-app-installed.js +22 -1
  52. package/dist/api-routes/setup-github-app-repos.js +5 -2
  53. package/dist/api-routes/setup-github-app.d.ts +4 -0
  54. package/dist/api-routes/setup-github-app.js +19 -2
  55. package/dist/api-routes/updater-register.js +7 -1
  56. package/dist/api-routes/webhooks-status.js +5 -2
  57. package/dist/api-routes/webhooks-test.js +9 -8
  58. package/dist/api-routes/webhooks.js +12 -14
  59. package/dist/api-routes/websites-add.js +5 -2
  60. package/dist/api-routes/websites-remove.js +5 -2
  61. package/dist/{chunk-ZQDGGWJP.js → chunk-5KMGSFCZ.js} +2 -2
  62. package/dist/{chunk-Q3N336KR.js → chunk-CDXCYYQR.js} +29 -24
  63. package/dist/{chunk-NKDATSPA.js → chunk-DP6RTINQ.js} +1 -1
  64. package/dist/chunk-KENFINT4.js +76 -0
  65. package/dist/chunk-ONP6BRZO.js +47 -0
  66. package/dist/{chunk-INIWFKQ3.js → chunk-Q5HV47DW.js} +33 -19
  67. package/dist/chunk-QVCW6EF3.js +26 -0
  68. package/dist/{chunk-TD76R3A6.js → chunk-UHI6323G.js} +293 -174
  69. package/dist/{chunk-AM4DZXXM.js → chunk-UJAFZEX2.js} +76 -9
  70. package/package.json +12 -6
  71. package/src/api-routes/__tests__/_session-signing.test.ts +114 -0
  72. package/src/api-routes/__tests__/_session-test-helper.ts +27 -0
  73. package/src/api-routes/__tests__/add-section-helpers.test.ts +59 -25
  74. package/src/api-routes/__tests__/auth-guard.test.ts +46 -7
  75. package/src/api-routes/__tests__/catalog-api.test.ts +14 -6
  76. package/src/api-routes/__tests__/commit-trailers.test.ts +5 -5
  77. package/src/api-routes/__tests__/deferred-operations.test.ts +9 -12
  78. package/src/api-routes/__tests__/deploy-hook.test.ts +3 -8
  79. package/src/api-routes/__tests__/feature-gate.test.ts +1 -1
  80. package/src/api-routes/__tests__/github-cache.test.ts +1 -1
  81. package/src/api-routes/__tests__/github-token.test.ts +1 -1
  82. package/src/api-routes/__tests__/global-config-theme.test.ts +4 -4
  83. package/src/api-routes/__tests__/history-rollback.test.ts +6 -3
  84. package/src/api-routes/__tests__/history.test.ts +9 -6
  85. package/src/api-routes/__tests__/init-scan-page-resolve-config.test.ts +11 -3
  86. package/src/api-routes/__tests__/migrate-to-multi.test.ts +5 -1
  87. package/src/api-routes/__tests__/pages-meta-store.test.ts +10 -5
  88. package/src/api-routes/__tests__/pages.test.ts +7 -2
  89. package/src/api-routes/__tests__/patch-page-file.test.ts +71 -19
  90. package/src/api-routes/__tests__/route-registry.test.ts +11 -18
  91. package/src/api-routes/__tests__/scan-page-helpers.test.ts +13 -10
  92. package/src/api-routes/__tests__/section-management.test.ts +28 -28
  93. package/src/api-routes/__tests__/setup-github-app-callback.test.ts +58 -16
  94. package/src/api-routes/__tests__/setup-github-app-repos.test.ts +4 -5
  95. package/src/api-routes/__tests__/setup-github-app.test.ts +27 -7
  96. package/src/api-routes/__tests__/storage-config-for-request.test.ts +83 -0
  97. package/src/api-routes/__tests__/updater-register.test.ts +230 -0
  98. package/src/api-routes/__tests__/webhook-signing.test.ts +1 -1
  99. package/src/api-routes/__tests__/webhooks.test.ts +19 -7
  100. package/src/api-routes/__tests__/websites-add.test.ts +2 -1
  101. package/src/api-routes/__tests__/websites-remove.test.ts +2 -1
  102. package/src/api-routes/_auth-guard.ts +47 -15
  103. package/src/api-routes/_commit-trailers.ts +3 -2
  104. package/src/api-routes/_dev-session-secret.ts +79 -0
  105. package/src/api-routes/_github-token.ts +1 -1
  106. package/src/api-routes/_pages-meta-store.ts +2 -2
  107. package/src/api-routes/_role-resolver.ts +7 -5
  108. package/src/api-routes/_session-secret.ts +46 -0
  109. package/src/api-routes/_session-signing.ts +135 -0
  110. package/src/api-routes/_vercel-origin.ts +2 -6
  111. package/src/api-routes/_webhook-dispatcher.ts +12 -16
  112. package/src/api-routes/_website-resolver.ts +3 -10
  113. package/src/api-routes/auth-callback.ts +9 -5
  114. package/src/api-routes/auth-login.ts +5 -3
  115. package/src/api-routes/auth-logout.ts +18 -1
  116. package/src/api-routes/auth-session.ts +13 -21
  117. package/src/api-routes/auth-setzkasten-login.ts +12 -9
  118. package/src/api-routes/catalog-add.ts +89 -31
  119. package/src/api-routes/catalog-export.ts +30 -10
  120. package/src/api-routes/config.ts +39 -6
  121. package/src/api-routes/deploy-hook.ts +13 -11
  122. package/src/api-routes/editors.ts +33 -22
  123. package/src/api-routes/github-proxy.ts +25 -11
  124. package/src/api-routes/global-config.ts +103 -18
  125. package/src/api-routes/history-rollback.ts +41 -14
  126. package/src/api-routes/history-version.ts +5 -6
  127. package/src/api-routes/history.ts +3 -3
  128. package/src/api-routes/icons-local.ts +2 -2
  129. package/src/api-routes/init-add-section.ts +174 -79
  130. package/src/api-routes/init-apply.ts +71 -56
  131. package/src/api-routes/init-migrate.ts +54 -48
  132. package/src/api-routes/init-scan-page.ts +77 -30
  133. package/src/api-routes/init-scan.ts +19 -11
  134. package/src/api-routes/pages.ts +16 -11
  135. package/src/api-routes/section-add.ts +98 -27
  136. package/src/api-routes/section-commit-pending.ts +87 -34
  137. package/src/api-routes/section-delete.ts +76 -27
  138. package/src/api-routes/section-duplicate.ts +95 -28
  139. package/src/api-routes/section-management.ts +3 -7
  140. package/src/api-routes/section-prepare-copy.ts +29 -8
  141. package/src/api-routes/section-prepare.ts +38 -10
  142. package/src/api-routes/setup-github-app-bounce.ts +7 -1
  143. package/src/api-routes/setup-github-app-branches.ts +6 -7
  144. package/src/api-routes/setup-github-app-callback.ts +18 -1
  145. package/src/api-routes/setup-github-app-credentials.ts +55 -0
  146. package/src/api-routes/setup-github-app-installed.ts +12 -1
  147. package/src/api-routes/setup-github-app-repos.ts +2 -3
  148. package/src/api-routes/setup-github-app.ts +14 -5
  149. package/src/api-routes/updater-check.ts +6 -4
  150. package/src/api-routes/updater-register.ts +34 -20
  151. package/src/api-routes/updater-transfer.ts +8 -6
  152. package/src/api-routes/updater-unbind.ts +14 -10
  153. package/src/api-routes/webhooks-test.ts +9 -11
  154. package/src/api-routes/webhooks.ts +15 -19
  155. package/src/init/__tests__/page-level.test.ts +279 -105
  156. package/src/init/__tests__/page-list-coverage.test.ts +70 -70
  157. package/src/init/__tests__/patcher-child-component.test.ts +12 -3
  158. package/src/init/__tests__/patcher-edge-cases.test.ts +47 -23
  159. package/src/init/__tests__/patcher-mixed-content-wrapper.test.ts +16 -6
  160. package/src/init/__tests__/patcher-page-mode.test.ts +30 -20
  161. package/src/init/__tests__/section-pipeline.test.ts +53 -19
  162. package/src/init/astro-config-patcher.ts +4 -18
  163. package/src/init/astro-detector.ts +2 -7
  164. package/src/init/astro-section-analyzer-v2.ts +475 -193
  165. package/src/init/field-label-enricher.ts +6 -6
  166. package/src/init/template-patcher-v2.ts +218 -97
@@ -1,3 +1,9 @@
1
+ import {
2
+ resolveSessionSecret
3
+ } from "./chunk-QVCW6EF3.js";
4
+ import {
5
+ verifySessionCookie
6
+ } from "./chunk-KENFINT4.js";
1
7
  import {
2
8
  resolveStorageConfig
3
9
  } from "./chunk-6UIKVKED.js";
@@ -10,17 +16,21 @@ import {
10
16
  } from "./chunk-45ARVNT3.js";
11
17
  import {
12
18
  resolveConfigRepoToken
13
- } from "./chunk-NKDATSPA.js";
19
+ } from "./chunk-DP6RTINQ.js";
14
20
  import {
15
21
  withTrailers
16
22
  } from "./chunk-KH22FJO5.js";
17
23
 
24
+ // src/api-routes/editors.ts
25
+ import { validateEditorsUpdate } from "@setzkasten-cms/core";
26
+
18
27
  // src/api-routes/_auth-guard.ts
19
28
  import { canEditPage } from "@setzkasten-cms/auth";
20
29
  function parseSession(raw) {
21
30
  if (!raw) return null;
22
31
  try {
23
- return JSON.parse(raw);
32
+ const result = verifySessionCookie(raw, resolveSessionSecret());
33
+ return result.ok ? result.value : null;
24
34
  } catch {
25
35
  return null;
26
36
  }
@@ -45,10 +55,9 @@ async function guardPageAccess(session, pageKey, fullConfig, request) {
45
55
  if (!session) return new Response("Unauthorized", { status: 401 });
46
56
  const editorsLookup = await resolveDynamicEditors();
47
57
  if (!editorsLookup.ok) {
48
- return new Response(
49
- `Forbidden: editor permissions unavailable (${editorsLookup.error})`,
50
- { status: 503 }
51
- );
58
+ return new Response(`Forbidden: editor permissions unavailable (${editorsLookup.error})`, {
59
+ status: 503
60
+ });
52
61
  }
53
62
  if (!canEditPage(session, pageKey, editorsLookup.editors)) {
54
63
  return new Response("Forbidden: you do not have access to this page", { status: 403 });
@@ -65,13 +74,15 @@ async function guardWebsiteAccess(session, request) {
65
74
  const website = await resolveCurrentWebsite(request);
66
75
  if (!website.ok) return null;
67
76
  const allowed = website.value.allowedEmails;
68
- if (!allowed || allowed.length === 0) return null;
69
- if (!allowed.includes(session.user.email)) {
77
+ if (!allowed || allowed.length === 0) {
70
78
  return new Response(
71
- `Forbidden: not allowed on website "${website.value.id}"`,
79
+ `Forbidden: website "${website.value.id}" has no editor allow-list \u2014 add the editor's email to allowedEmails or grant admin role`,
72
80
  { status: 403 }
73
81
  );
74
82
  }
83
+ if (!allowed.includes(session.user.email)) {
84
+ return new Response(`Forbidden: not allowed on website "${website.value.id}"`, { status: 403 });
85
+ }
75
86
  return null;
76
87
  }
77
88
  async function resolveDynamicEditors() {
@@ -96,7 +107,6 @@ async function resolveDynamicEditors() {
96
107
  }
97
108
 
98
109
  // src/api-routes/editors.ts
99
- import { validateEditorsUpdate } from "@setzkasten-cms/core";
100
110
  var EDITORS_FILE = (contentPath) => `${contentPath}/_editors.json`;
101
111
  function configRepoStorage() {
102
112
  const storage = resolveStorageConfig();
@@ -138,10 +148,7 @@ var PUT = async ({ request, cookies }) => {
138
148
  }
139
149
  const validation = validateEditorsUpdate(editors, session.user.email);
140
150
  if (!validation.ok) {
141
- return Response.json(
142
- { error: validation.message, code: validation.code },
143
- { status: 400 }
144
- );
151
+ return Response.json({ error: validation.message, code: validation.code }, { status: 400 });
145
152
  }
146
153
  const filePath = EDITORS_FILE(contentPath);
147
154
  const fileContent = JSON.stringify(editors, null, 2);
@@ -158,10 +165,11 @@ var PUT = async ({ request, cookies }) => {
158
165
  branch
159
166
  };
160
167
  if (existing) body.sha = existing;
161
- const res = await fetch(
162
- `https://api.github.com/repos/${owner}/${repo}/contents/${filePath}`,
163
- { method: "PUT", headers, body: JSON.stringify(body) }
164
- );
168
+ const res = await fetch(`https://api.github.com/repos/${owner}/${repo}/contents/${filePath}`, {
169
+ method: "PUT",
170
+ headers,
171
+ body: JSON.stringify(body)
172
+ });
165
173
  if (!res.ok) {
166
174
  const text = await res.text();
167
175
  return Response.json({ error: `GitHub write failed: ${text}` }, { status: 502 });
@@ -187,7 +195,13 @@ async function readEditorsFile(owner, repo, branch, contentPath, token) {
187
195
  return cachedFetch(key, 2 * 6e4, async () => {
188
196
  const res = await fetch(
189
197
  `https://api.github.com/repos/${owner}/${repo}/contents/${EDITORS_FILE(contentPath)}?ref=${branch}`,
190
- { headers: { Authorization: `Bearer ${token}`, Accept: "application/vnd.github+json", "X-GitHub-Api-Version": "2022-11-28" } }
198
+ {
199
+ headers: {
200
+ Authorization: `Bearer ${token}`,
201
+ Accept: "application/vnd.github+json",
202
+ "X-GitHub-Api-Version": "2022-11-28"
203
+ }
204
+ }
191
205
  );
192
206
  if (!res.ok) return null;
193
207
  const data = await res.json();
@@ -0,0 +1,26 @@
1
+ import {
2
+ ensureDevSessionSecret
3
+ } from "./chunk-ONP6BRZO.js";
4
+
5
+ // src/api-routes/_session-secret.ts
6
+ var MIN_SECRET_LENGTH = 32;
7
+ function resolveSessionSecret() {
8
+ const fromEnv = process.env.SETZKASTEN_SESSION_SECRET;
9
+ if (typeof fromEnv === "string" && fromEnv.trim().length >= MIN_SECRET_LENGTH) {
10
+ return fromEnv.trim();
11
+ }
12
+ const fromBuild = globalThis.__SETZKASTEN_BUILD_CONFIG__;
13
+ if (typeof fromBuild?.sessionSecret === "string" && fromBuild.sessionSecret.trim().length >= MIN_SECRET_LENGTH) {
14
+ return fromBuild.sessionSecret.trim();
15
+ }
16
+ if (process.env.NODE_ENV === "production") {
17
+ throw new Error(
18
+ "SETZKASTEN_SESSION_SECRET is missing or too short (need \u226532 chars). Generate one with `openssl rand -hex 32` and set it as an env var."
19
+ );
20
+ }
21
+ return ensureDevSessionSecret();
22
+ }
23
+
24
+ export {
25
+ resolveSessionSecret
26
+ };