@lastshotlabs/bunshot 0.0.27 → 0.0.28

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 (742) hide show
  1. package/.oclif.manifest.json +39 -0
  2. package/README.md +8282 -2147
  3. package/dist/cli/commands/init.js +690 -0
  4. package/dist/cli/index.js +6 -0
  5. package/dist/cli.js +4 -4
  6. package/dist/packages/bunshot-admin/src/index.d.ts +15 -0
  7. package/dist/packages/bunshot-admin/src/index.js +11 -0
  8. package/dist/packages/bunshot-admin/src/lib/resourceTypes.d.ts +8 -0
  9. package/dist/packages/bunshot-admin/src/lib/resourceTypes.js +33 -0
  10. package/dist/packages/bunshot-admin/src/lib/typedRoute.d.ts +14 -0
  11. package/dist/packages/bunshot-admin/src/lib/typedRoute.js +17 -0
  12. package/dist/packages/bunshot-admin/src/plugin.d.ts +4 -0
  13. package/dist/packages/bunshot-admin/src/plugin.js +46 -0
  14. package/dist/packages/bunshot-admin/src/providers/auth0Access.d.ts +6 -0
  15. package/dist/packages/bunshot-admin/src/providers/auth0Access.js +32 -0
  16. package/dist/packages/bunshot-admin/src/routes/admin.d.ts +10 -0
  17. package/dist/packages/bunshot-admin/src/routes/admin.js +923 -0
  18. package/dist/packages/bunshot-admin/src/routes/mail.d.ts +6 -0
  19. package/dist/packages/bunshot-admin/src/routes/mail.js +114 -0
  20. package/dist/packages/bunshot-admin/src/routes/permissions.d.ts +8 -0
  21. package/dist/packages/bunshot-admin/src/routes/permissions.js +315 -0
  22. package/dist/packages/bunshot-admin/src/types/config.d.ts +16 -0
  23. package/dist/packages/bunshot-admin/src/types/config.js +37 -0
  24. package/dist/packages/bunshot-admin/src/types/env.d.ts +14 -0
  25. package/dist/packages/bunshot-admin/src/types/provider.d.ts +1 -0
  26. package/dist/packages/bunshot-admin/src/types/provider.js +4 -0
  27. package/dist/packages/bunshot-auth/src/adapters/memoryAuth.d.ts +66 -0
  28. package/dist/packages/bunshot-auth/src/adapters/memoryAuth.js +1063 -0
  29. package/dist/packages/bunshot-auth/src/adapters/mongoAuth.d.ts +2 -0
  30. package/dist/packages/bunshot-auth/src/adapters/mongoAuth.js +536 -0
  31. package/dist/packages/bunshot-auth/src/adapters/sqliteAuth.d.ts +88 -0
  32. package/dist/packages/bunshot-auth/src/adapters/sqliteAuth.js +1366 -0
  33. package/dist/packages/bunshot-auth/src/admin/bunshotAccess.d.ts +2 -0
  34. package/dist/packages/bunshot-auth/src/admin/bunshotAccess.js +23 -0
  35. package/dist/packages/bunshot-auth/src/admin/bunshotUsers.d.ts +5 -0
  36. package/dist/packages/bunshot-auth/src/admin/bunshotUsers.js +131 -0
  37. package/dist/packages/bunshot-auth/src/bootstrap.d.ts +38 -0
  38. package/dist/packages/bunshot-auth/src/bootstrap.js +384 -0
  39. package/dist/packages/bunshot-auth/src/config/appConfig.d.ts +3 -0
  40. package/dist/packages/bunshot-auth/src/config/appConfig.js +4 -0
  41. package/dist/packages/bunshot-auth/src/config/authConfig.d.ts +478 -0
  42. package/dist/packages/bunshot-auth/src/config/authConfig.js +46 -0
  43. package/dist/packages/bunshot-auth/src/config/configLock.d.ts +2 -0
  44. package/dist/packages/bunshot-auth/src/config/configLock.js +10 -0
  45. package/dist/packages/bunshot-auth/src/index.d.ts +25 -0
  46. package/dist/packages/bunshot-auth/src/index.js +23 -0
  47. package/dist/packages/bunshot-auth/src/infra/mongo.d.ts +15 -0
  48. package/dist/packages/bunshot-auth/src/infra/mongo.js +44 -0
  49. package/dist/packages/bunshot-auth/src/infra/queue.d.ts +14 -0
  50. package/dist/packages/bunshot-auth/src/infra/queue.js +27 -0
  51. package/dist/packages/bunshot-auth/src/infra/redis.d.ts +5 -0
  52. package/dist/packages/bunshot-auth/src/infra/redis.js +15 -0
  53. package/dist/packages/bunshot-auth/src/infra/signing.d.ts +7 -0
  54. package/dist/packages/bunshot-auth/src/infra/signing.js +8 -0
  55. package/dist/packages/bunshot-auth/src/lib/accountLockout.d.ts +34 -0
  56. package/dist/packages/bunshot-auth/src/lib/accountLockout.js +244 -0
  57. package/dist/packages/bunshot-auth/src/lib/adapterTiers.d.ts +1 -0
  58. package/dist/packages/bunshot-auth/src/lib/adapterTiers.js +1 -0
  59. package/dist/packages/bunshot-auth/src/lib/authAdapter.d.ts +1 -0
  60. package/dist/packages/bunshot-auth/src/lib/authAdapter.js +1 -0
  61. package/dist/packages/bunshot-auth/src/lib/authContext.d.ts +15 -0
  62. package/dist/packages/bunshot-auth/src/lib/authContext.js +1 -0
  63. package/dist/packages/bunshot-auth/src/lib/authEventBus.d.ts +4 -0
  64. package/dist/packages/bunshot-auth/src/lib/authEventBus.js +15 -0
  65. package/dist/packages/bunshot-auth/src/lib/authRateLimit.d.ts +28 -0
  66. package/dist/packages/bunshot-auth/src/lib/authRateLimit.js +205 -0
  67. package/dist/{lib → packages/bunshot-auth/src/lib}/breachedPassword.d.ts +8 -2
  68. package/dist/{lib → packages/bunshot-auth/src/lib}/breachedPassword.js +22 -9
  69. package/dist/packages/bunshot-auth/src/lib/cache.d.ts +12 -0
  70. package/dist/packages/bunshot-auth/src/lib/cache.js +120 -0
  71. package/dist/packages/bunshot-auth/src/lib/clientIp.d.ts +4 -0
  72. package/dist/{lib → packages/bunshot-auth/src/lib}/clientIp.js +14 -7
  73. package/dist/packages/bunshot-auth/src/lib/cookieOptions.d.ts +27 -0
  74. package/dist/packages/bunshot-auth/src/lib/cookieOptions.js +33 -0
  75. package/dist/packages/bunshot-auth/src/lib/credentialStuffing.d.ts +40 -0
  76. package/dist/packages/bunshot-auth/src/lib/credentialStuffing.js +221 -0
  77. package/dist/packages/bunshot-auth/src/lib/deletionCancelToken.d.ts +19 -0
  78. package/dist/packages/bunshot-auth/src/lib/deletionCancelToken.js +148 -0
  79. package/dist/packages/bunshot-auth/src/lib/emailTemplates.d.ts +23 -0
  80. package/dist/packages/bunshot-auth/src/lib/emailTemplates.js +265 -0
  81. package/dist/packages/bunshot-auth/src/lib/emailVerification.d.ts +30 -0
  82. package/dist/packages/bunshot-auth/src/lib/emailVerification.js +200 -0
  83. package/dist/packages/bunshot-auth/src/lib/env.d.ts +1 -0
  84. package/dist/packages/bunshot-auth/src/lib/env.js +3 -0
  85. package/dist/packages/bunshot-auth/src/lib/fingerprint.js +36 -0
  86. package/dist/{lib → packages/bunshot-auth/src/lib}/groups.d.ts +15 -16
  87. package/dist/{lib → packages/bunshot-auth/src/lib}/groups.js +22 -34
  88. package/dist/packages/bunshot-auth/src/lib/jwks.d.ts +28 -0
  89. package/dist/packages/bunshot-auth/src/lib/jwks.js +79 -0
  90. package/dist/packages/bunshot-auth/src/lib/jwt.d.ts +12 -0
  91. package/dist/packages/bunshot-auth/src/lib/jwt.js +86 -0
  92. package/dist/{lib → packages/bunshot-auth/src/lib}/logger.js +3 -3
  93. package/dist/{lib → packages/bunshot-auth/src/lib}/m2m.d.ts +5 -4
  94. package/dist/{lib → packages/bunshot-auth/src/lib}/m2m.js +6 -10
  95. package/dist/packages/bunshot-auth/src/lib/magicLink.d.ts +13 -0
  96. package/dist/packages/bunshot-auth/src/lib/magicLink.js +145 -0
  97. package/dist/packages/bunshot-auth/src/lib/mfaChallenge.d.ts +60 -0
  98. package/dist/packages/bunshot-auth/src/lib/mfaChallenge.js +419 -0
  99. package/dist/packages/bunshot-auth/src/lib/oauth.d.ts +82 -0
  100. package/dist/packages/bunshot-auth/src/lib/oauth.js +177 -0
  101. package/dist/packages/bunshot-auth/src/lib/oauthCode.d.ts +19 -0
  102. package/dist/packages/bunshot-auth/src/lib/oauthCode.js +182 -0
  103. package/dist/packages/bunshot-auth/src/lib/oauthReauth.d.ts +19 -0
  104. package/dist/packages/bunshot-auth/src/lib/oauthReauth.js +255 -0
  105. package/dist/packages/bunshot-auth/src/lib/organization.d.ts +66 -0
  106. package/dist/packages/bunshot-auth/src/lib/organization.js +225 -0
  107. package/dist/packages/bunshot-auth/src/lib/passwordHistory.d.ts +12 -0
  108. package/dist/packages/bunshot-auth/src/lib/passwordHistory.js +31 -0
  109. package/dist/packages/bunshot-auth/src/lib/resetPassword.d.ts +20 -0
  110. package/dist/packages/bunshot-auth/src/lib/resetPassword.js +148 -0
  111. package/dist/packages/bunshot-auth/src/lib/roles.d.ts +9 -0
  112. package/dist/packages/bunshot-auth/src/lib/roles.js +93 -0
  113. package/dist/packages/bunshot-auth/src/lib/saml.d.ts +29 -0
  114. package/dist/packages/bunshot-auth/src/lib/saml.js +73 -0
  115. package/dist/packages/bunshot-auth/src/lib/samlRequestId.d.ts +13 -0
  116. package/dist/packages/bunshot-auth/src/lib/samlRequestId.js +129 -0
  117. package/dist/{lib → packages/bunshot-auth/src/lib}/scim.d.ts +7 -7
  118. package/dist/{lib → packages/bunshot-auth/src/lib}/scim.js +15 -13
  119. package/dist/packages/bunshot-auth/src/lib/securityEventWiring.d.ts +22 -0
  120. package/dist/packages/bunshot-auth/src/lib/securityEventWiring.js +65 -0
  121. package/dist/packages/bunshot-auth/src/lib/session.d.ts +45 -0
  122. package/dist/packages/bunshot-auth/src/lib/session.js +1211 -0
  123. package/dist/packages/bunshot-auth/src/lib/storeInfra.d.ts +26 -0
  124. package/dist/packages/bunshot-auth/src/lib/storeInfra.js +18 -0
  125. package/dist/{lib → packages/bunshot-auth/src/lib}/suspension.d.ts +3 -2
  126. package/dist/{lib → packages/bunshot-auth/src/lib}/suspension.js +2 -5
  127. package/dist/packages/bunshot-auth/src/lib/validateAdapter.d.ts +16 -0
  128. package/dist/packages/bunshot-auth/src/lib/validateAdapter.js +161 -0
  129. package/dist/packages/bunshot-auth/src/middleware/bearerAuth.d.ts +13 -0
  130. package/dist/packages/bunshot-auth/src/middleware/bearerAuth.js +58 -0
  131. package/dist/{middleware → packages/bunshot-auth/src/middleware}/csrf.d.ts +5 -4
  132. package/dist/packages/bunshot-auth/src/middleware/csrf.js +138 -0
  133. package/dist/packages/bunshot-auth/src/middleware/identify.d.ts +4 -0
  134. package/dist/packages/bunshot-auth/src/middleware/identify.js +124 -0
  135. package/dist/{middleware → packages/bunshot-auth/src/middleware}/requireMfaSetup.d.ts +2 -2
  136. package/dist/{middleware → packages/bunshot-auth/src/middleware}/requireMfaSetup.js +10 -8
  137. package/dist/{middleware → packages/bunshot-auth/src/middleware}/requireRole.d.ts +2 -2
  138. package/dist/{middleware → packages/bunshot-auth/src/middleware}/requireRole.js +20 -16
  139. package/dist/{middleware → packages/bunshot-auth/src/middleware}/requireScope.d.ts +2 -2
  140. package/dist/{middleware → packages/bunshot-auth/src/middleware}/requireScope.js +6 -6
  141. package/dist/{middleware → packages/bunshot-auth/src/middleware}/requireStepUp.d.ts +2 -2
  142. package/dist/{middleware → packages/bunshot-auth/src/middleware}/requireStepUp.js +8 -7
  143. package/dist/{middleware → packages/bunshot-auth/src/middleware}/requireVerifiedEmail.d.ts +2 -2
  144. package/dist/{middleware → packages/bunshot-auth/src/middleware}/requireVerifiedEmail.js +7 -6
  145. package/dist/packages/bunshot-auth/src/middleware/scimAuth.d.ts +8 -0
  146. package/dist/packages/bunshot-auth/src/middleware/scimAuth.js +29 -0
  147. package/dist/packages/bunshot-auth/src/middleware/userAuth.d.ts +3 -0
  148. package/dist/packages/bunshot-auth/src/middleware/userAuth.js +6 -0
  149. package/dist/{models → packages/bunshot-auth/src/models}/AuthUser.d.ts +12 -8
  150. package/dist/packages/bunshot-auth/src/models/AuthUser.js +53 -0
  151. package/dist/packages/bunshot-auth/src/models/Group.d.ts +19 -0
  152. package/dist/packages/bunshot-auth/src/models/Group.js +22 -0
  153. package/dist/{models → packages/bunshot-auth/src/models}/GroupMembership.d.ts +6 -8
  154. package/dist/packages/bunshot-auth/src/models/GroupMembership.js +19 -0
  155. package/dist/{models → packages/bunshot-auth/src/models}/M2MClient.d.ts +1 -1
  156. package/dist/{models → packages/bunshot-auth/src/models}/M2MClient.js +5 -5
  157. package/dist/packages/bunshot-auth/src/models/TenantRole.d.ts +13 -0
  158. package/dist/packages/bunshot-auth/src/models/TenantRole.js +17 -0
  159. package/dist/packages/bunshot-auth/src/plugin.d.ts +4 -0
  160. package/dist/packages/bunshot-auth/src/plugin.js +274 -0
  161. package/dist/packages/bunshot-auth/src/routes/auth.d.ts +15 -0
  162. package/dist/packages/bunshot-auth/src/routes/auth.js +1624 -0
  163. package/dist/packages/bunshot-auth/src/routes/groups.d.ts +4 -0
  164. package/dist/packages/bunshot-auth/src/routes/groups.js +481 -0
  165. package/dist/packages/bunshot-auth/src/routes/m2m.d.ts +2 -0
  166. package/dist/packages/bunshot-auth/src/routes/m2m.js +145 -0
  167. package/dist/packages/bunshot-auth/src/routes/mfa.d.ts +6 -0
  168. package/dist/packages/bunshot-auth/src/routes/mfa.js +991 -0
  169. package/dist/packages/bunshot-auth/src/routes/oauth.d.ts +3 -0
  170. package/dist/packages/bunshot-auth/src/routes/oauth.js +1727 -0
  171. package/dist/packages/bunshot-auth/src/routes/oidc.d.ts +2 -0
  172. package/dist/packages/bunshot-auth/src/routes/oidc.js +84 -0
  173. package/dist/packages/bunshot-auth/src/routes/organizations.d.ts +3 -0
  174. package/dist/packages/bunshot-auth/src/routes/organizations.js +741 -0
  175. package/dist/packages/bunshot-auth/src/routes/passkey.d.ts +2 -0
  176. package/dist/packages/bunshot-auth/src/routes/passkey.js +199 -0
  177. package/dist/packages/bunshot-auth/src/routes/saml.d.ts +2 -0
  178. package/dist/packages/bunshot-auth/src/routes/saml.js +226 -0
  179. package/dist/packages/bunshot-auth/src/routes/scim.d.ts +3 -0
  180. package/dist/packages/bunshot-auth/src/routes/scim.js +588 -0
  181. package/dist/packages/bunshot-auth/src/runtime.d.ts +52 -0
  182. package/dist/packages/bunshot-auth/src/runtime.js +11 -0
  183. package/dist/{schemas → packages/bunshot-auth/src/schemas}/auth.d.ts +4 -5
  184. package/dist/packages/bunshot-auth/src/schemas/auth.js +24 -0
  185. package/dist/packages/bunshot-auth/src/schemas/error.d.ts +10 -0
  186. package/dist/packages/bunshot-auth/src/schemas/error.js +10 -0
  187. package/dist/packages/bunshot-auth/src/schemas/success.d.ts +10 -0
  188. package/dist/packages/bunshot-auth/src/schemas/success.js +10 -0
  189. package/dist/packages/bunshot-auth/src/services/auth.d.ts +39 -0
  190. package/dist/packages/bunshot-auth/src/services/auth.js +378 -0
  191. package/dist/{services → packages/bunshot-auth/src/services}/mfa.d.ts +41 -17
  192. package/dist/{services → packages/bunshot-auth/src/services}/mfa.js +259 -183
  193. package/dist/packages/bunshot-auth/src/testing.d.ts +31 -0
  194. package/dist/packages/bunshot-auth/src/testing.js +23 -0
  195. package/dist/packages/bunshot-auth/src/types/adapter.d.ts +1 -0
  196. package/dist/packages/bunshot-auth/src/types/adapter.js +1 -0
  197. package/dist/packages/bunshot-auth/src/types/config.d.ts +152 -0
  198. package/dist/packages/bunshot-auth/src/types/config.js +179 -0
  199. package/dist/{routes → packages/bunshot-auth/src/types}/groups.d.ts +2 -3
  200. package/dist/packages/bunshot-auth/src/types/groups.js +1 -0
  201. package/dist/packages/bunshot-auth/src/types/oauthCode.d.ts +6 -0
  202. package/dist/packages/bunshot-auth/src/types/oauthCode.js +1 -0
  203. package/dist/packages/bunshot-auth/src/types/oauthReauth.d.ts +13 -0
  204. package/dist/packages/bunshot-auth/src/types/oauthReauth.js +1 -0
  205. package/dist/packages/bunshot-auth/src/types/redis.d.ts +1 -0
  206. package/dist/packages/bunshot-auth/src/types/redis.js +1 -0
  207. package/dist/packages/bunshot-auth/src/types/saml.d.ts +10 -0
  208. package/dist/packages/bunshot-auth/src/types/saml.js +1 -0
  209. package/dist/packages/bunshot-auth/src/types/session.d.ts +18 -0
  210. package/dist/packages/bunshot-auth/src/types/session.js +1 -0
  211. package/dist/packages/bunshot-auth/src/types/store.d.ts +1 -0
  212. package/dist/packages/bunshot-auth/src/types/store.js +1 -0
  213. package/dist/packages/bunshot-core/src/adminProvider.d.ts +95 -0
  214. package/dist/packages/bunshot-core/src/adminProvider.js +1 -0
  215. package/dist/packages/bunshot-core/src/auditLog.d.ts +34 -0
  216. package/dist/packages/bunshot-core/src/auditLog.js +1 -0
  217. package/dist/packages/bunshot-core/src/auth-adapter.d.ts +227 -0
  218. package/dist/packages/bunshot-core/src/auth-adapter.js +4 -0
  219. package/dist/packages/bunshot-core/src/authVariables.d.ts +14 -0
  220. package/dist/packages/bunshot-core/src/authVariables.js +4 -0
  221. package/dist/packages/bunshot-core/src/cache.d.ts +12 -0
  222. package/dist/packages/bunshot-core/src/cache.js +21 -0
  223. package/dist/{lib → packages/bunshot-core/src}/captcha.d.ts +1 -10
  224. package/dist/packages/bunshot-core/src/captcha.js +1 -0
  225. package/dist/packages/bunshot-core/src/clearRegistry.d.ts +6 -0
  226. package/dist/packages/bunshot-core/src/clearRegistry.js +17 -0
  227. package/dist/packages/bunshot-core/src/clientIp.d.ts +3 -0
  228. package/dist/packages/bunshot-core/src/clientIp.js +45 -0
  229. package/dist/packages/bunshot-core/src/configLock.d.ts +4 -0
  230. package/dist/packages/bunshot-core/src/configLock.js +7 -0
  231. package/dist/packages/bunshot-core/src/configValidation.d.ts +22 -0
  232. package/dist/packages/bunshot-core/src/configValidation.js +39 -0
  233. package/dist/packages/bunshot-core/src/constants.js +10 -0
  234. package/dist/packages/bunshot-core/src/context/bunshotContext.d.ts +232 -0
  235. package/dist/packages/bunshot-core/src/context/bunshotContext.js +1 -0
  236. package/dist/packages/bunshot-core/src/context/contextAccess.d.ts +3 -0
  237. package/dist/packages/bunshot-core/src/context/contextAccess.js +16 -0
  238. package/dist/packages/bunshot-core/src/context/contextStore.d.ts +16 -0
  239. package/dist/packages/bunshot-core/src/context/contextStore.js +31 -0
  240. package/dist/packages/bunshot-core/src/context/frameworkConfig.d.ts +38 -0
  241. package/dist/packages/bunshot-core/src/context/frameworkConfig.js +1 -0
  242. package/dist/packages/bunshot-core/src/context/index.d.ts +4 -0
  243. package/dist/packages/bunshot-core/src/context/index.js +2 -0
  244. package/dist/packages/bunshot-core/src/context.d.ts +40 -0
  245. package/dist/packages/bunshot-core/src/context.js +35 -0
  246. package/dist/packages/bunshot-core/src/coreContracts.d.ts +47 -0
  247. package/dist/packages/bunshot-core/src/coreContracts.js +1 -0
  248. package/dist/packages/bunshot-core/src/coreRegistrar.d.ts +6 -0
  249. package/dist/packages/bunshot-core/src/coreRegistrar.js +42 -0
  250. package/dist/{lib → packages/bunshot-core/src}/createRoute.d.ts +4 -30
  251. package/dist/{lib → packages/bunshot-core/src}/createRoute.js +39 -88
  252. package/dist/packages/bunshot-core/src/cronRegistry.d.ts +11 -0
  253. package/dist/packages/bunshot-core/src/cronRegistry.js +1 -0
  254. package/dist/packages/bunshot-core/src/crypto.d.ts +43 -0
  255. package/dist/packages/bunshot-core/src/crypto.js +74 -0
  256. package/dist/packages/bunshot-core/src/csrf.d.ts +8 -0
  257. package/dist/packages/bunshot-core/src/csrf.js +1 -0
  258. package/dist/packages/bunshot-core/src/defaults/defaultFingerprint.d.ts +7 -0
  259. package/dist/packages/bunshot-core/src/defaults/defaultFingerprint.js +19 -0
  260. package/dist/packages/bunshot-core/src/defaults/memoryCacheAdapter.d.ts +6 -0
  261. package/dist/packages/bunshot-core/src/defaults/memoryCacheAdapter.js +40 -0
  262. package/dist/packages/bunshot-core/src/defaults/memoryRateLimit.d.ts +6 -0
  263. package/dist/packages/bunshot-core/src/defaults/memoryRateLimit.js +24 -0
  264. package/dist/packages/bunshot-core/src/emailTemplates.d.ts +5 -0
  265. package/dist/packages/bunshot-core/src/emailTemplates.js +10 -0
  266. package/dist/{lib/HttpError.d.ts → packages/bunshot-core/src/errors.d.ts} +4 -1
  267. package/dist/{lib/HttpError.js → packages/bunshot-core/src/errors.js} +7 -1
  268. package/dist/packages/bunshot-core/src/eventBus.d.ts +270 -0
  269. package/dist/packages/bunshot-core/src/eventBus.js +143 -0
  270. package/dist/packages/bunshot-core/src/idempotency.d.ts +18 -0
  271. package/dist/packages/bunshot-core/src/idempotency.js +1 -0
  272. package/dist/packages/bunshot-core/src/index.d.ts +60 -0
  273. package/dist/packages/bunshot-core/src/index.js +34 -0
  274. package/dist/packages/bunshot-core/src/mail.d.ts +14 -0
  275. package/dist/packages/bunshot-core/src/mail.js +8 -0
  276. package/dist/packages/bunshot-core/src/memoryEviction.d.ts +24 -0
  277. package/dist/packages/bunshot-core/src/memoryEviction.js +52 -0
  278. package/dist/packages/bunshot-core/src/pagination.d.ts +45 -0
  279. package/dist/packages/bunshot-core/src/pagination.js +61 -0
  280. package/dist/packages/bunshot-core/src/permissions.d.ts +64 -0
  281. package/dist/packages/bunshot-core/src/permissions.js +27 -0
  282. package/dist/packages/bunshot-core/src/plugin.d.ts +44 -0
  283. package/dist/packages/bunshot-core/src/plugin.js +1 -0
  284. package/dist/packages/bunshot-core/src/rateLimit.d.ts +5 -0
  285. package/dist/packages/bunshot-core/src/rateLimit.js +18 -0
  286. package/dist/packages/bunshot-core/src/redis.d.ts +21 -0
  287. package/dist/packages/bunshot-core/src/redis.js +1 -0
  288. package/dist/packages/bunshot-core/src/routeAuth.d.ts +5 -0
  289. package/dist/packages/bunshot-core/src/routeAuth.js +11 -0
  290. package/dist/packages/bunshot-core/src/routeOverrides.d.ts +24 -0
  291. package/dist/packages/bunshot-core/src/routeOverrides.js +25 -0
  292. package/dist/packages/bunshot-core/src/routerAdapter.d.ts +6 -0
  293. package/dist/packages/bunshot-core/src/routerAdapter.js +56 -0
  294. package/dist/packages/bunshot-core/src/secrets.d.ts +48 -0
  295. package/dist/packages/bunshot-core/src/secrets.js +8 -0
  296. package/dist/packages/bunshot-core/src/signing.d.ts +41 -0
  297. package/dist/packages/bunshot-core/src/signing.js +1 -0
  298. package/dist/packages/bunshot-core/src/sse.d.ts +36 -0
  299. package/dist/packages/bunshot-core/src/sse.js +1 -0
  300. package/dist/packages/bunshot-core/src/storageAdapter.js +1 -0
  301. package/dist/packages/bunshot-core/src/storeInfra.d.ts +44 -0
  302. package/dist/packages/bunshot-core/src/storeInfra.js +18 -0
  303. package/dist/packages/bunshot-core/src/storeType.d.ts +7 -0
  304. package/dist/packages/bunshot-core/src/storeType.js +1 -0
  305. package/dist/packages/bunshot-core/src/testing.d.ts +1 -0
  306. package/dist/packages/bunshot-core/src/testing.js +1 -0
  307. package/dist/packages/bunshot-core/src/uploadRegistry.d.ts +23 -0
  308. package/dist/packages/bunshot-core/src/uploadRegistry.js +4 -0
  309. package/dist/packages/bunshot-core/src/userResolver.d.ts +5 -0
  310. package/dist/packages/bunshot-core/src/userResolver.js +14 -0
  311. package/dist/packages/bunshot-core/src/wsMessages.d.ts +42 -0
  312. package/dist/packages/bunshot-core/src/wsMessages.js +4 -0
  313. package/dist/packages/bunshot-permissions/src/adapters/memory.d.ts +7 -0
  314. package/dist/packages/bunshot-permissions/src/adapters/memory.js +73 -0
  315. package/dist/packages/bunshot-permissions/src/index.d.ts +10 -0
  316. package/dist/packages/bunshot-permissions/src/index.js +5 -0
  317. package/dist/packages/bunshot-permissions/src/lib/bootstrap.d.ts +7 -0
  318. package/dist/packages/bunshot-permissions/src/lib/bootstrap.js +12 -0
  319. package/dist/packages/bunshot-permissions/src/lib/evaluator.d.ts +10 -0
  320. package/dist/packages/bunshot-permissions/src/lib/evaluator.js +165 -0
  321. package/dist/packages/bunshot-permissions/src/lib/registry.d.ts +2 -0
  322. package/dist/packages/bunshot-permissions/src/lib/registry.js +31 -0
  323. package/dist/packages/bunshot-permissions/src/lib/validation.d.ts +1 -0
  324. package/dist/packages/bunshot-permissions/src/lib/validation.js +1 -0
  325. package/dist/packages/bunshot-permissions/src/types/adapter.d.ts +1 -0
  326. package/dist/packages/bunshot-permissions/src/types/adapter.js +1 -0
  327. package/dist/packages/bunshot-permissions/src/types/evaluator.d.ts +1 -0
  328. package/dist/packages/bunshot-permissions/src/types/evaluator.js +1 -0
  329. package/dist/packages/bunshot-permissions/src/types/models.d.ts +1 -0
  330. package/dist/packages/bunshot-permissions/src/types/models.js +1 -0
  331. package/dist/packages/bunshot-permissions/src/types/registry.d.ts +1 -0
  332. package/dist/packages/bunshot-permissions/src/types/registry.js +1 -0
  333. package/dist/packages/bunshot-postgres/src/adapter.d.ts +6 -0
  334. package/dist/packages/bunshot-postgres/src/adapter.js +794 -0
  335. package/dist/packages/bunshot-postgres/src/connection.d.ts +15 -0
  336. package/dist/packages/bunshot-postgres/src/connection.js +16 -0
  337. package/dist/packages/bunshot-postgres/src/index.d.ts +4 -0
  338. package/dist/packages/bunshot-postgres/src/index.js +2 -0
  339. package/dist/packages/bunshot-postgres/src/schema.d.ts +997 -0
  340. package/dist/packages/bunshot-postgres/src/schema.js +105 -0
  341. package/dist/src/app.d.ts +230 -0
  342. package/dist/src/app.js +182 -0
  343. package/dist/src/cli/commands/init.d.ts +10 -0
  344. package/dist/src/cli/commands/init.js +709 -0
  345. package/dist/src/cli/index.d.ts +1 -0
  346. package/dist/src/cli/index.js +3 -0
  347. package/dist/src/entrypoints/mongo.d.ts +6 -0
  348. package/dist/src/entrypoints/mongo.js +4 -0
  349. package/dist/src/entrypoints/queue.d.ts +2 -0
  350. package/dist/src/entrypoints/queue.js +1 -0
  351. package/dist/src/entrypoints/redis.d.ts +1 -0
  352. package/dist/src/entrypoints/redis.js +1 -0
  353. package/dist/{adapters → src/framework/adapters}/localStorage.d.ts +1 -1
  354. package/dist/{adapters → src/framework/adapters}/localStorage.js +10 -10
  355. package/dist/src/framework/adapters/memoryStorage.d.ts +2 -0
  356. package/dist/src/framework/adapters/memoryStorage.js +45 -0
  357. package/dist/{adapters → src/framework/adapters}/s3Storage.d.ts +1 -1
  358. package/dist/{adapters → src/framework/adapters}/s3Storage.js +12 -12
  359. package/dist/src/framework/admin/bunshotAccess.d.ts +2 -0
  360. package/dist/src/framework/admin/bunshotAccess.js +23 -0
  361. package/dist/src/framework/admin/bunshotUsers.d.ts +2 -0
  362. package/dist/src/framework/admin/bunshotUsers.js +103 -0
  363. package/dist/src/framework/admin/index.d.ts +7 -0
  364. package/dist/src/framework/admin/index.js +21 -0
  365. package/dist/src/framework/boundaryAdapters/cacheFactories.d.ts +13 -0
  366. package/dist/src/framework/boundaryAdapters/cacheFactories.js +86 -0
  367. package/dist/src/framework/boundaryAdapters/index.d.ts +2 -0
  368. package/dist/src/framework/boundaryAdapters/index.js +1 -0
  369. package/dist/src/framework/boundaryAdapters.d.ts +17 -0
  370. package/dist/src/framework/boundaryAdapters.js +62 -0
  371. package/dist/src/framework/buildContext.d.ts +33 -0
  372. package/dist/src/framework/buildContext.js +119 -0
  373. package/dist/src/framework/config/schema.d.ts +447 -0
  374. package/dist/src/framework/config/schema.js +528 -0
  375. package/dist/src/framework/createInfrastructure.d.ts +76 -0
  376. package/dist/src/framework/createInfrastructure.js +221 -0
  377. package/dist/src/framework/lib/auditLog.d.ts +23 -0
  378. package/dist/src/framework/lib/auditLog.js +416 -0
  379. package/dist/src/framework/lib/captcha.d.ts +11 -0
  380. package/dist/{lib → src/framework/lib}/captcha.js +13 -10
  381. package/dist/{lib → src/framework/lib}/createDtoMapper.js +4 -4
  382. package/dist/src/framework/lib/createRoute.d.ts +1 -0
  383. package/dist/src/framework/lib/createRoute.js +2 -0
  384. package/dist/{lib → src/framework/lib}/idempotency.d.ts +2 -6
  385. package/dist/src/framework/lib/idempotency.js +74 -0
  386. package/dist/src/framework/lib/logger.d.ts +3 -0
  387. package/dist/src/framework/lib/logger.js +14 -0
  388. package/dist/src/framework/lib/metrics.d.ts +34 -0
  389. package/dist/{lib → src/framework/lib}/metrics.js +49 -57
  390. package/dist/src/framework/lib/pagination.d.ts +42 -0
  391. package/dist/src/framework/lib/pagination.js +51 -0
  392. package/dist/src/framework/lib/redisTransport.d.ts +38 -0
  393. package/dist/src/framework/lib/redisTransport.js +107 -0
  394. package/dist/src/framework/lib/resolveUserId.d.ts +2 -0
  395. package/dist/src/framework/lib/resolveUserId.js +5 -0
  396. package/dist/src/framework/lib/sseCollision.d.ts +6 -0
  397. package/dist/src/framework/lib/sseCollision.js +26 -0
  398. package/dist/src/framework/lib/storageAdapter.d.ts +1 -0
  399. package/dist/src/framework/lib/storageAdapter.js +1 -0
  400. package/dist/{lib → src/framework/lib}/stripUnreferencedSchemas.js +4 -4
  401. package/dist/src/framework/lib/tenant.d.ts +21 -0
  402. package/dist/src/framework/lib/tenant.js +70 -0
  403. package/dist/{lib → src/framework/lib}/upload.d.ts +11 -10
  404. package/dist/src/framework/lib/upload.js +132 -0
  405. package/dist/src/framework/lib/uploadRegistry.d.ts +23 -0
  406. package/dist/src/framework/lib/uploadRegistry.js +34 -0
  407. package/dist/{lib → src/framework/lib}/validate.d.ts +1 -1
  408. package/dist/{lib → src/framework/lib}/validate.js +2 -2
  409. package/dist/src/framework/lib/ws.d.ts +19 -0
  410. package/dist/src/framework/lib/ws.js +130 -0
  411. package/dist/src/framework/lib/wsHeartbeat.d.ts +12 -0
  412. package/dist/src/framework/lib/wsHeartbeat.js +53 -0
  413. package/dist/src/framework/lib/wsMessages.d.ts +25 -0
  414. package/dist/src/framework/lib/wsMessages.js +45 -0
  415. package/dist/src/framework/lib/wsNamespace.d.ts +17 -0
  416. package/dist/src/framework/lib/wsNamespace.js +19 -0
  417. package/dist/src/framework/lib/wsPresence.d.ts +17 -0
  418. package/dist/src/framework/lib/wsPresence.js +84 -0
  419. package/dist/src/framework/lib/wsTransport.d.ts +38 -0
  420. package/dist/src/framework/lib/wsTransport.js +9 -0
  421. package/dist/{lib → src/framework/lib}/zodToMongoose.d.ts +1 -1
  422. package/dist/{lib → src/framework/lib}/zodToMongoose.js +11 -11
  423. package/dist/{middleware → src/framework/middleware}/auditLog.d.ts +4 -3
  424. package/dist/src/framework/middleware/auditLog.js +42 -0
  425. package/dist/{middleware → src/framework/middleware}/botProtection.d.ts +2 -2
  426. package/dist/{middleware → src/framework/middleware}/botProtection.js +8 -9
  427. package/dist/src/framework/middleware/cacheResponse.d.ts +35 -0
  428. package/dist/src/framework/middleware/cacheResponse.js +126 -0
  429. package/dist/{middleware → src/framework/middleware}/captcha.d.ts +2 -3
  430. package/dist/src/framework/middleware/captcha.js +37 -0
  431. package/dist/{middleware → src/framework/middleware}/errorHandler.d.ts +1 -1
  432. package/dist/{middleware → src/framework/middleware}/errorHandler.js +2 -2
  433. package/dist/src/framework/middleware/index.js +1 -0
  434. package/dist/{middleware → src/framework/middleware}/logger.d.ts +1 -1
  435. package/dist/src/framework/middleware/metrics.d.ts +12 -0
  436. package/dist/src/framework/middleware/metrics.js +26 -0
  437. package/dist/{middleware → src/framework/middleware}/rateLimit.d.ts +2 -2
  438. package/dist/src/framework/middleware/rateLimit.js +22 -0
  439. package/dist/src/framework/middleware/requestId.d.ts +3 -0
  440. package/dist/{middleware → src/framework/middleware}/requestId.js +2 -2
  441. package/dist/{middleware → src/framework/middleware}/requestLogger.d.ts +3 -3
  442. package/dist/{middleware → src/framework/middleware}/requestLogger.js +17 -12
  443. package/dist/{middleware → src/framework/middleware}/requestSigning.d.ts +2 -2
  444. package/dist/{middleware → src/framework/middleware}/requestSigning.js +18 -20
  445. package/dist/src/framework/middleware/tenant.d.ts +14 -0
  446. package/dist/{middleware → src/framework/middleware}/tenant.js +31 -27
  447. package/dist/src/framework/middleware/upload.d.ts +5 -0
  448. package/dist/{middleware → src/framework/middleware}/upload.js +4 -4
  449. package/dist/{middleware → src/framework/middleware}/webhookAuth.d.ts +3 -3
  450. package/dist/{middleware → src/framework/middleware}/webhookAuth.js +11 -12
  451. package/dist/src/framework/models/AuditLog.d.ts +21 -0
  452. package/dist/src/framework/models/AuditLog.js +31 -0
  453. package/dist/src/framework/mountMiddleware.d.ts +91 -0
  454. package/dist/src/framework/mountMiddleware.js +128 -0
  455. package/dist/src/framework/mountOptionalEndpoints.d.ts +103 -0
  456. package/dist/src/framework/mountOptionalEndpoints.js +47 -0
  457. package/dist/src/framework/mountRoutes.d.ts +21 -0
  458. package/dist/src/framework/mountRoutes.js +144 -0
  459. package/dist/src/framework/persistence/cronRegistry.d.ts +28 -0
  460. package/dist/src/framework/persistence/cronRegistry.js +139 -0
  461. package/dist/src/framework/persistence/idempotency.d.ts +26 -0
  462. package/dist/src/framework/persistence/idempotency.js +178 -0
  463. package/dist/src/framework/persistence/index.d.ts +6 -0
  464. package/dist/src/framework/persistence/index.js +8 -0
  465. package/dist/src/framework/persistence/storeInfra.d.ts +9 -0
  466. package/dist/src/framework/persistence/storeInfra.js +1 -0
  467. package/dist/src/framework/persistence/uploadRegistry.d.ts +35 -0
  468. package/dist/src/framework/persistence/uploadRegistry.js +235 -0
  469. package/dist/src/framework/persistence/wsMessages.d.ts +22 -0
  470. package/dist/src/framework/persistence/wsMessages.js +296 -0
  471. package/dist/src/framework/preloadSchemas.d.ts +24 -0
  472. package/dist/src/framework/preloadSchemas.js +42 -0
  473. package/dist/src/framework/registerBoundaryAdapters.d.ts +23 -0
  474. package/dist/src/framework/registerBoundaryAdapters.js +46 -0
  475. package/dist/src/framework/routes/admin.d.ts +9 -0
  476. package/dist/src/framework/routes/admin.js +361 -0
  477. package/dist/src/framework/routes/health.d.ts +1 -0
  478. package/dist/src/framework/routes/health.js +21 -0
  479. package/dist/src/framework/routes/home.d.ts +1 -0
  480. package/dist/src/framework/routes/home.js +18 -0
  481. package/dist/src/framework/routes/jobs.d.ts +3 -0
  482. package/dist/{routes → src/framework/routes}/jobs.js +128 -103
  483. package/dist/src/framework/routes/metrics.d.ts +10 -0
  484. package/dist/src/framework/routes/metrics.js +57 -0
  485. package/dist/{routes → src/framework/routes}/uploads.d.ts +3 -3
  486. package/dist/src/framework/routes/uploads.js +262 -0
  487. package/dist/src/framework/runPluginLifecycle.d.ts +27 -0
  488. package/dist/src/framework/runPluginLifecycle.js +121 -0
  489. package/dist/src/framework/secrets/frameworkSecretSchema.d.ts +58 -0
  490. package/dist/src/framework/secrets/frameworkSecretSchema.js +20 -0
  491. package/dist/src/framework/secrets/index.d.ts +9 -0
  492. package/dist/src/framework/secrets/index.js +7 -0
  493. package/dist/src/framework/secrets/providers/envProvider.d.ts +15 -0
  494. package/dist/src/framework/secrets/providers/envProvider.js +18 -0
  495. package/dist/src/framework/secrets/providers/fileProvider.d.ts +8 -0
  496. package/dist/src/framework/secrets/providers/fileProvider.js +82 -0
  497. package/dist/src/framework/secrets/providers/ssmProvider.d.ts +20 -0
  498. package/dist/src/framework/secrets/providers/ssmProvider.js +127 -0
  499. package/dist/src/framework/secrets/resolveSecretBundle.d.ts +53 -0
  500. package/dist/src/framework/secrets/resolveSecretBundle.js +84 -0
  501. package/dist/src/framework/secrets/resolveSecrets.d.ts +18 -0
  502. package/dist/src/framework/secrets/resolveSecrets.js +34 -0
  503. package/dist/src/framework/sse/index.d.ts +21 -0
  504. package/dist/src/framework/sse/index.js +109 -0
  505. package/dist/src/framework/ws/index.d.ts +11 -0
  506. package/dist/src/framework/ws/index.js +8 -0
  507. package/dist/src/index.d.ts +87 -0
  508. package/dist/src/index.js +58 -0
  509. package/dist/src/lib/appConfig.d.ts +7 -0
  510. package/dist/src/lib/appConfig.js +27 -0
  511. package/dist/src/lib/appMeta.d.ts +7 -0
  512. package/dist/src/lib/appMeta.js +3 -0
  513. package/dist/src/lib/authConfig.d.ts +532 -0
  514. package/dist/{lib/appConfig.js → src/lib/authConfig.js} +75 -17
  515. package/dist/{lib → src/lib}/context.d.ts +6 -12
  516. package/dist/{lib → src/lib}/context.js +5 -5
  517. package/dist/src/lib/logger.d.ts +1 -0
  518. package/dist/src/lib/logger.js +1 -0
  519. package/dist/src/lib/mongo.d.ts +58 -0
  520. package/dist/src/lib/mongo.js +96 -0
  521. package/dist/src/lib/queue.d.ts +72 -0
  522. package/dist/src/lib/queue.js +152 -0
  523. package/dist/src/lib/redis.d.ts +28 -0
  524. package/dist/src/lib/redis.js +72 -0
  525. package/dist/{lib → src/lib}/signing.d.ts +2 -2
  526. package/dist/src/lib/signing.js +210 -0
  527. package/dist/src/lib/signingConfig.d.ts +40 -0
  528. package/dist/src/lib/signingConfig.js +28 -0
  529. package/dist/src/server.d.ts +146 -0
  530. package/dist/src/server.js +469 -0
  531. package/dist/src/shared/lib/HttpError.d.ts +1 -0
  532. package/dist/src/shared/lib/HttpError.js +2 -0
  533. package/dist/src/shared/lib/constants.d.ts +10 -0
  534. package/dist/src/shared/lib/crypto.d.ts +43 -0
  535. package/dist/src/shared/lib/crypto.js +74 -0
  536. package/dist/src/shared/lib/signing.d.ts +52 -0
  537. package/dist/{lib → src/shared/lib}/signing.js +35 -8
  538. package/dist/src/testing.d.ts +34 -0
  539. package/dist/src/testing.js +93 -0
  540. package/package.json +60 -24
  541. package/dist/adapters/memoryAuth.d.ts +0 -52
  542. package/dist/adapters/memoryAuth.js +0 -749
  543. package/dist/adapters/memoryStorage.d.ts +0 -3
  544. package/dist/adapters/memoryStorage.js +0 -44
  545. package/dist/adapters/mongoAuth.d.ts +0 -2
  546. package/dist/adapters/mongoAuth.js +0 -403
  547. package/dist/adapters/sqliteAuth.d.ts +0 -72
  548. package/dist/adapters/sqliteAuth.js +0 -858
  549. package/dist/app.d.ts +0 -559
  550. package/dist/app.js +0 -651
  551. package/dist/entrypoints/mongo.d.ts +0 -5
  552. package/dist/entrypoints/mongo.js +0 -4
  553. package/dist/entrypoints/queue.d.ts +0 -2
  554. package/dist/entrypoints/queue.js +0 -1
  555. package/dist/entrypoints/redis.d.ts +0 -1
  556. package/dist/entrypoints/redis.js +0 -1
  557. package/dist/index.d.ts +0 -117
  558. package/dist/index.js +0 -88
  559. package/dist/lib/appConfig.d.ts +0 -275
  560. package/dist/lib/auditLog.d.ts +0 -58
  561. package/dist/lib/auditLog.js +0 -218
  562. package/dist/lib/authAdapter.d.ts +0 -246
  563. package/dist/lib/authAdapter.js +0 -7
  564. package/dist/lib/authRateLimit.d.ts +0 -13
  565. package/dist/lib/authRateLimit.js +0 -117
  566. package/dist/lib/clientIp.d.ts +0 -14
  567. package/dist/lib/credentialStuffing.d.ts +0 -31
  568. package/dist/lib/credentialStuffing.js +0 -77
  569. package/dist/lib/crypto.d.ts +0 -11
  570. package/dist/lib/crypto.js +0 -22
  571. package/dist/lib/deletionCancelToken.d.ts +0 -12
  572. package/dist/lib/deletionCancelToken.js +0 -88
  573. package/dist/lib/emailVerification.d.ts +0 -19
  574. package/dist/lib/emailVerification.js +0 -129
  575. package/dist/lib/fingerprint.js +0 -36
  576. package/dist/lib/idempotency.js +0 -182
  577. package/dist/lib/jwks.d.ts +0 -25
  578. package/dist/lib/jwks.js +0 -51
  579. package/dist/lib/jwt.d.ts +0 -15
  580. package/dist/lib/jwt.js +0 -111
  581. package/dist/lib/metrics.d.ts +0 -14
  582. package/dist/lib/mfaChallenge.d.ts +0 -55
  583. package/dist/lib/mfaChallenge.js +0 -398
  584. package/dist/lib/mongo.d.ts +0 -39
  585. package/dist/lib/mongo.js +0 -124
  586. package/dist/lib/oauth.d.ts +0 -40
  587. package/dist/lib/oauth.js +0 -101
  588. package/dist/lib/oauthCode.d.ts +0 -15
  589. package/dist/lib/oauthCode.js +0 -95
  590. package/dist/lib/pagination.d.ts +0 -119
  591. package/dist/lib/pagination.js +0 -166
  592. package/dist/lib/queue.d.ts +0 -37
  593. package/dist/lib/queue.js +0 -117
  594. package/dist/lib/redis.d.ts +0 -9
  595. package/dist/lib/redis.js +0 -61
  596. package/dist/lib/resetPassword.d.ts +0 -12
  597. package/dist/lib/resetPassword.js +0 -93
  598. package/dist/lib/roles.d.ts +0 -7
  599. package/dist/lib/roles.js +0 -49
  600. package/dist/lib/saml.d.ts +0 -25
  601. package/dist/lib/saml.js +0 -64
  602. package/dist/lib/securityEvents.d.ts +0 -28
  603. package/dist/lib/securityEvents.js +0 -26
  604. package/dist/lib/session.d.ts +0 -49
  605. package/dist/lib/session.js +0 -597
  606. package/dist/lib/tenant.d.ts +0 -15
  607. package/dist/lib/tenant.js +0 -65
  608. package/dist/lib/upload.js +0 -112
  609. package/dist/lib/uploadRegistry.d.ts +0 -18
  610. package/dist/lib/uploadRegistry.js +0 -83
  611. package/dist/lib/ws.d.ts +0 -22
  612. package/dist/lib/ws.js +0 -96
  613. package/dist/lib/wsHeartbeat.d.ts +0 -12
  614. package/dist/lib/wsHeartbeat.js +0 -57
  615. package/dist/lib/wsMessages.d.ts +0 -40
  616. package/dist/lib/wsMessages.js +0 -330
  617. package/dist/lib/wsPresence.d.ts +0 -25
  618. package/dist/lib/wsPresence.js +0 -99
  619. package/dist/middleware/auditLog.js +0 -39
  620. package/dist/middleware/bearerAuth.d.ts +0 -2
  621. package/dist/middleware/bearerAuth.js +0 -11
  622. package/dist/middleware/cacheResponse.d.ts +0 -15
  623. package/dist/middleware/cacheResponse.js +0 -178
  624. package/dist/middleware/captcha.js +0 -36
  625. package/dist/middleware/csrf.js +0 -129
  626. package/dist/middleware/identify.d.ts +0 -3
  627. package/dist/middleware/identify.js +0 -122
  628. package/dist/middleware/index.js +0 -1
  629. package/dist/middleware/metrics.d.ts +0 -9
  630. package/dist/middleware/metrics.js +0 -26
  631. package/dist/middleware/rateLimit.js +0 -22
  632. package/dist/middleware/requestId.d.ts +0 -3
  633. package/dist/middleware/scimAuth.d.ts +0 -8
  634. package/dist/middleware/scimAuth.js +0 -29
  635. package/dist/middleware/tenant.d.ts +0 -5
  636. package/dist/middleware/upload.d.ts +0 -5
  637. package/dist/middleware/userAuth.d.ts +0 -3
  638. package/dist/middleware/userAuth.js +0 -6
  639. package/dist/models/AuditLog.d.ts +0 -30
  640. package/dist/models/AuditLog.js +0 -39
  641. package/dist/models/AuthUser.js +0 -55
  642. package/dist/models/Group.d.ts +0 -21
  643. package/dist/models/Group.js +0 -28
  644. package/dist/models/GroupMembership.js +0 -25
  645. package/dist/models/TenantRole.d.ts +0 -15
  646. package/dist/models/TenantRole.js +0 -23
  647. package/dist/routes/auth.d.ts +0 -12
  648. package/dist/routes/auth.js +0 -744
  649. package/dist/routes/groups.js +0 -346
  650. package/dist/routes/health.d.ts +0 -1
  651. package/dist/routes/health.js +0 -22
  652. package/dist/routes/home.d.ts +0 -1
  653. package/dist/routes/home.js +0 -16
  654. package/dist/routes/jobs.d.ts +0 -2
  655. package/dist/routes/m2m.d.ts +0 -2
  656. package/dist/routes/m2m.js +0 -72
  657. package/dist/routes/metrics.d.ts +0 -8
  658. package/dist/routes/metrics.js +0 -55
  659. package/dist/routes/mfa.d.ts +0 -5
  660. package/dist/routes/mfa.js +0 -628
  661. package/dist/routes/oauth.d.ts +0 -2
  662. package/dist/routes/oauth.js +0 -520
  663. package/dist/routes/oidc.d.ts +0 -2
  664. package/dist/routes/oidc.js +0 -29
  665. package/dist/routes/passkey.d.ts +0 -1
  666. package/dist/routes/passkey.js +0 -157
  667. package/dist/routes/saml.d.ts +0 -2
  668. package/dist/routes/saml.js +0 -86
  669. package/dist/routes/scim.d.ts +0 -2
  670. package/dist/routes/scim.js +0 -255
  671. package/dist/routes/uploads.js +0 -227
  672. package/dist/schemas/auth.js +0 -30
  673. package/dist/server.d.ts +0 -57
  674. package/dist/server.js +0 -112
  675. package/dist/services/auth.d.ts +0 -29
  676. package/dist/services/auth.js +0 -238
  677. package/dist/ws/index.d.ts +0 -10
  678. package/dist/ws/index.js +0 -39
  679. package/docs/sections/adding-middleware/full.md +0 -35
  680. package/docs/sections/adding-models/full.md +0 -125
  681. package/docs/sections/adding-models/overview.md +0 -13
  682. package/docs/sections/adding-routes/full.md +0 -182
  683. package/docs/sections/adding-routes/overview.md +0 -23
  684. package/docs/sections/auth-flow/full.md +0 -790
  685. package/docs/sections/auth-flow/overview.md +0 -10
  686. package/docs/sections/auth-security-examples/full.md +0 -388
  687. package/docs/sections/authentication/full.md +0 -130
  688. package/docs/sections/authentication/overview.md +0 -5
  689. package/docs/sections/cli/full.md +0 -42
  690. package/docs/sections/configuration/full.md +0 -172
  691. package/docs/sections/configuration/overview.md +0 -18
  692. package/docs/sections/configuration-example/full.md +0 -117
  693. package/docs/sections/configuration-example/overview.md +0 -30
  694. package/docs/sections/documentation/full.md +0 -171
  695. package/docs/sections/environment-variables/full.md +0 -55
  696. package/docs/sections/exports/full.md +0 -123
  697. package/docs/sections/extending-context/full.md +0 -59
  698. package/docs/sections/header.md +0 -3
  699. package/docs/sections/installation/full.md +0 -6
  700. package/docs/sections/jobs/full.md +0 -140
  701. package/docs/sections/jobs/overview.md +0 -15
  702. package/docs/sections/logging/full.md +0 -83
  703. package/docs/sections/metrics/full.md +0 -131
  704. package/docs/sections/mongodb-connections/full.md +0 -45
  705. package/docs/sections/mongodb-connections/overview.md +0 -7
  706. package/docs/sections/multi-tenancy/full.md +0 -66
  707. package/docs/sections/multi-tenancy/overview.md +0 -15
  708. package/docs/sections/oauth/full.md +0 -189
  709. package/docs/sections/oauth/overview.md +0 -16
  710. package/docs/sections/package-development/full.md +0 -7
  711. package/docs/sections/pagination/full.md +0 -93
  712. package/docs/sections/passkey-login/full.md +0 -90
  713. package/docs/sections/passkey-login/overview.md +0 -1
  714. package/docs/sections/peer-dependencies/full.md +0 -47
  715. package/docs/sections/quick-start/full.md +0 -43
  716. package/docs/sections/response-caching/full.md +0 -117
  717. package/docs/sections/response-caching/overview.md +0 -13
  718. package/docs/sections/roles/full.md +0 -225
  719. package/docs/sections/roles/overview.md +0 -14
  720. package/docs/sections/running-without-redis/full.md +0 -16
  721. package/docs/sections/running-without-redis-or-mongodb/full.md +0 -60
  722. package/docs/sections/signing/full.md +0 -203
  723. package/docs/sections/stack/full.md +0 -10
  724. package/docs/sections/uploads/full.md +0 -208
  725. package/docs/sections/versioning/full.md +0 -85
  726. package/docs/sections/webhook-auth/full.md +0 -100
  727. package/docs/sections/websocket/full.md +0 -196
  728. package/docs/sections/websocket/overview.md +0 -5
  729. package/docs/sections/websocket-rooms/full.md +0 -102
  730. package/docs/sections/websocket-rooms/overview.md +0 -5
  731. /package/dist/{lib/storageAdapter.js → packages/bunshot-admin/src/types/env.js} +0 -0
  732. /package/dist/{lib → packages/bunshot-auth/src/lib}/fingerprint.d.ts +0 -0
  733. /package/dist/{lib → packages/bunshot-auth/src/lib}/logger.d.ts +0 -0
  734. /package/dist/{lib → packages/bunshot-core/src}/constants.d.ts +0 -0
  735. /package/dist/{lib → packages/bunshot-core/src}/storageAdapter.d.ts +0 -0
  736. /package/dist/{lib → src/framework/lib}/createDtoMapper.d.ts +0 -0
  737. /package/dist/{lib → src/framework/lib}/stripUnreferencedSchemas.d.ts +0 -0
  738. /package/dist/{middleware → src/framework/middleware}/cors.d.ts +0 -0
  739. /package/dist/{middleware → src/framework/middleware}/cors.js +0 -0
  740. /package/dist/{middleware → src/framework/middleware}/index.d.ts +0 -0
  741. /package/dist/{middleware → src/framework/middleware}/logger.js +0 -0
  742. /package/dist/{lib → src/shared/lib}/constants.js +0 -0
