@camstack/server 1.2.592 → 1.2.594

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 (256) hide show
  1. package/dist/addon-root-inventory.js +11 -50
  2. package/dist/agent/addon-scan.js +6 -44
  3. package/dist/agent/agent-addon-runtime.js +3 -8
  4. package/dist/agent/agent-addon-updates.js +12 -52
  5. package/dist/agent/agent-cap-dispatch-service.js +3 -5
  6. package/dist/agent/agent-config.js +7 -42
  7. package/dist/agent/agent-deploy-swap.js +5 -41
  8. package/dist/agent/agent-group-runner.js +8 -47
  9. package/dist/agent/agent-http-auth.js +10 -22
  10. package/dist/agent/agent-http.js +69 -115
  11. package/dist/agent/agent-hub-addon-update.js +10 -16
  12. package/dist/agent/agent-hub-registration.js +4 -7
  13. package/dist/agent/agent-infra-capabilities.js +5 -9
  14. package/dist/agent/agent-json-file.js +5 -42
  15. package/dist/agent/agent-mesh-gate.js +5 -8
  16. package/dist/agent/agent-node-certificates.js +25 -28
  17. package/dist/agent/agent-pairing-local.js +10 -47
  18. package/dist/agent/agent-pairing-routes.js +16 -20
  19. package/dist/agent/agent-pairing-store.js +18 -58
  20. package/dist/agent/agent-reconnect.js +1 -4
  21. package/dist/agent/agent-service.js +42 -78
  22. package/dist/agent/agent-sniffing-listener.js +11 -48
  23. package/dist/agent/agent-undeploy.js +5 -41
  24. package/dist/agent/agent-update-routes.js +14 -19
  25. package/dist/agent/agent-update-service.js +38 -80
  26. package/dist/agent/apply-model-distribution.js +1 -4
  27. package/dist/agent/apply-stage-dev-uploads.js +6 -9
  28. package/dist/agent/derive-hub-url.js +3 -8
  29. package/dist/agent/fetch-bundle-from-hub.js +6 -9
  30. package/dist/agent/hubs-found.js +6 -43
  31. package/dist/agent/infra-boot-guard.js +1 -4
  32. package/dist/agent/infra-boot-plan.js +2 -6
  33. package/dist/agent/main.js +158 -186
  34. package/dist/agent/register-agent-cap-dispatch.js +3 -6
  35. package/dist/agent/serial-queue.js +2 -7
  36. package/dist/agent-status-page.js +1 -4
  37. package/dist/api/addon-upload.js +22 -61
  38. package/dist/api/agent-addon-delivery.js +6 -11
  39. package/dist/api/auth-whoami.js +1 -4
  40. package/dist/api/backup-download-pump.js +5 -9
  41. package/dist/api/backup-download.js +7 -10
  42. package/dist/api/core/addon-settings.router.js +16 -19
  43. package/dist/api/core/agent-pairing.router.js +76 -79
  44. package/dist/api/core/agents.router.js +21 -24
  45. package/dist/api/core/auth-admin-tokens.procedures.js +48 -52
  46. package/dist/api/core/auth-device-cert.procedures.js +62 -67
  47. package/dist/api/core/auth-limits.js +16 -25
  48. package/dist/api/core/auth-reauth.procedures.js +32 -37
  49. package/dist/api/core/auth-revoke-credentials.procedures.js +22 -26
  50. package/dist/api/core/auth-sessions.procedures.js +52 -56
  51. package/dist/api/core/auth.router.js +300 -304
  52. package/dist/api/core/cap-providers.js +74 -121
  53. package/dist/api/core/capabilities.router.js +34 -37
  54. package/dist/api/core/capability-preference-writes.js +10 -17
  55. package/dist/api/core/certificates.router.js +106 -109
  56. package/dist/api/core/cluster-nodes.router.js +15 -18
  57. package/dist/api/core/collection-preference.js +2 -6
  58. package/dist/api/core/event-bus-proxy.router.js +34 -37
  59. package/dist/api/core/failure-contributions.js +4 -8
  60. package/dist/api/core/hwaccel.router.js +17 -20
  61. package/dist/api/core/integration-secrets.js +8 -12
  62. package/dist/api/core/lifecycle-job-runner.js +13 -49
  63. package/dist/api/core/live-events.router.js +29 -32
  64. package/dist/api/core/load-contributions.js +4 -8
  65. package/dist/api/core/logging-settings.js +30 -43
  66. package/dist/api/core/logs.router.js +40 -43
  67. package/dist/api/core/notifications.router.js +15 -18
  68. package/dist/api/core/public-event-filter.js +4 -8
  69. package/dist/api/core/repl.router.js +18 -21
  70. package/dist/api/core/request-census-settings.js +11 -16
  71. package/dist/api/core/server-management.provider.js +1 -4
  72. package/dist/api/core/server-name.js +9 -17
  73. package/dist/api/core/site-location.js +16 -24
  74. package/dist/api/core/stream-probe.router.js +21 -24
  75. package/dist/api/core/system-events.router.js +23 -26
  76. package/dist/api/cors/cors-policy.js +20 -29
  77. package/dist/api/cors/register-cors-policy.js +9 -14
  78. package/dist/api/deploy-stage-registry.js +6 -10
  79. package/dist/api/dev-uploads-bundle.js +12 -50
  80. package/dist/api/health/adaptive-probe.routes.js +9 -13
  81. package/dist/api/health/health.routes.js +8 -13
  82. package/dist/api/hub-cluster-url.js +3 -9
  83. package/dist/api/model-distributor.js +12 -50
  84. package/dist/api/oauth2/consent-page.js +10 -13
  85. package/dist/api/oauth2/oauth2-routes.js +17 -25
  86. package/dist/api/oauth2/private-host.js +1 -4
  87. package/dist/api/server-upload-propagate.js +15 -51
  88. package/dist/api/server-upload.js +13 -50
  89. package/dist/api/sse-no-compression.js +1 -4
  90. package/dist/api/static/frame-policy.js +4 -9
  91. package/dist/api/static/precompressed-asset.js +15 -57
  92. package/dist/api/static/spa-mount.js +8 -47
  93. package/dist/api/static/spa-static.js +5 -12
  94. package/dist/api/tarball-manifest.js +7 -44
  95. package/dist/api/trpc/cap-mount-helpers.js +7 -12
  96. package/dist/api/trpc/cap-route-error-formatter.js +10 -13
  97. package/dist/api/trpc/cap-router-runtime.js +40 -51
  98. package/dist/api/trpc/client-ip.js +9 -20
  99. package/dist/api/trpc/core-cap-bridge.js +32 -42
  100. package/dist/api/trpc/device-collection-dispatch.js +23 -27
  101. package/dist/api/trpc/device-config-secret-redaction.js +24 -40
  102. package/dist/api/trpc/generated-cap-mounts.js +219 -221
  103. package/dist/api/trpc/generated-cap-routers.js +4878 -4726
  104. package/dist/api/trpc/http-request-census-hook.js +8 -11
  105. package/dist/api/trpc/http-request-census.js +34 -41
  106. package/dist/api/trpc/http-request-census.singleton.js +4 -8
  107. package/dist/api/trpc/localized-schema-paths.js +1 -4
  108. package/dist/api/trpc/principal-visibility.js +14 -22
  109. package/dist/api/trpc/remote-addon-update-grant.js +1 -4
  110. package/dist/api/trpc/scope-access.js +10 -15
  111. package/dist/api/trpc/server-provided-caps.js +3 -7
  112. package/dist/api/trpc/share-view-access.js +6 -14
  113. package/dist/api/trpc/trpc-error-device-tags.js +3 -6
  114. package/dist/api/trpc/trpc-error-principal.js +2 -6
  115. package/dist/api/trpc/trpc.context.js +20 -25
  116. package/dist/api/trpc/trpc.middleware.js +38 -46
  117. package/dist/api/trpc/trpc.router.js +58 -99
  118. package/dist/api/trpc/user-error.js +5 -8
  119. package/dist/api/trpc/ws-request-census.js +17 -24
  120. package/dist/api/trpc/ws-slow-consumer-guard.js +11 -16
  121. package/dist/api/upload-auth.js +5 -9
  122. package/dist/auth/addon-route-jwt-gate.js +4 -7
  123. package/dist/auth/addon-route-share-gate.js +7 -12
  124. package/dist/auth/app-confirm-page.js +17 -22
  125. package/dist/auth/app-confirm-routes.js +26 -31
  126. package/dist/auth/app-confirmations.js +7 -44
  127. package/dist/auth/app-page-shell.js +17 -30
  128. package/dist/auth/app-page-strings.js +11 -17
  129. package/dist/auth/app-passkey-page.js +16 -21
  130. package/dist/auth/app-passkey-routes.js +37 -41
  131. package/dist/auth/app-refused-route.js +13 -18
  132. package/dist/auth/auth-network-policy.js +11 -15
  133. package/dist/auth/auth-provider-gate.js +4 -9
  134. package/dist/auth/auth-rate-limit.js +3 -7
  135. package/dist/auth/client-address.js +6 -9
  136. package/dist/auth/device-enroll-proofs.js +6 -43
  137. package/dist/auth/external-link-intents.js +3 -7
  138. package/dist/auth/hub-sessions.js +6 -12
  139. package/dist/auth/native-link-completions.js +7 -11
  140. package/dist/auth/native-return.js +9 -13
  141. package/dist/auth/passkey-provider.js +26 -32
  142. package/dist/auth/second-factors.js +6 -10
  143. package/dist/auth/session-connections.js +6 -12
  144. package/dist/auth/session-cookie.js +12 -23
  145. package/dist/auth/session-lifetimes.js +8 -12
  146. package/dist/auth/session-mint.js +4 -11
  147. package/dist/auth/sso-finish-app.js +13 -16
  148. package/dist/auth/sso-finish-deps.js +21 -27
  149. package/dist/auth/sso-finish.js +28 -38
  150. package/dist/auth/sso-routes.js +22 -25
  151. package/dist/auth/used-bridge-ids.js +1 -5
  152. package/dist/boot/boot-config.js +16 -55
  153. package/dist/boot/init-sequence.js +1 -4
  154. package/dist/boot/integration-id-backfill.js +3 -8
  155. package/dist/boot/platform-keychain-key.js +5 -42
  156. package/dist/boot/post-boot.service.js +14 -18
  157. package/dist/boot/reconcile-lifecycle-jobs.js +3 -6
  158. package/dist/boot/retired-public-url-env.js +4 -8
  159. package/dist/bootstrap-packages.js +1 -4
  160. package/dist/closure-node-modules.js +2 -38
  161. package/dist/closure-patches/patch-reach.json +6 -2
  162. package/dist/core/addon/addon-call-gateway.js +1 -5
  163. package/dist/core/addon/addon-package.service.js +83 -123
  164. package/dist/core/addon/addon-process-view.js +2 -6
  165. package/dist/core/addon/addon-realign-plan.js +1 -4
  166. package/dist/core/addon/addon-registry.service.js +254 -197
  167. package/dist/core/addon/addon-row-manifest.js +1 -4
  168. package/dist/core/addon/addon-search.service.js +3 -7
  169. package/dist/core/addon/addon-settings-provider.js +1 -3
  170. package/dist/core/addon/addon-uninstall.js +4 -11
  171. package/dist/core/addon/addon.tokens.js +2 -5
  172. package/dist/core/addon/device-meta-mirror.js +8 -13
  173. package/dist/core/addon/forked-custom-actions.js +6 -11
  174. package/dist/core/addon/integration-visibility.js +3 -6
  175. package/dist/core/addon/materialize-route-path.js +1 -4
  176. package/dist/core/addon/package-dir-utils.js +8 -45
  177. package/dist/core/addon/prune-misplaced-addons.js +5 -43
  178. package/dist/core/addon/runner-convergence.js +1 -4
  179. package/dist/core/addon/runner-serialization.js +1 -4
  180. package/dist/core/addon/runner-spawn-fanout.js +3 -8
  181. package/dist/core/addon/settings-door-wiring.js +5 -8
  182. package/dist/core/addon/single-flight-refresh.js +1 -4
  183. package/dist/core/addon-bridge/addon-bridge.service.js +7 -44
  184. package/dist/core/addon-pages/addon-pages.service.js +3 -40
  185. package/dist/core/addon-widgets/addon-widgets.service.js +4 -42
  186. package/dist/core/agent/agent-addon-backfill.js +9 -17
  187. package/dist/core/agent/agent-delivery-ledger.js +3 -7
  188. package/dist/core/agent/agent-liveness-event.js +2 -6
  189. package/dist/core/agent/agent-pairing-http.js +41 -45
  190. package/dist/core/agent/agent-registry.service.js +53 -92
  191. package/dist/core/agent/cluster-node-history-mirror.js +3 -7
  192. package/dist/core/agent/cluster-node-history-store.js +113 -58
  193. package/dist/core/agent/hub-agent-pairing.js +1 -5
  194. package/dist/core/agent/node-certificates-client.js +3 -6
  195. package/dist/core/agent/node-directory.js +1 -4
  196. package/dist/core/app-links/well-known-app-links.js +2 -6
  197. package/dist/core/auth/auth.service.js +3 -8
  198. package/dist/core/auth/handoff-code.service.js +11 -49
  199. package/dist/core/auth/record-kinds.js +35 -0
  200. package/dist/core/auth/share-token.service.js +174 -122
  201. package/dist/core/capability/capability.service.js +1 -5
  202. package/dist/core/config/config.schema.js +1 -6
  203. package/dist/core/config/config.service.js +2 -6
  204. package/dist/core/events/event-bus.service.js +3 -7
  205. package/dist/core/feature/feature.service.js +2 -6
  206. package/dist/core/lifecycle/lifecycle-runner.singleton.js +5 -10
  207. package/dist/core/lifecycle/lifecycle-state-machine.js +1 -5
  208. package/dist/core/logging/log-ring-buffer.js +1 -5
  209. package/dist/core/logging/logging.service.js +5 -9
  210. package/dist/core/logging/scoped-logger.js +1 -5
  211. package/dist/core/moleculer/agent-readiness-pull.js +1 -4
  212. package/dist/core/moleculer/agent-registration-request.js +3 -7
  213. package/dist/core/moleculer/cap-call-fn.js +39 -5
  214. package/dist/core/moleculer/cap-route-authority.js +3 -8
  215. package/dist/core/moleculer/hub-mesh-guard.js +5 -9
  216. package/dist/core/moleculer/moleculer.service.js +108 -119
  217. package/dist/core/network/network-quality.service.js +2 -6
  218. package/dist/core/notification/notification-wrapper.service.js +3 -7
  219. package/dist/core/notification/toast-wrapper.service.js +3 -7
  220. package/dist/core/provider/provider.tokens.js +1 -4
  221. package/dist/core/repl/repl-engine.service.js +4 -8
  222. package/dist/core/runner-health/runner-boot-check.js +7 -15
  223. package/dist/core/runner-health/update-preflight.js +9 -14
  224. package/dist/core/server-update/server-update.service.js +12 -49
  225. package/dist/core/server-update/system-apply-closure-patches.js +6 -42
  226. package/dist/core/server-update/system-ensure-prebuilds.js +3 -6
  227. package/dist/core/server-update/system-exec-npm.js +2 -5
  228. package/dist/core/storage/fs-storage-backend.js +1 -5
  229. package/dist/core/storage/storage-location-manager.js +1 -5
  230. package/dist/core/storage/storage.service.js +2 -6
  231. package/dist/core/streaming/ffmpeg-stream-info.js +3 -8
  232. package/dist/core/streaming/stream-probe.service.js +12 -16
  233. package/dist/core/streaming/ttl-cache.js +1 -5
  234. package/dist/core/topology/topology-emitter.service.js +19 -23
  235. package/dist/core/update-availability-emitter.js +3 -7
  236. package/dist/core/update-availability-store.js +8 -45
  237. package/dist/core/updates/agent-installed-packages.js +5 -9
  238. package/dist/core/updates/restart-marker.js +3 -8
  239. package/dist/core/updates/update-check-scheduler.js +13 -18
  240. package/dist/core/updates/wrapper-update-checker.js +3 -7
  241. package/dist/first-boot-addon-plan.js +2 -6
  242. package/dist/framework-nodepath.js +2 -38
  243. package/dist/i18n/request-lang.js +7 -11
  244. package/dist/launcher.js +30 -65
  245. package/dist/lifecycle-journal-path.js +2 -38
  246. package/dist/main.js +287 -324
  247. package/dist/manual-boot.js +120 -157
  248. package/dist/node-role.js +1 -4
  249. package/dist/package-inventory.js +7 -48
  250. package/dist/pending-restore.js +7 -43
  251. package/dist/single-copy-cleanup-runner.js +9 -45
  252. package/dist/single-copy-cleanup.js +7 -15
  253. package/dist/sqlite-restore.js +9 -48
  254. package/dist/starter.js +4 -39
  255. package/dist/ui-serving/lazy-ui-serving.js +3 -39
  256. package/package.json +13 -13
