@learncard/lca-api-service 1.3.2 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. package/.env.example +99 -2
  2. package/AGENTS.md +155 -44
  3. package/CHANGELOG.md +84 -0
  4. package/bootstrapLambda.test.ts +76 -0
  5. package/compose.env +5 -0
  6. package/config/config.dev.json +23 -0
  7. package/config/config.example.json +22 -0
  8. package/config/config.json +1 -0
  9. package/config/config.production.json +12 -0
  10. package/config/config.scouts.dev.json +11 -0
  11. package/config/config.scouts.production.json +11 -0
  12. package/dist/accesslayer/signing-authority/index.d.ts +8 -2
  13. package/dist/app.d.ts +361 -8
  14. package/dist/cache/challenges.d.ts +2 -0
  15. package/dist/cache/getDel.d.ts +2 -0
  16. package/dist/cache/getDel.test.d.ts +1 -0
  17. package/dist/cache/login-tickets.d.ts +12 -0
  18. package/dist/cache/recoverySessions.d.ts +42 -0
  19. package/dist/config/applyDockerStageConfig.d.ts +1 -0
  20. package/dist/config/cacheEnvironment.d.ts +16 -0
  21. package/dist/config/environment.d.ts +253 -2
  22. package/dist/config/environment.test.d.ts +1 -0
  23. package/dist/config/escrowBundleMode.test.d.ts +1 -0
  24. package/dist/config/escrowDeployment.test.d.ts +1 -0
  25. package/dist/config/oidcEnvironment.d.ts +74 -0
  26. package/dist/config/serverlessFunctionEnv.test.d.ts +1 -0
  27. package/dist/config/stageConfig.d.ts +62 -0
  28. package/dist/config/stageConfig.test.d.ts +1 -0
  29. package/dist/didkit_wasm_bg.wasm +0 -0
  30. package/dist/docker-entry.d.ts +1 -1
  31. package/dist/helpers/auth.helpers.d.ts +1 -1
  32. package/dist/helpers/escrowCancelLink.d.ts +7 -0
  33. package/dist/helpers/escrowCancelLink.test.d.ts +1 -0
  34. package/dist/helpers/escrowCancelToken.d.ts +4 -0
  35. package/dist/helpers/escrowCancelToken.test.d.ts +1 -0
  36. package/dist/helpers/keycloak.helpers.d.ts +23 -0
  37. package/dist/helpers/learnCard.signingAuthority.test.d.ts +1 -0
  38. package/dist/helpers/login-ticket.helpers.d.ts +31 -0
  39. package/dist/helpers/login-ticket.helpers.test.d.ts +1 -0
  40. package/dist/helpers/oidc.helpers.d.ts +47 -0
  41. package/dist/helpers/rate-limit.helpers.d.ts +6 -0
  42. package/dist/helpers/rate-limit.helpers.test.d.ts +1 -0
  43. package/dist/helpers/rateLimit.helpers.d.ts +4 -0
  44. package/dist/helpers/seedEncryption.helpers.d.ts +23 -0
  45. package/dist/helpers/seedEncryption.helpers.test.d.ts +1 -0
  46. package/dist/helpers/social-token.helpers.d.ts +19 -0
  47. package/dist/index.d.ts +1 -0
  48. package/dist/index.js +2 -2
  49. package/dist/jobs/escrowBlobRewrap.d.ts +9 -0
  50. package/dist/jobs/escrowHoldReminders.d.ts +12 -0
  51. package/dist/migrations/signingAuthoritySeeds.d.ts +13 -0
  52. package/dist/migrations/signingAuthoritySeedsCli.test.d.ts +1 -0
  53. package/dist/models/AuthSubject.d.ts +20 -0
  54. package/dist/models/EscrowHold.d.ts +153 -0
  55. package/dist/models/Notification.d.ts +5 -0
  56. package/dist/models/SigningAuthority.d.ts +7 -1
  57. package/dist/models/UserKey.d.ts +326 -3
  58. package/dist/models/UserKey.escrowPin.test.d.ts +1 -0
  59. package/dist/models/index.d.ts +2 -0
  60. package/dist/oidc.d.ts +5 -0
  61. package/dist/routes/auth.d.ts +31 -0
  62. package/dist/routes/escrow.d.ts +164 -0
  63. package/dist/routes/index.d.ts +6 -0
  64. package/dist/routes/keys.d.ts +182 -7
  65. package/dist/routes/notifications.d.ts +5 -0
  66. package/dist/routes/qr-login.d.ts +1 -1
  67. package/dist/routes/signing-authority.d.ts +14 -0
  68. package/dist/services/escrow-enclave/blobIdentity.d.ts +10 -0
  69. package/dist/services/escrow-enclave/blobIdentity.test.d.ts +1 -0
  70. package/dist/services/escrow-enclave/cancellation.d.ts +3 -0
  71. package/dist/services/escrow-enclave/enclaveTrustAnchors.d.ts +1 -0
  72. package/dist/services/escrow-enclave/index.d.ts +25 -0
  73. package/dist/services/escrow-enclave/notifications.d.ts +24 -0
  74. package/dist/services/escrow-enclave/notifications.test.d.ts +1 -0
  75. package/dist/services/escrow-enclave/production.test.d.ts +1 -0
  76. package/dist/services/escrow-enclave/remoteEnclave.contract.test.d.ts +1 -0
  77. package/dist/services/escrow-enclave/remoteEnclave.d.ts +20 -0
  78. package/dist/services/escrow-enclave/remoteEnclave.test.d.ts +1 -0
  79. package/dist/services/escrow-enclave/remoteEnclave.tls.test.d.ts +1 -0
  80. package/dist/services/escrow-enclave/softwareEnclave.d.ts +27 -0
  81. package/dist/services/escrow-enclave/softwareEnclave.test.d.ts +1 -0
  82. package/dist/services/escrow-enclave/types.d.ts +111 -0
  83. package/dist/types/notifications.d.ts +5 -0
  84. package/dist/types/seed-encryption.d.ts +31 -0
  85. package/dist/types/seed-migration.d.ts +49 -0
  86. package/esbuildPlugins.cjs +1 -0
  87. package/lambda.ts +27 -112
  88. package/lambdaApp.ts +146 -0
  89. package/oidcLambda.test.ts +38 -0
  90. package/oidcLambda.ts +18 -0
  91. package/oidcLambdaApp.ts +11 -0
  92. package/package.json +30 -14
  93. package/scripts/README.md +88 -0
  94. package/scripts/check-seed-encryption-infrastructure.mjs +139 -0
  95. package/scripts/check-signing-authority-redis.mjs +93 -0
  96. package/scripts/escrow-blob-mode-report.test.ts +227 -0
  97. package/scripts/escrow-blob-mode-report.ts +465 -0
  98. package/scripts/keycloak-admin.ts +108 -0
  99. package/scripts/keycloak-provider-links.ts +147 -0
  100. package/scripts/migrate-signing-authority-seeds-local.sh +51 -0
  101. package/scripts/migrate-signing-authority-seeds.mjs +105 -0
  102. package/scripts/print-seed-rollout-flags.ts +21 -0
  103. package/scripts/provision-keycloak-users.ts +419 -0
  104. package/seedMigrationApp.test.ts +145 -0
  105. package/seedMigrationApp.ts +50 -0
  106. package/seedMigrationLambda.test.ts +40 -0
  107. package/seedMigrationLambda.ts +19 -0
  108. package/serverless-local.yml +28 -1
  109. package/serverless.function-env.cjs +58 -0
  110. package/serverless.yml +294 -26
  111. package/src/accesslayer/notifications/index.ts +9 -2
  112. package/src/accesslayer/signing-authority/create.ts +11 -7
  113. package/src/accesslayer/signing-authority/index.ts +4 -1
  114. package/src/app.ts +4 -0
  115. package/src/cache/challenges.ts +12 -2
  116. package/src/cache/getDel.test.ts +34 -0
  117. package/src/cache/getDel.ts +32 -0
  118. package/src/cache/in-memory-lru.ts +1 -0
  119. package/src/cache/index.ts +1 -1
  120. package/src/cache/login-tickets.ts +26 -0
  121. package/src/cache/recoverySessions.ts +252 -0
  122. package/src/config/applyDockerStageConfig.ts +6 -0
  123. package/src/config/cacheEnvironment.ts +34 -0
  124. package/src/config/environment.test.ts +159 -0
  125. package/src/config/environment.ts +164 -0
  126. package/src/config/escrowBundleMode.test.ts +52 -0
  127. package/src/config/escrowDeployment.test.ts +114 -0
  128. package/src/config/oidcEnvironment.ts +59 -0
  129. package/src/config/serverlessFunctionEnv.test.ts +98 -0
  130. package/src/config/stageConfig.test.ts +26 -0
  131. package/src/config/stageConfig.ts +24 -0
  132. package/src/docker-entry.ts +13 -0
  133. package/src/helpers/auth.helpers.ts +68 -30
  134. package/src/helpers/escrowCancelLink.test.ts +60 -0
  135. package/src/helpers/escrowCancelLink.ts +38 -0
  136. package/src/helpers/escrowCancelToken.test.ts +105 -0
  137. package/src/helpers/escrowCancelToken.ts +47 -0
  138. package/src/helpers/keycloak.helpers.ts +120 -0
  139. package/src/helpers/learnCard.helpers.test.ts +11 -1
  140. package/src/helpers/learnCard.helpers.ts +57 -45
  141. package/src/helpers/learnCard.signingAuthority.test.ts +194 -0
  142. package/src/helpers/login-ticket.helpers.test.ts +45 -0
  143. package/src/helpers/login-ticket.helpers.ts +91 -0
  144. package/src/helpers/oidc.helpers.ts +354 -0
  145. package/src/helpers/rate-limit.helpers.test.ts +61 -0
  146. package/src/helpers/rate-limit.helpers.ts +73 -0
  147. package/src/helpers/rateLimit.helpers.ts +112 -0
  148. package/src/helpers/seedEncryption.helpers.test.ts +427 -0
  149. package/src/helpers/seedEncryption.helpers.ts +372 -0
  150. package/src/helpers/signingAuthority.helpers.ts +4 -1
  151. package/src/helpers/social-token.helpers.ts +144 -0
  152. package/src/index.ts +1 -0
  153. package/src/jobs/escrowBlobRewrap.ts +121 -0
  154. package/src/jobs/escrowHoldReminders.ts +177 -0
  155. package/src/migrations/signingAuthoritySeeds.ts +430 -0
  156. package/src/migrations/signingAuthoritySeedsCli.test.ts +70 -0
  157. package/src/models/AuthSubject.ts +147 -0
  158. package/src/models/EscrowHold.ts +541 -0
  159. package/src/models/SigningAuthority.ts +14 -3
  160. package/src/models/UserKey.escrowPin.test.ts +49 -0
  161. package/src/models/UserKey.ts +1109 -40
  162. package/src/models/index.ts +2 -0
  163. package/src/models/pruneOrphanedRecoveryMethods.ts +3 -1
  164. package/src/oidc.ts +371 -0
  165. package/src/routes/auth.ts +173 -0
  166. package/src/routes/credentials.ts +8 -0
  167. package/src/routes/escrow.ts +1073 -0
  168. package/src/routes/firebase.ts +90 -48
  169. package/src/routes/index.ts +98 -5
  170. package/src/routes/keys.ts +1022 -174
  171. package/src/routes/qr-login.ts +51 -53
  172. package/src/routes/signing-authority.ts +39 -1
  173. package/src/services/delivery/adapters/postmark.adapter.ts +48 -1
  174. package/src/services/escrow-enclave/README.md +122 -0
  175. package/src/services/escrow-enclave/__fixtures__/tls/pinned-ca.pem +11 -0
  176. package/src/services/escrow-enclave/__fixtures__/tls/pinned-leaf.key +5 -0
  177. package/src/services/escrow-enclave/__fixtures__/tls/pinned-leaf.pem +12 -0
  178. package/src/services/escrow-enclave/__fixtures__/tls/rogue-ca.pem +11 -0
  179. package/src/services/escrow-enclave/__fixtures__/tls/rogue-leaf.key +5 -0
  180. package/src/services/escrow-enclave/__fixtures__/tls/rogue-leaf.pem +12 -0
  181. package/src/services/escrow-enclave/blobIdentity.test.ts +42 -0
  182. package/src/services/escrow-enclave/blobIdentity.ts +55 -0
  183. package/src/services/escrow-enclave/cancellation.ts +59 -0
  184. package/src/services/escrow-enclave/enclaveTrustAnchors.ts +34 -0
  185. package/src/services/escrow-enclave/index.ts +174 -0
  186. package/src/services/escrow-enclave/notifications.test.ts +377 -0
  187. package/src/services/escrow-enclave/notifications.ts +348 -0
  188. package/src/services/escrow-enclave/production.test.ts +34 -0
  189. package/src/services/escrow-enclave/remoteEnclave.contract.test.ts +344 -0
  190. package/src/services/escrow-enclave/remoteEnclave.test.ts +490 -0
  191. package/src/services/escrow-enclave/remoteEnclave.tls.test.ts +62 -0
  192. package/src/services/escrow-enclave/remoteEnclave.ts +263 -0
  193. package/src/services/escrow-enclave/softwareEnclave.test.ts +450 -0
  194. package/src/services/escrow-enclave/softwareEnclave.ts +254 -0
  195. package/src/services/escrow-enclave/types.ts +122 -0
  196. package/src/types/seed-encryption.ts +51 -0
  197. package/src/types/seed-migration.ts +61 -0
  198. package/test/auth-tickets.spec.ts +480 -0
  199. package/test/credentials.spec.ts +2 -0
  200. package/test/helpers/keycloak-broker.ts +181 -0
  201. package/test/helpers/live-mongo.ts +9 -0
  202. package/test/jobs/escrowBlobRewrap.spec.ts +262 -0
  203. package/test/jobs/escrowHoldReminders.spec.ts +319 -0
  204. package/test/keycloak-admin.spec.ts +58 -0
  205. package/test/keycloak-broker-roundtrip.integration.spec.ts +40 -0
  206. package/test/keycloak-migration.integration.spec.ts +266 -0
  207. package/test/keycloak-provider-links.spec.ts +201 -0
  208. package/test/keycloak-social-broker.integration.spec.ts +228 -0
  209. package/test/keycloak-verify.integration.spec.ts +100 -0
  210. package/test/keycloak-verify.spec.ts +307 -0
  211. package/test/keys-escrow.spec.ts +2328 -0
  212. package/test/keys-identity-rebind.spec.ts +456 -0
  213. package/test/keys-lifecycle-invariants.spec.ts +785 -0
  214. package/test/keys-recovery-confirmation.spec.ts +586 -0
  215. package/test/keys-recovery-rate-limit.spec.ts +123 -0
  216. package/test/keys-secret-leakage.spec.ts +265 -0
  217. package/test/models/authSubjectIndexes.spec.ts +132 -0
  218. package/test/models/escrow.spec.ts +572 -0
  219. package/test/notifications.spec.ts +4 -0
  220. package/test/oidc-e2e/broker.spec.ts +116 -0
  221. package/test/oidc-e2e/compose.yaml +33 -0
  222. package/test/oidc-e2e/fixtures.ts +245 -0
  223. package/test/oidc-e2e/lock.test.mjs +73 -0
  224. package/test/oidc-e2e/playwright.config.ts +21 -0
  225. package/test/oidc-e2e/run.mjs +312 -0
  226. package/test/oidc-e2e/tsconfig.json +10 -0
  227. package/test/oidc-e2e/types.ts +21 -0
  228. package/test/oidc.integration.spec.ts +54 -0
  229. package/test/oidc.spec.ts +697 -0
  230. package/test/oidcLambdaApp.boot.spec.ts +105 -0
  231. package/test/provision-keycloak-users.spec.ts +299 -0
  232. package/test/signing-authority-http.spec.ts +161 -0
  233. package/test/signing-authority-seed-migration.spec.ts +414 -0
  234. package/test/signing-authority.spec.ts +90 -0
  235. package/tsconfig.build.json +1 -1
  236. package/tsconfig.json +1 -0
  237. package/vitest.config.ts +24 -1
  238. package/vitest.integration.config.ts +25 -3
  239. package/dist/cache/signing-authority.d.ts +0 -6
  240. package/src/cache/signing-authority.ts +0 -37
