@camstack/server 1.2.593 → 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 +218 -222
  103. package/dist/api/trpc/generated-cap-routers.js +4688 -4850
  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 +199 -185
  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,33 +1,28 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toWireReason = toWireReason;
4
- exports.refusal = refusal;
5
- exports.createDeviceCertProcedures = createDeviceCertProcedures;
6
- const system_1 = require("@camstack/system");
7
- const types_1 = require("@camstack/types");
8
- const server_1 = require("@trpc/server");
9
- const zod_1 = require("zod");
10
- const session_mint_js_1 = require("../../auth/session-mint.js");
11
- const trpc_middleware_js_1 = require("../trpc/trpc.middleware.js");
12
- const auth_reauth_procedures_js_1 = require("./auth-reauth.procedures.js");
13
- const user_error_js_1 = require("../trpc/user-error.js");
14
- const DeviceLoginResultSchema = zod_1.z.discriminatedUnion('ok', [
15
- zod_1.z.object({
16
- ok: zod_1.z.literal(true),
17
- token: zod_1.z.string(),
18
- user: zod_1.z.object({ id: zod_1.z.string(), username: zod_1.z.string(), isAdmin: zod_1.z.boolean() }),
19
- expiresAt: zod_1.z.number().optional(),
20
- sessionId: zod_1.z.string().optional(),
21
- sessionExpiresAt: zod_1.z.number().optional(),
22
- refreshToken: zod_1.z.string().optional(),
23
- credentialId: zod_1.z.string(),
1
+ import { getUserManagementInternal } from '@camstack/system';
2
+ import { CompleteEnrollmentInputSchema, CompleteEnrollmentResultSchema, DEVICE_CERT_SIGNATURE, DeviceChallengeResultSchema, DeviceCredentialSchema, DeviceEnrollProofSchema, DeviceProofInputSchema, DeviceRefusalSchema, EnrollSelfInputSchema, formatDeviceRevoker, isDefinitiveDeviceRefusal, RenewDeviceCertificateResultSchema, RevokeOwnDeviceCertificateResultSchema, } from '@camstack/types';
3
+ import { TRPCError } from '@trpc/server';
4
+ import { z } from 'zod';
5
+ import { SessionUserGoneError, } from '../../auth/session-mint.js';
6
+ import { protectedProcedure } from '../trpc/trpc.middleware.js';
7
+ import { assertReauthenticated, ReauthTokenInput } from './auth-reauth.procedures.js';
8
+ import { trpcUserError } from '../trpc/user-error.js';
9
+ const DeviceLoginResultSchema = z.discriminatedUnion('ok', [
10
+ z.object({
11
+ ok: z.literal(true),
12
+ token: z.string(),
13
+ user: z.object({ id: z.string(), username: z.string(), isAdmin: z.boolean() }),
14
+ expiresAt: z.number().optional(),
15
+ sessionId: z.string().optional(),
16
+ sessionExpiresAt: z.number().optional(),
17
+ refreshToken: z.string().optional(),
18
+ credentialId: z.string(),
24
19
  /** The certificate's expiry (epoch ms): the app renews when < 30 days remain. */
25
- certNotAfter: zod_1.z.number(),
20
+ certNotAfter: z.number(),
26
21
  }),
27
- types_1.DeviceRefusalSchema,
22
+ DeviceRefusalSchema,
28
23
  ]);
29
24
  /** Internal manager reason → the wire reason an app switches on. */
30
- function toWireReason(reason) {
25
+ export function toWireReason(reason) {
31
26
  switch (reason) {
32
27
  case 'revoked':
33
28
  case 'unknown-credential':
@@ -58,11 +53,11 @@ function toWireReason(reason) {
58
53
  return 'superseded';
59
54
  }
60
55
  }
61
- function refusal(reason, retryAfterSeconds) {
56
+ export function refusal(reason, retryAfterSeconds) {
62
57
  return {
63
58
  ok: false,
64
59
  reason,
65
- definitive: (0, types_1.isDefinitiveDeviceRefusal)(reason),
60
+ definitive: isDefinitiveDeviceRefusal(reason),
66
61
  ...(retryAfterSeconds !== undefined ? { retryAfterSeconds } : {}),
67
62
  };
68
63
  }
@@ -70,13 +65,13 @@ function fromAddress(req, network) {
70
65
  const ip = network.clientAddress(req).ip;
71
66
  return ip ?? undefined;
72
67
  }
73
- function createDeviceCertProcedures(deps) {
68
+ export function createDeviceCertProcedures(deps) {
74
69
  const internal = () => {
75
70
  const found = deps.registry === null
76
71
  ? null
77
- : (0, system_1.getUserManagementInternal)(deps.registry.getSingleton('user-management'));
72
+ : getUserManagementInternal(deps.registry.getSingleton('user-management'));
78
73
  if (found === null) {
79
- throw (0, user_error_js_1.trpcUserError)('PRECONDITION_FAILED', 'device.certificates-unavailable', undefined, 'Device certificates are not available');
74
+ throw trpcUserError('PRECONDITION_FAILED', 'device.certificates-unavailable', undefined, 'Device certificates are not available');
80
75
  }
81
76
  return found;
82
77
  };
@@ -111,13 +106,13 @@ function createDeviceCertProcedures(deps) {
111
106
  };
112
107
  const assertPerson = (user) => {
113
108
  if (user.isScoped === true || user.shareView !== undefined || user.adminTokenId !== undefined) {
114
- throw (0, user_error_js_1.trpcUserError)('FORBIDDEN', 'auth.session-required', undefined, 'Requires a signed-in user session');
109
+ throw trpcUserError('FORBIDDEN', 'auth.session-required', undefined, 'Requires a signed-in user session');
115
110
  }
116
111
  };
117
112
  const selfLimit = (userId, path) => {
118
113
  const verdict = deps.selfLimiter.check(`${path}:${userId}`);
119
114
  if (!verdict.allowed) {
120
- throw new server_1.TRPCError({
115
+ throw new TRPCError({
121
116
  code: 'TOO_MANY_REQUESTS',
122
117
  message: `Too many attempts — retry in ${verdict.retryAfterSeconds}s`,
123
118
  });
@@ -126,8 +121,8 @@ function createDeviceCertProcedures(deps) {
126
121
  return {
127
122
  /** PUBLIC — redeem a QR enrollment code with the device's PUBLIC key; answers the certificate. */
128
123
  completeEnrollment: deps.publicProcedure
129
- .input(types_1.CompleteEnrollmentInputSchema)
130
- .output(types_1.CompleteEnrollmentResultSchema)
124
+ .input(CompleteEnrollmentInputSchema)
125
+ .output(CompleteEnrollmentResultSchema)
131
126
  .mutation(async ({ input, ctx }) => {
132
127
  const slow = limited(deps.credentialLimiter, 'completeEnrollment', ctx.req);
133
128
  if (slow !== null)
@@ -150,8 +145,8 @@ function createDeviceCertProcedures(deps) {
150
145
  }),
151
146
  /** PUBLIC — a single-use nonce (60 s), bound to the hub origin this request is entitled to. */
152
147
  getDeviceChallenge: deps.publicProcedure
153
- .input(zod_1.z.void())
154
- .output(types_1.DeviceChallengeResultSchema)
148
+ .input(z.void())
149
+ .output(DeviceChallengeResultSchema)
155
150
  .mutation(async ({ ctx }) => {
156
151
  const slow = limited(deps.ceremonyLimiter, 'getDeviceChallenge', ctx.req);
157
152
  if (slow !== null)
@@ -167,7 +162,7 @@ function createDeviceCertProcedures(deps) {
167
162
  if (origin === null)
168
163
  return refusal('unavailable');
169
164
  const { nonce, expiresAt } = internal().deviceCredentials.issueNonce(origin, partition);
170
- return { ok: true, nonce, origin, expiresAt, signature: types_1.DEVICE_CERT_SIGNATURE };
165
+ return { ok: true, nonce, origin, expiresAt, signature: DEVICE_CERT_SIGNATURE };
171
166
  }),
172
167
  /**
173
168
  * PUBLIC — sign in with the device certificate: chain to the device CA, not
@@ -175,7 +170,7 @@ function createDeviceCertProcedures(deps) {
175
170
  * Opens the SAME session a password login opens, carrying the credential id.
176
171
  */
177
172
  loginWithDeviceCertificate: deps.publicProcedure
178
- .input(types_1.DeviceProofInputSchema.extend({ refreshable: zod_1.z.boolean().optional() }))
173
+ .input(DeviceProofInputSchema.extend({ refreshable: z.boolean().optional() }))
179
174
  .output(DeviceLoginResultSchema)
180
175
  .mutation(async ({ input, ctx }) => {
181
176
  const slow = limited(deps.credentialLimiter, 'loginWithDeviceCertificate', ctx.req);
@@ -220,7 +215,7 @@ function createDeviceCertProcedures(deps) {
220
215
  };
221
216
  }
222
217
  catch (error) {
223
- if (error instanceof session_mint_js_1.SessionUserGoneError) {
218
+ if (error instanceof SessionUserGoneError) {
224
219
  deps.logger?.warn('Device certificate login refused: user-gone', {
225
220
  tags: { credentialId: credential.id, userId: credential.userId },
226
221
  });
@@ -231,8 +226,8 @@ function createDeviceCertProcedures(deps) {
231
226
  }),
232
227
  /** PUBLIC — a new leaf for the SAME public key, while the certificate is valid and not revoked. */
233
228
  renewDeviceCertificate: deps.publicProcedure
234
- .input(types_1.DeviceProofInputSchema)
235
- .output(types_1.RenewDeviceCertificateResultSchema)
229
+ .input(DeviceProofInputSchema)
230
+ .output(RenewDeviceCertificateResultSchema)
236
231
  .mutation(async ({ input, ctx }) => {
237
232
  const slow = limited(deps.credentialLimiter, 'renewDeviceCertificate', ctx.req);
238
233
  if (slow !== null)
@@ -261,8 +256,8 @@ function createDeviceCertProcedures(deps) {
261
256
  * purpose): works with no session. Ends every session the credential opened.
262
257
  */
263
258
  revokeOwnDeviceCertificate: deps.publicProcedure
264
- .input(types_1.DeviceProofInputSchema)
265
- .output(types_1.RevokeOwnDeviceCertificateResultSchema)
259
+ .input(DeviceProofInputSchema)
260
+ .output(RevokeOwnDeviceCertificateResultSchema)
266
261
  .mutation(async ({ input, ctx }) => {
267
262
  const slow = limited(deps.credentialLimiter, 'revokeOwnDeviceCertificate', ctx.req);
268
263
  if (slow !== null)
@@ -276,7 +271,7 @@ function createDeviceCertProcedures(deps) {
276
271
  if (!checked.ok)
277
272
  return refusal(toWireReason(checked.reason));
278
273
  const id = checked.credential.id;
279
- await internal().deviceCredentials.revoke(id, (0, types_1.formatDeviceRevoker)({ kind: 'device' }));
274
+ await internal().deviceCredentials.revoke(id, formatDeviceRevoker({ kind: 'device' }));
280
275
  const sessionsEnded = await internal().sessions.revokeByCredential(id);
281
276
  await audit('device-credential-revoked', checked.credential.userId, ctx.req, {
282
277
  credentialId: id,
@@ -287,9 +282,9 @@ function createDeviceCertProcedures(deps) {
287
282
  }),
288
283
  // ── Signed-in legs ───────────────────────────────────────────────
289
284
  /** The caller's own device credentials (live ones, and revoked when asked). */
290
- listOwnDeviceCredentials: trpc_middleware_js_1.protectedProcedure
291
- .input(zod_1.z.object({ includeRevoked: zod_1.z.boolean().optional() }).optional())
292
- .output(zod_1.z.array(types_1.DeviceCredentialSchema))
285
+ listOwnDeviceCredentials: protectedProcedure
286
+ .input(z.object({ includeRevoked: z.boolean().optional() }).optional())
287
+ .output(z.array(DeviceCredentialSchema))
293
288
  .query(({ ctx, input }) => {
294
289
  assertPerson(ctx.user);
295
290
  const manager = internal().deviceCredentials;
@@ -317,9 +312,9 @@ function createDeviceCertProcedures(deps) {
317
312
  }));
318
313
  }),
319
314
  /** Revoke one of the caller's OWN credentials by id, from a session (e.g. a lost phone). */
320
- revokeOwnDeviceCredential: trpc_middleware_js_1.protectedProcedure
321
- .input(zod_1.z.object({ id: zod_1.z.string().min(1) }))
322
- .output(zod_1.z.object({ revoked: zod_1.z.boolean(), sessionsEnded: zod_1.z.number().int() }))
315
+ revokeOwnDeviceCredential: protectedProcedure
316
+ .input(z.object({ id: z.string().min(1) }))
317
+ .output(z.object({ revoked: z.boolean(), sessionsEnded: z.number().int() }))
323
318
  .mutation(async ({ ctx, input }) => {
324
319
  assertPerson(ctx.user);
325
320
  selfLimit(ctx.user.id, 'revokeOwnDeviceCredential');
@@ -331,7 +326,7 @@ function createDeviceCertProcedures(deps) {
331
326
  });
332
327
  return { revoked: false, sessionsEnded: 0 };
333
328
  }
334
- const revoked = await internal().deviceCredentials.revoke(input.id, (0, types_1.formatDeviceRevoker)({ kind: 'user', userId: ctx.user.id }));
329
+ const revoked = await internal().deviceCredentials.revoke(input.id, formatDeviceRevoker({ kind: 'user', userId: ctx.user.id }));
335
330
  const sessionsEnded = await internal().sessions.revokeByCredential(input.id);
336
331
  if (revoked) {
337
332
  await audit('device-credential-revoked', ctx.user.id, ctx.req, {
@@ -343,16 +338,16 @@ function createDeviceCertProcedures(deps) {
343
338
  return { revoked, sessionsEnded };
344
339
  }),
345
340
  /** Step-up, password / passkey: turn a fresh `reauthenticate` proof into a single-use device-enroll proof. */
346
- deviceEnrollProofFromReauth: trpc_middleware_js_1.protectedProcedure
347
- .input(zod_1.z.object({ reauthToken: auth_reauth_procedures_js_1.ReauthTokenInput }))
348
- .output(types_1.DeviceEnrollProofSchema)
341
+ deviceEnrollProofFromReauth: protectedProcedure
342
+ .input(z.object({ reauthToken: ReauthTokenInput }))
343
+ .output(DeviceEnrollProofSchema)
349
344
  .mutation(({ ctx, input }) => {
350
345
  assertPerson(ctx.user);
351
346
  selfLimit(ctx.user.id, 'deviceEnrollProofFromReauth');
352
- (0, auth_reauth_procedures_js_1.assertReauthenticated)(deps.auth, ctx.user, input.reauthToken);
347
+ assertReauthenticated(deps.auth, ctx.user, input.reauthToken);
353
348
  // One reauthentication, one proof (or one step-up handoff code).
354
349
  if (!deps.enrollProofs.consumeReauth(input.reauthToken)) {
355
- throw new server_1.TRPCError({
350
+ throw new TRPCError({
356
351
  code: 'FORBIDDEN',
357
352
  message: 'This re-authentication was already used - confirm it is you again',
358
353
  });
@@ -364,13 +359,13 @@ function createDeviceCertProcedures(deps) {
364
359
  * `code` is a handoff code minted with purpose `step-up` by a browser sign-in
365
360
  * of the SAME user. Opens no session and replaces none.
366
361
  */
367
- deviceEnrollProofFromHandoff: trpc_middleware_js_1.protectedProcedure
368
- .input(zod_1.z.object({
369
- code: zod_1.z.string().min(1).max(256),
370
- codeVerifier: zod_1.z.string().min(1).max(256).optional(),
371
- state: zod_1.z.string().min(1).max(256).optional(),
362
+ deviceEnrollProofFromHandoff: protectedProcedure
363
+ .input(z.object({
364
+ code: z.string().min(1).max(256),
365
+ codeVerifier: z.string().min(1).max(256).optional(),
366
+ state: z.string().min(1).max(256).optional(),
372
367
  }))
373
- .output(types_1.DeviceEnrollProofSchema)
368
+ .output(DeviceEnrollProofSchema)
374
369
  .mutation(({ ctx, input }) => {
375
370
  assertPerson(ctx.user);
376
371
  selfLimit(ctx.user.id, 'deviceEnrollProofFromHandoff');
@@ -386,7 +381,7 @@ function createDeviceCertProcedures(deps) {
386
381
  reason: reason ?? (grant?.purpose !== 'step-up' ? 'wrong-purpose' : 'other-user'),
387
382
  },
388
383
  });
389
- throw new server_1.TRPCError({
384
+ throw new TRPCError({
390
385
  code: 'UNAUTHORIZED',
391
386
  message: 'Invalid, expired or mismatched step-up code — sign in again',
392
387
  });
@@ -399,9 +394,9 @@ function createDeviceCertProcedures(deps) {
399
394
  * a merely refreshed session can never mint a permanent credential.
400
395
  * Hub-wide `deviceCertificates.selfEnrollment = disabled` refuses.
401
396
  */
402
- enrollSelf: trpc_middleware_js_1.protectedProcedure
403
- .input(types_1.EnrollSelfInputSchema)
404
- .output(types_1.CompleteEnrollmentResultSchema)
397
+ enrollSelf: protectedProcedure
398
+ .input(EnrollSelfInputSchema)
399
+ .output(CompleteEnrollmentResultSchema)
405
400
  .mutation(async ({ ctx, input }) => {
406
401
  assertPerson(ctx.user);
407
402
  selfLimit(ctx.user.id, 'enrollSelf');
@@ -1,12 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PROCESS_AUTH_LIMITERS = void 0;
4
- exports.createAuthLimiters = createAuthLimiters;
5
- exports.tooMany = tooMany;
6
- exports.limitByClient = limitByClient;
7
- exports.assertAccountNotLocked = assertAccountNotLocked;
8
- exports.recordAccountFailure = recordAccountFailure;
9
- exports.limitByUser = limitByUser;
10
1
  /**
11
2
  * Rate limits of the public auth surface, in one place.
12
3
  *
@@ -29,29 +20,29 @@ exports.limitByUser = limitByUser;
29
20
  *
30
21
  * Mesh-internal calls (no originating request) are never limited.
31
22
  */
32
- const server_1 = require("@trpc/server");
33
- const auth_network_policy_js_1 = require("../../auth/auth-network-policy.js");
34
- const auth_rate_limit_js_1 = require("../../auth/auth-rate-limit.js");
35
- function createAuthLimiters(now) {
23
+ import { TRPCError } from '@trpc/server';
24
+ import { DEFAULT_AUTH_NETWORK_POLICY, } from '../../auth/auth-network-policy.js';
25
+ import { createRateLimiter } from '../../auth/auth-rate-limit.js';
26
+ export function createAuthLimiters(now) {
36
27
  const clock = now !== undefined ? { now } : {};
37
28
  return {
38
- credential: (0, auth_rate_limit_js_1.createRateLimiter)({ windowMs: 60_000, max: 10, ...clock }),
39
- ceremony: (0, auth_rate_limit_js_1.createRateLimiter)({ windowMs: 60_000, max: 30, ...clock }),
40
- accountFailures: (0, auth_rate_limit_js_1.createRateLimiter)({ windowMs: 15 * 60_000, max: 20, ...clock }),
41
- link: (0, auth_rate_limit_js_1.createRateLimiter)({ windowMs: 60_000, max: 5, ...clock }),
42
- reauth: (0, auth_rate_limit_js_1.createRateLimiter)({ windowMs: 60_000, max: 10, ...clock }),
29
+ credential: createRateLimiter({ windowMs: 60_000, max: 10, ...clock }),
30
+ ceremony: createRateLimiter({ windowMs: 60_000, max: 30, ...clock }),
31
+ accountFailures: createRateLimiter({ windowMs: 15 * 60_000, max: 20, ...clock }),
32
+ link: createRateLimiter({ windowMs: 60_000, max: 5, ...clock }),
33
+ reauth: createRateLimiter({ windowMs: 60_000, max: 10, ...clock }),
43
34
  };
44
35
  }
45
36
  /** The process-wide limiters: router rebuilds must not reset an attacker's budget. */
46
- exports.PROCESS_AUTH_LIMITERS = createAuthLimiters();
47
- function tooMany(retryAfterSeconds) {
48
- return new server_1.TRPCError({
37
+ export const PROCESS_AUTH_LIMITERS = createAuthLimiters();
38
+ export function tooMany(retryAfterSeconds) {
39
+ return new TRPCError({
49
40
  code: 'TOO_MANY_REQUESTS',
50
41
  message: `Too many attempts — retry in ${retryAfterSeconds}s`,
51
42
  });
52
43
  }
53
44
  /** Count one attempt from the request's client address; throws when over. */
54
- function limitByClient(limiter, bucket, req, network = auth_network_policy_js_1.DEFAULT_AUTH_NETWORK_POLICY) {
45
+ export function limitByClient(limiter, bucket, req, network = DEFAULT_AUTH_NETWORK_POLICY) {
55
46
  const ip = network.clientAddress(req).ip;
56
47
  if (ip === null)
57
48
  return;
@@ -60,17 +51,17 @@ function limitByClient(limiter, bucket, req, network = auth_network_policy_js_1.
60
51
  throw tooMany(verdict.retryAfterSeconds);
61
52
  }
62
53
  /** Refuse before checking a secret when `account` already failed too often. */
63
- function assertAccountNotLocked(limiters, account) {
54
+ export function assertAccountNotLocked(limiters, account) {
64
55
  const verdict = limiters.accountFailures.peek(`account:${account.toLowerCase()}`);
65
56
  if (!verdict.allowed)
66
57
  throw tooMany(verdict.retryAfterSeconds);
67
58
  }
68
59
  /** Count one failed secret against `account`. */
69
- function recordAccountFailure(limiters, account) {
60
+ export function recordAccountFailure(limiters, account) {
70
61
  limiters.accountFailures.check(`account:${account.toLowerCase()}`);
71
62
  }
72
63
  /** Count one call of an authenticated leg against the user; throws when over. */
73
- function limitByUser(limiter, bucket, userId) {
64
+ export function limitByUser(limiter, bucket, userId) {
74
65
  const verdict = limiter.check(`${bucket}:${userId}`);
75
66
  if (!verdict.allowed)
76
67
  throw tooMany(verdict.retryAfterSeconds);
@@ -1,28 +1,23 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.REAUTH_REQUIRED_MESSAGE = exports.ReauthTokenInput = void 0;
4
- exports.assertReauthenticated = assertReauthenticated;
5
- exports.createReauthProcedures = createReauthProcedures;
6
- const server_1 = require("@trpc/server");
7
- const zod_1 = require("zod");
8
- const passkey_provider_js_1 = require("../../auth/passkey-provider.js");
9
- const trpc_middleware_js_1 = require("../trpc/trpc.middleware.js");
10
- const auth_limits_js_1 = require("./auth-limits.js");
11
- const user_error_js_1 = require("../trpc/user-error.js");
1
+ import { TRPCError } from '@trpc/server';
2
+ import { z } from 'zod';
3
+ import { OptionsJsonSchema, resolvePasskeyProvider } from '../../auth/passkey-provider.js';
4
+ import { protectedProcedure } from '../trpc/trpc.middleware.js';
5
+ import { assertAccountNotLocked, limitByUser, recordAccountFailure, } from './auth-limits.js';
6
+ import { trpcUserError } from '../trpc/user-error.js';
12
7
  /** The input field a re-auth-gated procedure takes. */
13
- exports.ReauthTokenInput = zod_1.z.string().min(1).max(4096);
14
- exports.REAUTH_REQUIRED_MESSAGE = 'Confirm it is you first: re-enter your password or use a passkey (update the app if it cannot ask).';
8
+ export const ReauthTokenInput = z.string().min(1).max(4096);
9
+ export const REAUTH_REQUIRED_MESSAGE = 'Confirm it is you first: re-enter your password or use a passkey (update the app if it cannot ask).';
15
10
  /**
16
11
  * Throw unless `reauthToken` is a live proof by THIS user, made in THIS
17
12
  * session. A missing token is the same refusal: the action needs one.
18
13
  */
19
- function assertReauthenticated(auth, user, reauthToken) {
14
+ export function assertReauthenticated(auth, user, reauthToken) {
20
15
  const claims = reauthToken === undefined ? null : auth.verifyReauthToken(reauthToken);
21
16
  const valid = claims !== null &&
22
17
  claims.userId === user.id &&
23
18
  (user.sessionId === undefined || claims.sessionId === user.sessionId);
24
19
  if (!valid)
25
- throw new server_1.TRPCError({ code: 'FORBIDDEN', message: exports.REAUTH_REQUIRED_MESSAGE });
20
+ throw new TRPCError({ code: 'FORBIDDEN', message: REAUTH_REQUIRED_MESSAGE });
26
21
  }
27
22
  function isPasswordChecker(value) {
28
23
  return (value !== null &&
@@ -32,19 +27,19 @@ function isPasswordChecker(value) {
32
27
  /** Real user sessions only: a scoped or share token cannot prove a password. */
33
28
  function assertPerson(user) {
34
29
  if (user.isScoped === true || user.shareView !== undefined || user.adminTokenId !== undefined) {
35
- throw (0, user_error_js_1.trpcUserError)('FORBIDDEN', 'auth.session-required', undefined, 'Requires a signed-in user session');
30
+ throw trpcUserError('FORBIDDEN', 'auth.session-required', undefined, 'Requires a signed-in user session');
36
31
  }
37
32
  }
38
- function createReauthProcedures(deps) {
33
+ export function createReauthProcedures(deps) {
39
34
  return {
40
35
  /** Passkey re-authentication, step 1: assertion options for the caller's own credentials. */
41
- reauthBeginPasskey: trpc_middleware_js_1.protectedProcedure
42
- .input(zod_1.z.void())
43
- .output(passkey_provider_js_1.OptionsJsonSchema)
36
+ reauthBeginPasskey: protectedProcedure
37
+ .input(z.void())
38
+ .output(OptionsJsonSchema)
44
39
  .mutation(async ({ ctx }) => {
45
40
  assertPerson(ctx.user);
46
- (0, auth_limits_js_1.limitByUser)(deps.limiters.reauth, 'auth.reauthBeginPasskey', ctx.user.id);
47
- const provider = (0, passkey_provider_js_1.resolvePasskeyProvider)(deps.registry, deps.moleculer);
41
+ limitByUser(deps.limiters.reauth, 'auth.reauthBeginPasskey', ctx.user.id);
42
+ const provider = resolvePasskeyProvider(deps.registry, deps.moleculer);
48
43
  if (!provider)
49
44
  throw new Error('Passkey authentication is not available');
50
45
  return provider.beginAuthentication({ userId: ctx.user.id });
@@ -54,20 +49,20 @@ function createReauthProcedures(deps) {
54
49
  * `reauthBeginPasskey`. Answers a 5-minute proof for the re-auth-gated
55
50
  * actions, valid only for this user in this session.
56
51
  */
57
- reauthenticate: trpc_middleware_js_1.protectedProcedure
58
- .input(zod_1.z.union([
59
- zod_1.z.object({ password: zod_1.z.string().min(1).max(1024) }),
60
- zod_1.z.object({ passkeyResponse: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()) }),
52
+ reauthenticate: protectedProcedure
53
+ .input(z.union([
54
+ z.object({ password: z.string().min(1).max(1024) }),
55
+ z.object({ passkeyResponse: z.record(z.string(), z.unknown()) }),
61
56
  ]))
62
- .output(zod_1.z.object({
63
- reauthToken: zod_1.z.string(),
64
- expiresAt: zod_1.z.number(),
65
- method: zod_1.z.enum(['password', 'passkey']),
57
+ .output(z.object({
58
+ reauthToken: z.string(),
59
+ expiresAt: z.number(),
60
+ method: z.enum(['password', 'passkey']),
66
61
  }))
67
62
  .mutation(async ({ ctx, input }) => {
68
63
  assertPerson(ctx.user);
69
- (0, auth_limits_js_1.limitByUser)(deps.limiters.reauth, 'auth.reauthenticate', ctx.user.id);
70
- (0, auth_limits_js_1.assertAccountNotLocked)(deps.limiters, ctx.user.username);
64
+ limitByUser(deps.limiters.reauth, 'auth.reauthenticate', ctx.user.id);
65
+ assertAccountNotLocked(deps.limiters, ctx.user.username);
71
66
  let method;
72
67
  if ('password' in input) {
73
68
  const userMgmt = deps.registry?.getSingleton('user-management');
@@ -79,13 +74,13 @@ function createReauthProcedures(deps) {
79
74
  password: input.password,
80
75
  });
81
76
  if (record === null || record.id !== ctx.user.id) {
82
- (0, auth_limits_js_1.recordAccountFailure)(deps.limiters, ctx.user.username);
83
- throw (0, user_error_js_1.trpcUserError)('UNAUTHORIZED', 'auth.password-incorrect', undefined, 'Password is incorrect');
77
+ recordAccountFailure(deps.limiters, ctx.user.username);
78
+ throw trpcUserError('UNAUTHORIZED', 'auth.password-incorrect', undefined, 'Password is incorrect');
84
79
  }
85
80
  method = 'password';
86
81
  }
87
82
  else {
88
- const provider = (0, passkey_provider_js_1.resolvePasskeyProvider)(deps.registry, deps.moleculer);
83
+ const provider = resolvePasskeyProvider(deps.registry, deps.moleculer);
89
84
  if (!provider)
90
85
  throw new Error('Passkey authentication is not available');
91
86
  const result = await provider.finishAuthentication({
@@ -93,8 +88,8 @@ function createReauthProcedures(deps) {
93
88
  response: input.passkeyResponse,
94
89
  });
95
90
  if (!result.verified) {
96
- (0, auth_limits_js_1.recordAccountFailure)(deps.limiters, ctx.user.username);
97
- throw (0, user_error_js_1.trpcUserError)('UNAUTHORIZED', 'auth.passkey-verification-failed', undefined, 'Passkey verification failed');
91
+ recordAccountFailure(deps.limiters, ctx.user.username);
92
+ throw trpcUserError('UNAUTHORIZED', 'auth.passkey-verification-failed', undefined, 'Passkey verification failed');
98
93
  }
99
94
  method = 'passkey';
100
95
  }
@@ -1,36 +1,32 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RevokeSkipReasonSchema = exports.RevocableCredentialKindSchema = exports.REVOKE_CREDENTIALS_MAX = void 0;
4
- exports.createRevokeCredentialsProcedures = createRevokeCredentialsProcedures;
5
- const server_1 = require("@trpc/server");
6
- const zod_1 = require("zod");
7
- const hub_sessions_js_1 = require("../../auth/hub-sessions.js");
8
- const trpc_middleware_js_1 = require("../trpc/trpc.middleware.js");
1
+ import { TRPCError } from '@trpc/server';
2
+ import { z } from 'zod';
3
+ import { userManagementInternal } from '../../auth/hub-sessions.js';
4
+ import { adminProcedure } from '../trpc/trpc.middleware.js';
9
5
  /** Upper bound of one bulk call — a page of a table, several times over. */
10
- exports.REVOKE_CREDENTIALS_MAX = 500;
6
+ export const REVOKE_CREDENTIALS_MAX = 500;
11
7
  /** What a bulk revoke can target. Each has a per-row revoke on the server. */
12
- exports.RevocableCredentialKindSchema = zod_1.z.enum([
8
+ export const RevocableCredentialKindSchema = z.enum([
13
9
  'share-link',
14
10
  'admin-token',
15
11
  'login-session',
16
12
  'scoped-token',
17
13
  'oauth-session',
18
14
  ]);
19
- exports.RevokeSkipReasonSchema = zod_1.z.enum(['current-session', 'not-active']);
20
- const RevokeCredentialsInputSchema = zod_1.z
15
+ export const RevokeSkipReasonSchema = z.enum(['current-session', 'not-active']);
16
+ const RevokeCredentialsInputSchema = z
21
17
  .object({
22
- kind: exports.RevocableCredentialKindSchema,
23
- ids: zod_1.z.array(zod_1.z.string().min(1)).min(1).max(exports.REVOKE_CREDENTIALS_MAX),
18
+ kind: RevocableCredentialKindSchema,
19
+ ids: z.array(z.string().min(1)).min(1).max(REVOKE_CREDENTIALS_MAX),
24
20
  /** The count the operator confirmed. Must equal `ids.length`. */
25
- confirmCount: zod_1.z.number().int().min(1),
21
+ confirmCount: z.number().int().min(1),
26
22
  })
27
23
  .refine((input) => new Set(input.ids).size === input.ids.length, {
28
24
  message: 'Each id may be listed once',
29
25
  path: ['ids'],
30
26
  });
31
- const RevokeCredentialsOutputSchema = zod_1.z.object({
32
- revoked: zod_1.z.array(zod_1.z.string()),
33
- skipped: zod_1.z.array(zod_1.z.object({ id: zod_1.z.string(), reason: exports.RevokeSkipReasonSchema })),
27
+ const RevokeCredentialsOutputSchema = z.object({
28
+ revoked: z.array(z.string()),
29
+ skipped: z.array(z.object({ id: z.string(), reason: RevokeSkipReasonSchema })),
34
30
  });
35
31
  /** Keep the audit row bounded; the ids beyond this are counted, not listed. */
36
32
  const AUDIT_IDS_MAX_CHARS = 4000;
@@ -39,16 +35,16 @@ function assertSignedInAdminSession(user) {
39
35
  user.shareView !== undefined ||
40
36
  user.credential !== undefined ||
41
37
  user.adminTokenId !== undefined) {
42
- throw new server_1.TRPCError({
38
+ throw new TRPCError({
43
39
  code: 'FORBIDDEN',
44
40
  message: 'Revoking credentials in bulk needs a signed-in admin session',
45
41
  });
46
42
  }
47
43
  }
48
44
  function requireInternal(registry) {
49
- const internal = registry === null ? null : (0, hub_sessions_js_1.userManagementInternal)(registry);
45
+ const internal = registry === null ? null : userManagementInternal(registry);
50
46
  if (internal === null) {
51
- throw new server_1.TRPCError({
47
+ throw new TRPCError({
52
48
  code: 'PRECONDITION_FAILED',
53
49
  message: 'User management is not available',
54
50
  });
@@ -60,7 +56,7 @@ function revokerFor(kind, caller, deps) {
60
56
  if (kind === 'share-link') {
61
57
  const service = deps.shareTokens;
62
58
  if (service === null) {
63
- throw new server_1.TRPCError({ code: 'PRECONDITION_FAILED', message: 'Share links are not available' });
59
+ throw new TRPCError({ code: 'PRECONDITION_FAILED', message: 'Share links are not available' });
64
60
  }
65
61
  return async (id) => (await service.revoke({ id, callerUserId: caller.id, callerIsAdmin: true }))
66
62
  ? null
@@ -88,16 +84,16 @@ function auditIds(ids) {
88
84
  const joined = ids.join(',');
89
85
  return joined.length <= AUDIT_IDS_MAX_CHARS ? joined : `${joined.slice(0, AUDIT_IDS_MAX_CHARS)}…`;
90
86
  }
91
- function createRevokeCredentialsProcedures(deps) {
87
+ export function createRevokeCredentialsProcedures(deps) {
92
88
  return {
93
89
  /** ADMIN — revoke exactly `ids` of one kind; see the module header. */
94
- revokeCredentials: trpc_middleware_js_1.adminProcedure
90
+ revokeCredentials: adminProcedure
95
91
  .input(RevokeCredentialsInputSchema)
96
92
  .output(RevokeCredentialsOutputSchema)
97
93
  .mutation(async ({ ctx, input }) => {
98
94
  assertSignedInAdminSession(ctx.user);
99
95
  if (input.confirmCount !== input.ids.length) {
100
- throw new server_1.TRPCError({
96
+ throw new TRPCError({
101
97
  code: 'BAD_REQUEST',
102
98
  message: `Confirmed ${input.confirmCount} but ${input.ids.length} were listed — nothing was revoked`,
103
99
  });
@@ -114,7 +110,7 @@ function createRevokeCredentialsProcedures(deps) {
114
110
  else
115
111
  skipped.push({ id, reason });
116
112
  }
117
- const internal = deps.registry === null ? null : (0, hub_sessions_js_1.userManagementInternal)(deps.registry);
113
+ const internal = deps.registry === null ? null : userManagementInternal(deps.registry);
118
114
  if (internal !== null) {
119
115
  const ip = deps.network.clientAddress(ctx.req).ip;
120
116
  await internal.audit.record({