@techelusive/nest-auth 0.0.0-stage → 0.2.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 (340) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/LICENSE +21 -0
  3. package/README.md +204 -2
  4. package/api/openapi.json +4399 -0
  5. package/api/techelusive-authentication.postman_collection.json +3178 -0
  6. package/dist/auth-options.d.ts +156 -0
  7. package/dist/auth-options.js +3 -0
  8. package/dist/auth-options.js.map +1 -0
  9. package/dist/auth-options.validation.d.ts +9 -0
  10. package/dist/auth-options.validation.js +74 -0
  11. package/dist/auth-options.validation.js.map +1 -0
  12. package/dist/auth.module.d.ts +38 -0
  13. package/dist/auth.module.js +173 -0
  14. package/dist/auth.module.js.map +1 -0
  15. package/dist/common/auth-error.d.ts +16 -0
  16. package/dist/common/auth-error.js +23 -0
  17. package/dist/common/auth-error.js.map +1 -0
  18. package/dist/common/auth-exception.filter.d.ts +24 -0
  19. package/dist/common/auth-exception.filter.js +66 -0
  20. package/dist/common/auth-exception.filter.js.map +1 -0
  21. package/dist/common/crypto/jwt.d.ts +89 -0
  22. package/dist/common/crypto/jwt.js +144 -0
  23. package/dist/common/crypto/jwt.js.map +1 -0
  24. package/dist/common/crypto/random-secrets.d.ts +78 -0
  25. package/dist/common/crypto/random-secrets.js +113 -0
  26. package/dist/common/crypto/random-secrets.js.map +1 -0
  27. package/dist/common/crypto/remote-public-keys.d.ts +49 -0
  28. package/dist/common/crypto/remote-public-keys.js +105 -0
  29. package/dist/common/crypto/remote-public-keys.js.map +1 -0
  30. package/dist/common/crypto/totp.d.ts +68 -0
  31. package/dist/common/crypto/totp.js +148 -0
  32. package/dist/common/crypto/totp.js.map +1 -0
  33. package/dist/common/encryption.service.d.ts +36 -0
  34. package/dist/common/encryption.service.js +111 -0
  35. package/dist/common/encryption.service.js.map +1 -0
  36. package/dist/common/identifiers.d.ts +48 -0
  37. package/dist/common/identifiers.js +89 -0
  38. package/dist/common/identifiers.js.map +1 -0
  39. package/dist/common/network-safety.d.ts +19 -0
  40. package/dist/common/network-safety.js +72 -0
  41. package/dist/common/network-safety.js.map +1 -0
  42. package/dist/common/rate-limiter.service.d.ts +63 -0
  43. package/dist/common/rate-limiter.service.js +158 -0
  44. package/dist/common/rate-limiter.service.js.map +1 -0
  45. package/dist/common/refresh-token-cookie.d.ts +78 -0
  46. package/dist/common/refresh-token-cookie.js +185 -0
  47. package/dist/common/refresh-token-cookie.js.map +1 -0
  48. package/dist/common/request-context.d.ts +14 -0
  49. package/dist/common/request-context.js +22 -0
  50. package/dist/common/request-context.js.map +1 -0
  51. package/dist/common/strict-validation.pipe.d.ts +8 -0
  52. package/dist/common/strict-validation.pipe.js +16 -0
  53. package/dist/common/strict-validation.pipe.js.map +1 -0
  54. package/dist/common/time.d.ts +15 -0
  55. package/dist/common/time.js +34 -0
  56. package/dist/common/time.js.map +1 -0
  57. package/dist/constants.d.ts +1326 -0
  58. package/dist/constants.js +1142 -0
  59. package/dist/constants.js.map +1 -0
  60. package/dist/database/create-auth-tables.migration.d.ts +26 -0
  61. package/dist/database/create-auth-tables.migration.js +291 -0
  62. package/dist/database/create-auth-tables.migration.js.map +1 -0
  63. package/dist/database/email-change-and-retention.migration.d.ts +25 -0
  64. package/dist/database/email-change-and-retention.migration.js +54 -0
  65. package/dist/database/email-change-and-retention.migration.js.map +1 -0
  66. package/dist/database/entities/api-key.entity.d.ts +17 -0
  67. package/dist/database/entities/api-key.entity.js +80 -0
  68. package/dist/database/entities/api-key.entity.js.map +1 -0
  69. package/dist/database/entities/audit-log.entity.d.ts +13 -0
  70. package/dist/database/entities/audit-log.entity.js +64 -0
  71. package/dist/database/entities/audit-log.entity.js.map +1 -0
  72. package/dist/database/entities/backup-code.entity.d.ts +9 -0
  73. package/dist/database/entities/backup-code.entity.js +52 -0
  74. package/dist/database/entities/backup-code.entity.js.map +1 -0
  75. package/dist/database/entities/index.d.ts +43 -0
  76. package/dist/database/entities/index.js +82 -0
  77. package/dist/database/entities/index.js.map +1 -0
  78. package/dist/database/entities/json-object.d.ts +12 -0
  79. package/dist/database/entities/json-object.js +3 -0
  80. package/dist/database/entities/json-object.js.map +1 -0
  81. package/dist/database/entities/link-token.entity.d.ts +15 -0
  82. package/dist/database/entities/link-token.entity.js +64 -0
  83. package/dist/database/entities/link-token.entity.js.map +1 -0
  84. package/dist/database/entities/one-time-code.entity.d.ts +16 -0
  85. package/dist/database/entities/one-time-code.entity.js +69 -0
  86. package/dist/database/entities/one-time-code.entity.js.map +1 -0
  87. package/dist/database/entities/organization-invitation.entity.d.ts +14 -0
  88. package/dist/database/entities/organization-invitation.entity.js +73 -0
  89. package/dist/database/entities/organization-invitation.entity.js.map +1 -0
  90. package/dist/database/entities/organization-member.entity.d.ts +9 -0
  91. package/dist/database/entities/organization-member.entity.js +48 -0
  92. package/dist/database/entities/organization-member.entity.js.map +1 -0
  93. package/dist/database/entities/organization.entity.d.ts +12 -0
  94. package/dist/database/entities/organization.entity.js +58 -0
  95. package/dist/database/entities/organization.entity.js.map +1 -0
  96. package/dist/database/entities/passkey.entity.d.ts +19 -0
  97. package/dist/database/entities/passkey.entity.js +78 -0
  98. package/dist/database/entities/passkey.entity.js.map +1 -0
  99. package/dist/database/entities/password.entity.d.ts +6 -0
  100. package/dist/database/entities/password.entity.js +36 -0
  101. package/dist/database/entities/password.entity.js.map +1 -0
  102. package/dist/database/entities/refresh-token.entity.d.ts +9 -0
  103. package/dist/database/entities/refresh-token.entity.js +53 -0
  104. package/dist/database/entities/refresh-token.entity.js.map +1 -0
  105. package/dist/database/entities/session.entity.d.ts +20 -0
  106. package/dist/database/entities/session.entity.js +87 -0
  107. package/dist/database/entities/session.entity.js.map +1 -0
  108. package/dist/database/entities/settings.entity.d.ts +7 -0
  109. package/dist/database/entities/settings.entity.js +41 -0
  110. package/dist/database/entities/settings.entity.js.map +1 -0
  111. package/dist/database/entities/sign-in-challenge.entity.d.ts +23 -0
  112. package/dist/database/entities/sign-in-challenge.entity.js +80 -0
  113. package/dist/database/entities/sign-in-challenge.entity.js.map +1 -0
  114. package/dist/database/entities/signing-key.entity.d.ts +11 -0
  115. package/dist/database/entities/signing-key.entity.js +54 -0
  116. package/dist/database/entities/signing-key.entity.js.map +1 -0
  117. package/dist/database/entities/social-account.entity.d.ts +13 -0
  118. package/dist/database/entities/social-account.entity.js +54 -0
  119. package/dist/database/entities/social-account.entity.js.map +1 -0
  120. package/dist/database/entities/two-factor-secret.entity.d.ts +10 -0
  121. package/dist/database/entities/two-factor-secret.entity.js +48 -0
  122. package/dist/database/entities/two-factor-secret.entity.js.map +1 -0
  123. package/dist/database/entities/user.entity.d.ts +34 -0
  124. package/dist/database/entities/user.entity.js +129 -0
  125. package/dist/database/entities/user.entity.js.map +1 -0
  126. package/dist/database/entities/webhook-delivery.entity.d.ts +17 -0
  127. package/dist/database/entities/webhook-delivery.entity.js +79 -0
  128. package/dist/database/entities/webhook-delivery.entity.js.map +1 -0
  129. package/dist/database/entities/webhook.entity.d.ts +12 -0
  130. package/dist/database/entities/webhook.entity.js +58 -0
  131. package/dist/database/entities/webhook.entity.js.map +1 -0
  132. package/dist/database/typeorm-row.d.ts +21 -0
  133. package/dist/database/typeorm-row.js +29 -0
  134. package/dist/database/typeorm-row.js.map +1 -0
  135. package/dist/features/account/account.controller.d.ts +259 -0
  136. package/dist/features/account/account.controller.js +372 -0
  137. package/dist/features/account/account.controller.js.map +1 -0
  138. package/dist/features/account/account.dto.d.ts +16 -0
  139. package/dist/features/account/account.dto.js +61 -0
  140. package/dist/features/account/account.dto.js.map +1 -0
  141. package/dist/features/account/data-export.service.d.ts +85 -0
  142. package/dist/features/account/data-export.service.js +125 -0
  143. package/dist/features/account/data-export.service.js.map +1 -0
  144. package/dist/features/account/health.service.d.ts +30 -0
  145. package/dist/features/account/health.service.js +59 -0
  146. package/dist/features/account/health.service.js.map +1 -0
  147. package/dist/features/admin/admin.controller.d.ts +382 -0
  148. package/dist/features/admin/admin.controller.js +623 -0
  149. package/dist/features/admin/admin.controller.js.map +1 -0
  150. package/dist/features/admin/admin.dto.d.ts +61 -0
  151. package/dist/features/admin/admin.dto.js +253 -0
  152. package/dist/features/admin/admin.dto.js.map +1 -0
  153. package/dist/features/admin/admin.service.d.ts +142 -0
  154. package/dist/features/admin/admin.service.js +227 -0
  155. package/dist/features/admin/admin.service.js.map +1 -0
  156. package/dist/features/api-keys/api-keys.service.d.ts +67 -0
  157. package/dist/features/api-keys/api-keys.service.js +144 -0
  158. package/dist/features/api-keys/api-keys.service.js.map +1 -0
  159. package/dist/features/email-change/email-change.controller.d.ts +38 -0
  160. package/dist/features/email-change/email-change.controller.js +85 -0
  161. package/dist/features/email-change/email-change.controller.js.map +1 -0
  162. package/dist/features/email-change/email-change.dto.d.ts +10 -0
  163. package/dist/features/email-change/email-change.dto.js +43 -0
  164. package/dist/features/email-change/email-change.dto.js.map +1 -0
  165. package/dist/features/email-change/email-change.service.d.ts +74 -0
  166. package/dist/features/email-change/email-change.service.js +179 -0
  167. package/dist/features/email-change/email-change.service.js.map +1 -0
  168. package/dist/features/email-links/email-verification.service.d.ts +46 -0
  169. package/dist/features/email-links/email-verification.service.js +94 -0
  170. package/dist/features/email-links/email-verification.service.js.map +1 -0
  171. package/dist/features/email-links/link-tokens.service.d.ts +44 -0
  172. package/dist/features/email-links/link-tokens.service.js +122 -0
  173. package/dist/features/email-links/link-tokens.service.js.map +1 -0
  174. package/dist/features/events/auth-events.service.d.ts +52 -0
  175. package/dist/features/events/auth-events.service.js +117 -0
  176. package/dist/features/events/auth-events.service.js.map +1 -0
  177. package/dist/features/maintenance/data-retention.service.d.ts +60 -0
  178. package/dist/features/maintenance/data-retention.service.js +182 -0
  179. package/dist/features/maintenance/data-retention.service.js.map +1 -0
  180. package/dist/features/notifications/notifications.service.d.ts +40 -0
  181. package/dist/features/notifications/notifications.service.js +94 -0
  182. package/dist/features/notifications/notifications.service.js.map +1 -0
  183. package/dist/features/one-time-codes/one-time-codes.service.d.ts +40 -0
  184. package/dist/features/one-time-codes/one-time-codes.service.js +102 -0
  185. package/dist/features/one-time-codes/one-time-codes.service.js.map +1 -0
  186. package/dist/features/organizations/organizations.controller.d.ts +220 -0
  187. package/dist/features/organizations/organizations.controller.js +337 -0
  188. package/dist/features/organizations/organizations.controller.js.map +1 -0
  189. package/dist/features/organizations/organizations.dto.d.ts +31 -0
  190. package/dist/features/organizations/organizations.dto.js +100 -0
  191. package/dist/features/organizations/organizations.dto.js.map +1 -0
  192. package/dist/features/organizations/organizations.service.d.ts +274 -0
  193. package/dist/features/organizations/organizations.service.js +481 -0
  194. package/dist/features/organizations/organizations.service.js.map +1 -0
  195. package/dist/features/passkeys/passkeys.controller.d.ts +92 -0
  196. package/dist/features/passkeys/passkeys.controller.js +183 -0
  197. package/dist/features/passkeys/passkeys.controller.js.map +1 -0
  198. package/dist/features/passkeys/passkeys.dto.d.ts +13 -0
  199. package/dist/features/passkeys/passkeys.dto.js +50 -0
  200. package/dist/features/passkeys/passkeys.dto.js.map +1 -0
  201. package/dist/features/passkeys/passkeys.service.d.ts +159 -0
  202. package/dist/features/passkeys/passkeys.service.js +350 -0
  203. package/dist/features/passkeys/passkeys.service.js.map +1 -0
  204. package/dist/features/passwordless/passwordless-auth.service.d.ts +152 -0
  205. package/dist/features/passwordless/passwordless-auth.service.js +304 -0
  206. package/dist/features/passwordless/passwordless-auth.service.js.map +1 -0
  207. package/dist/features/passwordless/passwordless.controller.d.ts +75 -0
  208. package/dist/features/passwordless/passwordless.controller.js +163 -0
  209. package/dist/features/passwordless/passwordless.controller.js.map +1 -0
  210. package/dist/features/passwordless/passwordless.dto.d.ts +29 -0
  211. package/dist/features/passwordless/passwordless.dto.js +101 -0
  212. package/dist/features/passwordless/passwordless.dto.js.map +1 -0
  213. package/dist/features/passwords/password-auth.service.d.ts +154 -0
  214. package/dist/features/passwords/password-auth.service.js +317 -0
  215. package/dist/features/passwords/password-auth.service.js.map +1 -0
  216. package/dist/features/passwords/password-policy.service.d.ts +63 -0
  217. package/dist/features/passwords/password-policy.service.js +175 -0
  218. package/dist/features/passwords/password-policy.service.js.map +1 -0
  219. package/dist/features/passwords/password.controller.d.ts +95 -0
  220. package/dist/features/passwords/password.controller.js +193 -0
  221. package/dist/features/passwords/password.controller.js.map +1 -0
  222. package/dist/features/passwords/password.dto.d.ts +36 -0
  223. package/dist/features/passwords/password.dto.js +140 -0
  224. package/dist/features/passwords/password.dto.js.map +1 -0
  225. package/dist/features/sessions/session.service.d.ts +132 -0
  226. package/dist/features/sessions/session.service.js +308 -0
  227. package/dist/features/sessions/session.service.js.map +1 -0
  228. package/dist/features/sessions/session.types.d.ts +34 -0
  229. package/dist/features/sessions/session.types.js +3 -0
  230. package/dist/features/sessions/session.types.js.map +1 -0
  231. package/dist/features/settings/settings.defaults.d.ts +2 -0
  232. package/dist/features/settings/settings.defaults.js +7 -0
  233. package/dist/features/settings/settings.defaults.js.map +1 -0
  234. package/dist/features/settings/settings.service.d.ts +44 -0
  235. package/dist/features/settings/settings.service.js +112 -0
  236. package/dist/features/settings/settings.service.js.map +1 -0
  237. package/dist/features/settings/settings.types.d.ts +133 -0
  238. package/dist/features/settings/settings.types.js +3 -0
  239. package/dist/features/settings/settings.types.js.map +1 -0
  240. package/dist/features/settings/settings.validation.d.ts +33 -0
  241. package/dist/features/settings/settings.validation.js +614 -0
  242. package/dist/features/settings/settings.validation.js.map +1 -0
  243. package/dist/features/sign-in/sign-in-challenges.service.d.ts +54 -0
  244. package/dist/features/sign-in/sign-in-challenges.service.js +104 -0
  245. package/dist/features/sign-in/sign-in-challenges.service.js.map +1 -0
  246. package/dist/features/sign-in/sign-in.service.d.ts +127 -0
  247. package/dist/features/sign-in/sign-in.service.js +248 -0
  248. package/dist/features/sign-in/sign-in.service.js.map +1 -0
  249. package/dist/features/sign-in/sign-in.types.d.ts +22 -0
  250. package/dist/features/sign-in/sign-in.types.js +3 -0
  251. package/dist/features/sign-in/sign-in.types.js.map +1 -0
  252. package/dist/features/signing-keys/jwks.controller.d.ts +17 -0
  253. package/dist/features/signing-keys/jwks.controller.js +51 -0
  254. package/dist/features/signing-keys/jwks.controller.js.map +1 -0
  255. package/dist/features/signing-keys/signing-keys.service.d.ts +67 -0
  256. package/dist/features/signing-keys/signing-keys.service.js +142 -0
  257. package/dist/features/signing-keys/signing-keys.service.js.map +1 -0
  258. package/dist/features/social/social-auth.service.d.ts +100 -0
  259. package/dist/features/social/social-auth.service.js +232 -0
  260. package/dist/features/social/social-auth.service.js.map +1 -0
  261. package/dist/features/social/social-providers.service.d.ts +97 -0
  262. package/dist/features/social/social-providers.service.js +214 -0
  263. package/dist/features/social/social-providers.service.js.map +1 -0
  264. package/dist/features/social/social.controller.d.ts +54 -0
  265. package/dist/features/social/social.controller.js +124 -0
  266. package/dist/features/social/social.controller.js.map +1 -0
  267. package/dist/features/social/social.dto.d.ts +11 -0
  268. package/dist/features/social/social.dto.js +38 -0
  269. package/dist/features/social/social.dto.js.map +1 -0
  270. package/dist/features/two-factor/two-factor.controller.d.ts +84 -0
  271. package/dist/features/two-factor/two-factor.controller.js +174 -0
  272. package/dist/features/two-factor/two-factor.controller.js.map +1 -0
  273. package/dist/features/two-factor/two-factor.dto.d.ts +10 -0
  274. package/dist/features/two-factor/two-factor.dto.js +37 -0
  275. package/dist/features/two-factor/two-factor.dto.js.map +1 -0
  276. package/dist/features/two-factor/two-factor.service.d.ts +171 -0
  277. package/dist/features/two-factor/two-factor.service.js +348 -0
  278. package/dist/features/two-factor/two-factor.service.js.map +1 -0
  279. package/dist/features/users/sign-in-methods.service.d.ts +40 -0
  280. package/dist/features/users/sign-in-methods.service.js +81 -0
  281. package/dist/features/users/sign-in-methods.service.js.map +1 -0
  282. package/dist/features/users/sign-up-rules.d.ts +12 -0
  283. package/dist/features/users/sign-up-rules.js +29 -0
  284. package/dist/features/users/sign-up-rules.js.map +1 -0
  285. package/dist/features/users/users.service.d.ts +246 -0
  286. package/dist/features/users/users.service.js +509 -0
  287. package/dist/features/users/users.service.js.map +1 -0
  288. package/dist/features/users/users.types.d.ts +24 -0
  289. package/dist/features/users/users.types.js +3 -0
  290. package/dist/features/users/users.types.js.map +1 -0
  291. package/dist/features/webhooks/webhook-delivery.worker.d.ts +55 -0
  292. package/dist/features/webhooks/webhook-delivery.worker.js +175 -0
  293. package/dist/features/webhooks/webhook-delivery.worker.js.map +1 -0
  294. package/dist/features/webhooks/webhook-signature.d.ts +28 -0
  295. package/dist/features/webhooks/webhook-signature.js +85 -0
  296. package/dist/features/webhooks/webhook-signature.js.map +1 -0
  297. package/dist/features/webhooks/webhooks.service.d.ts +144 -0
  298. package/dist/features/webhooks/webhooks.service.js +238 -0
  299. package/dist/features/webhooks/webhooks.service.js.map +1 -0
  300. package/dist/guards/auth.decorators.d.ts +65 -0
  301. package/dist/guards/auth.decorators.js +68 -0
  302. package/dist/guards/auth.decorators.js.map +1 -0
  303. package/dist/guards/auth.guard.d.ts +47 -0
  304. package/dist/guards/auth.guard.js +132 -0
  305. package/dist/guards/auth.guard.js.map +1 -0
  306. package/dist/index.d.ts +38 -0
  307. package/dist/index.js +95 -0
  308. package/dist/index.js.map +1 -0
  309. package/dist/integrations/console-email-sender.d.ts +15 -0
  310. package/dist/integrations/console-email-sender.js +26 -0
  311. package/dist/integrations/console-email-sender.js.map +1 -0
  312. package/dist/integrations/msg91-sms-sender.d.ts +28 -0
  313. package/dist/integrations/msg91-sms-sender.js +46 -0
  314. package/dist/integrations/msg91-sms-sender.js.map +1 -0
  315. package/docs/README.md +39 -0
  316. package/docs/admin-api-keys-webhooks.md +147 -0
  317. package/docs/api-reference.md +175 -0
  318. package/docs/architecture.md +119 -0
  319. package/docs/client-integration.md +192 -0
  320. package/docs/code-walkthrough.md +273 -0
  321. package/docs/configuration.md +229 -0
  322. package/docs/endpoints/README.md +151 -0
  323. package/docs/endpoints/account.md +363 -0
  324. package/docs/endpoints/admin.md +422 -0
  325. package/docs/endpoints/email-password.md +261 -0
  326. package/docs/endpoints/organizations.md +192 -0
  327. package/docs/endpoints/passkeys.md +195 -0
  328. package/docs/endpoints/passwordless.md +214 -0
  329. package/docs/endpoints/social.md +116 -0
  330. package/docs/endpoints/two-factor.md +146 -0
  331. package/docs/error-codes.md +100 -0
  332. package/docs/events.md +83 -0
  333. package/docs/getting-started.md +139 -0
  334. package/docs/manual-testing.md +215 -0
  335. package/docs/organizations.md +86 -0
  336. package/docs/production-checklist.md +60 -0
  337. package/docs/protecting-routes.md +147 -0
  338. package/docs/security.md +61 -0
  339. package/docs/sign-in-flows.md +294 -0
  340. package/package.json +92 -4