@@ -1,26 +1,27 @@
1
- import { getAuthAdapter } from "../lib/authAdapter";
2
- import { HttpError } from "../lib/HttpError";
3
- import { getMfaIssuer, getMfaAlgorithm, getMfaDigits, getMfaPeriod, getMfaRecoveryCodeCount, getMfaEmailOtpConfig, getMfaEmailOtpCodeLength, getMfaWebAuthnConfig, getAppName } from "../lib/appConfig";
4
- import { createMfaChallenge } from "../lib/mfaChallenge";
1
+ import { createMfaChallenge } from '../lib/mfaChallenge';
2
+ import { HttpError } from '../../../bunshot-core/src/index.js';
3
+ import { decryptField, encryptField, isEncryptedField, sha256, timingSafeEqual, } from '../../../bunshot-core/src/index.js';
5
4
  // Lazy-load otpauth to keep it as an optional peer dependency
6
- let _otpauth = null;
7
5
  async function getOtpAuth() {
8
- if (!_otpauth)
9
- _otpauth = await import("otpauth");
10
- return _otpauth;
6
+ return import('otpauth');
11
7
  }
12
- import { sha256, timingSafeEqual } from "../lib/crypto";
13
8
  function generateRandomCode(length) {
14
- const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"; // no ambiguous chars: I/1/O/0
15
- let code = "";
9
+ const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'; // no ambiguous chars: I/1/O/0
10
+ const charLen = chars.length; // 31
11
+ const maxUnbiased = 248; // largest multiple of 31 below 256 (31 * 8 = 248)
12
+ let code = '';
16
13
  const bytes = crypto.getRandomValues(new Uint8Array(length));
17
14
  for (let i = 0; i < length; i++) {
18
- code += chars[bytes[i] % chars.length];
15
+ let byte = bytes[i];
16
+ while (byte >= maxUnbiased) {
17
+ byte = crypto.getRandomValues(new Uint8Array(1))[0];
18
+ }
19
+ code += chars[byte % charLen];
19
20
  }
20
21
  return code;
21
22
  }