@@ -0,0 +1,12 @@
1
+ {
2
+ "DOMAIN_NAME": "api.learncard.app",
3
+ "POSTMARK_BRAND_NAME": "LearnCard",
4
+ "POSTMARK_ENDORSEMENT_REQUEST_TEMPLATE_ALIAS": "universal-inbox-claim-1",
5
+ "POSTMARK_FROM_EMAIL": "learncard.com",
6
+ "POSTMARK_LOGIN_CODE_TEMPLATE_ALIAS": "contact-method-verification-1",
7
+ "POSTMARK_RECOVERY_EMAIL_CODE_TEMPLATE_ALIAS": "recovery-email-verification",
8
+ "POSTMARK_RECOVERY_KEY_TEMPLATE_ALIAS": "recovery-key-backup",
9
+ "SA_SEED_ALLOW_LEGACY_READ": "false",
10
+ "SA_SEED_ENCRYPT_WRITES": "true",
11
+ "SENTRY_ENV": "lca-api-production"
12
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "DOMAIN_NAME": "staging.api.scoutnetwork.org",
3
+ "POSTMARK_BRAND_NAME": "ScoutPass",
4
+ "POSTMARK_FROM_EMAIL": "staging.scoutnetwork.org",
5
+ "POSTMARK_LOGIN_CODE_TEMPLATE_ALIAS": "sp-login-verification",
6
+ "POSTMARK_RECOVERY_EMAIL_CODE_TEMPLATE_ALIAS": "sp-recovery-email-verification",
7
+ "POSTMARK_RECOVERY_KEY_TEMPLATE_ALIAS": "recovery-key-backup",
8
+ "SA_SEED_ALLOW_LEGACY_READ": "false",
9
+ "SA_SEED_ENCRYPT_WRITES": "true",
10
+ "SENTRY_ENV": "scouts-api-staging"
11
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "DOMAIN_NAME": "api.scoutnetwork.org",
3
+ "POSTMARK_BRAND_NAME": "ScoutPass",
4
+ "POSTMARK_FROM_EMAIL": "scoutnetwork.org",
5
+ "POSTMARK_LOGIN_CODE_TEMPLATE_ALIAS": "sp-login-verification",
6
+ "POSTMARK_RECOVERY_EMAIL_CODE_TEMPLATE_ALIAS": "sp-recovery-email-verification",
7
+ "POSTMARK_RECOVERY_KEY_TEMPLATE_ALIAS": "recovery-key-backup",
8
+ "SA_SEED_ALLOW_LEGACY_READ": "true",
9
+ "SA_SEED_ENCRYPT_WRITES": "false",
10
+ "SENTRY_ENV": "lca-api-production"
11
+ }
@@ -1,16 +1,22 @@
1
1
  export declare const getSigningAuthoritiesCollection: () => import("mongodb").Collection<{
2
2
  ownerDid: string;
3
3
  name: string;
4
- seed: string;
5
4
  _id?: string | undefined;
5
+ seed?: string | undefined;
6
+ encryptedSeed?: string | undefined;
7
+ encryptedDek?: string | undefined;
8
+ keyVersion?: "kms-v1" | "local-v1" | undefined;
6
9
  did?: string | undefined;
7
10
  endpoint?: string | undefined;
8
11
  }>;