@@ -1,9 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.appCancelLink = exports.appHiddenField = exports.appSubmitButton = exports.appErrorLine = exports.appButton = exports.appHint = exports.appParagraph = exports.APP_PAGE_STYLE = exports.APP_PAGE_LOGOS = void 0;
4
- exports.appPageCsp = appPageCsp;
5
- exports.escapeHtml = escapeHtml;
6
- exports.renderAppPage = renderAppPage;
7
1
  /**
8
2
  * The one shell of every standalone page the hub renders for a native app
9
3
  * sign-in (D858): the passkey page, the confirmation page, the refusal pages.
@@ -23,13 +17,13 @@ exports.renderAppPage = renderAppPage;
23
17
  * of the very string that is served, computed at module load - there is no
24
18
  * hand-pasted hash that can fall out of step with the CSS.
25
19
  */
26
- const node_crypto_1 = require("node:crypto");
27
- const tokens_1 = require("@camstack/ui-library/theme/tokens");
20
+ import { createHash } from 'node:crypto';
21
+ import { defaultTheme, themeToRootCss } from '@camstack/ui-library/theme/tokens';
28
22
  /** The brand mark and wordmark, one per colour scheme (the files under `addon-admin-ui/public/brand`). */
29
23
  const LOGO_DARK = '<svg class="logo logo-dark" role="img" aria-label="CamStack" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 48" fill="none"><g transform="translate(4, 2) scale(0.68)"><rect x="8" y="28" width="48" height="28" rx="6" fill="#292524"/><rect x="12" y="16" width="40" height="28" rx="6" fill="#44403c"/><rect x="16" y="4" width="32" height="28" rx="6" fill="#f59e42"/><circle cx="32" cy="18" r="8" fill="#0c0a09" opacity="0.3"/><circle cx="32" cy="18" r="5" fill="#0c0a09" opacity="0.2"/><circle cx="32" cy="18" r="2.5" fill="#fafaf9" opacity="0.8"/></g><text x="52" y="31" font-family="system-ui, -apple-system, sans-serif" font-size="26" font-weight="700" letter-spacing="-0.5" fill="#fafaf9">Cam<tspan fill="#f59e42">Stack</tspan></text></svg>';