@@ -0,0 +1,350 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.PasskeysService = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const server_1 = require("@simplewebauthn/server");
18
+ const typeorm_1 = require("typeorm");
19
+ const auth_error_1 = require("../../common/auth-error.js");
20
+ const random_secrets_1 = require("../../common/crypto/random-secrets.js");
21
+ const rate_limiter_service_1 = require("../../common/rate-limiter.service.js");
22
+ const constants_1 = require("../../constants.js");
23
+ const entities_1 = require("../../database/entities/index.js");
24
+ const auth_events_service_1 = require("../events/auth-events.service.js");
25
+ const settings_service_1 = require("../settings/settings.service.js");
26
+ const sign_in_service_1 = require("../sign-in/sign-in.service.js");
27
+ const sign_in_methods_service_1 = require("../users/sign-in-methods.service.js");
28
+ const users_service_1 = require("../users/users.service.js");
29
+ /**
30
+ * Passkeys (Face ID, Touch ID, Windows Hello, Android, security keys) through WebAuthn.
31
+ *
32
+ * Adding a passkey and signing in with one each take two requests:
33
+ * - ".../options": we create a random challenge and return options for the browser or app,
34
+ * plus a `challengeToken` to send back with the verify request.
35
+ * - ".../verify": the device signed the challenge; we check the signature.
36
+ *
37
+ * Passkeys must use a fingerprint, face or PIN (user verification = required), which is why
38
+ * a passkey sign-in counts as two factors and skips the authenticator-app step.
39
+ */
40
+ let PasskeysService = class PasskeysService {
41
+ options;
42
+ settingsService;
43
+ users;
44
+ signIn;
45
+ signInMethods;
46
+ rateLimiter;
47
+ events;
48
+ database;
49
+ constructor(options, settingsService, users, signIn, signInMethods, rateLimiter, events) {
50
+ this.options = options;
51
+ this.settingsService = settingsService;
52
+ this.users = users;
53
+ this.signIn = signIn;
54
+ this.signInMethods = signInMethods;
55
+ this.rateLimiter = rateLimiter;
56
+ this.events = events;
57
+ this.database = options.dataSource;
58
+ }
59
+ // -------------------------------------------------------------------------------------------
60
+ // Adding a passkey (user is signed in)
61
+ // -------------------------------------------------------------------------------------------
62
+ /**
63
+ * Starts adding a passkey: creates a challenge and the options to pass to the browser
64
+ * (`navigator.credentials.create`, or SimpleWebAuthn's `startRegistration`).
65
+ *
66
+ * @param userId - The signed-in user.
67
+ * @returns `options` for the device, and a `challengeToken` to send back to finishRegistration.
68
+ * @throws AuthError SIGN_IN_METHOD_DISABLED or NOT_CONFIGURED when passkeys are off or not set up.
69
+ * @throws AuthError VALIDATION_ERROR when the user already has the maximum number of passkeys.
70
+ */
71
+ async startRegistration(userId) {
72
+ const { passkeyOptions } = await this.getEnabledPasskeySettings();
73
+ const user = await this.users.getUserOrThrow(userId);
74
+ const existingPasskeys = await this.database.getRepository(entities_1.PasskeyEntity).find({ where: { userId } });
75
+ if (existingPasskeys.length >= constants_1.MAXIMUM_PASSKEYS_PER_USER)
76
+ throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.validationFailed, { problems: [constants_1.VALIDATION_PROBLEM.tooManyPasskeys] });
77
+ const browserOptions = await (0, server_1.generateRegistrationOptions)({
78
+ rpName: passkeyOptions.relyingPartyName,
79
+ rpID: passkeyOptions.relyingPartyId,
80
+ userID: new TextEncoder().encode(user.id),
81
+ userName: user.email ?? user.phoneNumber ?? user.id,
82
+ userDisplayName: [user.firstName, user.lastName].filter(Boolean).join(constants_1.DISPLAY_NAME_SEPARATOR) || (user.email ?? ''),
83
+ attestationType: constants_1.PASSKEY_ATTESTATION_TYPE,
84
+ // Stops the same device from being registered twice.
85
+ excludeCredentials: existingPasskeys.map((passkey) => ({
86
+ id: passkey.credentialId,
87
+ transports: passkey.transports,
88
+ })),
89
+ authenticatorSelection: { residentKey: constants_1.PASSKEY_RESIDENT_KEY, userVerification: constants_1.PASSKEY_USER_VERIFICATION },
90
+ });
91
+ const challengeToken = await this.saveCeremonyChallenge(constants_1.CHALLENGE_PURPOSE.passkeyRegistration, browserOptions.challenge, userId);
92
+ return { success: true, challengeToken, options: browserOptions };
93
+ }
94
+ /**
95
+ * Finishes adding a passkey: checks the device's response and saves the new passkey.
96
+ *
97
+ * @param userId - The signed-in user (must be the one who called startRegistration).
98
+ * @param challengeToken - The token from startRegistration.
99
+ * @param deviceResponse - What the browser returned from `navigator.credentials.create`.
100
+ * @param passkeyName - A label like "MacBook"; a default name is used when empty.
101
+ * @param request - Who is asking (for the audit log).
102
+ * @returns The saved passkey.
103
+ * @throws AuthError INVALID_TOKEN when the challenge is unknown, used or expired.
104
+ * @throws AuthError INVALID_PASSKEY when the response doesn't check out.
105
+ */
106
+ async finishRegistration(userId, challengeToken, deviceResponse, passkeyName, request) {
107
+ const { passkeyOptions } = await this.getEnabledPasskeySettings();
108
+ const challenge = await this.useCeremonyChallenge(challengeToken, constants_1.CHALLENGE_PURPOSE.passkeyRegistration);
109
+ if (challenge.userId !== userId)
110
+ throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.invalidPasskey);
111
+ let verification;
112
+ try {
113
+ verification = await (0, server_1.verifyRegistrationResponse)({
114
+ response: deviceResponse,
115
+ expectedChallenge: challenge.webauthnChallenge,
116
+ expectedOrigin: passkeyOptions.allowedOrigins,
117
+ expectedRPID: passkeyOptions.relyingPartyId,
118
+ requireUserVerification: true,
119
+ });
120
+ }
121
+ catch {
122
+ throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.invalidPasskey);
123
+ }
124
+ if (!verification?.verified || !verification.registrationInfo)
125
+ throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.invalidPasskey);
126
+ const credential = this.readRegisteredCredential(verification.registrationInfo, deviceResponse);
127
+ const savedPasskey = await this.database.getRepository(entities_1.PasskeyEntity).save({
128
+ userId,
129
+ credentialId: credential.id,
130
+ publicKey: credential.publicKey,
131
+ signCount: credential.counter,
132
+ transports: credential.transports,
133
+ isBackedUp: credential.isBackedUp,
134
+ name: passkeyName?.trim() || constants_1.DEFAULT_PASSKEY_NAME,
135
+ });
136
+ await this.events.record({ name: constants_1.AUTH_EVENTS.passkeyAdded, userId, request, details: { passkeyId: savedPasskey.id } });
137
+ return { success: true, passkey: this.toSummary(savedPasskey) };
138
+ }
139
+ // -------------------------------------------------------------------------------------------
140
+ // Signing in with a passkey (no email needed: the device offers the user's passkeys)
141
+ // -------------------------------------------------------------------------------------------
142
+ /**
143
+ * Starts signing in with a passkey. No email is needed: the device offers the user's passkeys.
144
+ *
145
+ * @param request - Who is asking (for rate limits).
146
+ * @returns `options` for `navigator.credentials.get`, and a `challengeToken` for finishSignIn.
147
+ * @throws AuthError TOO_MANY_REQUESTS after too many attempts from this IP.
148
+ */
149
+ async startSignIn(request) {
150
+ const { passkeyOptions } = await this.getEnabledPasskeySettings();
151
+ await this.rateLimiter.consume(constants_1.RATE_LIMIT_KEY.signInPerIp(request.ipAddress), constants_1.RATE_LIMITS.signInPerIp);
152
+ const browserOptions = await (0, server_1.generateAuthenticationOptions)({
153
+ rpID: passkeyOptions.relyingPartyId,
154
+ userVerification: constants_1.PASSKEY_USER_VERIFICATION,
155
+ });
156
+ const challengeToken = await this.saveCeremonyChallenge(constants_1.CHALLENGE_PURPOSE.passkeySignIn, browserOptions.challenge, null);
157
+ return { success: true, challengeToken, options: browserOptions };
158
+ }
159
+ /**
160
+ * Finishes signing in with a passkey: checks the signature and signs the user in.
161
+ * Passkeys count as two factors, so the authenticator-app step is skipped.
162
+ *
163
+ * @param challengeToken - The token from startSignIn.
164
+ * @param deviceResponse - What the browser returned from `navigator.credentials.get`.
165
+ * @param request - Who is asking.
166
+ * @returns Tokens.
167
+ * @throws AuthError INVALID_TOKEN when the challenge is unknown, used or expired.
168
+ * @throws AuthError INVALID_PASSKEY when the passkey is unknown or the signature is wrong.
169
+ */
170
+ async finishSignIn(challengeToken, deviceResponse, request) {
171
+ const { settings, passkeyOptions } = await this.getEnabledPasskeySettings();
172
+ const challenge = await this.useCeremonyChallenge(challengeToken, constants_1.CHALLENGE_PURPOSE.passkeySignIn);
173
+ const credentialId = typeof deviceResponse?.id === 'string' ? deviceResponse.id : '';
174
+ const passkey = await this.database.getRepository(entities_1.PasskeyEntity).findOne({ where: { credentialId } });
175
+ if (!passkey)
176
+ throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.invalidPasskey);
177
+ let verification;
178
+ try {
179
+ verification = await (0, server_1.verifyAuthenticationResponse)({
180
+ response: deviceResponse,
181
+ expectedChallenge: challenge.webauthnChallenge,
182
+ expectedOrigin: passkeyOptions.allowedOrigins,
183
+ expectedRPID: passkeyOptions.relyingPartyId,
184
+ requireUserVerification: true,
185
+ credential: {
186
+ id: passkey.credentialId,
187
+ publicKey: new Uint8Array(Buffer.from(passkey.publicKey, constants_1.TEXT_ENCODING.base64Url)),
188
+ counter: passkey.signCount,
189
+ transports: passkey.transports,
190
+ },
191
+ });
192
+ }
193
+ catch {
194
+ verification = undefined;
195
+ }
196
+ if (!verification?.verified) {
197
+ await this.signIn.recordFailedSignIn(passkey.userId, constants_1.SIGN_IN_METHOD.passkey, constants_1.SIGN_IN_FAILURE_REASON.passkeySignatureInvalid, request);
198
+ throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.invalidPasskey);
199
+ }
200
+ await this.database.getRepository(entities_1.PasskeyEntity).update({ id: passkey.id }, { signCount: verification.authenticationInfo?.newCounter ?? passkey.signCount, lastUsedAt: new Date() });
201
+ const user = await this.users.findUserById(passkey.userId);
202
+ if (!user)
203
+ throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.invalidPasskey);
204
+ return this.signIn.completeSignIn(user, constants_1.SIGN_IN_METHOD.passkey, request, settings);
205
+ }
206
+ // -------------------------------------------------------------------------------------------
207
+ // Managing passkeys
208
+ // -------------------------------------------------------------------------------------------
209
+ /**
210
+ * @param userId - The signed-in user.
211
+ * @returns The user's passkeys, oldest first.
212
+ */
213
+ async listPasskeys(userId) {
214
+ const passkeys = await this.database.getRepository(entities_1.PasskeyEntity).find({ where: { userId }, order: { createdAt: constants_1.SORT_ORDER.oldestFirst } });
215
+ return passkeys.map((passkey) => this.toSummary(passkey));
216
+ }
217
+ /**
218
+ * @param userId - The signed-in user.
219
+ * @param passkeyId - One of the user's passkeys.
220
+ * @param newName - The new label.
221
+ * @returns `{ success: true }`.
222
+ * @throws AuthError NOT_FOUND when the passkey isn't the user's.
223
+ */
224
+ async renamePasskey(userId, passkeyId, newName) {
225
+ const result = await this.database.getRepository(entities_1.PasskeyEntity).update({ id: passkeyId, userId }, { name: newName.trim() });
226
+ if (!result.affected)
227
+ throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.notFound);
228
+ return { success: true };
229
+ }
230
+ /**
231
+ * Removes one of the user's passkeys, unless it is their last way to sign in.
232
+ *
233
+ * @param userId - The signed-in user.
234
+ * @param passkeyId - One of the user's passkeys.
235
+ * @param request - Who is asking (for the audit log).
236
+ * @returns `{ success: true }`.
237
+ * @throws AuthError NOT_FOUND when the passkey isn't the user's.
238
+ * @throws AuthError LAST_SIGN_IN_METHOD when it is the user's only way to sign in.
239
+ */
240
+ async removePasskey(userId, passkeyId, request) {
241
+ const settings = await this.settingsService.getSettings();
242
+ const passkeys = this.database.getRepository(entities_1.PasskeyEntity);
243
+ if (!(await passkeys.exists({ where: { id: passkeyId, userId } })))
244
+ throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.notFound);
245
+ await this.signInMethods.assertCanRemove(await this.users.getUserOrThrow(userId), settings, constants_1.REMOVABLE_SIGN_IN_METHOD.passkey);
246
+ await passkeys.delete({ id: passkeyId, userId });
247
+ await this.events.record({ name: constants_1.AUTH_EVENTS.passkeyRemoved, userId, request, details: { passkeyId } });
248
+ return { success: true };
249
+ }
250
+ // -------------------------------------------------------------------------------------------
251
+ /**
252
+ * @returns The current settings and the app's passkey options (relying party id, origins).
253
+ * @throws AuthError SIGN_IN_METHOD_DISABLED when passkeys are turned off in settings.
254
+ * @throws AuthError NOT_CONFIGURED when AuthOptions.passkeys is not set.
255
+ */
256
+ async getEnabledPasskeySettings() {
257
+ const settings = await this.settingsService.getSettings();
258
+ if (!settings.passkeys.enabled)
259
+ throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.signInMethodDisabled);
260
+ if (!this.options.passkeys)
261
+ throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.notConfigured);
262
+ return { settings, passkeyOptions: this.options.passkeys };
263
+ }
264
+ /**
265
+ * Stores the WebAuthn challenge until the finish request arrives, behind a "ch_..." token (only the token's hash is stored).
266
+ *
267
+ * @param purpose - Registration or sign-in.
268
+ * @param webauthnChallenge - The random challenge the device must sign.
269
+ * @param userId - The user adding a passkey, or null for sign-in.
270
+ * @returns The plain token for the client.
271
+ */
272
+ async saveCeremonyChallenge(purpose, webauthnChallenge, userId) {
273
+ const { plainToken, tokenHash } = (0, random_secrets_1.createRandomToken)(constants_1.TOKEN_PREFIX.signInChallenge);
274
+ await this.database.getRepository(entities_1.SignInChallengeEntity).insert({
275
+ purpose,
276
+ userId,
277
+ webauthnChallenge,
278
+ challengeTokenHash: tokenHash,
279
+ expiresAt: new Date(Date.now() + constants_1.PASSKEY_CHALLENGE_LIFETIME_SECONDS * constants_1.SECOND_IN_MILLISECONDS),
280
+ });
281
+ return plainToken;
282
+ }
283
+ /**
284
+ * Uses up a ceremony challenge (once only, before it expires).
285
+ *
286
+ * @param challengeToken - The token from startRegistration or startSignIn.
287
+ * @param purpose - Registration or sign-in.
288
+ * @returns The user who started it (null for sign-in) and the WebAuthn challenge.
289
+ * @throws AuthError INVALID_TOKEN when the token is unknown, used, expired or for another purpose.
290
+ */
291
+ async useCeremonyChallenge(challengeToken, purpose) {
292
+ if (!(0, random_secrets_1.hasRandomTokenFormat)(challengeToken, constants_1.TOKEN_PREFIX.signInChallenge))
293
+ throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.invalidOrExpiredLink);
294
+ const challenges = this.database.getRepository(entities_1.SignInChallengeEntity);
295
+ const challenge = await challenges.findOne({
296
+ where: { challengeTokenHash: (0, random_secrets_1.sha256Hex)(challengeToken), purpose, usedAt: (0, typeorm_1.IsNull)() },
297
+ });
298
+ if (!challenge || !challenge.webauthnChallenge || challenge.expiresAt.getTime() <= Date.now()) {
299
+ throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.invalidOrExpiredLink);
300
+ }
301
+ const result = await challenges.update({ id: challenge.id, usedAt: (0, typeorm_1.IsNull)() }, { usedAt: new Date() });
302
+ if (!result.affected)
303
+ throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.invalidOrExpiredLink);
304
+ return { userId: challenge.userId, webauthnChallenge: challenge.webauthnChallenge };
305
+ }
306
+ /**
307
+ * Reads the new credential from the library's result. SimpleWebAuthn v11+ nests it under
308
+ * `credential`; older versions used flat fields. Both are handled so an upgrade can't break sign-up.
309
+ *
310
+ * @param registrationInfo - `verification.registrationInfo` from SimpleWebAuthn.
311
+ * @param deviceResponse - The browser's response (fallback source for transports).
312
+ * @returns The credential id and public key (base64url), counter, transports and backup state.
313
+ */
314
+ readRegisteredCredential(registrationInfo, deviceResponse) {
315
+ const toBase64Url = (bytes) => typeof bytes === 'string' ? bytes : Buffer.from(bytes).toString(constants_1.TEXT_ENCODING.base64Url);
316
+ const nested = registrationInfo.credential;
317
+ return {
318
+ id: toBase64Url(nested?.id ?? registrationInfo.credentialID),
319
+ publicKey: toBase64Url(nested?.publicKey ?? registrationInfo.credentialPublicKey),
320
+ counter: Number(nested?.counter ?? registrationInfo.counter ?? 0),
321
+ transports: (nested?.transports ?? deviceResponse?.response?.transports ?? []),
322
+ isBackedUp: registrationInfo.credentialBackedUp === true,
323
+ };
324
+ }
325
+ /**
326
+ * @param passkey - The passkey row.
327
+ * @returns The passkey as shown to its owner (no public key).
328
+ */
329
+ toSummary(passkey) {
330
+ return {
331
+ id: passkey.id,
332
+ name: passkey.name,
333
+ isBackedUp: passkey.isBackedUp,
334
+ createdAt: passkey.createdAt.toISOString(),
335
+ lastUsedAt: passkey.lastUsedAt?.toISOString() ?? null,
336
+ };
337
+ }
338
+ };
339
+ exports.PasskeysService = PasskeysService;
340
+ exports.PasskeysService = PasskeysService = __decorate([
341
+ (0, common_1.Injectable)(),
342
+ __param(0, (0, common_1.Inject)(constants_1.AUTH_OPTIONS_TOKEN)),
343
+ __metadata("design:paramtypes", [Object, settings_service_1.SettingsService,
344
+ users_service_1.UsersService,
345
+ sign_in_service_1.SignInService,
346
+ sign_in_methods_service_1.SignInMethodsService,
347
+ rate_limiter_service_1.RateLimiterService,
348
+ auth_events_service_1.AuthEventsService])
349
+ ], PasskeysService);
350
+ //# sourceMappingURL=passkeys.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passkeys.service.js","sourceRoot":"","sources":["../../../src/features/passkeys/passkeys.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,152 @@
1
+ import { RateLimiterService } from '../../common/rate-limiter.service.js';
2
+ import { RequestContext } from '../../common/request-context.js';
3
+ import { LinkTokensService } from '../email-links/link-tokens.service.js';
4
+ import { NotificationsService } from '../notifications/notifications.service.js';
5
+ import { OneTimeCodesService } from '../one-time-codes/one-time-codes.service.js';
6
+ import { SettingsService } from '../settings/settings.service.js';
7
+ import { SignInService } from '../sign-in/sign-in.service.js';
8
+ import { SignInResult } from '../sign-in/sign-in.types.js';
9
+ import { UsersService } from '../users/users.service.js';
10
+ import { SignUpDetailsInput } from './passwordless.dto';
11
+ /**
12
+ * Sign in without a password:
13
+ * - Email OTP: a 6-digit code by email.
14
+ * - Magic link: a one-click link by email.
15
+ * - Phone OTP: a 6-digit code by SMS.
16
+ *
17
+ * The same endpoints also VERIFY the email / phone of an existing account, because receiving the
18
+ * code proves ownership. If the settings allow sign-up, an unknown email / phone gets a new account.
19
+ *
20
+ * "Send" endpoints always answer the same, so they never reveal who has an account.
21
+ */
22
+ export declare class PasswordlessAuthService {
23
+ private readonly settingsService;
24
+ private readonly users;
25
+ private readonly signIn;
26
+ private readonly oneTimeCodes;
27
+ private readonly linkTokens;
28
+ private readonly notifications;
29
+ private readonly rateLimiter;
30
+ constructor(settingsService: SettingsService, users: UsersService, signIn: SignInService, oneTimeCodes: OneTimeCodesService, linkTokens: LinkTokensService, notifications: NotificationsService, rateLimiter: RateLimiterService);
31
+ /**
32
+ * Emails a 6-digit sign-in code. Always answers the same, whether or not the email has an account.
33
+ *
34
+ * @param typedEmail - The email from the request.
35
+ * @param request - Who is asking (for rate limits).
36
+ * @returns A generic success message.
37
+ * @throws AuthError SIGN_IN_METHOD_DISABLED when email codes are turned off.
38
+ * @throws AuthError TOO_MANY_REQUESTS (with `retryAfterSeconds`) when a code was sent to this email a moment ago.
39
+ * @throws AuthError TOO_MANY_REQUESTS after too many codes for this IP or email.
40
+ */
41
+ sendEmailCode(typedEmail: unknown, request: RequestContext): Promise<{
42
+ success: true;
43
+ message: "If this destination can receive codes, a code is on its way.";
44
+ }>;
45
+ /**
46
+ * Signs in with an email code. This also verifies the email, and creates the account when the
47
+ * email is new and sign-up is allowed.
48
+ *
49
+ * @param typedEmail - The email the code was sent to.
50
+ * @param code - The code the user typed.
51
+ * @param signUpDetails - Names and consents, only needed when this creates a new account.
52
+ * @param request - Who is asking.
53
+ * @returns Tokens, or a 2FA challenge.
54
+ * @throws AuthError OTP_EXPIRED or INVALID_OTP when the code is not usable or wrong.
55
+ * @throws AuthError SIGN_UP_CLOSED when the email is new and sign-up is not allowed.
56
+ */
57
+ verifyEmailCode(typedEmail: unknown, code: unknown, signUpDetails: SignUpDetailsInput, request: RequestContext): Promise<SignInResult>;
58
+ /**
59
+ * Emails a one-click sign-in link. Always answers the same, whether or not the email has an account.
60
+ *
61
+ * @param typedEmail - The email from the request.
62
+ * @param request - Who is asking (for rate limits).
63
+ * @returns A generic success message.
64
+ * @throws AuthError SIGN_IN_METHOD_DISABLED when magic links are turned off.
65
+ * @throws AuthError TOO_MANY_REQUESTS after too many emails for this IP or address.
66
+ */
67
+ sendMagicLink(typedEmail: unknown, request: RequestContext): Promise<{
68
+ success: true;
69
+ message: "If this email can sign in, a sign-in link is on its way.";
70
+ }>;
71
+ /**
72
+ * Signs in with the token from a magic link. This also verifies the email, and creates the account
73
+ * when the email is new and sign-up is allowed.
74
+ *
75
+ * @param token - The token from the link.
76
+ * @param signUpDetails - Names and consents, only needed when this creates a new account.
77
+ * @param request - Who is asking.
78
+ * @returns Tokens, or a 2FA challenge.
79
+ * @throws AuthError INVALID_TOKEN when the link is unknown, used or expired.
80
+ * @throws AuthError SIGN_UP_CLOSED when the email is new and sign-up is not allowed.
81
+ */
82
+ verifyMagicLink(token: unknown, signUpDetails: SignUpDetailsInput, request: RequestContext): Promise<SignInResult>;
83
+ /**
84
+ * Sends a 6-digit sign-in code by SMS. Always answers the same, whether or not the number has an account.
85
+ *
86
+ * @param typedPhoneNumber - The phone number from the request, with country code.
87
+ * @param request - Who is asking (for rate limits).
88
+ * @returns A generic success message.
89
+ * @throws AuthError PHONE_COUNTRY_NOT_ALLOWED when the country code is not in the allowed list.
90
+ * @throws AuthError TOO_MANY_REQUESTS (with `retryAfterSeconds`) when a code was sent to this number a moment ago.
91
+ */
92
+ sendPhoneCode(typedPhoneNumber: unknown, request: RequestContext): Promise<{
93
+ success: true;
94
+ message: "If this destination can receive codes, a code is on its way.";
95
+ }>;
96
+ /**
97
+ * Signs in with an SMS code. This also verifies the phone number, and creates the account when the
98
+ * number is new and sign-up is allowed.
99
+ *
100
+ * @param typedPhoneNumber - The number the code was sent to.
101
+ * @param code - The code the user typed.
102
+ * @param signUpDetails - Names and consents, only needed when this creates a new account.
103
+ * @param request - Who is asking.
104
+ * @returns Tokens, or a 2FA challenge.
105
+ * @throws AuthError OTP_EXPIRED or INVALID_OTP when the code is not usable or wrong.
106
+ */
107
+ verifyPhoneCode(typedPhoneNumber: unknown, code: unknown, signUpDetails: SignUpDetailsInput, request: RequestContext): Promise<SignInResult>;
108
+ /**
109
+ * @returns The current settings.
110
+ * @throws AuthError SIGN_IN_METHOD_DISABLED when phone codes are turned off.
111
+ * @throws AuthError NOT_CONFIGURED when the app has no SMS sender.
112
+ */
113
+ private getPhoneSettings;
114
+ /**
115
+ * Applies the "send a code" rate limits for both the IP and the destination.
116
+ *
117
+ * @param destination - The email or phone number the code goes to.
118
+ * @param request - Who is asking.
119
+ * @throws AuthError TOO_MANY_REQUESTS when either limit is reached.
120
+ */
121
+ private consumeSendLimits;
122
+ /**
123
+ * Decides whether to actually send: existing users who may sign in, or new ones when sign-up is allowed.
124
+ *
125
+ * @param user - The existing account, or null.
126
+ * @param allowSignUp - Whether this sign-in method may create accounts.
127
+ * @param email - The normalized email.
128
+ * @param settings - The current settings.
129
+ * @returns True when the code or link should be sent.
130
+ */
131
+ private mayReceiveMessage;
132
+ /**
133
+ * Checks that a new account may be created with this method and these details.
134
+ *
135
+ * @param allowSignUp - Whether this sign-in method may create accounts.
136
+ * @param details - The names and consents from the request.
137
+ * @param settings - The current settings.
138
+ * @param email - The new account's email, or null for phone sign-up.
139
+ * @throws AuthError SIGN_UP_CLOSED, EMAIL_DOMAIN_NOT_ALLOWED, or an error for missing details.
140
+ */
141
+ private assertMaySignUp;
142
+ /**
143
+ * Creates an account whose email or phone is already verified (the user just received the code).
144
+ *
145
+ * @param contact - The email or the phone number the code was sent to.
146
+ * @param details - The names and consents from the request.
147
+ * @param settings - The current settings.
148
+ * @param request - Who is asking (for the audit log).
149
+ * @returns The new user.
150
+ */
151
+ private createVerifiedUser;
152
+ }