9
12
  export declare const SigningAuthorities: import("mongodb").Collection<{
10
13
  ownerDid: string;
11
14
  name: string;
12
- seed: string;
13
15
  _id?: string | undefined;
16
+ seed?: string | undefined;
17
+ encryptedSeed?: string | undefined;
18
+ encryptedDek?: string | undefined;
19
+ keyVersion?: "kms-v1" | "local-v1" | undefined;
14
20
  did?: string | undefined;
15
21
  endpoint?: string | undefined;
16
22
  }>;
package/dist/app.d.ts CHANGED
@@ -214,6 +214,11 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
214
214
  approvedAt: string;
215
215
  contractUpdatedAt: string;
216
216
  } | undefined;
217
+ referral?: {
218
+ requestId: string;
219
+ requestedBy: string;
220
+ externalReferenceId?: string | undefined;
221
+ } | undefined;
217
222
  uris?: string[] | undefined;
218
223
  } | undefined;
219
224
  inbox?: {
@@ -305,6 +310,20 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
305
310
  };
306
311
  meta: import("trpc-to-openapi").OpenApiMeta;
307
312
  }>;
313
+ ensureManagedSigningAuthority: import("@trpc/server").TRPCMutationProcedure<{
314
+ input: {
315
+ name: string;
316
+ ownerDid: string;
317
+ };
318
+ output: {
319
+ ownerDid: string;
320
+ name: string;
321
+ did: string;
322
+ endpoint: string;
323
+ _id?: string | undefined;
324
+ };
325
+ meta: import("trpc-to-openapi").OpenApiMeta;
326
+ }>;
308
327
  signingAuthorities: import("@trpc/server").TRPCQueryProcedure<{
309
328
  input: void;
310
329
  output: {
@@ -994,6 +1013,88 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
994
1013
  errorShape: import("@trpc/server").TRPCDefaultErrorShape;
995
1014
  transformer: false;
996
1015
  }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
1016
+ startRecoverySession: import("@trpc/server").TRPCMutationProcedure<{
1017
+ input: {
1018
+ email: string;
1019
+ };
1020
+ output: {
1021
+ success: true;
1022
+ };
1023
+ meta: import("trpc-to-openapi").OpenApiMeta;
1024
+ }>;
1025
+ verifyRecoverySession: import("@trpc/server").TRPCMutationProcedure<{
1026
+ input: {
1027
+ email: string;
1028
+ code: string;
1029
+ };
1030
+ output: {
1031
+ recoverySessionToken: string;
1032
+ recoveryMethods: {
1033
+ type: "email" | "passkey" | "backup" | "phrase" | "escrow";
1034
+ createdAt: string;
1035
+ credentialId?: string | undefined;
1036
+ shareVersion?: number | undefined;
1037
+ }[];
1038
+ escrowPin: {
1039
+ state: "enabled" | "none" | "locked" | "stale";
1040
+ enabled: boolean;
1041
+ attemptsRemaining: number;
1042
+ salt?: string | undefined;
1043
+ };
1044
+ };
1045
+ meta: import("trpc-to-openapi").OpenApiMeta;
1046
+ }>;
1047
+ useRecoverySession: import("@trpc/server").TRPCMutationProcedure<{
1048
+ input: {
1049
+ recoverySessionToken: string;
1050
+ type: "email" | "passkey" | "backup" | "phrase" | "escrow";
1051
+ credentialId?: string | undefined;
1052
+ };
1053
+ output: {
1054
+ authShare: {
1055
+ encryptedData: string;
1056
+ encryptedDek: string;
1057
+ iv: string;
1058
+ };
1059
+ primaryDid: string;
1060
+ shareVersion: number;
1061
+ rebindSessionToken: string;
1062
+ encryptedShare?: {
1063
+ encryptedData: string;
1064
+ iv: string;
1065
+ salt?: string | undefined;
1066
+ } | undefined;
1067
+ };
1068
+ meta: import("trpc-to-openapi").OpenApiMeta;
1069
+ }>;
1070
+ completeRecoveryRebind: import("@trpc/server").TRPCMutationProcedure<{
1071
+ input: {
1072
+ recoverySessionToken: string;
1073
+ providerType: "firebase" | "supertokens" | "keycloak" | "oidc";
1074
+ primaryDid: string;
1075
+ authShare: {
1076
+ encryptedData: string;
1077
+ encryptedDek: string;
1078
+ iv: string;
1079
+ };
1080
+ newAuthToken?: string | undefined;
1081
+ };
1082
+ output: {
1083
+ success: true;
1084
+ shareVersion: number;
1085
+ recoveryMethodsRequireConfirmation: ("email" | "passkey" | "backup" | "phrase" | "escrow")[];
1086
+ };
1087
+ meta: import("trpc-to-openapi").OpenApiMeta;
1088
+ }>;
1089
+ issueDidChallenge: import("@trpc/server").TRPCMutationProcedure<{
1090
+ input: {
1091
+ did: string;
1092
+ };
1093
+ output: {
1094
+ challenge: string;
1095
+ };
1096
+ meta: import("trpc-to-openapi").OpenApiMeta;
1097
+ }>;
997
1098
  getAuthShare: import("@trpc/server").TRPCMutationProcedure<{
998
1099
  input: {
999
1100
  authToken: string;
@@ -1009,14 +1110,24 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
1009
1110
  primaryDid: string | null;
1010
1111
  securityLevel: "basic" | "enhanced" | "advanced";
1011
1112
  recoveryMethods: {
1012
- type: "email" | "passkey" | "backup" | "phrase";
1113
+ type: "email" | "passkey" | "backup" | "phrase" | "escrow";
1013
1114
  createdAt: string;
1014
1115
  credentialId?: string | undefined;
1015
1116
  shareVersion?: number | undefined;
1117
+ confirmedAt?: string | undefined;
1016
1118
  }[];
1017
1119
  keyProvider: "web3auth" | "sss";
1018
1120
  shareVersion: number;
1019
1121
  maskedRecoveryEmail: string | null;
1122
+ escrowOptedOut: boolean;
1123
+ escrowPin: {
1124
+ state: "enabled" | "none" | "locked" | "stale";
1125
+ enabled: boolean;
1126
+ attemptsRemaining: number;
1127
+ salt?: string | undefined;
1128
+ };
1129
+ sssActivationState: "provisional" | "active";
1130
+ escrowStale?: "mode-mismatch" | "key-rotated" | undefined;
1020
1131
  } | null;
1021
1132
  meta: import("trpc-to-openapi").OpenApiMeta;
1022
1133
  }>;
@@ -1032,10 +1143,13 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
1032
1143
  primaryDid: string;
1033
1144
  securityLevel?: "basic" | "enhanced" | "advanced" | undefined;
1034
1145
  keyProvider?: "web3auth" | "sss" | undefined;
1146
+ sssActivationState?: "provisional" | undefined;
1147
+ expectedShareVersion?: number | undefined;
1035
1148
  };
