@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,744 +0,0 @@
1
- import { createRoute, withSecurity } from "../lib/createRoute";
2
- import { HttpError } from "../lib/HttpError";
3
- import { z } from "zod";
4
- import { setCookie, getCookie, deleteCookie } from "hono/cookie";
5
- import * as AuthService from "../services/auth";
6
- import { makeRegisterSchema, makeLoginSchema, resetPasswordSchema } from "../schemas/auth";
7
- import { COOKIE_TOKEN, HEADER_USER_TOKEN, COOKIE_REFRESH_TOKEN, HEADER_REFRESH_TOKEN } from "../lib/constants";
8
- import { userAuth } from "../middleware/userAuth";
9
- import { isLimited, trackAttempt, bustAuthLimit } from "../lib/authRateLimit";
10
- import { isStuffingBlocked, trackFailedLogin } from "../lib/credentialStuffing";
11
- import { getAuthAdapter } from "../lib/authAdapter";
12
- import { createRouter } from "../lib/context";
13
- import { consumeVerificationToken, createVerificationToken } from "../lib/emailVerification";
14
- import { createResetToken, consumeResetToken } from "../lib/resetPassword";
15
- import { createDeletionCancelToken, consumeDeletionCancelToken } from "../lib/deletionCancelToken";
16
- import { getRefreshTokenExpiry, getAccessTokenExpiry, getCsrfEnabled, getAppName, getBreachedPasswordConfig } from "../lib/appConfig";
17
- import { checkBreachedPassword } from "../lib/breachedPassword";
18
- import { refreshCsrfToken, clearCsrfToken } from "../middleware/csrf";
19
- import { getUserSessions, deleteSession, deleteUserSessions, setMfaVerifiedAt } from "../lib/session";
20
- import { getClientIp } from "../lib/clientIp";
21
- import { emitSecurityEvent } from "../lib/securityEvents";
22
- const isProd = process.env.NODE_ENV === "production";
23
- const TokenResponse = z.object({
24
- token: z.string().describe("JWT session token. Also set as an HttpOnly session cookie. Empty string when mfaRequired is true."),
25
- userId: z.string().describe("Unique user ID."),
26
- email: z.string().optional().describe("User's email address (present when primaryField is 'email')."),
27
- emailVerified: z.boolean().optional().describe("Whether the email address has been verified (present when emailVerification is configured)."),
28
- googleLinked: z.boolean().optional().describe("Whether a Google OAuth account is linked to this user."),
29
- refreshToken: z.string().optional().describe("Refresh token (present when refreshTokens is configured). Also set as an HttpOnly cookie."),
30
- mfaRequired: z.boolean().optional().describe("When true, complete MFA via POST /auth/mfa/verify before accessing the API."),
31
- mfaToken: z.string().optional().describe("MFA challenge token. Pass to POST /auth/mfa/verify with a TOTP or recovery code."),
32
- mfaMethods: z.array(z.string()).optional().describe("Available MFA methods when mfaRequired is true (e.g., 'totp', 'emailOtp', 'webauthn')."),
33
- webauthnOptions: z.record(z.string(), z.unknown()).optional().describe("WebAuthn assertion options (present when mfaMethods includes 'webauthn'). Pass directly to navigator.credentials.get()."),
34
- }).openapi("TokenResponse");
35
- const ErrorResponse = z.object({ error: z.string().describe("Human-readable error message.") }).openapi("ErrorResponse");
36
- const tags = ["Auth"];
37
- const cookieOptions = (maxAge) => ({
38
- httpOnly: true,
39
- secure: isProd,
40
- sameSite: "Lax",
41
- path: "/",
42
- maxAge: maxAge ?? 60 * 60 * 24 * 7, // 7 days
43
- });
44
- export const createAuthRouter = ({ primaryField, emailVerification, passwordReset, rateLimit, accountDeletion, refreshTokens, stepUp }) => {
45
- const router = createRouter();
46
- const RegisterSchema = makeRegisterSchema(primaryField);
47
- const LoginSchema = makeLoginSchema(primaryField);
48
- const fieldLabel = primaryField.charAt(0).toUpperCase() + primaryField.slice(1);
49
- const alreadyRegisteredMsg = `${fieldLabel} already registered`;
50
- // Resolve limits with defaults
51
- const loginOpts = { windowMs: rateLimit?.login?.windowMs ?? 15 * 60 * 1000, max: rateLimit?.login?.max ?? 10 };
52
- const registerOpts = { windowMs: rateLimit?.register?.windowMs ?? 60 * 60 * 1000, max: rateLimit?.register?.max ?? 5 };
53
- const verifyOpts = { windowMs: rateLimit?.verifyEmail?.windowMs ?? 15 * 60 * 1000, max: rateLimit?.verifyEmail?.max ?? 10 };
54
- const resendOpts = { windowMs: rateLimit?.resendVerification?.windowMs ?? 60 * 60 * 1000, max: rateLimit?.resendVerification?.max ?? 3 };
55
- const forgotOpts = { windowMs: rateLimit?.forgotPassword?.windowMs ?? 15 * 60 * 1000, max: rateLimit?.forgotPassword?.max ?? 5 };
56
- const resetOpts = { windowMs: rateLimit?.resetPassword?.windowMs ?? 15 * 60 * 1000, max: rateLimit?.resetPassword?.max ?? 10 };
57
- router.openapi(createRoute({
58
- method: "post",
59
- path: "/auth/register",
60
- summary: "Register a new account",
61
- description: "Creates a new user account and returns a JWT session token. The token is also set as an HttpOnly session cookie. Rate-limited by IP.",
62
- tags,
63
- request: { body: { content: { "application/json": { schema: RegisterSchema } }, description: "Registration credentials." } },
64
- responses: {
65
- 201: { content: { "application/json": { schema: TokenResponse } }, description: "Account created. Returns a session token." },
66
- 400: { content: { "application/json": { schema: ErrorResponse } }, description: "Validation error (e.g. missing field, password too short)." },
67
- 409: { content: { "application/json": { schema: ErrorResponse } }, description: alreadyRegisteredMsg },
68
- 429: { content: { "application/json": { schema: ErrorResponse } }, description: "Too many registration attempts from this IP. Try again later." },
69
- },
70
- }), async (c) => {
71
- const ip = getClientIp(c);
72
- if (await trackAttempt(`register:${ip}`, registerOpts)) {
73
- emitSecurityEvent({ eventType: "security.rate_limit.exceeded", severity: "warn", timestamp: new Date().toISOString(), meta: { path: c.req.path } });
74
- return c.json({ error: "Too many registration attempts. Try again later." }, 429);
75
- }
76
- const body = c.req.valid("json");
77
- const identifier = body[primaryField];
78
- const breachConfig = getBreachedPasswordConfig();
79
- if (breachConfig) {
80
- const { breached } = await checkBreachedPassword(body.password, breachConfig);
81
- if (breached && breachConfig.block !== false) {
82
- throw new HttpError(400, "This password has appeared in a data breach. Please choose a different password.", "BREACHED_PASSWORD");
83
- }
84
- }
85
- const metadata = {
86
- ipAddress: ip !== "unknown" ? ip : undefined,
87
- userAgent: c.req.header("user-agent") ?? undefined,
88
- };
89
- const result = await AuthService.register(identifier, body.password, metadata);
90
- setCookie(c, COOKIE_TOKEN, result.token, cookieOptions(refreshTokens ? getAccessTokenExpiry() : undefined));
91
- if (result.refreshToken) {
92
- setCookie(c, COOKIE_REFRESH_TOKEN, result.refreshToken, cookieOptions(getRefreshTokenExpiry()));
93
- }
94
- if (getCsrfEnabled())
95
- refreshCsrfToken(c);
96
- const { refreshToken: _rt, ...safeResult } = result;
97
- return c.json(result.refreshToken ? safeResult : result, 201);
98
- });
99
- router.openapi(createRoute({
100
- method: "post",
101
- path: "/auth/login",
102
- summary: "Log in",
103
- description: "Authenticates with credentials and returns a JWT session token. The token is also set as an HttpOnly session cookie. Failed attempts are rate-limited per identifier.",
104
- tags,
105
- request: { body: { content: { "application/json": { schema: LoginSchema } }, description: "Login credentials." } },
106
- responses: {
107
- 200: { content: { "application/json": { schema: TokenResponse } }, description: "Authenticated. Returns a session token." },
108
- 401: { content: { "application/json": { schema: ErrorResponse } }, description: "Invalid credentials." },
109
- 403: { content: { "application/json": { schema: ErrorResponse } }, description: "Email not verified. Verification is required before login." },
110
- 429: { content: { "application/json": { schema: ErrorResponse } }, description: "Too many failed login attempts for this identifier. Try again later." },
111
- },
112
- }), async (c) => {
113
- const body = c.req.valid("json");
114
- const identifier = body[primaryField];
115
- const limitKey = `login:${identifier}`;
116
- const clientIp = getClientIp(c) ?? "unknown";
117
- if (isStuffingBlocked(clientIp, identifier)) {
118
- emitSecurityEvent({
119
- eventType: "security.credential_stuffing.detected",
120
- severity: "critical",
121
- timestamp: new Date().toISOString(),
122
- ip: clientIp,
123
- meta: { identifier },
124
- });
125
- throw new HttpError(429, "Too many login attempts from this source", "CREDENTIAL_STUFFING_BLOCKED");
126
- }
127
- if (await isLimited(limitKey, loginOpts)) {
128
- emitSecurityEvent({ eventType: "security.rate_limit.exceeded", severity: "warn", timestamp: new Date().toISOString(), meta: { path: c.req.path } });
129
- return c.json({ error: "Too many failed login attempts. Try again later." }, 429);
130
- }
131
- const metadata = {
132
- ipAddress: clientIp !== "unknown" ? clientIp : undefined,
133
- userAgent: c.req.header("user-agent") ?? undefined,
134
- };
135
- try {
136
- const result = await AuthService.login(identifier, body.password, metadata);
137
- await bustAuthLimit(limitKey); // success — clear failure count
138
- if (!result.mfaRequired) {
139
- setCookie(c, COOKIE_TOKEN, result.token, cookieOptions(refreshTokens ? getAccessTokenExpiry() : undefined));
140
- if (result.refreshToken) {
141
- setCookie(c, COOKIE_REFRESH_TOKEN, result.refreshToken, cookieOptions(getRefreshTokenExpiry()));
142
- }
143
- if (getCsrfEnabled())
144
- refreshCsrfToken(c);
145
- }
146
- const { refreshToken: _rt, ...safeResult } = result;
147
- return c.json(result.refreshToken ? safeResult : result, 200);
148
- }
149
- catch (err) {
150
- if (err instanceof HttpError && err.status === 401) {
151
- trackFailedLogin(clientIp, identifier);
152
- }
153
- await trackAttempt(limitKey, loginOpts); // failure — count it
154
- throw err;
155
- }
156
- });
157
- router.use("/auth/me", userAuth);
158
- router.openapi(withSecurity(createRoute({
159
- method: "get",
160
- path: "/auth/me",
161
- summary: "Get current user",
162
- description: "Returns the authenticated user's profile. Requires a valid session via cookie or x-user-token header.",
163
- tags,
164
- responses: {
165
- 200: {
166
- content: {
167
- "application/json": {
168
- schema: z.object({
169
- userId: z.string().describe("Unique user ID."),
170
- email: z.string().optional().describe("User's email address."),
171
- emailVerified: z.boolean().optional().describe("Whether the email address has been verified."),
172
- googleLinked: z.boolean().optional().describe("Whether a Google OAuth account is linked."),
173
- }),
174
- },
175
- },
176
- description: "Authenticated user's profile.",
177
- },
178
- 401: { content: { "application/json": { schema: ErrorResponse } }, description: "No valid session." },
179
- },
180
- }), { cookieAuth: [] }, { userToken: [] }), async (c) => {
181
- const authUserId = c.get("authUserId");
182
- const adapter = getAuthAdapter();
183
- const user = adapter.getUser ? await adapter.getUser(authUserId) : null;
184
- const googleLinked = user?.providerIds?.some((id) => id.startsWith("google:")) ?? false;
185
- return c.json({ userId: authUserId, email: user?.email, emailVerified: user?.emailVerified, googleLinked }, 200);
186
- });
187
- // ---------------------------------------------------------------------------
188
- // Account deletion
189
- // ---------------------------------------------------------------------------
190
- const deleteAccountOpts = { windowMs: rateLimit?.deleteAccount?.windowMs ?? 60 * 60 * 1000, max: rateLimit?.deleteAccount?.max ?? 3 };
191
- router.openapi(withSecurity(createRoute({
192
- method: "delete",
193
- path: "/auth/me",
194
- summary: "Delete account",
195
- description: "Permanently deletes the authenticated user's account. Requires password confirmation for credential accounts. MFA is not required — the password serves as the identity check. Revokes all active sessions.",
196
- tags,
197
- request: {
198
- body: {
199
- content: {
200
- "application/json": {
201
- schema: z.object({
202
- password: z.string().optional().describe("Current password. Required for credential accounts, optional for OAuth-only accounts."),
203
- }),
204
- },
205
- },
206
- description: "Password confirmation.",
207
- },
208
- },
209
- responses: {
210
- 200: { content: { "application/json": { schema: z.object({ message: z.string() }) } }, description: "Account deleted." },
211
- 202: { content: { "application/json": { schema: z.object({ message: z.string() }) } }, description: "Account deletion has been scheduled." },
212
- 400: { content: { "application/json": { schema: ErrorResponse } }, description: "Password is required for credential accounts." },
213
- 401: { content: { "application/json": { schema: ErrorResponse } }, description: "Invalid password or no valid session." },
214
- 429: { content: { "application/json": { schema: ErrorResponse } }, description: "Too many deletion attempts. Try again later." },
215
- 501: { content: { "application/json": { schema: ErrorResponse } }, description: "The configured auth adapter does not support deleteUser." },
216
- },
217
- }), { cookieAuth: [] }, { userToken: [] }), async (c) => {
218
- const authUserId = c.get("authUserId");
219
- if (await trackAttempt(`deleteaccount:${authUserId}`, deleteAccountOpts)) {
220
- return c.json({ error: "Too many deletion attempts. Try again later." }, 429);
221
- }
222
- const adapter = getAuthAdapter();
223
- if (!adapter.deleteUser) {
224
- return c.json({ error: "Auth adapter does not support deleteUser" }, 501);
225
- }
226
- const { password } = c.req.valid("json");
227
- // Verify password for credential accounts
228
- if (password) {
229
- const user = adapter.getUser ? await adapter.getUser(authUserId) : null;
230
- const email = user?.email;
231
- if (email) {
232
- const findFn = adapter.findByIdentifier ?? adapter.findByEmail.bind(adapter);
233
- const found = await findFn(email);
234
- if (found && !(await Bun.password.verify(password, found.passwordHash))) {
235
- return c.json({ error: "Invalid password" }, 401);
236
- }
237
- }
238
- }
239
- else if (adapter.hasPassword && await adapter.hasPassword(authUserId)) {
240
- return c.json({ error: "Password is required to delete a credential account" }, 400);
241
- }
242
- // Call onBeforeDelete hook
243
- if (accountDeletion?.onBeforeDelete) {
244
- await accountDeletion.onBeforeDelete(authUserId);
245
- }
246
- // Queued deletion via BullMQ
247
- if (accountDeletion?.queued) {
248
- const { createQueue } = await import("../lib/queue");
249
- const appName = getAppName();
250
- const queue = createQueue(`${appName}:account-deletions`);
251
- const delayMs = (accountDeletion.gracePeriod ?? 0) * 1000;
252
- const job = await queue.add("delete-account", { userId: authUserId }, {
253
- delay: delayMs,
254
- attempts: 3,
255
- backoff: { type: "exponential", delay: 1000 },
256
- removeOnComplete: true,
257
- removeOnFail: 100,
258
- });
259
- await queue.close();
260
- // Revoke sessions immediately so the user is logged out
261
- await deleteUserSessions(authUserId);
262
- if (accountDeletion.gracePeriod && accountDeletion.onDeletionScheduled) {
263
- const user = adapter.getUser ? await adapter.getUser(authUserId) : null;
264
- const email = user?.email ?? "";
265
- if (email) {
266
- const cancelToken = await createDeletionCancelToken(authUserId, job.id, accountDeletion.gracePeriod);
267
- await accountDeletion.onDeletionScheduled(authUserId, email, cancelToken);
268
- }
269
- }
270
- deleteCookie(c, COOKIE_TOKEN, { path: "/" });
271
- return c.json({ message: "Account deletion scheduled" }, 202);
272
- }
273
- // Synchronous deletion (default)
274
- await deleteUserSessions(authUserId);
275
- await adapter.deleteUser(authUserId);
276
- if (accountDeletion?.onAfterDelete) {
277
- await accountDeletion.onAfterDelete(authUserId);
278
- }
279
- deleteCookie(c, COOKIE_TOKEN, { path: "/" });
280
- return c.json({ message: "Account deleted" }, 200);
281
- });
282
- router.use("/auth/set-password", userAuth);
283
- router.openapi(withSecurity(createRoute({
284
- method: "post",
285
- path: "/auth/set-password",
286
- summary: "Set or update password",
287
- description: "Sets or updates the password for the authenticated user. Useful for OAuth-only users who want to add a password. If the account already has a password set, `currentPassword` is required. Requires a valid session.",
288
- tags,
289
- request: {
290
- body: {
291
- content: {
292
- "application/json": {
293
- schema: z.object({
294
- password: z.string().min(8).describe("New password."),
295
- currentPassword: z.string().optional().describe("Current password. Required if the account already has a password set."),
296
- }),
297
- },
298
- },
299
- description: "New password.",
300
- },
301
- },
302
- responses: {
303
- 200: { content: { "application/json": { schema: z.object({ message: z.string() }) } }, description: "Password updated successfully." },
304
- 400: { content: { "application/json": { schema: ErrorResponse } }, description: "Validation error, or current password is required when one is already set." },
305
- 401: { content: { "application/json": { schema: ErrorResponse } }, description: "No valid session, or current password is incorrect." },
306
- 501: { content: { "application/json": { schema: ErrorResponse } }, description: "The configured auth adapter does not support setPassword." },
307
- },
308
- }), { cookieAuth: [] }, { userToken: [] }), async (c) => {
309
- const adapter = getAuthAdapter();
310
- if (!adapter.setPassword) {
311
- return c.json({ error: "Auth adapter does not support setPassword" }, 501);
312
- }
313
- const { password, currentPassword } = c.req.valid("json");
314
- const authUserId = c.get("authUserId");
315
- // If the user already has a password, require currentPassword to change it
316
- const user = adapter.getUser ? await adapter.getUser(authUserId) : null;
317
- if (user) {
318
- const findFn = adapter.findByIdentifier ?? (user.email ? adapter.findByEmail.bind(adapter) : null);
319
- if (findFn && user.email) {
320
- const found = await findFn(user.email);
321
- if (found?.passwordHash) {
322
- if (!currentPassword) {
323
- return c.json({ error: "Current password is required to change an existing password." }, 400);
324
- }
325
- if (!(await Bun.password.verify(currentPassword, found.passwordHash))) {
326
- return c.json({ error: "Current password is incorrect." }, 401);
327
- }
328
- }
329
- }
330
- }
331
- const passwordHash = await Bun.password.hash(password);
332
- await adapter.setPassword(authUserId, passwordHash);
333
- emitSecurityEvent({ eventType: "auth.password.change", severity: "info", timestamp: new Date().toISOString() });
334
- return c.json({ message: "Password updated" }, 200);
335
- });
336
- router.openapi(createRoute({
337
- method: "post",
338
- path: "/auth/logout",
339
- summary: "Log out",
340
- description: "Invalidates the current session and clears the session cookie. Safe to call even without an active session.",
341
- tags,
342
- responses: {
343
- 200: { content: { "application/json": { schema: z.object({ message: z.string() }) } }, description: "Logged out. Session is invalidated and cookie is cleared." },
344
- },
345
- }), async (c) => {
346
- const token = getCookie(c, COOKIE_TOKEN) ?? c.req.header(HEADER_USER_TOKEN) ?? null;
347
- await AuthService.logout(token);
348
- deleteCookie(c, COOKIE_TOKEN, { path: "/" });
349
- deleteCookie(c, COOKIE_REFRESH_TOKEN, { path: "/" });
350
- if (getCsrfEnabled())
351
- clearCsrfToken(c);
352
- return c.json({ message: "Logged out" }, 200);
353
- });
354
- // Email verification routes — only mounted when emailVerification is configured and primaryField is "email"
355
- if (emailVerification && primaryField === "email") {
356
- router.openapi(createRoute({
357
- method: "post",
358
- path: "/auth/verify-email",
359
- summary: "Verify email address",
360
- description: "Consumes a single-use email verification token and marks the account as verified. The token is delivered by the `emailVerification.onSend` callback configured in CreateAppConfig. Rate-limited by IP.",
361
- tags,
362
- request: { body: { content: { "application/json": { schema: z.object({ token: z.string().describe("Single-use verification token received via email.") }) } }, description: "Verification token." } },
363
- responses: {
364
- 200: { content: { "application/json": { schema: z.object({ message: z.string() }) } }, description: "Email verified successfully." },
365
- 400: { content: { "application/json": { schema: ErrorResponse } }, description: "Invalid or expired verification token." },
366
- 429: { content: { "application/json": { schema: ErrorResponse } }, description: "Too many verification attempts from this IP. Try again later." },
367
- },
368
- }), async (c) => {
369
- const ip = getClientIp(c);
370
- if (await trackAttempt(`verify:${ip}`, verifyOpts)) {
371
- return c.json({ error: "Too many verification attempts. Try again later." }, 429);
372
- }
373
- const { token } = c.req.valid("json");
374
- const adapter = getAuthAdapter();
375
- const entry = await consumeVerificationToken(token);
376
- if (!entry)
377
- return c.json({ error: "Invalid or expired verification token" }, 400);
378
- if (adapter.setEmailVerified)
379
- await adapter.setEmailVerified(entry.userId, true);
380
- if (getCsrfEnabled())
381
- refreshCsrfToken(c);
382
- return c.json({ message: "Email verified" }, 200);
383
- });
384
- router.openapi(createRoute({
385
- method: "post",
386
- path: "/auth/resend-verification",
387
- summary: "Resend verification email",
388
- description: "Authenticates with credentials and sends a new verification email. Always returns 200 for valid credentials regardless of verification status, to prevent user enumeration. Rate-limited per identifier. Does not require a session.",
389
- tags,
390
- request: { body: { content: { "application/json": { schema: LoginSchema } }, description: "Login credentials to identify the account." } },
391
- responses: {
392
- 200: { content: { "application/json": { schema: z.object({ message: z.string() }) } }, description: "Verification email sent, or account is already verified (indistinguishable by design)." },
393
- 400: { content: { "application/json": { schema: ErrorResponse } }, description: "No email address on file for this account." },
394
- 401: { content: { "application/json": { schema: ErrorResponse } }, description: "Invalid credentials." },
395
- 429: { content: { "application/json": { schema: ErrorResponse } }, description: "Too many resend attempts for this identifier. Try again later." },
396
- 501: { content: { "application/json": { schema: ErrorResponse } }, description: "The configured auth adapter does not support email verification." },
397
- },
398
- }), async (c) => {
399
- const adapter = getAuthAdapter();
400
- if (!adapter.getEmailVerified || !adapter.getUser) {
401
- return c.json({ error: "Auth adapter does not support email verification" }, 501);
402
- }
403
- const body = c.req.valid("json");
404
- const identifier = body[primaryField];
405
- if (await trackAttempt(`resend:${identifier}`, resendOpts)) {
406
- return c.json({ error: "Too many resend attempts. Try again later." }, 429);
407
- }
408
- const findFn = adapter.findByIdentifier ?? adapter.findByEmail.bind(adapter);
409
- const user = await findFn(identifier);
410
- if (!user || !(await Bun.password.verify(body.password, user.passwordHash))) {
411
- return c.json({ error: "Invalid credentials" }, 401);
412
- }
413
- const alreadyVerified = await adapter.getEmailVerified(user.id);
414
- // Return 200 (not 400) to avoid revealing whether the account is verified —
415
- // distinguishing verified vs unverified would let attackers confirm valid credentials.
416
- if (alreadyVerified)
417
- return c.json({ message: "Verification email sent if not already verified" }, 200);
418
- const fullUser = await adapter.getUser(user.id);
419
- if (!fullUser?.email)
420
- return c.json({ error: "No email address on file" }, 400);
421
- const verificationToken = await createVerificationToken(user.id, fullUser.email);
422
- await emailVerification.onSend(fullUser.email, verificationToken);
423
- return c.json({ message: "Verification email sent" }, 200);
424
- });
425
- }
426
- // Password reset routes — only mounted when passwordReset is configured and primaryField is "email"
427
- if (passwordReset && primaryField === "email") {
428
- router.openapi(createRoute({
429
- method: "post",
430
- path: "/auth/forgot-password",
431
- summary: "Request password reset",
432
- description: "Sends a password reset email if the address is registered. Always returns 200 regardless of whether the address exists, to prevent email enumeration. Rate-limited by both IP and email address.",
433
- tags,
434
- request: { body: { content: { "application/json": { schema: z.object({ email: z.string().email().describe("Email address to send the reset link to.") }) } }, description: "Email address for the account to reset." } },
435
- responses: {
436
- 200: { content: { "application/json": { schema: z.object({ message: z.string() }) } }, description: "Request received. A reset email will be sent if the address is registered." },
437
- 400: { content: { "application/json": { schema: ErrorResponse } }, description: "Validation error (e.g. not a valid email address)." },
438
- 429: { content: { "application/json": { schema: ErrorResponse } }, description: "Too many attempts from this IP or for this email address. Try again later." },
439
- },
440
- }), async (c) => {
441
- const ip = getClientIp(c);
442
- const { email } = c.req.valid("json");
443
- // Rate-limit by both IP and email to prevent distributed email-bombing
444
- const ipLimited = await trackAttempt(`forgot:ip:${ip}`, forgotOpts);
445
- const emailLimited = await trackAttempt(`forgot:email:${email}`, forgotOpts);
446
- if (ipLimited || emailLimited) {
447
- return c.json({ error: "Too many attempts. Try again later." }, 429);
448
- }
449
- const adapter = getAuthAdapter();
450
- const user = await adapter.findByEmail(email);
451
- // Fire-and-forget: the response does not wait for token creation or email sending,
452
- // which reduces obvious timing differences between registered and unregistered emails.
453
- const msg = { message: "If that email is registered, a password reset link has been sent." };
454
- if (user) {
455
- void (async () => {
456
- try {
457
- const token = await createResetToken(user.id, email);
458
- await passwordReset.onSend(email, token);
459
- }
460
- catch (err) {
461
- console.error("Failed to send password reset email:", err);
462
- }
463
- })();
464
- }
465
- return c.json(msg, 200);
466
- });
467
- router.openapi(createRoute({
468
- method: "post",
469
- path: "/auth/reset-password",
470
- summary: "Reset password",
471
- description: "Consumes a single-use reset token and sets a new password. All active sessions are revoked after a successful reset to invalidate any stolen JWTs. Rate-limited by IP.",
472
- tags,
473
- request: {
474
- body: {
475
- content: {
476
- "application/json": {
477
- schema: z.object({
478
- token: z.string().describe("Single-use reset token received via email."),
479
- password: resetPasswordSchema().describe("New password."),
480
- }),
481
- },
482
- },
483
- description: "Reset token and new password.",
484
- },
485
- },
486
- responses: {
487
- 200: { content: { "application/json": { schema: z.object({ message: z.string() }) } }, description: "Password reset. All sessions have been revoked." },
488
- 400: { content: { "application/json": { schema: ErrorResponse } }, description: "Validation error, or the reset token is invalid or expired." },
489
- 429: { content: { "application/json": { schema: ErrorResponse } }, description: "Too many reset attempts from this IP. Try again later." },
490
- 501: { content: { "application/json": { schema: ErrorResponse } }, description: "The configured auth adapter does not support setPassword." },
491
- },
492
- }), async (c) => {
493
- const ip = getClientIp(c);
494
- if (await trackAttempt(`reset:${ip}`, resetOpts)) {
495
- return c.json({ error: "Too many attempts. Try again later." }, 429);
496
- }
497
- const { token, password } = c.req.valid("json");
498
- const breachConfig = getBreachedPasswordConfig();
499
- if (breachConfig) {
500
- const { breached } = await checkBreachedPassword(password, breachConfig);
501
- if (breached && breachConfig.block !== false) {
502
- throw new HttpError(400, "This password has appeared in a data breach. Please choose a different password.", "BREACHED_PASSWORD");
503
- }
504
- }
505
- // consumeResetToken atomically gets and deletes — prevents concurrent replay
506
- const entry = await consumeResetToken(token);
507
- if (!entry)
508
- return c.json({ error: "Invalid or expired reset token" }, 400);
509
- const adapter = getAuthAdapter();
510
- if (!adapter.setPassword) {
511
- return c.json({ error: "Auth adapter does not support setPassword" }, 501);
512
- }
513
- const passwordHash = await Bun.password.hash(password);
514
- await adapter.setPassword(entry.userId, passwordHash);
515
- // Revoke all sessions so stolen JWTs can't stay valid after a reset
516
- const sessions = await getUserSessions(entry.userId);
517
- await Promise.all(sessions.map((s) => deleteSession(s.sessionId)));
518
- emitSecurityEvent({ eventType: "auth.password.reset", severity: "info", timestamp: new Date().toISOString() });
519
- return c.json({ message: "Password reset successfully" }, 200);
520
- });
521
- }
522
- // ---------------------------------------------------------------------------
523
- // Refresh token route — only mounted when refreshTokens is configured
524
- // ---------------------------------------------------------------------------
525
- if (refreshTokens) {
526
- const RefreshResponse = z.object({
527
- token: z.string().describe("New short-lived JWT access token."),
528
- userId: z.string().describe("Unique user ID."),
529
- }).openapi("RefreshResponse");
530
- router.openapi(createRoute({
531
- method: "post",
532
- path: "/auth/refresh",
533
- summary: "Refresh access token",
534
- description: "Exchanges a valid refresh token for a new access token and rotated refresh token. The old refresh token remains valid for a short grace window to handle network drops. If a previously rotated token is reused after the grace window, the entire session is invalidated (token theft detection).",
535
- tags,
536
- request: {
537
- body: {
538
- content: {
539
- "application/json": {
540
- schema: z.object({
541
- refreshToken: z.string().optional().describe("Refresh token. Can also be sent via the refresh_token cookie or x-refresh-token header."),
542
- }),
543
- },
544
- },
545
- description: "Refresh token (optional if sent via cookie or header).",
546
- },
547
- },
548
- responses: {
549
- 200: { content: { "application/json": { schema: RefreshResponse } }, description: "New access and refresh tokens." },
550
- 401: { content: { "application/json": { schema: ErrorResponse } }, description: "Invalid or expired refresh token, or session invalidated due to token theft detection." },
551
- 429: { content: { "application/json": { schema: ErrorResponse } }, description: "Too many refresh attempts. Try again later." },
552
- },
553
- }), async (c) => {
554
- const ip = getClientIp(c);
555
- if (await trackAttempt(`refresh:ip:${ip}`, { max: 30, windowMs: 60_000 })) {
556
- return c.json({ error: "Too many refresh attempts. Try again later." }, 429);
557
- }
558
- const body = c.req.valid("json");
559
- const rt = body.refreshToken ?? getCookie(c, COOKIE_REFRESH_TOKEN) ?? c.req.header(HEADER_REFRESH_TOKEN) ?? null;
560
- if (!rt) {
561
- return c.json({ error: "Refresh token is required" }, 401);
562
- }
563
- const result = await AuthService.refresh(rt);
564
- setCookie(c, COOKIE_TOKEN, result.token, cookieOptions(getAccessTokenExpiry()));
565
- setCookie(c, COOKIE_REFRESH_TOKEN, result.refreshToken, cookieOptions(getRefreshTokenExpiry()));
566
- const { refreshToken: _rt, ...safeResult } = result;
567
- return c.json(safeResult, 200);
568
- });
569
- }
570
- // ---------------------------------------------------------------------------
571
- // Account deletion cancellation — only mounted when queued: true + gracePeriod > 0
572
- // ---------------------------------------------------------------------------
573
- if (accountDeletion?.queued && accountDeletion.gracePeriod) {
574
- router.openapi(createRoute({
575
- method: "post",
576
- path: "/auth/cancel-deletion",
577
- summary: "Cancel scheduled account deletion",
578
- description: "Cancels a pending queued account deletion using the cancel token sent via the onDeletionScheduled callback. Must be called before the grace period expires.",
579
- tags,
580
- request: {
581
- body: {
582
- content: {
583
- "application/json": {
584
- schema: z.object({
585
- token: z.string().describe("Cancel token received in the deletion scheduled notification."),
586
- }),
587
- },
588
- },
589
- description: "Cancel token.",
590
- },
591
- },
592
- responses: {
593
- 200: { content: { "application/json": { schema: z.object({ message: z.string() }) } }, description: "Account deletion cancelled." },
594
- 400: { content: { "application/json": { schema: ErrorResponse } }, description: "Invalid or expired cancel token." },
595
- },
596
- }), async (c) => {
597
- const { token } = c.req.valid("json");
598
- const entry = await consumeDeletionCancelToken(token);
599
- if (!entry)
600
- return c.json({ error: "Invalid or expired cancel token" }, 400);
601
- // Remove the pending BullMQ job
602
- try {
603
- const { createQueue } = await import("../lib/queue");
604
- const appName = getAppName();
605
- const queue = createQueue(`${appName}:account-deletions`);
606
- const job = await queue.getJob(entry.jobId);
607
- if (job)
608
- await job.remove();
609
- await queue.close();
610
- }
611
- catch {
612
- // Job may have already executed — that's an error case but we still consumed the token
613
- }
614
- return c.json({ message: "Account deletion cancelled" }, 200);
615
- });
616
- }
617
- // ---------------------------------------------------------------------------
618
- // Step-up MFA re-authentication — only mounted when stepUp is configured
619
- // ---------------------------------------------------------------------------
620
- if (stepUp) {
621
- const stepUpOpts = { windowMs: rateLimit?.mfaVerify?.windowMs ?? 15 * 60 * 1000, max: rateLimit?.mfaVerify?.max ?? 10 };
622
- const stepUpSchema = z.object({
623
- mfaCode: z.string().optional().describe("6-digit TOTP code or recovery code."),
624
- password: z.string().optional().describe("Account password."),
625
- }).refine(data => data.mfaCode || data.password, {
626
- message: "Either mfaCode or password is required",
627
- });
628
- router.use("/auth/step-up", userAuth);
629
- router.openapi(withSecurity(createRoute({
630
- method: "post",
631
- path: "/auth/step-up",
632
- summary: "Step-up MFA re-authentication",
633
- description: "Re-authenticates the current session via TOTP code or password to satisfy step-up requirements for sensitive operations. On success, sets mfaVerifiedAt in the session.",
634
- tags,
635
- request: {
636
- body: {
637
- content: {
638
- "application/json": {
639
- schema: stepUpSchema,
640
- },
641
- },
642
- description: "TOTP code or password for re-authentication.",
643
- },
644
- },
645
- responses: {
646
- 200: { content: { "application/json": { schema: z.object({ ok: z.literal(true) }) } }, description: "Step-up authentication successful." },
647
- 400: { content: { "application/json": { schema: ErrorResponse } }, description: "Neither mfaCode nor password provided." },
648
- 401: { content: { "application/json": { schema: ErrorResponse } }, description: "Invalid code or password, or no valid session." },
649
- 429: { content: { "application/json": { schema: ErrorResponse } }, description: "Too many step-up attempts. Try again later." },
650
- },
651
- }), { cookieAuth: [] }, { userToken: [] }), async (c) => {
652
- const ip = getClientIp(c);
653
- if (await trackAttempt(`step-up:${ip}`, stepUpOpts)) {
654
- return c.json({ error: "Too many step-up attempts. Try again later." }, 429);
655
- }
656
- const userId = c.get("authUserId");
657
- const sessionId = c.get("sessionId");
658
- const { mfaCode, password } = c.req.valid("json");
659
- let valid = false;
660
- if (mfaCode) {
661
- const { verifyTotp, verifyRecoveryCode } = await import("../services/mfa");
662
- valid = await verifyTotp(userId, mfaCode);
663
- if (!valid)
664
- valid = await verifyRecoveryCode(userId, mfaCode);
665
- }
666
- else if (password) {
667
- const adapter = getAuthAdapter();
668
- const findFn = adapter.findByIdentifier ?? (adapter.findByEmail ? adapter.findByEmail.bind(adapter) : null);
669
- if (findFn) {
670
- const user = adapter.getUser ? await adapter.getUser(userId) : null;
671
- const identifier = user?.email ?? "";
672
- if (identifier) {
673
- const found = await findFn(identifier);
674
- if (found?.passwordHash) {
675
- valid = await Bun.password.verify(password, found.passwordHash);
676
- }
677
- }
678
- }
679
- }
680
- if (!valid) {
681
- emitSecurityEvent({ eventType: "auth.step_up.failure", severity: "warn", timestamp: new Date().toISOString(), userId });
682
- return c.json({ error: "Invalid credentials" }, 401);
683
- }
684
- await setMfaVerifiedAt(sessionId);
685
- emitSecurityEvent({ eventType: "auth.step_up.success", severity: "info", timestamp: new Date().toISOString(), userId });
686
- return c.json({ ok: true }, 200);
687
- });
688
- }
689
- // ---------------------------------------------------------------------------
690
- // Session management
691
- // ---------------------------------------------------------------------------
692
- const SessionInfoSchema = z.object({
693
- sessionId: z.string().describe("Unique session identifier (UUID)."),
694
- createdAt: z.number().describe("Unix timestamp (ms) when the session was created."),
695
- lastActiveAt: z.number().describe("Unix timestamp (ms) of the most recent authenticated request (updated when trackLastActive is enabled)."),
696
- expiresAt: z.number().describe("Unix timestamp (ms) when the session expires."),
697
- ipAddress: z.string().optional().describe("IP address of the client at session creation."),
698
- userAgent: z.string().optional().describe("User-agent string of the client at session creation."),
699
- isActive: z.boolean().describe("Whether the session is currently valid and unexpired."),
700
- }).openapi("SessionInfo");
701
- router.use("/auth/sessions", userAuth);
702
- router.use("/auth/sessions/*", userAuth);
703
- router.openapi(withSecurity(createRoute({
704
- method: "get",
705
- path: "/auth/sessions",
706
- summary: "List sessions",
707
- description: "Returns all sessions for the authenticated user. Includes inactive sessions when `sessionPolicy.includeInactiveSessions` is enabled. Requires a valid session.",
708
- tags,
709
- responses: {
710
- 200: {
711
- content: { "application/json": { schema: z.object({ sessions: z.array(SessionInfoSchema) }) } },
712
- description: "Sessions belonging to the authenticated user.",
713
- },
714
- 401: { content: { "application/json": { schema: ErrorResponse } }, description: "No valid session." },
715
- },
716
- }), { cookieAuth: [] }, { userToken: [] }), async (c) => {
717
- const userId = c.get("authUserId");
718
- const sessions = await getUserSessions(userId);
719
- return c.json({ sessions }, 200);
720
- });
721
- router.openapi(withSecurity(createRoute({
722
- method: "delete",
723
- path: "/auth/sessions/{sessionId}",
724
- summary: "Revoke a session",
725
- description: "Revokes a specific session by ID. Users can only revoke their own sessions. Useful for 'sign out of other devices' flows. Requires a valid session.",
726
- tags,
727
- request: { params: z.object({ sessionId: z.string().describe("UUID of the session to revoke.") }) },
728
- responses: {
729
- 200: { content: { "application/json": { schema: z.object({ message: z.string() }) } }, description: "Session revoked successfully." },
730
- 401: { content: { "application/json": { schema: ErrorResponse } }, description: "No valid session." },
731
- 404: { content: { "application/json": { schema: ErrorResponse } }, description: "Session not found or does not belong to the authenticated user." },
732
- },
733
- }), { cookieAuth: [] }, { userToken: [] }), async (c) => {
734
- const userId = c.get("authUserId");
735
- const { sessionId } = c.req.valid("param");
736
- const sessions = await getUserSessions(userId);
737
- const session = sessions.find((s) => s.sessionId === sessionId);
738
- if (!session)
739
- return c.json({ error: "Session not found" }, 404);
740
- await deleteSession(sessionId);
741
- return c.json({ message: "Session revoked" }, 200);
742
- });
743
- return router;
744
- };