22
- function generateRecoveryCodes() {
23
- const count = getMfaRecoveryCodeCount();
23
+ function generateRecoveryCodes(runtime) {
24
+ const count = runtime.config.mfa?.recoveryCodes ?? 10;
24
25
  const plainCodes = [];
25
26
  const hashedCodes = [];
26
27
  for (let i = 0; i < count; i++) {
@@ -30,96 +31,118 @@ function generateRecoveryCodes() {
30
31
  }
31
32
  return { plainCodes, hashedCodes };
32
33
  }
33
- export const setupMfa = async (userId) => {
34
- const adapter = getAuthAdapter();
34
+ export const setupMfa = async (userId, runtime) => {
35
+ const { adapter, config } = runtime;
35
36
  if (!adapter.setMfaSecret)
36
- throw new HttpError(501, "Auth adapter does not support MFA");
37
+ throw new HttpError(501, 'Auth adapter does not support MFA');
37
38
  const otpauth = await getOtpAuth();
38
39
  const secret = new otpauth.Secret();
40
+ const mfaCfg = config.mfa;
39
41
  const totp = new otpauth.TOTP({
40
- issuer: getMfaIssuer(),
42
+ issuer: mfaCfg?.issuer ?? config.appName,
41
43
  label: userId,
42
- algorithm: getMfaAlgorithm(),
43
- digits: getMfaDigits(),
44
- period: getMfaPeriod(),
44
+ algorithm: mfaCfg?.algorithm ?? 'SHA1',
45
+ digits: mfaCfg?.digits ?? 6,
46
+ period: mfaCfg?.period ?? 30,
45
47
  secret,
46
48
  });
47
49
  // Store the secret but don't enable MFA yet — user must confirm with a code
48
- await adapter.setMfaSecret(userId, secret.base32);
50
+ // Encrypt at rest when encryption keys are available; store plaintext in dev otherwise.
51
+ const deks = [...runtime.dataEncryptionKeys];
52
+ const storedSecret = deks.length > 0 ? await encryptField(secret.base32, deks) : secret.base32;
53
+ await adapter.setMfaSecret(userId, storedSecret);
49
54
  return {
50
55
  secret: secret.base32,
51
56
  uri: totp.toString(),
52
57
  };
53
58
  };
54
- export const verifySetup = async (userId, code) => {
55
- const adapter = getAuthAdapter();
59
+ /**
60
+ * Resolve a stored MFA secret: decrypt it if it looks like an encrypted ciphertext
61
+ * (produced by encryptField), otherwise return as-is (plaintext — allowed in dev).
62
+ */
63
+ async function resolveStoredSecret(stored, runtime) {
64
+ if (isEncryptedField(stored)) {
65
+ const deks = [...runtime.dataEncryptionKeys];
66
+ if (deks.length === 0) {
67
+ throw new HttpError(500, 'TOTP secret is encrypted but BUNSHOT_DATA_ENCRYPTION_KEY is not set');
68
+ }
69
+ return decryptField(stored, deks);
70
+ }
71
+ return stored;
72
+ }
73
+ export const verifySetup = async (userId, code, runtime) => {
74
+ const { adapter, config } = runtime;
56
75
  if (!adapter.getMfaSecret || !adapter.setMfaEnabled || !adapter.setRecoveryCodes) {
57
- throw new HttpError(501, "Auth adapter does not support MFA");
76
+ throw new HttpError(501, 'Auth adapter does not support MFA');
58
77
  }
59
- const secretStr = await adapter.getMfaSecret(userId);
60
- if (!secretStr)
61
- throw new HttpError(400, "MFA setup not initiated. Call POST /auth/mfa/setup first.");
78
+ const storedSecretStr = await adapter.getMfaSecret(userId);
79
+ if (!storedSecretStr)
80
+ throw new HttpError(400, 'MFA setup not initiated. Call POST /auth/mfa/setup first.');
81
+ const secretStr = await resolveStoredSecret(storedSecretStr, runtime);
82
+ const mfaCfg = config.mfa;
62
83
  const otpauth = await getOtpAuth();
63
84
  const totp = new otpauth.TOTP({
64
- issuer: getMfaIssuer(),
65
- algorithm: getMfaAlgorithm(),
66
- digits: getMfaDigits(),
67
- period: getMfaPeriod(),
85
+ issuer: mfaCfg?.issuer ?? config.appName,
86
+ algorithm: mfaCfg?.algorithm ?? 'SHA1',
87
+ digits: mfaCfg?.digits ?? 6,
88
+ period: mfaCfg?.period ?? 30,
68
89
  secret: otpauth.Secret.fromBase32(secretStr),
69
90
  });
70
91
  const delta = totp.validate({ token: code, window: 1 });
71
92
  if (delta === null)
72
- throw new HttpError(401, "Invalid TOTP code");
93
+ throw new HttpError(401, 'Invalid TOTP code');
73
94
  // Generate recovery codes (regenerates if enabling a second method)
74
- const { plainCodes, hashedCodes } = generateRecoveryCodes();
95
+ const { plainCodes, hashedCodes } = generateRecoveryCodes(runtime);
75
96
  await adapter.setRecoveryCodes(userId, hashedCodes);
76
97
  await adapter.setMfaEnabled(userId, true);
77
98
  // Add "totp" to mfaMethods
78
99
  if (adapter.getMfaMethods && adapter.setMfaMethods) {
79
100
  const methods = await adapter.getMfaMethods(userId);
80
- if (!methods.includes("totp")) {
81
- await adapter.setMfaMethods(userId, [...methods, "totp"]);
101
+ if (!methods.includes('totp')) {
102
+ await adapter.setMfaMethods(userId, [...methods, 'totp']);
82
103
  }
83
104
  }
84
105
  return plainCodes;
85
106
  };
86
- export const verifyTotp = async (userId, code) => {
87
- const adapter = getAuthAdapter();
107
+ export const verifyTotp = async (userId, code, runtime) => {
108
+ const { adapter, config } = runtime;
88
109
  if (!adapter.getMfaSecret)
89
- throw new HttpError(501, "Auth adapter does not support MFA");
90
- const secretStr = await adapter.getMfaSecret(userId);
91
- if (!secretStr)
110
+ throw new HttpError(501, 'Auth adapter does not support MFA');
111
+ const storedSecretStr = await adapter.getMfaSecret(userId);
112
+ if (!storedSecretStr)
92
113
  return false;
114
+ const secretStr = await resolveStoredSecret(storedSecretStr, runtime);
115
+ const mfaCfg = config.mfa;
93
116
  const otpauth = await getOtpAuth();
94
117
  const totp = new otpauth.TOTP({
95
- issuer: getMfaIssuer(),
96
- algorithm: getMfaAlgorithm(),
97
- digits: getMfaDigits(),
98
- period: getMfaPeriod(),
118
+ issuer: mfaCfg?.issuer ?? config.appName,
119
+ algorithm: mfaCfg?.algorithm ?? 'SHA1',
120
+ digits: mfaCfg?.digits ?? 6,
121
+ period: mfaCfg?.period ?? 30,
99
122
  secret: otpauth.Secret.fromBase32(secretStr),
100
123
  });
101
124
  return totp.validate({ token: code, window: 1 }) !== null;
102
125
  };
103
- export const verifyRecoveryCode = async (userId, code) => {
104
- const adapter = getAuthAdapter();
105
- if (!adapter.getRecoveryCodes || !adapter.removeRecoveryCode)
106
- return false;
107
- const hashedCodes = await adapter.getRecoveryCodes(userId);
126
+ export const verifyRecoveryCode = async (userId, code, runtime) => {
127
+ const { adapter } = runtime;
128
+ // consumeRecoveryCode is a required method on all adapters that support MFA.
129
+ // It atomically finds and removes the code in a single operation, eliminating the race
130
+ // condition where two concurrent requests could both match the same code.
131
+ // Note: timing is now at the DB level rather than using timingSafeEqual in application code.
132
+ // This is acceptable — the code is SHA-256 hashed before storage, so constant-time
133
+ // comparison in app code was only preventing hash enumeration, not timing-based attacks
134
+ // on the plaintext (which is already protected by the hash itself).
108
135
  const hashedInput = sha256(code.toUpperCase());
109
- const match = hashedCodes.find((h) => timingSafeEqual(h, hashedInput));
110
- if (!match)
111
- return false;
112
- await adapter.removeRecoveryCode(userId, match);
113
- return true;
136
+ return adapter.consumeRecoveryCode(userId, hashedInput);
114
137
  };
115
- export const disableMfa = async (userId, code) => {
116
- const adapter = getAuthAdapter();
138
+ export const disableMfa = async (userId, code, runtime) => {
139
+ const { adapter } = runtime;
117
140
  if (!adapter.setMfaEnabled || !adapter.setMfaSecret || !adapter.setRecoveryCodes) {
118
- throw new HttpError(501, "Auth adapter does not support MFA");
141
+ throw new HttpError(501, 'Auth adapter does not support MFA');
119
142
  }
120
- const valid = await verifyTotp(userId, code);
143
+ const valid = await verifyTotp(userId, code, runtime);
121
144
  if (!valid)
122
- throw new HttpError(401, "Invalid TOTP code");
145
+ throw new HttpError(401, 'Invalid TOTP code');
123
146
  await adapter.setMfaEnabled(userId, false);
124
147
  await adapter.setMfaSecret(userId, null);
125
148
  await adapter.setRecoveryCodes(userId, []);
@@ -128,14 +151,14 @@ export const disableMfa = async (userId, code) => {
128
151
  await adapter.setMfaMethods(userId, []);
129
152
  }
130
153
  };
131
- export const regenerateRecoveryCodes = async (userId, code) => {
132
- const adapter = getAuthAdapter();
154
+ export const regenerateRecoveryCodes = async (userId, code, runtime) => {
155
+ const { adapter } = runtime;
133
156
  if (!adapter.setRecoveryCodes)
134
- throw new HttpError(501, "Auth adapter does not support MFA");
135
- const valid = await verifyTotp(userId, code);
157
+ throw new HttpError(501, 'Auth adapter does not support MFA');
158
+ const valid = await verifyTotp(userId, code, runtime);
136
159
  if (!valid)
137
- throw new HttpError(401, "Invalid TOTP code");
138
- const { plainCodes, hashedCodes } = generateRecoveryCodes();
160
+ throw new HttpError(401, 'Invalid TOTP code');
161
+ const { plainCodes, hashedCodes } = generateRecoveryCodes(runtime);
139
162
  await adapter.setRecoveryCodes(userId, hashedCodes);
140
163
  return plainCodes;
141
164
  };
@@ -143,12 +166,17 @@ export const regenerateRecoveryCodes = async (userId, code) => {
143
166
  // Email OTP
144
167
  // ---------------------------------------------------------------------------
145
168
  /** Generate a cryptographically random numeric OTP code. Returns { code, hash }. */
146
- export const generateEmailOtpCode = (length) => {
147
- const len = length ?? getMfaEmailOtpCodeLength();
169
+ export const generateEmailOtpCode = (runtime, length) => {
170
+ const len = length ?? runtime.config.mfa?.emailOtp?.codeLength ?? 6;
171
+ const maxUnbiased = 250; // largest multiple of 10 below 256 (10 * 25 = 250)
148
172
  const bytes = crypto.getRandomValues(new Uint8Array(len));
149
- let code = "";
173
+ let code = '';
150
174
  for (let i = 0; i < len; i++) {
151
- code += (bytes[i] % 10).toString();
175
+ let byte = bytes[i];
176
+ while (byte >= maxUnbiased) {
177
+ byte = crypto.getRandomValues(new Uint8Array(1))[0];
178
+ }
179
+ code += (byte % 10).toString();
152
180
  }
153
181
  return { code, hash: sha256(code) };
154
182
  };
@@ -160,59 +188,59 @@ export const verifyEmailOtp = (emailOtpHash, code) => {
160
188
  * Initiate email OTP setup: sends a verification code to the user's email.
161
189
  * Returns a setup challenge token that must be confirmed via confirmEmailOtp.
162
190
  */
163
- export const initiateEmailOtp = async (userId) => {
164
- const adapter = getAuthAdapter();
165
- const emailOtpConfig = getMfaEmailOtpConfig();
191
+ export const initiateEmailOtp = async (userId, runtime) => {
192
+ const { adapter, eventBus, config } = runtime;
193
+ const emailOtpConfig = config.mfa?.emailOtp ?? null;
166
194
  if (!emailOtpConfig)
167
- throw new HttpError(501, "Email OTP is not configured");
195
+ throw new HttpError(501, 'Email OTP is not configured');
168
196
  const user = adapter.getUser ? await adapter.getUser(userId) : null;
169
197
  if (!user?.email)
170
- throw new HttpError(400, "No email address on account");
171
- const { code, hash } = generateEmailOtpCode();
172
- await emailOtpConfig.onSend(user.email, code);
198
+ throw new HttpError(400, 'No email address on account');
199
+ const { code, hash } = generateEmailOtpCode(runtime);
200
+ eventBus.emit('auth:delivery.email_otp', { email: user.email, code });
173
201
  // Store the hash in a challenge token for verification
174
- const setupToken = await createMfaChallenge(userId, { emailOtpHash: hash });
202
+ const setupToken = await createMfaChallenge(runtime.repos.mfaChallenge, userId, { emailOtpHash: hash }, config);
175
203
  return setupToken;
176
204
  };
177
205
  /**
178
206
  * Confirm email OTP setup: verifies the code sent during initiateEmailOtp.
179
207
  * Enables email OTP as an MFA method. Returns recovery codes if MFA was not previously active.
180
208
  */
181
- export const confirmEmailOtp = async (userId, setupToken, code) => {
182
- const adapter = getAuthAdapter();
209
+ export const confirmEmailOtp = async (userId, setupToken, code, runtime) => {
210
+ const { adapter } = runtime;
183
211
  if (!adapter.setMfaEnabled || !adapter.setRecoveryCodes) {
184
- throw new HttpError(501, "Auth adapter does not support MFA");
212
+ throw new HttpError(501, 'Auth adapter does not support MFA');
185
213
  }
186
214
  // Import consumeMfaChallenge here to avoid circular dependency issues at module level
187
- const { consumeMfaChallenge } = await import("../lib/mfaChallenge");
188
- const challenge = await consumeMfaChallenge(setupToken);
215
+ const { consumeMfaChallenge } = await import('../lib/mfaChallenge');
216
+ const challenge = await consumeMfaChallenge(runtime.repos.mfaChallenge, setupToken);
189
217
  if (!challenge)
190
- throw new HttpError(401, "Invalid or expired setup token");
218
+ throw new HttpError(401, 'Invalid or expired setup token');
191
219
  if (challenge.userId !== userId)
192
- throw new HttpError(401, "Token does not match user");
220
+ throw new HttpError(401, 'Token does not match user');
193
221
  if (!challenge.emailOtpHash)
194
- throw new HttpError(400, "Invalid setup token — no OTP hash");
222
+ throw new HttpError(400, 'Invalid setup token — no OTP hash');
195
223
  if (!verifyEmailOtp(challenge.emailOtpHash, code)) {
196
- throw new HttpError(401, "Invalid verification code");
224
+ throw new HttpError(401, 'Invalid verification code');
197
225
  }
198
226
  // Check if MFA was already active
199
227
  const wasEnabled = adapter.isMfaEnabled ? await adapter.isMfaEnabled(userId) : false;
200
228
  // Add "emailOtp" to mfaMethods
201
229
  if (adapter.getMfaMethods && adapter.setMfaMethods) {
202
230
  const methods = await adapter.getMfaMethods(userId);
203
- if (!methods.includes("emailOtp")) {
204
- await adapter.setMfaMethods(userId, [...methods, "emailOtp"]);
231
+ if (!methods.includes('emailOtp')) {
232
+ await adapter.setMfaMethods(userId, [...methods, 'emailOtp']);
205
233
  }
206
234
  }
207
235
  await adapter.setMfaEnabled(userId, true);
208
236
  // Generate recovery codes if MFA was not previously active
209
237
  if (!wasEnabled) {
210
- const { plainCodes, hashedCodes } = generateRecoveryCodes();
238
+ const { plainCodes, hashedCodes } = generateRecoveryCodes(runtime);
211
239
  await adapter.setRecoveryCodes(userId, hashedCodes);
212
240
  return plainCodes;
213
241
  }
214
242
  // Regenerate recovery codes when adding a second method
215
- const { plainCodes, hashedCodes } = generateRecoveryCodes();
243
+ const { plainCodes, hashedCodes } = generateRecoveryCodes(runtime);
216
244
  await adapter.setRecoveryCodes(userId, hashedCodes);
217
245
  return plainCodes;
218
246
  };
@@ -220,37 +248,31 @@ export const confirmEmailOtp = async (userId, setupToken, code) => {
220
248
  * Disable email OTP for a user.
221
249
  * If TOTP is also enabled, requires a TOTP code. Otherwise requires password.
222
250
  */
223
- export const disableEmailOtp = async (userId, params) => {
224
- const adapter = getAuthAdapter();
251
+ export const disableEmailOtp = async (userId, params, runtime) => {
252
+ const { adapter } = runtime;
225
253
  if (!adapter.setMfaEnabled)
226
- throw new HttpError(501, "Auth adapter does not support MFA");
254
+ throw new HttpError(501, 'Auth adapter does not support MFA');
227
255
  // Get current methods
228
256
  const methods = adapter.getMfaMethods ? await adapter.getMfaMethods(userId) : [];
229
- const hasTotpEnabled = methods.includes("totp");
257
+ const hasTotpEnabled = methods.includes('totp');
230
258
  // Verify identity
231
259
  if (hasTotpEnabled) {
232
260
  if (!params.code)
233
- throw new HttpError(400, "TOTP code required to disable email OTP");
234
- const valid = await verifyTotp(userId, params.code);
261
+ throw new HttpError(400, 'TOTP code required to disable email OTP');
262
+ const valid = await verifyTotp(userId, params.code, runtime);
235
263
  if (!valid)
236
- throw new HttpError(401, "Invalid TOTP code");
264
+ throw new HttpError(401, 'Invalid TOTP code');
237
265
  }
238
266
  else {
239
267
  if (!params.password)
240
- throw new HttpError(400, "Password required to disable email OTP");
241
- // Verify password look up the user's hash and compare
242
- const user = adapter.findByIdentifier
243
- ? await adapter.findByIdentifier((await adapter.getUser?.(userId))?.email ?? "")
244
- : await adapter.findByEmail((await adapter.getUser?.(userId))?.email ?? "");
245
- if (!user)
246
- throw new HttpError(404, "User not found");
247
- const valid = await Bun.password.verify(params.password, user.passwordHash);
268
+ throw new HttpError(400, 'Password required to disable email OTP');
269
+ const valid = await adapter.verifyPassword(userId, params.password);
248
270
  if (!valid)
249
- throw new HttpError(401, "Invalid password");
271
+ throw new HttpError(401, 'Invalid password');
250
272
  }
251
273
  // Remove "emailOtp" from methods
252
274
  if (adapter.setMfaMethods) {
253
- const updated = methods.filter((m) => m !== "emailOtp");
275
+ const updated = methods.filter(m => m !== 'emailOtp');
254
276
  await adapter.setMfaMethods(userId, updated);
255
277
  // If no methods remain, disable MFA entirely
256
278
  if (updated.length === 0) {
@@ -261,45 +283,39 @@ export const disableEmailOtp = async (userId, params) => {
261
283
  }
262
284
  };
263
285
  /** Get the MFA methods enabled for a user. */
264
- export const getMfaMethods = async (userId) => {
265
- const adapter = getAuthAdapter();
286
+ export const getMfaMethods = async (userId, runtime) => {
287
+ const { adapter } = runtime;
266
288
  if (adapter.getMfaMethods)
267
289
  return adapter.getMfaMethods(userId);
268
- // Backward compat
269
- if (adapter.isMfaEnabled && await adapter.isMfaEnabled(userId))
270
- return ["totp"];
271
290
  return [];
272
291
  };
273
292
  // ---------------------------------------------------------------------------
274
293
  // WebAuthn / FIDO2
275
294
  // ---------------------------------------------------------------------------
276
295
  // Lazy-load @simplewebauthn/server to keep it as an optional peer dependency
277
- let _simplewebauthn = null;
278
296
  async function getSimpleWebAuthn() {
279
- if (!_simplewebauthn)
280
- _simplewebauthn = await import("@simplewebauthn/server");
281
- return _simplewebauthn;
297
+ return import('@simplewebauthn/server');
282
298
  }
283
299
  /**
284
300
  * Eager startup check — call at route mount time to fail fast if the peer dependency is missing.
285
301
  */
286
302
  export const assertWebAuthnDependency = async () => {
287
303
  try {
288
- await import("@simplewebauthn/server");
304
+ await import('@simplewebauthn/server');
289
305
  }
290
306
  catch {
291
- throw new Error("@simplewebauthn/server is required when mfa.webauthn is configured. Install it: bun add @simplewebauthn/server");
307
+ throw new Error('@simplewebauthn/server is required when mfa.webauthn is configured. Install it: bun add @simplewebauthn/server');
292
308
  }
293
309
  };
294
310
  /**
295
311
  * Generate WebAuthn authentication options for the login MFA flow.
296
312
  * Called from auth.ts login when the user has "webauthn" in their methods.
297
313
  */
298
- export const generateWebAuthnAuthenticationOptions = async (userId) => {
299
- const config = getMfaWebAuthnConfig();
314
+ export const generateWebAuthnAuthenticationOptions = async (userId, runtime) => {
315
+ const config = runtime.config.mfa?.webauthn ?? null;
300
316
  if (!config)
301
317
  return null;
302
- const adapter = getAuthAdapter();
318
+ const { adapter } = runtime;
303
319
  if (!adapter.getWebAuthnCredentials)
304
320
  return null;
305
321
  const credentials = await adapter.getWebAuthnCredentials(userId);
@@ -308,11 +324,11 @@ export const generateWebAuthnAuthenticationOptions = async (userId) => {
308
324
  const { generateAuthenticationOptions } = await getSimpleWebAuthn();
309
325
  const options = await generateAuthenticationOptions({
310
326
  rpID: config.rpId,
311
- allowCredentials: credentials.map((c) => ({
327
+ allowCredentials: credentials.map(c => ({
312
328
  id: c.credentialId,
313
329
  transports: c.transports,
314
330
  })),
315
- userVerification: config.userVerification ?? "preferred",
331
+ userVerification: config.userVerification ?? 'preferred',
316
332
  timeout: config.timeout ?? 60000,
317
333
  });
318
334
  return { challenge: options.challenge, options: options };
@@ -321,55 +337,55 @@ export const generateWebAuthnAuthenticationOptions = async (userId) => {
321
337
  * Initiate WebAuthn registration: generates registration options for the client.
322
338
  * Returns options + a registration challenge token.
323
339
  */
324
- export const initiateWebAuthnRegistration = async (userId) => {
325
- const config = getMfaWebAuthnConfig();
340
+ export const initiateWebAuthnRegistration = async (userId, runtime) => {
341
+ const config = runtime.config.mfa?.webauthn ?? null;
326
342
  if (!config)
327
- throw new HttpError(501, "WebAuthn is not configured");
328
- const adapter = getAuthAdapter();
343
+ throw new HttpError(501, 'WebAuthn is not configured');
344
+ const { adapter } = runtime;
329
345
  if (!adapter.getWebAuthnCredentials)
330
- throw new HttpError(501, "Auth adapter does not support WebAuthn");
346
+ throw new HttpError(501, 'Auth adapter does not support WebAuthn');
331
347
  const user = adapter.getUser ? await adapter.getUser(userId) : null;
332
348
  // Get existing credentials to exclude (prevent re-registration)
333
349
  const existingCreds = await adapter.getWebAuthnCredentials(userId);
334
350
  const { generateRegistrationOptions } = await getSimpleWebAuthn();
335
351
  const options = await generateRegistrationOptions({
336
- rpName: config.rpName ?? getAppName(),
352
+ rpName: config.rpName ?? runtime.config.appName,
337
353
  rpID: config.rpId,
338
354
  userName: user?.email ?? userId,
339
- attestationType: config.attestationType ?? "none",
340
- excludeCredentials: existingCreds.map((c) => ({
355
+ attestationType: config.attestationType ?? 'none',
356
+ excludeCredentials: existingCreds.map(c => ({
341
357
  id: c.credentialId,
342
358
  transports: c.transports,
343
359
  })),
344
360
  authenticatorSelection: {
345
361
  authenticatorAttachment: config.authenticatorAttachment,
346
- userVerification: config.userVerification ?? "required",
347
- residentKey: "required",
362
+ userVerification: config.userVerification ?? 'required',
363
+ residentKey: 'required',
348
364
  },
349
365
  timeout: config.timeout ?? 60000,
350
366
  });
351
- const { createWebAuthnRegistrationChallenge } = await import("../lib/mfaChallenge");
352
- const registrationToken = await createWebAuthnRegistrationChallenge(userId, options.challenge);
367
+ const { createWebAuthnRegistrationChallenge } = await import('../lib/mfaChallenge');
368
+ const registrationToken = await createWebAuthnRegistrationChallenge(runtime.repos.mfaChallenge, userId, options.challenge, runtime.config);
353
369
  return { options: options, registrationToken };
354
370
  };
355
371
  /**
356
372
  * Complete WebAuthn registration: verifies attestation and stores the credential.
357
373
  * Returns recovery codes if this is the first MFA method.
358
374
  */
359
- export const completeWebAuthnRegistration = async (userId, registrationToken, attestationResponse, name) => {
360
- const config = getMfaWebAuthnConfig();
375
+ export const completeWebAuthnRegistration = async (userId, registrationToken, attestationResponse, runtime, name) => {
376
+ const config = runtime.config.mfa?.webauthn ?? null;
361
377
  if (!config)
362
- throw new HttpError(501, "WebAuthn is not configured");
363
- const adapter = getAuthAdapter();
378
+ throw new HttpError(501, 'WebAuthn is not configured');
379
+ const { adapter } = runtime;
364
380
  if (!adapter.addWebAuthnCredential || !adapter.setMfaEnabled || !adapter.setRecoveryCodes) {
365
- throw new HttpError(501, "Auth adapter does not support WebAuthn");
381
+ throw new HttpError(501, 'Auth adapter does not support WebAuthn');
366
382
  }
367
- const { consumeWebAuthnRegistrationChallenge } = await import("../lib/mfaChallenge");
368
- const challenge = await consumeWebAuthnRegistrationChallenge(registrationToken);
383
+ const { consumeWebAuthnRegistrationChallenge } = await import('../lib/mfaChallenge');
384
+ const challenge = await consumeWebAuthnRegistrationChallenge(runtime.repos.mfaChallenge, registrationToken);
369
385
  if (!challenge)
370
- throw new HttpError(401, "Invalid or expired registration token");
386
+ throw new HttpError(401, 'Invalid or expired registration token');
371
387
  if (challenge.userId !== userId)
372
- throw new HttpError(401, "Token does not match user");
388
+ throw new HttpError(401, 'Token does not match user');
373
389
  const { verifyRegistrationResponse } = await getSimpleWebAuthn();
374
390
  const verification = await verifyRegistrationResponse({
375
391
  response: attestationResponse,
@@ -378,7 +394,7 @@ export const completeWebAuthnRegistration = async (userId, registrationToken, at
378
394
  expectedRPID: config.rpId,
379
395
  });
380
396
  if (!verification.verified || !verification.registrationInfo) {
381
- throw new HttpError(401, "WebAuthn registration verification failed");
397
+ throw new HttpError(401, 'WebAuthn registration verification failed');
382
398
  }
383
399
  const { credential } = verification.registrationInfo;
384
400
  const credentialId = credential.id;
@@ -386,12 +402,12 @@ export const completeWebAuthnRegistration = async (userId, registrationToken, at
386
402
  if (adapter.findUserByWebAuthnCredentialId) {
387
403
  const existingOwner = await adapter.findUserByWebAuthnCredentialId(credentialId);
388
404
  if (existingOwner && existingOwner !== userId) {
389
- throw new HttpError(409, "This security key is already registered to another account");
405
+ throw new HttpError(409, 'This security key is already registered to another account');
390
406
  }
391
407
  }
392
408
  const newCredential = {
393
409
  credentialId,
394
- publicKey: Buffer.from(credential.publicKey).toString("base64url"),
410
+ publicKey: Buffer.from(credential.publicKey).toString('base64url'),
395
411
  signCount: credential.counter,
396
412
  transports: attestationResponse.response?.transports ?? [],
397
413
  name: name ?? undefined,
@@ -401,29 +417,29 @@ export const completeWebAuthnRegistration = async (userId, registrationToken, at
401
417
  // Add "webauthn" to methods
402
418
  if (adapter.getMfaMethods && adapter.setMfaMethods) {
403
419
  const methods = await adapter.getMfaMethods(userId);
404
- if (!methods.includes("webauthn")) {
405
- await adapter.setMfaMethods(userId, [...methods, "webauthn"]);
420
+ if (!methods.includes('webauthn')) {
421
+ await adapter.setMfaMethods(userId, [...methods, 'webauthn']);
406
422
  }
407
423
  }
408
424
  // Enable MFA + generate/regenerate recovery codes
409
425
  await adapter.setMfaEnabled(userId, true);
410
- const { plainCodes, hashedCodes } = generateRecoveryCodes();
426
+ const { plainCodes, hashedCodes } = generateRecoveryCodes(runtime);
411
427
  await adapter.setRecoveryCodes(userId, hashedCodes);
412
428
  return { credentialId, recoveryCodes: plainCodes };
413
429
  };
414
430
  /**
415
431
  * Verify a WebAuthn authentication assertion during login MFA.
416
432
  */
417
- export const verifyWebAuthn = async (userId, assertionResponse, expectedChallenge) => {
418
- const config = getMfaWebAuthnConfig();
433
+ export const verifyWebAuthn = async (userId, assertionResponse, expectedChallenge, runtime) => {
434
+ const config = runtime.config.mfa?.webauthn ?? null;
419
435
  if (!config)
420
436
  return false;
421
- const adapter = getAuthAdapter();
437
+ const { adapter } = runtime;
422
438
  if (!adapter.getWebAuthnCredentials || !adapter.updateWebAuthnCredentialSignCount)
423
439
  return false;
424
440
  const credentials = await adapter.getWebAuthnCredentials(userId);
425
441
  const credentialId = assertionResponse.id;
426
- const matchedCred = credentials.find((c) => c.credentialId === credentialId);
442
+ const matchedCred = credentials.find(c => c.credentialId === credentialId);
427
443
  if (!matchedCred)
428
444
  return false;
429
445
  const { verifyAuthenticationResponse } = await getSimpleWebAuthn();
@@ -435,7 +451,7 @@ export const verifyWebAuthn = async (userId, assertionResponse, expectedChalleng
435
451
  expectedRPID: config.rpId,
436
452
  credential: {
437
453
  id: matchedCred.credentialId,
438
- publicKey: new Uint8Array(Buffer.from(matchedCred.publicKey, "base64url")),
454
+ publicKey: new Uint8Array(Buffer.from(matchedCred.publicKey, 'base64url')),
439
455
  counter: matchedCred.signCount,
440
456
  transports: matchedCred.transports,
441
457
  },
@@ -462,26 +478,26 @@ export const verifyWebAuthn = async (userId, assertionResponse, expectedChalleng
462
478
  * Remove a single WebAuthn credential.
463
479
  * Only requires identity verification when removing the last credential of the last MFA method.
464
480
  */
465
- export const removeWebAuthnCredential = async (userId, credentialId, params) => {
466
- const adapter = getAuthAdapter();
481
+ export const removeWebAuthnCredential = async (userId, credentialId, params, runtime) => {
482
+ const { adapter } = runtime;
467
483
  if (!adapter.getWebAuthnCredentials || !adapter.removeWebAuthnCredential) {
468
- throw new HttpError(501, "Auth adapter does not support WebAuthn");
484
+ throw new HttpError(501, 'Auth adapter does not support WebAuthn');
469
485
  }
470
486
  const credentials = await adapter.getWebAuthnCredentials(userId);
471
- if (!credentials.some((c) => c.credentialId === credentialId)) {
472
- throw new HttpError(404, "Credential not found");
487
+ if (!credentials.some(c => c.credentialId === credentialId)) {
488
+ throw new HttpError(404, 'Credential not found');
473
489
  }
474
490
  const methods = adapter.getMfaMethods ? await adapter.getMfaMethods(userId) : [];
475
- const otherMethodsExist = methods.some((m) => m !== "webauthn");
491
+ const otherMethodsExist = methods.some(m => m !== 'webauthn');
476
492
  const otherCredsExist = credentials.length > 1;
477
493
  // Only require verification when removing the last credential of the last method
478
494
  if (!otherMethodsExist && !otherCredsExist) {
479
- await verifyIdentity(userId, params);
495
+ await verifyIdentity(userId, params, runtime);
480
496
  }
481
497
  await adapter.removeWebAuthnCredential(userId, credentialId);
482
498
  // If that was the last credential, remove "webauthn" from methods
483
499
  if (!otherCredsExist && adapter.setMfaMethods) {
484
- const updated = methods.filter((m) => m !== "webauthn");
500
+ const updated = methods.filter(m => m !== 'webauthn');
485
501
  await adapter.setMfaMethods(userId, updated);
486
502
  // If no methods remain, disable MFA entirely
487
503
  if (updated.length === 0 && adapter.setMfaEnabled) {
@@ -494,12 +510,12 @@ export const removeWebAuthnCredential = async (userId, credentialId, params) =>
494
510
  /**
495
511
  * Disable WebAuthn entirely: removes all credentials and the method.
496
512
  */
497
- export const disableWebAuthn = async (userId, params) => {
498
- const adapter = getAuthAdapter();
513
+ export const disableWebAuthn = async (userId, params, runtime) => {
514
+ const { adapter } = runtime;
499
515
  if (!adapter.getWebAuthnCredentials || !adapter.removeWebAuthnCredential) {
500
- throw new HttpError(501, "Auth adapter does not support WebAuthn");
516
+ throw new HttpError(501, 'Auth adapter does not support WebAuthn');
501
517
  }
502
- await verifyIdentity(userId, params);
518
+ await verifyIdentity(userId, params, runtime);
503
519
  const credentials = await adapter.getWebAuthnCredentials(userId);
504
520
  for (const cred of credentials) {
505
521
  await adapter.removeWebAuthnCredential(userId, cred.credentialId);
@@ -507,7 +523,7 @@ export const disableWebAuthn = async (userId, params) => {
507
523
  // Remove "webauthn" from methods
508
524
  if (adapter.getMfaMethods && adapter.setMfaMethods) {
509
525
  const methods = await adapter.getMfaMethods(userId);
510
- const updated = methods.filter((m) => m !== "webauthn");
526
+ const updated = methods.filter(m => m !== 'webauthn');
511
527
  await adapter.setMfaMethods(userId, updated);
512
528
  if (updated.length === 0 && adapter.setMfaEnabled) {
513
529
  await adapter.setMfaEnabled(userId, false);
@@ -516,28 +532,88 @@ export const disableWebAuthn = async (userId, params) => {
516
532
  }
517
533
  }
518
534
  };
535
+ // ---------------------------------------------------------------------------
536
+ // verifyAnyFactor — unified factor verification for reauth / destructive actions
537
+ // ---------------------------------------------------------------------------
538
+ /**
539
+ * Verify any supported authentication factor for a given user + session.
540
+ * Used by step-up, account deletion, and MFA disable flows.
541
+ *
542
+ * - "totp": TOTP code
543
+ * - "recovery": recovery code (only when method is explicitly "recovery")
544
+ * - "password": account password
545
+ * - "emailOtp": email OTP via reauth challenge token
546
+ * - "webauthn": WebAuthn assertion via reauth challenge token
547
+ *
548
+ * Hard boundaries:
549
+ * - "recovery" is ONLY checked when method is explicitly "recovery"
550
+ * - emailOtp / webauthn consume a reauth challenge bound to sessionId
551
+ *
552
+ * Returns false (never throws) when required params are missing.
553
+ */
554
+ export async function verifyAnyFactor(userId, sessionId, runtime, params) {
555
+ const { method, code, password, reauthToken, webauthnResponse } = params;
556
+ if (!method)
557
+ return false;
558
+ const { adapter } = runtime;
559
+ try {
560
+ if (method === 'totp') {
561
+ if (!code)
562
+ return false;
563
+ return verifyTotp(userId, code, runtime);
564
+ }
565
+ if (method === 'recovery') {
566
+ if (!code)
567
+ return false;
568
+ const hashedInput = sha256(code.toUpperCase());
569
+ return adapter.consumeRecoveryCode(userId, hashedInput);
570
+ }
571
+ if (method === 'password') {
572
+ if (!password)
573
+ return false;
574
+ return adapter.verifyPassword(userId, password);
575
+ }
576
+ if (method === 'emailOtp') {
577
+ if (!reauthToken || !code)
578
+ return false;
579
+ const { consumeReauthChallenge } = await import('../lib/mfaChallenge');
580
+ const challenge = await consumeReauthChallenge(runtime.repos.mfaChallenge, reauthToken, sessionId);
581
+ if (!challenge || !challenge.emailOtpHash)
582
+ return false;
583
+ return timingSafeEqual(sha256(code), challenge.emailOtpHash);
584
+ }
585
+ if (method === 'webauthn') {
586
+ if (!reauthToken || !webauthnResponse)
587
+ return false;
588
+ const { consumeReauthChallenge } = await import('../lib/mfaChallenge');
589
+ const challenge = await consumeReauthChallenge(runtime.repos.mfaChallenge, reauthToken, sessionId);
590
+ if (!challenge || !challenge.webauthnChallenge)
591
+ return false;
592
+ return verifyWebAuthn(userId, webauthnResponse, challenge.webauthnChallenge, runtime);
593
+ }
594
+ return false;
595
+ }
596
+ catch {
597
+ return false;
598
+ }
599
+ }
519
600
  /** Internal: verify identity via TOTP code or password. */
520
- async function verifyIdentity(userId, params) {
521
- const adapter = getAuthAdapter();
601
+ async function verifyIdentity(userId, params, runtime) {
602
+ const { adapter } = runtime;
522
603
  const methods = adapter.getMfaMethods ? await adapter.getMfaMethods(userId) : [];
523
- const hasTotpEnabled = methods.includes("totp");
604
+ const hasTotpEnabled = methods.includes('totp');
524
605
  if (hasTotpEnabled) {
525
606
  if (!params.code)
526
- throw new HttpError(400, "TOTP code required");
527
- const valid = await verifyTotp(userId, params.code);
607
+ throw new HttpError(400, 'TOTP code required');
608
+ const valid = await verifyTotp(userId, params.code, runtime);
528
609
  if (!valid)
529
- throw new HttpError(401, "Invalid TOTP code");
610
+ throw new HttpError(401, 'Invalid TOTP code');
530
611
  }
531
612
  else {
532
613
  if (!params.password)
533
- throw new HttpError(400, "Password required");
534
- const user = adapter.findByIdentifier
535
- ? await adapter.findByIdentifier((await adapter.getUser?.(userId))?.email ?? "")
536
- : await adapter.findByEmail((await adapter.getUser?.(userId))?.email ?? "");
537
- if (!user)
538
- throw new HttpError(404, "User not found");
539
- const valid = await Bun.password.verify(params.password, user.passwordHash);
614
+ throw new HttpError(400, 'Password required');
615
+ const valid = await adapter.verifyPassword(userId, params.password);
540
616
  if (!valid)
541
- throw new HttpError(401, "Invalid password");
617
+ throw new HttpError(401, 'Invalid password');
542
618
  }
543
619
  }