@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,4 +1,3 @@
1
- "use strict";
2
1
  /**
3
2
  * The WebSocket plane of the transport census — hooked PER OPERATION.
4
3
  *
@@ -51,13 +50,8 @@
51
50
  * {@link UNKNOWN} instead: a call this instrument saw is never dropped for
52
51
  * want of a name.
53
52
  */
54
- Object.defineProperty(exports, "__esModule", { value: true });
55
- exports.WsCensusSession = exports.MAX_PENDING_WS_OPERATIONS = exports.WS_PATHLESS_PROCEDURE = void 0;
56
- exports.parseTrpcWsFrame = parseTrpcWsFrame;
57
- exports.attachWsCensusSession = attachWsCensusSession;
58
- exports.identifyWsCensusSession = identifyWsCensusSession;
59
- const client_ip_js_1 = require("./client-ip.js");
60
- const http_request_census_js_1 = require("./http-request-census.js");
53
+ import { extractClientIp, extractUserAgent } from './client-ip.js';
54
+ import { BATCH_OVERFLOW_PROCEDURE, MAX_BATCH_PROCEDURES, UNKNOWN, } from './http-request-census.js';
61
55
  /** Keepalive frames the tRPC adapter answers before parsing. Not operations. */
62
56
  const KEEPALIVE_FRAMES = new Set(['PING', 'PONG']);
63
57
  /**
@@ -66,7 +60,7 @@ const KEEPALIVE_FRAMES = new Set(['PING', 'PONG']);
66
60
  * tRPC rejects such a frame, but it still ARRIVED, and a census that drops it
67
61
  * has a hole in the total the plane comparison rests on.
68
62
  */
69
- exports.WS_PATHLESS_PROCEDURE = '(ws-no-path)';
63
+ export const WS_PATHLESS_PROCEDURE = '(ws-no-path)';
70
64
  /**
71
65
  * Operations held for a connection whose principal has not resolved yet.
72
66
  *
@@ -75,7 +69,7 @@ exports.WS_PATHLESS_PROCEDURE = '(ws-no-path)';
75
69
  * without limit. Past it, operations are counted immediately under
76
70
  * {@link UNKNOWN} rather than dropped.
77
71
  */
78
- exports.MAX_PENDING_WS_OPERATIONS = 128;
72
+ export const MAX_PENDING_WS_OPERATIONS = 128;
79
73
  const NO_OPERATIONS = { calls: [], subscriptions: [], stops: 0 };
80
74
  /**
81
75
  * Read the operations out of one raw client frame.
@@ -84,7 +78,7 @@ const NO_OPERATIONS = { calls: [], subscriptions: [], stops: 0 };
84
78
  * every one of them is a place where the count could be wrong in the direction
85
79
  * that exonerates this plane.
86
80
  */