1036
1149
  output: {
1037
1150
  success: boolean;
1038
1151
  shareVersion: number;
1152
+ expectedShareVersionChecked: boolean;
1039
1153
  };
1040
1154
  meta: import("trpc-to-openapi").OpenApiMeta;
1041
1155
  }>;
@@ -1043,7 +1157,7 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
1043
1157
  input: {
1044
1158
  authToken: string;
1045
1159
  providerType: "firebase" | "supertokens" | "keycloak" | "oidc";
1046
- type: "email" | "passkey" | "backup" | "phrase";
1160
+ type: "email" | "passkey" | "backup" | "phrase" | "escrow";
1047
1161
  encryptedShare?: {
1048
1162
  encryptedData: string;
1049
1163
  iv: string;
@@ -1057,11 +1171,36 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
1057
1171
  };
1058
1172
  meta: import("trpc-to-openapi").OpenApiMeta;
1059
1173
  }>;
1060
- getRecoveryShare: import("@trpc/server").TRPCQueryProcedure<{
1174
+ confirmRecoveryMethod: import("@trpc/server").TRPCMutationProcedure<{
1061
1175
  input: {
1062
1176
  authToken: string;
1063
1177
  providerType: "firebase" | "supertokens" | "keycloak" | "oidc";
1064
- type: "email" | "passkey" | "backup" | "phrase";
1178
+ type: "email" | "passkey" | "backup" | "phrase" | "escrow";
1179
+ credentialId?: string | undefined;
1180
+ code?: string | undefined;
1181
+ };
1182
+ output: {
1183
+ success: boolean;
1184
+ };
1185
+ meta: import("trpc-to-openapi").OpenApiMeta;
1186
+ }>;
1187
+ deleteRecoveryMethod: import("@trpc/server").TRPCMutationProcedure<{
1188
+ input: {
1189
+ authToken: string;
1190
+ providerType: "firebase" | "supertokens" | "keycloak" | "oidc";
1191
+ type: "email" | "passkey" | "backup" | "phrase" | "escrow";
1192
+ credentialId?: string | undefined;
1193
+ };
1194
+ output: {
1195
+ success: boolean;
1196
+ };
1197
+ meta: import("trpc-to-openapi").OpenApiMeta;
1198
+ }>;
1199
+ getRecoveryShare: import("@trpc/server").TRPCQueryProcedure<{
1200
+ input: {
1201
+ providerType: "firebase" | "supertokens" | "keycloak" | "oidc";
1202
+ type: "email" | "passkey" | "backup" | "phrase" | "escrow";
1203
+ authToken?: string | undefined;
1065
1204
  credentialId?: string | undefined;
1066
1205
  };
1067
1206
  output: {
@@ -1084,6 +1223,16 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
1084
1223
  };
1085
1224
  meta: import("trpc-to-openapi").OpenApiMeta;
1086
1225
  }>;
1226
+ activate: import("@trpc/server").TRPCMutationProcedure<{
1227
+ input: {
1228
+ authToken: string;
1229
+ providerType: "firebase" | "supertokens" | "keycloak" | "oidc";
1230
+ };
1231
+ output: {
1232
+ success: boolean;
1233
+ };
1234
+ meta: import("trpc-to-openapi").OpenApiMeta;
1235
+ }>;
1087
1236
  addRecoveryEmail: import("@trpc/server").TRPCMutationProcedure<{
1088
1237
  input: {
1089
1238
  authToken: string;
@@ -1121,9 +1270,18 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
1121
1270
  input: {
1122
1271
  authToken: string;
1123
1272
  providerType: "firebase" | "supertokens" | "keycloak" | "oidc";
1124
- emailShare: string;
1125
- email?: string | undefined;
1126
- useRecoveryEmail?: boolean | undefined;
1273
+ relayPayload: {
1274
+ version: 1;
1275
+ algorithm: "P-256-HKDF-SHA256-AES-256-GCM";
1276
+ keyId: string;
1277
+ ephemeralPublicKey: string;
1278
+ salt: string;
1279
+ iv: string;
1280
+ ciphertext: string;
1281
+ };
1282
+ confirmationCode: string;
1283
+ email: string;
1284
+ shareVersion?: number | undefined;
1127
1285
  };
1128
1286
  output: {
1129
1287
  success: boolean;
@@ -1149,6 +1307,7 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
1149
1307
  input: {
1150
1308
  authToken: string;
1151
1309
  providerType: "firebase" | "supertokens" | "keycloak" | "oidc";
1310
+ challenge: string;
1152
1311
  };
1153
1312
  output: {
1154
1313
  success: boolean;
@@ -1156,6 +1315,169 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
1156
1315
  meta: import("trpc-to-openapi").OpenApiMeta;
1157
1316
  }>;
1158
1317
  }>>;
1318
+ escrow: import("@trpc/server").TRPCBuiltRouter<{
1319
+ ctx: import("@routes").Context;
1320
+ meta: import("trpc-to-openapi").OpenApiMeta;
1321
+ errorShape: import("@trpc/server").TRPCDefaultErrorShape;
1322
+ transformer: false;
1323
+ }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
1324
+ getAttestation: import("@trpc/server").TRPCQueryProcedure<{
1325
+ input: {
1326
+ nonce?: string | undefined;
1327
+ };
1328
+ output: {
1329
+ attestation: {
1330
+ mode: "software" | "nitro";
1331
+ keyId: string;
1332
+ publicKey: string;
1333
+ measurements: {
1334
+ imageSha384?: string | undefined;
1335
+ pcr0?: string | undefined;
1336
+ pcr1?: string | undefined;
1337
+ pcr2?: string | undefined;
1338
+ };
1339
+ document: string;
1340
+ issuedAt: string;
1341
+ previousKeyIds?: string[] | undefined;
1342
+ };
1343
+ holdDurationMs: number;
1344
+ };
1345
+ meta: import("trpc-to-openapi").OpenApiMeta;
1346
+ }>;
1347
+ enroll: import("@trpc/server").TRPCMutationProcedure<{
1348
+ input: {
1349
+ authToken: string;
1350
+ providerType: "firebase" | "supertokens" | "keycloak" | "oidc";
1351
+ envelope: {
1352
+ version: 1;
1353
+ algorithm: "P-256-HKDF-SHA256-AES-256-GCM";
1354
+ keyId: string;
1355
+ ephemeralPublicKey: string;
1356
+ salt: string;
1357
+ iv: string;
1358
+ ciphertext: string;
1359
+ };
1360
+ shareVersion: number;
1361
+ enclaveKeyId: string;
1362
+ pinSalt?: string | undefined;
1363
+ clearPin?: boolean | undefined;
1364
+ };
1365
+ output: {
1366
+ success: true;
1367
+ shareVersion: number;
1368
+ };
1369
+ meta: import("trpc-to-openapi").OpenApiMeta;
1370
+ }>;
1371
+ remove: import("@trpc/server").TRPCMutationProcedure<{
1372
+ input: {
1373
+ authToken: string;
1374
+ providerType: "firebase" | "supertokens" | "keycloak" | "oidc";
1375
+ optOut: boolean;
1376
+ };
1377
+ output: {
1378
+ success: true;
1379
+ };
1380
+ meta: import("trpc-to-openapi").OpenApiMeta;
1381
+ }>;
1382
+ optIn: import("@trpc/server").TRPCMutationProcedure<{
1383
+ input: {
1384
+ authToken: string;
1385
+ providerType: "firebase" | "supertokens" | "keycloak" | "oidc";
1386
+ };
1387
+ output: {
1388
+ success: true;
1389
+ };
1390
+ meta: import("trpc-to-openapi").OpenApiMeta;
1391
+ }>;
1392
+ startRecovery: import("@trpc/server").TRPCMutationProcedure<{
1393
+ input: {
1394
+ clientEphemeralPublicKey: string;
1395
+ releasePolicy?: "pin" | "hold" | undefined;
1396
+ restart?: boolean | undefined;
1397
+ authToken?: string | undefined;
1398
+ providerType?: "firebase" | "supertokens" | "keycloak" | "oidc" | undefined;
1399
+ recoverySessionToken?: string | undefined;
1400
+ };
1401
+ output: {
1402
+ holdId: string;
1403
+ releasePolicy: "pin" | "hold";
1404
+ requestedAt: string;
1405
+ releaseAfter: string;
1406
+ status: "pending";
1407
+ resumeToken: string | null;
1408
+ pinSalt?: string | undefined;
1409
+ };
1410
+ meta: import("trpc-to-openapi").OpenApiMeta;
1411
+ }>;
1412
+ getStatus: import("@trpc/server").TRPCQueryProcedure<{
1413
+ input: {
1414
+ holdId?: string | undefined;
1415
+ resumeToken?: string | undefined;
1416
+ authToken?: string | undefined;
1417
+ providerType?: "firebase" | "supertokens" | "keycloak" | "oidc" | undefined;
1418
+ };
1419
+ output: {
1420
+ hold: {
1421
+ holdId: string;
1422
+ status: "pending" | "cancelled" | "completed" | "expired";
1423
+ requestedAt: string;
1424
+ releaseAfter: string;
1425
+ releasePolicy: "pin" | "hold";
1426
+ cancelledAt?: string | undefined;
1427
+ completedAt?: string | undefined;
1428
+ } | null;
1429
+ };
1430
+ meta: import("trpc-to-openapi").OpenApiMeta;
1431
+ }>;
1432
+ cancelRecovery: import("@trpc/server").TRPCMutationProcedure<{
1433
+ input: {
1434
+ authToken: string;
1435
+ providerType: "firebase" | "supertokens" | "keycloak" | "oidc";
1436
+ };
1437
+ output: {
1438
+ success: true;
1439
+ cancelled: boolean;
1440
+ };
1441
+ meta: import("trpc-to-openapi").OpenApiMeta;
1442
+ }>;
1443
+ cancelRecoveryByLink: import("@trpc/server").TRPCMutationProcedure<{
1444
+ input: {
1445
+ holdId: string;
1446
+ token: string;
1447
+ };
1448
+ output: {
1449
+ cancelled: boolean;
1450
+ };
1451
+ meta: import("trpc-to-openapi").OpenApiMeta;
1452
+ }>;
1453
+ completeRecovery: import("@trpc/server").TRPCMutationProcedure<{
1454
+ input: {
1455
+ holdId: string;
1456
+ resumeToken: string;
1457
+ pinProof?: string | undefined;
1458
+ };
1459
+ output: {
1460
+ sealedShare: {
1461
+ version: 1;
1462
+ algorithm: "P-256-HKDF-SHA256-AES-256-GCM";
1463
+ keyId: string;
1464
+ ephemeralPublicKey: string;
1465
+ salt: string;
1466
+ iv: string;
1467
+ ciphertext: string;
1468
+ };
1469
+ authShare: {
1470
+ encryptedData: string;
1471
+ encryptedDek: string;
1472
+ iv: string;
1473
+ };
1474
+ primaryDid: string;
1475
+ shareVersion: number;
1476
+ rebindSessionToken: string;
1477
+ };
1478
+ meta: import("trpc-to-openapi").OpenApiMeta;
1479
+ }>;
1480
+ }>>;
1159
1481
  qrLogin: import("@trpc/server").TRPCBuiltRouter<{
1160
1482
  ctx: import("@routes").Context;
1161
1483
  meta: import("trpc-to-openapi").OpenApiMeta;
@@ -1180,7 +1502,7 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
1180
1502
  output: {
1181
1503
  sessionId: string;
1182
1504
  publicKey: string;
1183
- status: "approved" | "pending";
1505
+ status: "pending" | "approved";
1184
1506
  encryptedPayload?: string | undefined;
1185
1507
  approverDid?: string | undefined;
1186
1508
  };
@@ -1211,6 +1533,37 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
1211
1533
  meta: import("trpc-to-openapi").OpenApiMeta;
1212
1534
  }>;
1213
1535
  }>>;
1536
+ auth: import("@trpc/server").TRPCBuiltRouter<{
1537
+ ctx: import("@routes").Context;
1538
+ meta: import("trpc-to-openapi").OpenApiMeta;
1539
+ errorShape: import("@trpc/server").TRPCDefaultErrorShape;
1540
+ transformer: false;
1541
+ }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
1542
+ requestLoginTicket: import("@trpc/server").TRPCMutationProcedure<{
1543
+ input: {
1544
+ email: string;
1545
+ code: string;
1546
+ };
1547
+ output: {
1548
+ success: boolean;
1549
+ ticket?: string | undefined;
1550
+ error?: string | undefined;
1551
+ };
1552
+ meta: import("trpc-to-openapi").OpenApiMeta;
1553
+ }>;
1554
+ requestSocialLoginTicket: import("@trpc/server").TRPCMutationProcedure<{
1555
+ input: {
1556
+ provider: "google" | "apple";
1557
+ idToken: string;
1558
+ };
1559
+ output: {
1560
+ success: boolean;
1561
+ ticket?: string | undefined;
1562
+ error?: string | undefined;
1563
+ };
1564
+ meta: import("trpc-to-openapi").OpenApiMeta;
1565
+ }>;
1566
+ }>>;
1214
1567
  } & {
1215
1568
  test?: TestRouter;
1216
1569
  }>>;