30
24
  const LOGO_LIGHT = '<svg class="logo logo-light" role="img" aria-label="CamStack" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 48" fill="none"><g transform="translate(4, 2) scale(0.68)"><rect x="8" y="28" width="48" height="28" rx="6" fill="#d6d3d1"/><rect x="12" y="16" width="40" height="28" rx="6" fill="#a8a29e"/><rect x="16" y="4" width="32" height="28" rx="6" fill="#e67e22"/><circle cx="32" cy="18" r="8" fill="#fafaf9" opacity="0.3"/><circle cx="32" cy="18" r="5" fill="#fafaf9" opacity="0.2"/><circle cx="32" cy="18" r="2.5" fill="#1c1917" opacity="0.7"/></g><text x="52" y="31" font-family="system-ui, -apple-system, sans-serif" font-size="26" font-weight="700" letter-spacing="-0.5" fill="#1c1917">Cam<tspan fill="#e67e22">Stack</tspan></text></svg>';
31
25
  /** The logo markup, exposed so a spec can hold it against the brand files. */
32
- exports.APP_PAGE_LOGOS = {
26
+ export const APP_PAGE_LOGOS = {
33
27
  dark: LOGO_DARK,
34
28
  light: LOGO_LIGHT,
35
29
  };
@@ -68,19 +62,19 @@ const COMPONENT_CSS = [
68
62
  `.actions{display:flex;flex-direction:column;gap:var(--spacing-md)}`,
69
63
  ].join('');
70
64
  /** The one stylesheet, as served: the generated tokens followed by the component rules. */
71
- exports.APP_PAGE_STYLE = `${(0, tokens_1.themeToRootCss)(tokens_1.defaultTheme)}${COMPONENT_CSS}`;
72
- const sha256Source = (text) => `'sha256-${(0, node_crypto_1.createHash)('sha256').update(text).digest('base64')}'`;
65
+ export const APP_PAGE_STYLE = `${themeToRootCss(defaultTheme)}${COMPONENT_CSS}`;
66
+ const sha256Source = (text) => `'sha256-${createHash('sha256').update(text).digest('base64')}'`;
73
67
  /**
74
68
  * The CSP for a page rendered by {@link renderAppPage}: the inline style and
75
69
  * (when there is one) the inline script by hash, same-origin requests only, no
76
70
  * framing, no base rewrite. The hashes are computed from the strings the page
77
71
  * is built from, so they cannot disagree with it.
78
72
  */
79
- function appPageCsp(options = {}) {
73
+ export function appPageCsp(options = {}) {
80
74
  return [
81
75
  "default-src 'none'",
82
76
  ...(options.script === undefined ? [] : [`script-src ${sha256Source(options.script)}`]),
83
- `style-src ${sha256Source(exports.APP_PAGE_STYLE)}`,
77
+ `style-src ${sha256Source(APP_PAGE_STYLE)}`,
84
78
  ...(options.script === undefined ? [] : ["connect-src 'self'"]),
85
79
  "base-uri 'none'",
86
80
  `form-action ${options.formToSelf === true ? "'self'" : "'none'"}`,
@@ -88,36 +82,29 @@ function appPageCsp(options = {}) {
88
82
  ].join('; ');
89
83
  }
90
84
  /** Escapes text for an HTML text node or a double-quoted attribute. */
91
- function escapeHtml(text) {
85
+ export function escapeHtml(text) {
92
86
  return text.replace(/[&<>"']/g, (c) => `&#${c.charCodeAt(0)};`);
93
87
  }
94
88
  /** A full page: doctype, viewport (with safe-area fit), tokens, logo, a card holding `body`. */
95
- function renderAppPage(input) {
89
+ export function renderAppPage(input) {
96
90
  const referrer = input.noReferrer === true ? '<meta name="referrer" content="no-referrer">' : '';
97
91
  const script = input.script === undefined ? '' : `<script>${input.script}</script>`;
98
92
  const strings = Object.entries(input.scriptStrings ?? {})
99
93
  .map(([key, value]) => ` data-s-${key}="${escapeHtml(value)}"`)
100
94
  .join('');
101
- return `<!doctype html><html lang="${input.lang}"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><meta name="color-scheme" content="light dark">${referrer}<title>${escapeHtml(input.title)}</title><style>${exports.APP_PAGE_STYLE}</style></head><body${strings}><main><div class="brand">${LOGO_DARK}${LOGO_LIGHT}</div><div class="card"><h1>${escapeHtml(input.heading)}</h1>${input.body}</div></main>${script}</body></html>`;
95
+ return `<!doctype html><html lang="${input.lang}"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><meta name="color-scheme" content="light dark">${referrer}<title>${escapeHtml(input.title)}</title><style>${APP_PAGE_STYLE}</style></head><body${strings}><main><div class="brand">${LOGO_DARK}${LOGO_LIGHT}</div><div class="card"><h1>${escapeHtml(input.heading)}</h1>${input.body}</div></main>${script}</body></html>`;
102
96
  }
103
97
  /** A paragraph of the card (`text` is escaped). */
104
- const appParagraph = (text) => `<p>${escapeHtml(text)}</p>`;
105
- exports.appParagraph = appParagraph;
98
+ export const appParagraph = (text) => `<p>${escapeHtml(text)}</p>`;
106
99
  /** A smaller, muted paragraph (`text` is escaped). */
107
- const appHint = (text) => `<p class="hint">${escapeHtml(text)}</p>`;
108
- exports.appHint = appHint;
100
+ export const appHint = (text) => `<p class="hint">${escapeHtml(text)}</p>`;
109
101
  /** The primary button; `attributes` is trusted markup (already escaped), `label` is escaped. */
110
- const appButton = (label, attributes) => `<button class="btn" type="button" ${attributes}>${escapeHtml(label)}</button>`;
111
- exports.appButton = appButton;
102
+ export const appButton = (label, attributes) => `<button class="btn" type="button" ${attributes}>${escapeHtml(label)}</button>`;
112
103
  /** The error line a script fills in; empty it renders nothing. */
113
- const appErrorLine = (id) => `<p class="error" id="${id}" role="alert"></p>`;
114
- exports.appErrorLine = appErrorLine;
104
+ export const appErrorLine = (id) => `<p class="error" id="${id}" role="alert"></p>`;
115
105
  /** A submit button of a form (`name`/`value` are escaped); `secondary` is the outlined, non-default choice. */
116
- const appSubmitButton = (label, name, value, secondary = false) => `<button class="${secondary ? 'btn secondary' : 'btn'}" type="submit" name="${escapeHtml(name)}" value="${escapeHtml(value)}">${escapeHtml(label)}</button>`;
117
- exports.appSubmitButton = appSubmitButton;
106
+ export const appSubmitButton = (label, name, value, secondary = false) => `<button class="${secondary ? 'btn secondary' : 'btn'}" type="submit" name="${escapeHtml(name)}" value="${escapeHtml(value)}">${escapeHtml(label)}</button>`;
118
107
  /** A hidden form field (`name`/`value` are escaped). */
119
- const appHiddenField = (name, value) => `<input type="hidden" name="${escapeHtml(name)}" value="${escapeHtml(value)}">`;
120
- exports.appHiddenField = appHiddenField;
108
+ export const appHiddenField = (name, value) => `<input type="hidden" name="${escapeHtml(name)}" value="${escapeHtml(value)}">`;
121
109
  /** The quiet link under the actions (Cancel); `href` is escaped here. */
122
- const appCancelLink = (href, label) => `<a class="link" href="${escapeHtml(href)}">${escapeHtml(label)}</a>`;
123
- exports.appCancelLink = appCancelLink;
110
+ export const appCancelLink = (href, label) => `<a class="link" href="${escapeHtml(href)}">${escapeHtml(label)}</a>`;
@@ -1,9 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.APP_PAGE_STRINGS = exports.APP_PAGE_DEFAULT_LANG = void 0;
4
- exports.appStrings = appStrings;
5
- exports.langFromAcceptLanguage = langFromAcceptLanguage;
6
- exports.resolveAppPageLang = resolveAppPageLang;
7
1
  /**
8
2
  * Every word the hub's app landing pages show (D858), in both languages, and
9
3
  * the one rule that picks the language.
@@ -18,8 +12,8 @@ exports.resolveAppPageLang = resolveAppPageLang;
18
12
  * (allow-listed) wins; else the first supported tag of `Accept-Language`
19
13
  * (`it*` -> `it`); else English. Neither input is ever reflected into a page.
20
14
  */
21
- const types_1 = require("@camstack/types");
22
- exports.APP_PAGE_DEFAULT_LANG = 'en';
15
+ import { APP_START_REFUSAL_MESSAGES, parseAppPageLang, } from '@camstack/types';
16
+ export const APP_PAGE_DEFAULT_LANG = 'en';
23
17
  const EN = {
24
18
  confirm: {
25
19
  title: 'Sign in the CamStack app',
@@ -48,7 +42,7 @@ const EN = {
48
42
  title: 'Sign-in request refused',
49
43
  hint: 'Close this window and try again from the app.',
50
44
  generic: 'The sign-in request was refused.',
51
- reasons: types_1.APP_START_REFUSAL_MESSAGES,
45
+ reasons: APP_START_REFUSAL_MESSAGES,
52
46
  },
53
47
  consent: {
54
48
  titlePrefix: 'CamStack · Authorize ',
@@ -121,12 +115,12 @@ const IT = {
121
115
  signInFailed: 'Accesso non riuscito. Riprova.',
122
116
  },
123
117
  };
124
- exports.APP_PAGE_STRINGS = { en: EN, it: IT };
125
- function appStrings(lang) {
126
- return exports.APP_PAGE_STRINGS[lang];
118
+ export const APP_PAGE_STRINGS = { en: EN, it: IT };
119
+ export function appStrings(lang) {
120
+ return APP_PAGE_STRINGS[lang];
127
121
  }
128
122
  /** The first supported language of an `Accept-Language` value (by q, then order), or `undefined`. */
129
- function langFromAcceptLanguage(header) {
123
+ export function langFromAcceptLanguage(header) {
130
124
  const value = typeof header === 'string' ? header : header?.join(',');
131
125
  if (value === undefined || value.length > 512)
132
126
  return undefined;
@@ -143,15 +137,15 @@ function langFromAcceptLanguage(header) {
143
137
  .filter((t) => Number.isFinite(t.weight) && t.weight > 0)
144
138
  .sort((a, b) => b.weight - a.weight || a.index - b.index);
145
139
  for (const { primary } of ranked) {
146
- const lang = (0, types_1.parseAppPageLang)(primary);
140
+ const lang = parseAppPageLang(primary);
147
141
  if (lang !== undefined)
148
142
  return lang;
149
143
  }
150
144
  return undefined;
151
145
  }
152
146
  /** The page language: the app's `lang` (allow-listed), else `Accept-Language`, else English. */
153
- function resolveAppPageLang(input) {
154
- return ((0, types_1.parseAppPageLang)(input.lang) ??
147
+ export function resolveAppPageLang(input) {
148
+ return (parseAppPageLang(input.lang) ??
155
149
  langFromAcceptLanguage(input.acceptLanguage) ??
156
- exports.APP_PAGE_DEFAULT_LANG);
150
+ APP_PAGE_DEFAULT_LANG);
157
151
  }
@@ -1,8 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.APP_PASSKEY_REFUSAL_CSP = exports.APP_PASSKEY_CSP = void 0;
4
- exports.appPasskeyPage = appPasskeyPage;
5
- exports.appPasskeyRefusalPage = appPasskeyRefusalPage;
6
1
  /**
7
2
  * The standalone passkey page for a native app sign-in (D858).
8
3
  *
@@ -19,8 +14,8 @@ exports.appPasskeyRefusalPage = appPasskeyRefusalPage;
19
14
  * specific is ever placed in the script; the only server-rendered value is the
20
15
  * (allow-listed, HTML-escaped) cancel link.
21
16
  */
22
- const app_page_shell_js_1 = require("./app-page-shell.js");
23
- const app_page_strings_js_1 = require("./app-page-strings.js");
17
+ import { appButton, appCancelLink, appErrorLine, appHint, appPageCsp, appParagraph, escapeHtml, renderAppPage, } from './app-page-shell.js';
18
+ import { appStrings } from './app-page-strings.js';
24
19
  const PAGE_SCRIPT = `(function () {
25
20
  var q = new URLSearchParams(location.search);
26
21
  var base = location.pathname.replace(/\\/+$/, '');
@@ -117,11 +112,11 @@ const PAGE_SCRIPT = `(function () {
117
112
  * The page's CSP: the shell's style and the one script by hash, same-origin
118
113
  * requests only, no framing, no base rewrite, no form posts, no plugins.
119
114
  */
120
- exports.APP_PASSKEY_CSP = (0, app_page_shell_js_1.appPageCsp)({ script: PAGE_SCRIPT });
115
+ export const APP_PASSKEY_CSP = appPageCsp({ script: PAGE_SCRIPT });
121
116
  /** The page; `cancelHref` is the app callback carrying `error=cancelled`. */
122
- function appPasskeyPage(cancelHref, lang) {
123
- const t = (0, app_page_strings_js_1.appStrings)(lang);
124
- return (0, app_page_shell_js_1.renderAppPage)({
117
+ export function appPasskeyPage(cancelHref, lang) {
118
+ const t = appStrings(lang);
119
+ return renderAppPage({
125
120
  lang,
126
121
  title: t.passkey.title,
127
122
  heading: t.passkey.heading,
@@ -134,23 +129,23 @@ function appPasskeyPage(cancelHref, lang) {
134
129
  'sign-in-failed': t.script.signInFailed,
135
130
  },
136
131
  body: [
137
- (0, app_page_shell_js_1.appParagraph)(t.passkey.body),
138
- (0, app_page_shell_js_1.appButton)(t.passkey.button, 'id="go"'),
139
- (0, app_page_shell_js_1.appErrorLine)('msg'),
140
- (0, app_page_shell_js_1.appCancelLink)(cancelHref, t.passkey.cancel),
141
- `<noscript><p class="error">${(0, app_page_shell_js_1.escapeHtml)(t.passkey.noscript)}</p></noscript>`,
132
+ appParagraph(t.passkey.body),
133
+ appButton(t.passkey.button, 'id="go"'),
134
+ appErrorLine('msg'),
135
+ appCancelLink(cancelHref, t.passkey.cancel),
136
+ `<noscript><p class="error">${escapeHtml(t.passkey.noscript)}</p></noscript>`,
142
137
  ].join(''),
143
138
  });
144
139
  }
145
140
  /** The page for a request the hub refuses to serve: a sentence, no script, no assets. */
146
- function appPasskeyRefusalPage(message, lang) {
147
- const t = (0, app_page_strings_js_1.appStrings)(lang).refused;
148
- return (0, app_page_shell_js_1.renderAppPage)({
141
+ export function appPasskeyRefusalPage(message, lang) {
142
+ const t = appStrings(lang).refused;
143
+ return renderAppPage({
149
144
  lang,
150
145
  title: t.title,
151
146
  heading: t.title,
152
- body: (0, app_page_shell_js_1.appParagraph)(message) + (0, app_page_shell_js_1.appHint)(t.hint),
147
+ body: appParagraph(message) + appHint(t.hint),
153
148
  });
154
149
  }
155
150
  /** CSP of the refusal page: the shell's style only, nothing runs. */
156
- exports.APP_PASSKEY_REFUSAL_CSP = (0, app_page_shell_js_1.appPageCsp)();
151
+ export const APP_PASSKEY_REFUSAL_CSP = appPageCsp();
@@ -1,7 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.APP_PASSKEY_PATH = void 0;
4
- exports.registerAppPasskeyRoutes = registerAppPasskeyRoutes;
5
1
  /**
6
2
  * The passkey app sign-in routes (D858):
7
3
  *
@@ -18,30 +14,30 @@ exports.registerAppPasskeyRoutes = registerAppPasskeyRoutes;
18
14
  * `{ error }` for a request that is not an app flow at all), so the page just
19
15
  * navigates. The app's parameters are never logged.
20
16
  */
21
- const types_1 = require("@camstack/types");
22
- const zod_1 = require("zod");
23
- const app_confirm_routes_js_1 = require("./app-confirm-routes.js");
24
- const app_passkey_page_js_1 = require("./app-passkey-page.js");
25
- const app_page_strings_js_1 = require("./app-page-strings.js");
26
- const auth_rate_limit_js_1 = require("./auth-rate-limit.js");
27
- const session_mint_js_1 = require("./session-mint.js");
28
- exports.APP_PASSKEY_PATH = '/auth/app/passkey';
29
- const FinishBodySchema = zod_1.z.object({
30
- response: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()),
31
- code_challenge: zod_1.z.string().optional(),
32
- code_challenge_method: zod_1.z.string().optional(),
33
- state: zod_1.z.string().optional(),
34
- purpose: zod_1.z.string().optional(),
35
- redirect: zod_1.z.string().optional(),
36
- lang: zod_1.z.string().optional(),
17
+ import { APP_FLOW_REFUSAL_MESSAGES, appFlowLocation, parseAppFlowRequest, } from '@camstack/types';
18
+ import { z } from 'zod';
19
+ import { APP_CONFIRM_PARAM, appConfirmCookie } from './app-confirm-routes.js';
20
+ import { APP_PASSKEY_CSP, APP_PASSKEY_REFUSAL_CSP, appPasskeyPage, appPasskeyRefusalPage, } from './app-passkey-page.js';
21
+ import { appStrings, resolveAppPageLang } from './app-page-strings.js';
22
+ import { clientKeyFromRequest } from './auth-rate-limit.js';
23
+ import { SessionUserGoneError } from './session-mint.js';
24
+ export const APP_PASSKEY_PATH = '/auth/app/passkey';
25
+ const FinishBodySchema = z.object({
26
+ response: z.record(z.string(), z.unknown()),
27
+ code_challenge: z.string().optional(),
28
+ code_challenge_method: z.string().optional(),
29
+ state: z.string().optional(),
30
+ purpose: z.string().optional(),
31
+ redirect: z.string().optional(),
32
+ lang: z.string().optional(),
37
33
  });
38
34
  function noStore(reply) {
39
35
  reply.header('Cache-Control', 'no-store');
40
36
  reply.header('Referrer-Policy', 'no-referrer');
41
37
  }
42
- function registerAppPasskeyRoutes(fastify, deps) {
38
+ export function registerAppPasskeyRoutes(fastify, deps) {
43
39
  const limited = (bucket, request, reply) => {
44
- const client = (0, auth_rate_limit_js_1.clientKeyFromRequest)(request, deps.network);
40
+ const client = clientKeyFromRequest(request, deps.network);
45
41
  if (client === null)
46
42
  return false;
47
43
  const verdict = deps.limiter.check(`${bucket}:${client}`);
@@ -51,11 +47,11 @@ function registerAppPasskeyRoutes(fastify, deps) {
51
47
  void reply.status(429).send({ error: 'Too many attempts' });
52
48
  return true;
53
49
  };
54
- fastify.get(exports.APP_PASSKEY_PATH, async (request, reply) => {
50
+ fastify.get(APP_PASSKEY_PATH, async (request, reply) => {
55
51
  noStore(reply);
56
52
  reply.type('text/html; charset=utf-8');
57
- const parsed = (0, types_1.parseAppFlowRequest)(request.query);
58
- const lang = (0, app_page_strings_js_1.resolveAppPageLang)({
53
+ const parsed = parseAppFlowRequest(request.query);
54
+ const lang = resolveAppPageLang({
59
55
  lang: parsed.ok ? parsed.request.lang : request.query['lang'],
60
56
  acceptLanguage: request.headers['accept-language'],
61
57
  });
@@ -63,26 +59,26 @@ function registerAppPasskeyRoutes(fastify, deps) {
63
59
  deps.logger.warn('Passkey app sign-in refused at the page', {
64
60
  meta: { reason: parsed.reason },
65
61
  });
66
- reply.header('Content-Security-Policy', app_passkey_page_js_1.APP_PASSKEY_REFUSAL_CSP);
62
+ reply.header('Content-Security-Policy', APP_PASSKEY_REFUSAL_CSP);
67
63
  return reply
68
64
  .status(400)
69
- .send((0, app_passkey_page_js_1.appPasskeyRefusalPage)((0, app_page_strings_js_1.appStrings)(lang).refused.reasons[parsed.reason], lang));
65
+ .send(appPasskeyRefusalPage(appStrings(lang).refused.reasons[parsed.reason], lang));
70
66
  }
71
- reply.header('Content-Security-Policy', app_passkey_page_js_1.APP_PASSKEY_CSP);
72
- const cancel = (0, types_1.appFlowLocation)(parsed.request.redirect, { error: 'cancelled' }, parsed.request.state);
73
- return reply.send((0, app_passkey_page_js_1.appPasskeyPage)(cancel, lang));
67
+ reply.header('Content-Security-Policy', APP_PASSKEY_CSP);
68
+ const cancel = appFlowLocation(parsed.request.redirect, { error: 'cancelled' }, parsed.request.state);
69
+ return reply.send(appPasskeyPage(cancel, lang));
74
70
  });
75
- fastify.post(`${exports.APP_PASSKEY_PATH}/begin`, async (request, reply) => {
71
+ fastify.post(`${APP_PASSKEY_PATH}/begin`, async (request, reply) => {
76
72
  noStore(reply);
77
73
  if (limited('app-passkey-begin', request, reply))
78
74
  return reply;
79
- const body = zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).safeParse(request.body);
75
+ const body = z.record(z.string(), z.unknown()).safeParse(request.body);
80
76
  const query = body.success
81
77
  ? Object.fromEntries(Object.entries(body.data).flatMap(([k, v]) => (typeof v === 'string' ? [[k, v]] : [])))
82
78
  : {};
83
- const parsed = (0, types_1.parseAppFlowRequest)(query);
79
+ const parsed = parseAppFlowRequest(query);
84
80
  if (!parsed.ok)
85
- return reply.status(400).send({ error: types_1.APP_FLOW_REFUSAL_MESSAGES[parsed.reason] });
81
+ return reply.status(400).send({ error: APP_FLOW_REFUSAL_MESSAGES[parsed.reason] });
86
82
  const provider = deps.passkeys();
87
83
  if (provider === null)
88
84
  return reply.status(503).send({ error: 'Passkeys are not available.' });
@@ -96,14 +92,14 @@ function registerAppPasskeyRoutes(fastify, deps) {
96
92
  return reply.status(500).send({ error: 'Passkeys are not available.' });
97
93
  }
98
94
  });
99
- fastify.post(`${exports.APP_PASSKEY_PATH}/finish`, async (request, reply) => {
95
+ fastify.post(`${APP_PASSKEY_PATH}/finish`, async (request, reply) => {
100
96
  noStore(reply);
101
97
  if (limited('app-passkey-finish', request, reply))
102
98
  return reply;
103
99
  const body = FinishBodySchema.safeParse(request.body);
104
100
  if (!body.success)
105
101
  return reply.status(400).send({ error: 'Malformed sign-in request.' });
106
- const parsed = (0, types_1.parseAppFlowRequest)({
102
+ const parsed = parseAppFlowRequest({
107
103
  code_challenge: body.data.code_challenge,
108
104
  code_challenge_method: body.data.code_challenge_method,
109
105
  state: body.data.state,
@@ -112,11 +108,11 @@ function registerAppPasskeyRoutes(fastify, deps) {
112
108
  lang: body.data.lang,
113
109
  });
114
110
  if (!parsed.ok)
115
- return reply.status(400).send({ error: types_1.APP_FLOW_REFUSAL_MESSAGES[parsed.reason] });
111
+ return reply.status(400).send({ error: APP_FLOW_REFUSAL_MESSAGES[parsed.reason] });
116
112
  const app = parsed.request;
117
113
  const deny = (error) => {
118
114
  deps.logger.warn('Passkey app sign-in refused', { meta: { error } });
119
- return reply.send({ location: (0, types_1.appFlowLocation)(app.redirect, { error }, app.state) });
115
+ return reply.send({ location: appFlowLocation(app.redirect, { error }, app.state) });
120
116
  };
121
117
  const provider = deps.passkeys();
122
118
  if (provider === null)
@@ -142,13 +138,13 @@ function registerAppPasskeyRoutes(fastify, deps) {
142
138
  app,
143
139
  authMethod: 'passkey',
144
140
  });
145
- reply.header('Set-Cookie', (0, app_confirm_routes_js_1.appConfirmCookie)(parked.cookie, request.protocol === 'https'));
141
+ reply.header('Set-Cookie', appConfirmCookie(parked.cookie, request.protocol === 'https'));
146
142
  return reply.send({
147
- confirm: `confirm?${app_confirm_routes_js_1.APP_CONFIRM_PARAM}=${encodeURIComponent(parked.token)}`,
143
+ confirm: `confirm?${APP_CONFIRM_PARAM}=${encodeURIComponent(parked.token)}`,
148
144
  });
149
145
  }
150
146
  catch (error) {
151
- if (error instanceof session_mint_js_1.SessionUserGoneError)
147
+ if (error instanceof SessionUserGoneError)
152
148
  return deny('user-gone');
153
149
  deps.logger.error('Passkey app sign-in failed', {
154
150
  meta: { error: error instanceof Error ? error.message : String(error) },
@@ -1,8 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.APP_REFUSED_CSP = void 0;
4
- exports.appRefusedPage = appRefusedPage;
5
- exports.registerAppRefusedRoute = registerAppRefusedRoute;
6
1
  /**
7
2
  * `GET /auth/app/refused?reason=<code>` - the page that says why a native app
8
3
  * sign-in could not start (D858).
@@ -12,29 +7,29 @@ exports.registerAppRefusedRoute = registerAppRefusedRoute;
12
7
  * sentence, in the language of `lang`/`Accept-Language`, in the same shell as every other app page. The query is never echoed: an unknown or
13
8
  * absent code gets a generic sentence, a known one its fixed words.
14
9
  */
15
- const types_1 = require("@camstack/types");
16
- const app_page_shell_js_1 = require("./app-page-shell.js");
17
- const app_page_strings_js_1 = require("./app-page-strings.js");
10
+ import { APP_REFUSED_PATH, isAppStartRefusal } from '@camstack/types';
11
+ import { appHint, appPageCsp, appParagraph, renderAppPage } from './app-page-shell.js';
12
+ import { appStrings, resolveAppPageLang } from './app-page-strings.js';
18
13
  /** The refusal page for `reason` (a known code, or anything: unknown renders the generic sentence). */
19
- function appRefusedPage(reason, lang) {
20
- const t = (0, app_page_strings_js_1.appStrings)(lang).refused;
21
- const message = (0, types_1.isAppStartRefusal)(reason) ? t.reasons[reason] : t.generic;
22
- return (0, app_page_shell_js_1.renderAppPage)({
14
+ export function appRefusedPage(reason, lang) {
15
+ const t = appStrings(lang).refused;
16
+ const message = isAppStartRefusal(reason) ? t.reasons[reason] : t.generic;
17
+ return renderAppPage({
23
18
  lang,
24
19
  title: t.title,
25
20
  heading: t.title,
26
- body: (0, app_page_shell_js_1.appParagraph)(message) + (0, app_page_shell_js_1.appHint)(t.hint),
21
+ body: appParagraph(message) + appHint(t.hint),
27
22
  });
28
23
  }
29
24
  /** CSP of the refusal page: the shell's style only, nothing runs. */
30
- exports.APP_REFUSED_CSP = (0, app_page_shell_js_1.appPageCsp)();
31
- function registerAppRefusedRoute(fastify) {
32
- fastify.get(types_1.APP_REFUSED_PATH, async (request, reply) => {
25
+ export const APP_REFUSED_CSP = appPageCsp();
26
+ export function registerAppRefusedRoute(fastify) {
27
+ fastify.get(APP_REFUSED_PATH, async (request, reply) => {
33
28
  reply.header('Cache-Control', 'no-store');
34
29
  reply.header('Referrer-Policy', 'no-referrer');
35
- reply.header('Content-Security-Policy', exports.APP_REFUSED_CSP);
30
+ reply.header('Content-Security-Policy', APP_REFUSED_CSP);
36
31
  reply.type('text/html; charset=utf-8');
37
- const lang = (0, app_page_strings_js_1.resolveAppPageLang)({
32
+ const lang = resolveAppPageLang({
38
33
  lang: request.query['lang'],
39
34
  acceptLanguage: request.headers['accept-language'],
40
35
  });
@@ -1,7 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DEFAULT_AUTH_NETWORK_POLICY = exports.TRUSTED_NETWORKS_KEY = exports.TRUSTED_PROXIES_KEY = void 0;
4
- exports.createAuthNetworkPolicy = createAuthNetworkPolicy;
5
1
  /**
6
2
  * The two network facts the auth surface reads from settings:
7
3
  *
@@ -17,10 +13,10 @@ exports.createAuthNetworkPolicy = createAuthNetworkPolicy;
17
13
  * answer yet is treated as an EMPTY list: no extra proxy is trusted, and no
18
14
  * network skips a factor — both fail closed.
19
15
  */
20
- const system_1 = require("@camstack/system");
21
- const client_address_js_1 = require("./client-address.js");
22
- exports.TRUSTED_PROXIES_KEY = 'auth.trustedProxies';
23
- exports.TRUSTED_NETWORKS_KEY = 'auth.trustedNetworks';
16
+ import { createCidrMatcher, readCidrSetting } from '@camstack/system';
17
+ import { resolveClientAddress } from './client-address.js';
18
+ export const TRUSTED_PROXIES_KEY = 'auth.trustedProxies';
19
+ export const TRUSTED_NETWORKS_KEY = 'auth.trustedNetworks';
24
20
  function asRequest(req) {
25
21
  if (req === null || typeof req !== 'object')
26
22
  return null;
@@ -36,7 +32,7 @@ function asRequest(req) {
36
32
  }
37
33
  function safeList(read, key) {
38
34
  try {
39
- return (0, system_1.readCidrSetting)(read(key));
35
+ return readCidrSetting(read(key));
40
36
  }
41
37
  catch {
42
38
  return [];
@@ -45,31 +41,31 @@ function safeList(read, key) {
45
41
  /** One memo per list: rebuilding a BlockList per request is wasted work. */
46
42
  function memoMatcher() {
47
43
  let lastKey = null;
48
- let last = (0, system_1.createCidrMatcher)([]);
44
+ let last = createCidrMatcher([]);
49
45
  return (entries) => {
50
46
  const key = entries.join('\n');
51
47
  if (key !== lastKey) {
52
48
  lastKey = key;
53
- last = (0, system_1.createCidrMatcher)(entries);
49
+ last = createCidrMatcher(entries);
54
50
  }
55
51
  return last;
56
52
  };
57
53
  }
58
- function createAuthNetworkPolicy(read) {
54
+ export function createAuthNetworkPolicy(read) {
59
55
  const networks = memoMatcher();
60
56
  return {
61
57
  clientAddress(req) {
62
58
  const request = asRequest(req);
63
59
  if (request === null)
64
60
  return { ip: null, peer: null, viaProxy: false };
65
- return (0, client_address_js_1.resolveClientAddress)(request, { trustedProxies: safeList(read, exports.TRUSTED_PROXIES_KEY) });
61
+ return resolveClientAddress(request, { trustedProxies: safeList(read, TRUSTED_PROXIES_KEY) });
66
62
  },
67
63
  isTrustedNetworkLogin(address) {
68
64
  if (address.viaProxy || address.ip === null)
69
65
  return false;
70
- return networks(safeList(read, exports.TRUSTED_NETWORKS_KEY)).contains(address.ip);
66
+ return networks(safeList(read, TRUSTED_NETWORKS_KEY)).contains(address.ip);
71
67
  },
72
68
  };
73
69
  }
74
70
  /** No settings: loopback is the only trusted proxy, no network skips a factor. */
75
- exports.DEFAULT_AUTH_NETWORK_POLICY = createAuthNetworkPolicy(() => undefined);
71
+ export const DEFAULT_AUTH_NETWORK_POLICY = createAuthNetworkPolicy(() => undefined);
@@ -1,19 +1,14 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AUTH_GOVERNING_CAPS = void 0;
4
- exports.isAuthAddonDisabled = isAuthAddonDisabled;
5
- exports.bridgeProviderAddonId = bridgeProviderAddonId;
6
1
  /** Capabilities whose per-provider toggle is an auth addon's enable. */
7
- exports.AUTH_GOVERNING_CAPS = ['auth-provider', 'user-passkeys'];
2
+ export const AUTH_GOVERNING_CAPS = ['auth-provider', 'user-passkeys'];
8
3
  /** Whether the operator disabled `addonId` on Identity → Authentication. */
9
- function isAuthAddonDisabled(registry, addonId) {
10
- return exports.AUTH_GOVERNING_CAPS.some((cap) => registry.isProviderDisabled(cap, addonId));
4
+ export function isAuthAddonDisabled(registry, addonId) {
5
+ return AUTH_GOVERNING_CAPS.some((cap) => registry.isProviderDisabled(cap, addonId));
11
6
  }
12
7
  /**
13
8
  * The addon behind an SSO bridge's `provider` claim: `auth-oidc/<instance>`
14
9
  * is signed by `auth-oidc`, anything else names its addon directly.
15
10
  */
16
- function bridgeProviderAddonId(provider) {
11
+ export function bridgeProviderAddonId(provider) {
17
12
  const slash = provider.indexOf('/');
18
13
  return slash === -1 ? provider : provider.slice(0, slash);
19
14
  }
@@ -1,7 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createRateLimiter = createRateLimiter;
4
- exports.clientKeyFromRequest = clientKeyFromRequest;
5
1
  /**
6
2
  * Public-auth rate limiting — fixed window per (bucket, client ip).
7
3
  *
@@ -16,8 +12,8 @@ exports.clientKeyFromRequest = clientKeyFromRequest;
16
12
  * BOUNDED (`maxKeys`, oldest-window evicted first) so an attacker
17
13
  * rotating spoofed source addresses cannot grow it without limit.
18
14
  */
19
- const auth_network_policy_js_1 = require("./auth-network-policy.js");
20
- function createRateLimiter(options) {
15
+ import { DEFAULT_AUTH_NETWORK_POLICY } from './auth-network-policy.js';
16
+ export function createRateLimiter(options) {
21
17
  const maxKeys = options.maxKeys ?? 10_000;
22
18
  const now = options.now ?? Date.now;
23
19
  const entries = new Map();
@@ -76,6 +72,6 @@ function createRateLimiter(options) {
76
72
  * bucket locked the whole internet out. `null` = no originating request
77
73
  * (a mesh-internal `createCaller`) — never limited.
78
74
  */
79
- function clientKeyFromRequest(req, policy = auth_network_policy_js_1.DEFAULT_AUTH_NETWORK_POLICY) {
75
+ export function clientKeyFromRequest(req, policy = DEFAULT_AUTH_NETWORK_POLICY) {
80
76
  return policy.clientAddress(req).ip;
81
77
  }
@@ -1,6 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resolveClientAddress = resolveClientAddress;
4
1
  /**
5
2
  * The real client address of an HTTP / WS request.
6
3
  *
@@ -25,8 +22,8 @@ exports.resolveClientAddress = resolveClientAddress;
25
22
  * second factor from a trusted network) refuses `viaProxy` outright, whatever
26
23
  * address the headers name.
27
24
  */
28
- const system_1 = require("@camstack/system");
29
- const node_net_1 = require("node:net");
25
+ import { createCidrMatcher, normalizeIp } from '@camstack/system';
26
+ import { isIP } from 'node:net';
30
27
  const LOOPBACK = ['127.0.0.0/8', '::1/128'];
31
28
  function header(req, name) {
32
29
  const raw = req.headers[name];
@@ -34,15 +31,15 @@ function header(req, name) {
34
31
  return typeof value === 'string' && value.trim().length > 0 ? value : null;
35
32
  }
36
33
  function validIp(value) {
37
- const ip = (0, system_1.normalizeIp)(value);
38
- return (0, node_net_1.isIP)(ip) === 0 ? null : ip;
34
+ const ip = normalizeIp(value);
35
+ return isIP(ip) === 0 ? null : ip;
39
36
  }
40
- function resolveClientAddress(req, config) {
37
+ export function resolveClientAddress(req, config) {
41
38
  const rawPeer = req.socket?.remoteAddress;
42
39
  const peer = typeof rawPeer === 'string' && rawPeer.length > 0 ? validIp(rawPeer) : null;
43
40
  if (peer === null)
44
41
  return { ip: null, peer: null, viaProxy: false };
45
- const trusted = (0, system_1.createCidrMatcher)([...LOOPBACK, ...config.trustedProxies]);
42
+ const trusted = createCidrMatcher([...LOOPBACK, ...config.trustedProxies]);
46
43
  if (!trusted.contains(peer))
47
44
  return { ip: peer, peer, viaProxy: false };
48
45
  // Cloudflare stamps the connecting client itself; prefer it when it parses.