87
- function parseTrpcWsFrame(raw) {
81
+ export function parseTrpcWsFrame(raw) {
88
82
  const text = raw.trim();
89
83
  if (text.length === 0)
90
84
  return NO_OPERATIONS;
@@ -108,7 +102,7 @@ function parseTrpcWsFrame(raw) {
108
102
  }
109
103
  if (method !== 'query' && method !== 'mutation' && method !== 'subscription')
110
104
  continue;
111
- if (calls.length + subscriptions.length >= http_request_census_js_1.MAX_BATCH_PROCEDURES) {
105
+ if (calls.length + subscriptions.length >= MAX_BATCH_PROCEDURES) {
112
106
  overflowed = true;
113
107
  continue;
114
108
  }
@@ -119,7 +113,7 @@ function parseTrpcWsFrame(raw) {
119
113
  calls.push(path);
120
114
  }
121
115
  if (overflowed)
122
- calls.push(http_request_census_js_1.BATCH_OVERFLOW_PROCEDURE);
116
+ calls.push(BATCH_OVERFLOW_PROCEDURE);
123
117
  return { calls, subscriptions, stops };
124
118
  }
125
119
  function parseJsonSafely(text) {
@@ -134,12 +128,12 @@ function parseJsonSafely(text) {
134
128
  }
135
129
  function readPath(params) {
136
130
  if (typeof params !== 'object' || params === null)
137
- return exports.WS_PATHLESS_PROCEDURE;
131
+ return WS_PATHLESS_PROCEDURE;
138
132
  const path = Reflect.get(params, 'path');
139
- return typeof path === 'string' && path.length > 0 ? path : exports.WS_PATHLESS_PROCEDURE;
133
+ return typeof path === 'string' && path.length > 0 ? path : WS_PATHLESS_PROCEDURE;
140
134
  }
141
135
  /** One connection's census state: its identity, and anything held for it. */
142
- class WsCensusSession {
136
+ export class WsCensusSession {
143
137
  census;
144
138
  userAgent;
145
139
  ip;
@@ -149,8 +143,8 @@ class WsCensusSession {
149
143
  closed = false;
150
144
  constructor(census, req) {
151
145
  this.census = census;
152
- this.userAgent = (0, client_ip_js_1.extractUserAgent)(req);
153
- this.ip = (0, client_ip_js_1.extractClientIp)(req);
146
+ this.userAgent = extractUserAgent(req);
147
+ this.ip = extractClientIp(req);
154
148
  }
155
149
  /**
156
150
  * Count one raw client frame.
@@ -175,9 +169,9 @@ class WsCensusSession {
175
169
  this.flushFrame(operations, this.principal);
176
170
  return;
177
171
  }
178
- if (this.pending.length >= exports.MAX_PENDING_WS_OPERATIONS) {
172
+ if (this.pending.length >= MAX_PENDING_WS_OPERATIONS) {
179
173
  // Never dropped — attributed to the named bucket instead.
180
- this.flushFrame(operations, http_request_census_js_1.UNKNOWN);
174
+ this.flushFrame(operations, UNKNOWN);
181
175
  return;
182
176
  }
183
177
  this.pending.push(operations);
@@ -194,7 +188,7 @@ class WsCensusSession {
194
188
  if (this.closed)
195
189
  return;
196
190
  this.closed = true;
197
- this.drain(this.principal ?? http_request_census_js_1.UNKNOWN);
191
+ this.drain(this.principal ?? UNKNOWN);
198
192
  }
199
193
  drain(principal) {
200
194
  if (this.pending.length === 0)
@@ -227,7 +221,6 @@ class WsCensusSession {
227
221
  }
228
222
  }
229
223
  }
230
- exports.WsCensusSession = WsCensusSession;
231
224
  /**
232
225
  * Sessions by socket.
233
226
  *
@@ -243,7 +236,7 @@ const sessions = new WeakMap();
243
236
  * Registered from `main.ts` on the same `wss` `applyWSSHandler` is given. Both
244
237
  * listeners see every frame; ours only counts.
245
238
  */
246
- function attachWsCensusSession(census, client, req, logger) {
239
+ export function attachWsCensusSession(census, client, req, logger) {
247
240
  census.observeWsConnection();
248
241
  const session = new WsCensusSession(census, req);
249
242
  sessions.set(client, session);
@@ -280,7 +273,7 @@ function attachWsCensusSession(census, client, req, logger) {
280
273
  * harness or a future adapter that builds a context without a census session
281
274
  * does not have to know this exists.
282
275
  */
283
- function identifyWsCensusSession(client, principal) {
276
+ export function identifyWsCensusSession(client, principal) {
284
277
  sessions.get(client)?.identify(principal);
285
278
  }
286
279
  /** Decode a `ws` frame payload to text. Returns `null` for a shape that cannot
@@ -1,18 +1,14 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WsSlowConsumerGuard = exports.WS_SLOW_CONSUMER_POLL_MS = exports.WS_SLOW_CONSUMER_GRACE_MS = exports.WS_SLOW_CONSUMER_MAX_BUFFERED_BYTES = void 0;
4
- exports.wsConnectionFacts = wsConnectionFacts;
5
- const client_ip_js_1 = require("./client-ip.js");
1
+ import { extractClientIp, extractUserAgent } from './client-ip.js';
6
2
  /** Queued bytes above which a client is a slow consumer. */
7
- exports.WS_SLOW_CONSUMER_MAX_BUFFERED_BYTES = 16 * 1024 * 1024;
3
+ export const WS_SLOW_CONSUMER_MAX_BUFFERED_BYTES = 16 * 1024 * 1024;
8
4
  /** How long the queue may stay above the bound before the socket is terminated. */
9
- exports.WS_SLOW_CONSUMER_GRACE_MS = 30_000;
5
+ export const WS_SLOW_CONSUMER_GRACE_MS = 30_000;
10
6
  /** How often every connection's queue is read. A getter per socket; free. */
11
- exports.WS_SLOW_CONSUMER_POLL_MS = 5_000;
7
+ export const WS_SLOW_CONSUMER_POLL_MS = 5_000;
12
8
  /** WebSocket close code for a socket that was never closed cleanly. */
13
9
  const ABNORMAL_CLOSURE = 1006;
14
10
  const UNIDENTIFIED = '(unidentified)';
15
- class WsSlowConsumerGuard {
11
+ export class WsSlowConsumerGuard {
16
12
  connections = new Set();
17
13
  bySocket = new WeakMap();
18
14
  logger;
@@ -23,9 +19,9 @@ class WsSlowConsumerGuard {
23
19
  timer = null;
24
20
  constructor(options) {
25
21
  this.logger = options.logger;
26
- this.maxBufferedBytes = options.maxBufferedBytes ?? exports.WS_SLOW_CONSUMER_MAX_BUFFERED_BYTES;
27
- this.graceMs = options.graceMs ?? exports.WS_SLOW_CONSUMER_GRACE_MS;
28
- this.pollMs = options.pollMs ?? exports.WS_SLOW_CONSUMER_POLL_MS;
22
+ this.maxBufferedBytes = options.maxBufferedBytes ?? WS_SLOW_CONSUMER_MAX_BUFFERED_BYTES;
23
+ this.graceMs = options.graceMs ?? WS_SLOW_CONSUMER_GRACE_MS;
24
+ this.pollMs = options.pollMs ?? WS_SLOW_CONSUMER_POLL_MS;
29
25
  this.now = options.now ?? (() => Date.now());
30
26
  }
31
27
  /** Watch one connection until it closes. */
@@ -142,7 +138,6 @@ class WsSlowConsumerGuard {
142
138
  };
143
139
  }
144
140
  }
145
- exports.WsSlowConsumerGuard = WsSlowConsumerGuard;
146
141
  function safeCount(read) {
147
142
  try {
148
143
  return read();
@@ -156,10 +151,10 @@ function errorMessage(err) {
156
151
  return err instanceof Error ? err.message : String(err);
157
152
  }
158
153
  /** The facts a real `ws` upgrade request provides. */
159
- function wsConnectionFacts(req) {
154
+ export function wsConnectionFacts(req) {
160
155
  return {
161
- ip: (0, client_ip_js_1.extractClientIp)(req),
162
- userAgent: (0, client_ip_js_1.extractUserAgent)(req),
156
+ ip: extractClientIp(req),
157
+ userAgent: extractUserAgent(req),
163
158
  bytesRead: () => req.socket.bytesRead,
164
159
  bytesWritten: () => req.socket.bytesWritten,
165
160
  };
@@ -1,9 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.UPLOAD_TRPC_PATH = void 0;
4
- exports.authorizeUploadRequest = authorizeUploadRequest;
5
- const scope_access_js_1 = require("./trpc/scope-access.js");
6
- exports.UPLOAD_TRPC_PATH = 'addons.installPackage';
1
+ import { checkScopeAccess } from './trpc/scope-access.js';
2
+ export const UPLOAD_TRPC_PATH = 'addons.installPackage';
7
3
  /**
8
4
  * Validate a `cst_*` scoped token via the `user-management` cap singleton.
9
5
  * Returns null when the singleton isn't mounted yet (boot race) or the
@@ -20,7 +16,7 @@ async function validateScopedTokenViaCap(addonRegistry, token) {
20
16
  return userMgmt.validateScopedToken({ token });
21
17
  }
22
18
  function isUploadAllowed(scoped) {
23
- return (0, scope_access_js_1.checkScopeAccess)(scoped.scopes, exports.UPLOAD_TRPC_PATH).ok;
19
+ return checkScopeAccess(scoped.scopes, UPLOAD_TRPC_PATH).ok;
24
20
  }
25
21
  /**
26
22
  * Run the full upload auth chain. Returns `{ok: true}` on success, or the
@@ -28,7 +24,7 @@ function isUploadAllowed(scoped) {
28
24
  * - 401 `Unauthorized` when no Authorization header is present,
29
25
  * - 403 `Forbidden: <reason>` for any recognised-but-insufficient token.
30
26
  */
31
- async function authorizeUploadRequest(args) {
27
+ export async function authorizeUploadRequest(args) {
32
28
  const { authHeader, authService, addonRegistry } = args;
33
29
  if (!authHeader) {
34
30
  return { ok: false, status: 401, error: 'Unauthorized' };
@@ -55,7 +51,7 @@ async function authorizeUploadRequest(args) {
55
51
  return { ok: true };
56
52
  }
57
53
  else {
58
- authReason = `scoped token lacks create access on '${exports.UPLOAD_TRPC_PATH}'`;
54
+ authReason = `scoped token lacks create access on '${UPLOAD_TRPC_PATH}'`;
59
55
  }
60
56
  }
61
57
  catch (err) {
@@ -1,6 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.gateAddonJwt = gateAddonJwt;
4
1
  /**
5
2
  * The JWT half of the `/addon/:addonId/*` gate — shared by the HTTP data-plane
6
3
  * branch and the addon-route branch so there is exactly ONE answer to "may this
@@ -14,7 +11,7 @@ exports.gateAddonJwt = gateAddonJwt;
14
11
  * the per-camera switches and notification snooze. A 60-second authorization
15
12
  * CODE and a 30-day refresh token passed the same way. See D103.
16
13
  */
17
- const types_1 = require("@camstack/types");
14
+ import { classifyBearerPrincipal, principalMayReachAddon, } from '@camstack/types';
18
15
  function readScopes(raw) {
19
16
  return Array.isArray(raw) ? raw : [];
20
17
  }
@@ -27,8 +24,8 @@ function readScopes(raw) {
27
24
  * an admin-only route keeps the response it already had; nothing that is not a
28
25
  * session or an `oauth-access` token gets that far at all.
29
26
  */
30
- function gateAddonJwt(input, logger) {
31
- const principal = (0, types_1.classifyBearerPrincipal)(input.payload);
27
+ export function gateAddonJwt(input, logger) {
28
+ const principal = classifyBearerPrincipal(input.payload);
32
29
  const isAdmin = input.payload.isAdmin === true;
33
30
  if (principal.kind === 'not-a-credential') {
34
31
  logger.warn('addon route: refused a bearer that is not an API credential', {
@@ -42,7 +39,7 @@ function gateAddonJwt(input, logger) {
42
39
  });
43
40
  return { ok: false, status: 403, error: 'Admin required' };
44
41
  }
45
- const verdict = (0, types_1.principalMayReachAddon)({
42
+ const verdict = principalMayReachAddon({
46
43
  principal,
47
44
  scopes: readScopes(input.payload.scopes),
48
45
  isAdmin,
@@ -1,11 +1,6 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SHARE_DEVICES_HEADER = exports.SHARE_KIND_HEADER = void 0;
4
- exports.gateAddonShareToken = gateAddonShareToken;
5
- exports.stripShareHeaders = stripShareHeaders;
6
- exports.SHARE_KIND_HEADER = 'x-camstack-share-kind';
7
- exports.SHARE_DEVICES_HEADER = 'x-camstack-share-devices';
8
- function gateAddonShareToken(input) {
1
+ export const SHARE_KIND_HEADER = 'x-camstack-share-kind';
2
+ export const SHARE_DEVICES_HEADER = 'x-camstack-share-devices';
3
+ export function gateAddonShareToken(input) {
9
4
  if (input.record === null)
10
5
  return { ok: false, status: 401, error: 'Invalid token' };
11
6
  const kind = input.record.scope.kind;
@@ -15,17 +10,17 @@ function gateAddonShareToken(input) {
15
10
  return {
16
11
  ok: true,
17
12
  headers: {
18
- [exports.SHARE_KIND_HEADER]: kind,
19
- [exports.SHARE_DEVICES_HEADER]: input.record.scope.deviceIds.join(','),
13
+ [SHARE_KIND_HEADER]: kind,
14
+ [SHARE_DEVICES_HEADER]: input.record.scope.deviceIds.join(','),
20
15
  },
21
16
  };
22
17
  }
23
18
  /** The forwarded header set without any share header the client supplied. */
24
- function stripShareHeaders(headers) {
19
+ export function stripShareHeaders(headers) {
25
20
  const out = {};
26
21
  for (const [key, value] of Object.entries(headers)) {
27
22
  const lower = key.toLowerCase();
28
- if (lower === exports.SHARE_KIND_HEADER || lower === exports.SHARE_DEVICES_HEADER)
23
+ if (lower === SHARE_KIND_HEADER || lower === SHARE_DEVICES_HEADER)
29
24
  continue;
30
25
  out[key] = value;
31
26
  }
@@ -1,8 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.APP_CONFIRM_REFUSAL_CSP = exports.APP_CONFIRM_CSP = void 0;
4
- exports.appConfirmPage = appConfirmPage;
5
- exports.appConfirmRefusalPage = appConfirmRefusalPage;
6
1
  /**
7
2
  * The hub-rendered confirmation page of a native app sign-in (D858):
8
3
  * "Sign in the CamStack app as <username>?".
@@ -16,8 +11,8 @@ exports.appConfirmRefusalPage = appConfirmRefusalPage;
16
11
  * `location` the hub answers; Cancel is a plain link to the app with
17
12
  * `error=cancelled`.
18
13
  */
19
- const app_page_shell_js_1 = require("./app-page-shell.js");
20
- const app_page_strings_js_1 = require("./app-page-strings.js");
14
+ import { appButton, appCancelLink, appErrorLine, appHint, appPageCsp, appParagraph, escapeHtml, renderAppPage, } from './app-page-shell.js';
15
+ import { appStrings } from './app-page-strings.js';
21
16
  const PAGE_SCRIPT = `(function () {
22
17
  var btn = document.getElementById('go');
23
18
  var msg = document.getElementById('msg');
@@ -43,13 +38,13 @@ const PAGE_SCRIPT = `(function () {
43
38
  });
44
39
  })();`;
45
40
  /** The CSP: the shell's style and this page's one script by hash, same-origin requests, no framing, no form posts. */
46
- exports.APP_CONFIRM_CSP = (0, app_page_shell_js_1.appPageCsp)({ script: PAGE_SCRIPT });
41
+ export const APP_CONFIRM_CSP = appPageCsp({ script: PAGE_SCRIPT });
47
42
  /** CSP of the refusal page: the shell's style only, nothing runs. */
48
- exports.APP_CONFIRM_REFUSAL_CSP = (0, app_page_shell_js_1.appPageCsp)();
43
+ export const APP_CONFIRM_REFUSAL_CSP = appPageCsp();
49
44
  /** The confirmation page for `username`; `cancelHref` is the app callback carrying `error=cancelled`. */
50
- function appConfirmPage(input) {
51
- const t = (0, app_page_strings_js_1.appStrings)(input.lang);
52
- return (0, app_page_shell_js_1.renderAppPage)({
45
+ export function appConfirmPage(input) {
46
+ const t = appStrings(input.lang);
47
+ return renderAppPage({
53
48
  lang: input.lang,
54
49
  title: t.confirm.title,
55
50
  heading: t.confirm.heading,
@@ -57,22 +52,22 @@ function appConfirmPage(input) {
57
52
  script: PAGE_SCRIPT,
58
53
  scriptStrings: { 'confirm-expired': t.script.confirmExpired },
59
54
  body: [
60
- `<p>${(0, app_page_shell_js_1.escapeHtml)(t.confirm.signedInAsBefore)}<strong>${(0, app_page_shell_js_1.escapeHtml)(input.username)}</strong>${(0, app_page_shell_js_1.escapeHtml)(t.confirm.signedInAsAfter)}</p>`,
61
- (0, app_page_shell_js_1.appHint)(t.confirm.hint),
62
- (0, app_page_shell_js_1.appButton)(t.confirm.continueLabel, `id="go" data-confirm="${(0, app_page_shell_js_1.escapeHtml)(input.token)}"`),
63
- (0, app_page_shell_js_1.appErrorLine)('msg'),
64
- (0, app_page_shell_js_1.appCancelLink)(input.cancelHref, t.confirm.cancel),
65
- `<noscript><p class="error">${(0, app_page_shell_js_1.escapeHtml)(t.confirm.noscript)}</p></noscript>`,
55
+ `<p>${escapeHtml(t.confirm.signedInAsBefore)}<strong>${escapeHtml(input.username)}</strong>${escapeHtml(t.confirm.signedInAsAfter)}</p>`,
56
+ appHint(t.confirm.hint),
57
+ appButton(t.confirm.continueLabel, `id="go" data-confirm="${escapeHtml(input.token)}"`),
58
+ appErrorLine('msg'),
59
+ appCancelLink(input.cancelHref, t.confirm.cancel),
60
+ `<noscript><p class="error">${escapeHtml(t.confirm.noscript)}</p></noscript>`,
66
61
  ].join(''),
67
62
  });
68
63
  }
69
64
  /** A confirmation that is gone (expired, used, or opened in another browser): a sentence, nothing runs. */
70
- function appConfirmRefusalPage(lang) {
71
- const t = (0, app_page_strings_js_1.appStrings)(lang).confirmExpired;
72
- return (0, app_page_shell_js_1.renderAppPage)({
65
+ export function appConfirmRefusalPage(lang) {
66
+ const t = appStrings(lang).confirmExpired;
67
+ return renderAppPage({
73
68
  lang,
74
69
  title: t.title,
75
70
  heading: t.title,
76
- body: (0, app_page_shell_js_1.appParagraph)(t.body) + (0, app_page_shell_js_1.appHint)(t.hint),
71
+ body: appParagraph(t.body) + appHint(t.hint),
77
72
  });
78
73
  }
@@ -1,8 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.APP_CONFIRM_PARAM = exports.APP_CONFIRM_PATH = void 0;
4
- exports.appConfirmCookie = appConfirmCookie;
5
- exports.registerAppConfirmRoutes = registerAppConfirmRoutes;
6
1
  /**
7
2
  * `/auth/app/confirm` - the last step of a native app sign-in (D858).
8
3
  *
@@ -13,20 +8,20 @@ exports.registerAppConfirmRoutes = registerAppConfirmRoutes;
13
8
  * the handoff code and answers `{ location }` at the app's scheme. Nothing is
14
9
  * minted without the POST, and the token is useless in any other browser.
15
10
  */
16
- const types_1 = require("@camstack/types");
17
- const zod_1 = require("zod");
18
- const app_confirmations_js_1 = require("./app-confirmations.js");
19
- const app_confirm_page_js_1 = require("./app-confirm-page.js");
20
- const app_page_strings_js_1 = require("./app-page-strings.js");
21
- const auth_rate_limit_js_1 = require("./auth-rate-limit.js");
22
- const sso_finish_deps_js_1 = require("./sso-finish-deps.js");
23
- exports.APP_CONFIRM_PATH = '/auth/app/confirm';
11
+ import { appFlowLocation } from '@camstack/types';
12
+ import { z } from 'zod';
13
+ import { APP_CONFIRM_COOKIE, } from './app-confirmations.js';
14
+ import { APP_CONFIRM_CSP, APP_CONFIRM_REFUSAL_CSP, appConfirmPage, appConfirmRefusalPage, } from './app-confirm-page.js';
15
+ import { resolveAppPageLang } from './app-page-strings.js';
16
+ import { clientKeyFromRequest } from './auth-rate-limit.js';
17
+ import { readCookie } from './sso-finish-deps.js';
18
+ export const APP_CONFIRM_PATH = '/auth/app/confirm';
24
19
  /** The query parameter carrying the token (masked in logged URLs). */
25
- exports.APP_CONFIRM_PARAM = 'confirm';
20
+ export const APP_CONFIRM_PARAM = 'confirm';
26
21
  /** `Set-Cookie` for the browser binding: HttpOnly, Lax (the entry may come from a cross-site redirect chain). */
27
- function appConfirmCookie(value, secure) {
22
+ export function appConfirmCookie(value, secure) {
28
23
  return [
29
- `${app_confirmations_js_1.APP_CONFIRM_COOKIE}=${value}`,
24
+ `${APP_CONFIRM_COOKIE}=${value}`,
30
25
  'Path=/',
31
26
  'HttpOnly',
32
27
  'SameSite=Lax',
@@ -34,7 +29,7 @@ function appConfirmCookie(value, secure) {
34
29
  ...(secure ? ['Secure'] : []),
35
30
  ].join('; ');
36
31
  }
37
- const ConfirmBodySchema = zod_1.z.object({ confirm: zod_1.z.string().min(1).max(256) });
32
+ const ConfirmBodySchema = z.object({ confirm: z.string().min(1).max(256) });
38
33
  function noStore(reply) {
39
34
  reply.header('Cache-Control', 'no-store');
40
35
  reply.header('Referrer-Policy', 'no-referrer');
@@ -48,11 +43,11 @@ function mint(deps, confirmation) {
48
43
  state: app.state,
49
44
  authMethod: confirmation.authMethod,
50
45
  });
51
- return (0, types_1.appFlowLocation)(app.redirect, { code: minted.code }, app.state);
46
+ return appFlowLocation(app.redirect, { code: minted.code }, app.state);
52
47
  }
53
- function registerAppConfirmRoutes(fastify, deps) {
48
+ export function registerAppConfirmRoutes(fastify, deps) {
54
49
  const limited = (request, reply) => {
55
- const client = (0, auth_rate_limit_js_1.clientKeyFromRequest)(request, deps.network);
50
+ const client = clientKeyFromRequest(request, deps.network);
56
51
  if (client === null)
57
52
  return false;
58
53
  const verdict = deps.limiter.check(`app-confirm:${client}`);
@@ -62,43 +57,43 @@ function registerAppConfirmRoutes(fastify, deps) {
62
57
  void reply.status(429).send({ error: 'Too many attempts' });
63
58
  return true;
64
59
  };
65
- fastify.get(exports.APP_CONFIRM_PATH, async (request, reply) => {
60
+ fastify.get(APP_CONFIRM_PATH, async (request, reply) => {
66
61
  noStore(reply);
67
62
  reply.type('text/html; charset=utf-8');
68
63
  if (limited(request, reply))
69
64
  return reply;
70
- const token = request.query[exports.APP_CONFIRM_PARAM];
65
+ const token = request.query[APP_CONFIRM_PARAM];
71
66
  const confirmation = token === undefined
72
67
  ? null
73
- : deps.confirmations.peek(token, (0, sso_finish_deps_js_1.readCookie)(request.headers.cookie, app_confirmations_js_1.APP_CONFIRM_COOKIE));
68
+ : deps.confirmations.peek(token, readCookie(request.headers.cookie, APP_CONFIRM_COOKIE));
74
69
  if (token === undefined || confirmation === null) {
75
70
  deps.logger.warn('App sign-in confirmation page refused', {
76
71
  meta: { reason: 'unknown-expired-or-other-browser' },
77
72
  });
78
- reply.header('Content-Security-Policy', app_confirm_page_js_1.APP_CONFIRM_REFUSAL_CSP);
73
+ reply.header('Content-Security-Policy', APP_CONFIRM_REFUSAL_CSP);
79
74
  return reply
80
75
  .status(400)
81
- .send((0, app_confirm_page_js_1.appConfirmRefusalPage)((0, app_page_strings_js_1.resolveAppPageLang)({ acceptLanguage: request.headers['accept-language'] })));
76
+ .send(appConfirmRefusalPage(resolveAppPageLang({ acceptLanguage: request.headers['accept-language'] })));
82
77
  }
83
- reply.header('Content-Security-Policy', app_confirm_page_js_1.APP_CONFIRM_CSP);
84
- return reply.send((0, app_confirm_page_js_1.appConfirmPage)({
85
- lang: (0, app_page_strings_js_1.resolveAppPageLang)({
78
+ reply.header('Content-Security-Policy', APP_CONFIRM_CSP);
79
+ return reply.send(appConfirmPage({
80
+ lang: resolveAppPageLang({
86
81
  lang: confirmation.app.lang,
87
82
  acceptLanguage: request.headers['accept-language'],
88
83
  }),
89
84
  username: confirmation.username,
90
85
  token,
91
- cancelHref: (0, types_1.appFlowLocation)(confirmation.app.redirect, { error: 'cancelled' }, confirmation.app.state),
86
+ cancelHref: appFlowLocation(confirmation.app.redirect, { error: 'cancelled' }, confirmation.app.state),
92
87
  }));
93
88
  });
94
- fastify.post(exports.APP_CONFIRM_PATH, async (request, reply) => {
89
+ fastify.post(APP_CONFIRM_PATH, async (request, reply) => {
95
90
  noStore(reply);
96
91
  if (limited(request, reply))
97
92
  return reply;
98
93
  const body = ConfirmBodySchema.safeParse(request.body);
99
94
  if (!body.success)
100
95
  return reply.status(400).send({ error: 'Malformed confirmation.' });
101
- const confirmation = deps.confirmations.consume(body.data.confirm, (0, sso_finish_deps_js_1.readCookie)(request.headers.cookie, app_confirmations_js_1.APP_CONFIRM_COOKIE));
96
+ const confirmation = deps.confirmations.consume(body.data.confirm, readCookie(request.headers.cookie, APP_CONFIRM_COOKIE));
102
97
  if (confirmation === null) {
103
98
  deps.logger.warn('App sign-in confirmation refused', {
104
99
  meta: { reason: 'unknown-used-expired-or-other-browser' },
@@ -1,40 +1,4 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.AppConfirmations = exports.APP_CONFIRM_COOKIE = exports.APP_CONFIRM_TTL_MS = void 0;
37
- const types_1 = require("@camstack/types");
1
+ import { userError } from '@camstack/types';
38
2
  /**
39
3
  * Pending "Sign in the CamStack app as <user>?" confirmations (D858).
40
4
  *
@@ -52,18 +16,18 @@ const types_1 = require("@camstack/types");
52
16
  *
53
17
  * In-memory only: a hub restart simply means the person signs in again.
54
18
  */
55
- const crypto = __importStar(require("node:crypto"));
56
- exports.APP_CONFIRM_TTL_MS = 120_000;
19
+ import * as crypto from 'node:crypto';
20
+ export const APP_CONFIRM_TTL_MS = 120_000;
57
21
  const MAX_PENDING = 500;
58
22
  /** The cookie that binds a confirmation to the browser that finished the ceremony. */
59
- exports.APP_CONFIRM_COOKIE = 'camstack_app_confirm';
23
+ export const APP_CONFIRM_COOKIE = 'camstack_app_confirm';
60
24
  const sha256 = (value) => crypto.createHash('sha256').update(value).digest('hex');
61
25
  function sameDigest(a, b) {
62
26
  const left = Buffer.from(a, 'utf8');
63
27
  const right = Buffer.from(b, 'utf8');
64
28
  return left.length === right.length && crypto.timingSafeEqual(left, right);
65
29
  }
66
- class AppConfirmations {
30
+ export class AppConfirmations {
67
31
  now;
68
32
  /** Keyed by SHA-256(token). */
69
33
  pending = new Map();
@@ -74,13 +38,13 @@ class AppConfirmations {
74
38
  create(confirmation) {
75
39
  this.prune();
76
40
  if (this.pending.size >= MAX_PENDING)
77
- throw (0, types_1.userError)('server.app-confirmations-busy', undefined, 'Too many pending app confirmations');
41
+ throw userError('server.app-confirmations-busy', undefined, 'Too many pending app confirmations');
78
42
  const token = crypto.randomBytes(32).toString('base64url');
79
43
  const cookie = crypto.randomBytes(32).toString('base64url');
80
44
  this.pending.set(sha256(token), {
81
45
  ...confirmation,
82
46
  cookieHash: sha256(cookie),
83
- expiresAt: this.now() + exports.APP_CONFIRM_TTL_MS,
47
+ expiresAt: this.now() + APP_CONFIRM_TTL_MS,
84
48
  });
85
49
  return { token, cookie };
86
50
  }
@@ -126,4 +90,3 @@ class AppConfirmations {
126
90
  this.pending.delete(key);
127
91
  }
128
92
  }
129
- exports.AppConfirmations = AppConfirmations;