@@ -1,6 +1,8 @@
1
1
  export declare const getChallengeCacheKey: (did: string, challenge: string) => string;
2
2
  export declare const VALID = "valid";
3
+ export declare const DID_CHALLENGE_TTL_SECS: number;
3
4
  export declare const isChallengeValidForDid: (did: string, challenge: string) => Promise<typeof VALID | null | undefined>;
5
+ export declare const consumeChallengeForDid: (did: string, challenge: string) => Promise<boolean>;
4
6
  export declare const setValidChallengeForDid: (did: string, challenge: string) => Promise<"OK" | undefined>;
5
7
  export declare const setValidChallengesForDid: (did: string, challenges: string[]) => Promise<"OK" | undefined>;
6
8
  export declare const invalidateChallengeForDid: (did: string, challenge: string) => Promise<number | undefined>;
@@ -0,0 +1,2 @@
1
+ export declare const getDel: (key: string) => Promise<string | null>;
2
+ export declare const consumeMatchingCode: (key: string, code: string) => Promise<boolean>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ export interface LoginTicketPayload {
2
+ subject: string;
3
+ email?: string;
4
+ emailVerified?: boolean;
5
+ phoneNumber?: string;
6
+ phoneNumberVerified?: boolean;
7
+ name?: string;
8
+ picture?: string;
9
+ identityKey: string;
10
+ }
11
+ export declare const issueLoginTicket: (payload: LoginTicketPayload) => Promise<string>;
12
+ export declare const redeemLoginTicket: (ticket: string) => Promise<LoginTicketPayload | null>;
@@ -0,0 +1,42 @@
1
+ import type { AuthProviderType } from '@helpers/auth.helpers';
2
+ export declare const RECOVERY_SESSION_TTL_SECS: number;
3
+ export declare const RECOVERY_OTP_TTL_SECS: number;
4
+ export declare const RECOVERY_OTP_SEND_COOLDOWN_SECS = 60;
5
+ export declare const MAX_RECOVERY_OTP_ATTEMPTS = 5;
6
+ export type RecoverySessionScope = 'recover' | 'rebind';
7
+ export interface RecoverySessionRecord {
8
+ scope: RecoverySessionScope;
9
+ authProvider: {
10
+ type: AuthProviderType;
11
+ id: string;
12
+ };
13
+ }
14
+ export interface RecoveryOtpRecord {
15
+ codeHash: string;
16
+ authProvider: {
17
+ type: AuthProviderType;
18
+ id: string;
19
+ };
20
+ }
21
+ export type RecoveryOtpVerificationResult = {
22
+ status: 'ok';
23
+ record: RecoveryOtpRecord;
24
+ } | {
25
+ status: 'mismatch';
26
+ attempts: number;
27
+ } | {
28
+ status: 'locked';
29
+ } | {
30
+ status: 'none';
31
+ };
32
+ export declare const getRecoveryEmailDigest: (email: string) => string;
33
+ export declare const getRecoveryOtpCacheKey: (email: string) => string;
34
+ export declare const getRecoveryOtpAttemptsCacheKey: (email: string) => string;
35
+ export declare const getRecoveryOtpLockCacheKey: (email: string) => string;
36
+ export declare const getRecoveryOtpSendCacheKey: (email: string) => string;
37
+ export declare const getRecoverySessionCacheKey: (token: string) => string;
38
+ export declare const createRecoverySession: (record: RecoverySessionRecord, ttl?: number) => Promise<string>;
39
+ export declare const consumeRecoverySession: (token: string, expectedScope: RecoverySessionScope) => Promise<RecoverySessionRecord | null>;
40
+ export declare const storeRecoveryOtp: (email: string, record: RecoveryOtpRecord) => Promise<void>;
41
+ export declare const verifyRecoveryOtp: (email: string, submittedCodeHash: string) => Promise<RecoveryOtpVerificationResult>;
42
+ export declare const claimRecoveryOtpSendWindow: (email: string) => Promise<boolean>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ import 'dotenv/config';
2
+ import { z } from 'zod';
3
+ export declare const cacheEnvironmentShape: {
4
+ REDIS_HOST: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
5
+ REDIS_PORT: z.ZodPreprocess<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
6
+ };
7
+ export declare const cacheEnvironmentSchema: z.ZodObject<{
8
+ REDIS_HOST: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
9
+ REDIS_PORT: z.ZodPreprocess<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
10
+ }, z.core.$strip>;
11
+ export type CacheEnvironment = z.output<typeof cacheEnvironmentSchema>;
12
+ export declare const parseCacheEnvironment: (raw: Record<string, unknown>, source?: string) => CacheEnvironment;
13
+ export declare const environment: {
14
+ REDIS_HOST?: string | undefined;
15
+ REDIS_PORT?: number | undefined;
16
+ };