@nauth-toolkit/core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (778) hide show
  1. package/dist/adapters/database-columns.d.ts +10 -0
  2. package/dist/adapters/database-columns.d.ts.map +1 -0
  3. package/dist/adapters/database-columns.js +85 -0
  4. package/dist/adapters/database-columns.js.map +1 -0
  5. package/dist/adapters/express.adapter.d.ts +41 -0
  6. package/dist/adapters/express.adapter.d.ts.map +1 -0
  7. package/dist/adapters/express.adapter.js +188 -0
  8. package/dist/adapters/express.adapter.js.map +1 -0
  9. package/dist/adapters/fastify.adapter.d.ts +33 -0
  10. package/dist/adapters/fastify.adapter.d.ts.map +1 -0
  11. package/dist/adapters/fastify.adapter.js +223 -0
  12. package/dist/adapters/fastify.adapter.js.map +1 -0
  13. package/dist/adapters/index.d.ts +5 -0
  14. package/dist/adapters/index.d.ts.map +1 -0
  15. package/dist/adapters/index.js +25 -0
  16. package/dist/adapters/index.js.map +1 -0
  17. package/dist/adapters/storage.factory.d.ts +7 -0
  18. package/dist/adapters/storage.factory.d.ts.map +1 -0
  19. package/dist/adapters/storage.factory.js +24 -0
  20. package/dist/adapters/storage.factory.js.map +1 -0
  21. package/dist/bootstrap.d.ts +41 -0
  22. package/dist/bootstrap.d.ts.map +1 -0
  23. package/dist/bootstrap.js +113 -0
  24. package/dist/bootstrap.js.map +1 -0
  25. package/dist/dto/auth-challenge.dto.d.ts +19 -0
  26. package/dist/dto/auth-challenge.dto.d.ts.map +1 -0
  27. package/dist/dto/auth-challenge.dto.js +86 -0
  28. package/dist/dto/auth-challenge.dto.js.map +1 -0
  29. package/dist/dto/auth-response.dto.d.ts +31 -0
  30. package/dist/dto/auth-response.dto.d.ts.map +1 -0
  31. package/dist/dto/auth-response.dto.js +18 -0
  32. package/dist/dto/auth-response.dto.js.map +1 -0
  33. package/dist/dto/challenge-response.dto.d.ts +36 -0
  34. package/dist/dto/challenge-response.dto.d.ts.map +1 -0
  35. package/dist/dto/challenge-response.dto.js +3 -0
  36. package/dist/dto/challenge-response.dto.js.map +1 -0
  37. package/dist/dto/change-password-request.dto.d.ts +5 -0
  38. package/dist/dto/change-password-request.dto.d.ts.map +1 -0
  39. package/dist/dto/change-password-request.dto.js +30 -0
  40. package/dist/dto/change-password-request.dto.js.map +1 -0
  41. package/dist/dto/change-password-response.dto.d.ts +4 -0
  42. package/dist/dto/change-password-response.dto.d.ts.map +1 -0
  43. package/dist/dto/change-password-response.dto.js +8 -0
  44. package/dist/dto/change-password-response.dto.js.map +1 -0
  45. package/dist/dto/change-password.dto.d.ts +5 -0
  46. package/dist/dto/change-password.dto.d.ts.map +1 -0
  47. package/dist/dto/change-password.dto.js +29 -0
  48. package/dist/dto/change-password.dto.js.map +1 -0
  49. package/dist/dto/error-response.dto.d.ts +9 -0
  50. package/dist/dto/error-response.dto.d.ts.map +1 -0
  51. package/dist/dto/error-response.dto.js +59 -0
  52. package/dist/dto/error-response.dto.js.map +1 -0
  53. package/dist/dto/get-available-methods.dto.d.ts +7 -0
  54. package/dist/dto/get-available-methods.dto.d.ts.map +1 -0
  55. package/dist/dto/get-available-methods.dto.js +33 -0
  56. package/dist/dto/get-available-methods.dto.js.map +1 -0
  57. package/dist/dto/get-challenge-data-response.dto.d.ts +4 -0
  58. package/dist/dto/get-challenge-data-response.dto.d.ts.map +1 -0
  59. package/dist/dto/get-challenge-data-response.dto.js +8 -0
  60. package/dist/dto/get-challenge-data-response.dto.js.map +1 -0
  61. package/dist/dto/get-challenge-data.dto.d.ts +8 -0
  62. package/dist/dto/get-challenge-data.dto.d.ts.map +1 -0
  63. package/dist/dto/get-challenge-data.dto.js +40 -0
  64. package/dist/dto/get-challenge-data.dto.js.map +1 -0
  65. package/dist/dto/get-client-info.dto.d.ts +17 -0
  66. package/dist/dto/get-client-info.dto.d.ts.map +1 -0
  67. package/dist/dto/get-client-info.dto.js +20 -0
  68. package/dist/dto/get-client-info.dto.js.map +1 -0
  69. package/dist/dto/get-device-token-response.dto.d.ts +4 -0
  70. package/dist/dto/get-device-token-response.dto.d.ts.map +1 -0
  71. package/dist/dto/get-device-token-response.dto.js +8 -0
  72. package/dist/dto/get-device-token-response.dto.js.map +1 -0
  73. package/dist/dto/get-events-by-type.dto.d.ts +17 -0
  74. package/dist/dto/get-events-by-type.dto.d.ts.map +1 -0
  75. package/dist/dto/get-events-by-type.dto.js +20 -0
  76. package/dist/dto/get-events-by-type.dto.js.map +1 -0
  77. package/dist/dto/get-ip-address-response.dto.d.ts +4 -0
  78. package/dist/dto/get-ip-address-response.dto.d.ts.map +1 -0
  79. package/dist/dto/get-ip-address-response.dto.js +8 -0
  80. package/dist/dto/get-ip-address-response.dto.js.map +1 -0
  81. package/dist/dto/get-mfa-status.dto.d.ts +16 -0
  82. package/dist/dto/get-mfa-status.dto.d.ts.map +1 -0
  83. package/dist/dto/get-mfa-status.dto.js +41 -0
  84. package/dist/dto/get-mfa-status.dto.js.map +1 -0
  85. package/dist/dto/get-risk-assessment-history.dto.d.ts +9 -0
  86. package/dist/dto/get-risk-assessment-history.dto.d.ts.map +1 -0
  87. package/dist/dto/get-risk-assessment-history.dto.js +13 -0
  88. package/dist/dto/get-risk-assessment-history.dto.js.map +1 -0
  89. package/dist/dto/get-session-id-response.dto.d.ts +4 -0
  90. package/dist/dto/get-session-id-response.dto.d.ts.map +1 -0
  91. package/dist/dto/get-session-id-response.dto.js +8 -0
  92. package/dist/dto/get-session-id-response.dto.js.map +1 -0
  93. package/dist/dto/get-setup-data-response.dto.d.ts +4 -0
  94. package/dist/dto/get-setup-data-response.dto.d.ts.map +1 -0
  95. package/dist/dto/get-setup-data-response.dto.js +8 -0
  96. package/dist/dto/get-setup-data-response.dto.js.map +1 -0
  97. package/dist/dto/get-setup-data.dto.d.ts +7 -0
  98. package/dist/dto/get-setup-data.dto.d.ts.map +1 -0
  99. package/dist/dto/get-setup-data.dto.js +43 -0
  100. package/dist/dto/get-setup-data.dto.js.map +1 -0
  101. package/dist/dto/get-suspicious-activity.dto.d.ts +9 -0
  102. package/dist/dto/get-suspicious-activity.dto.d.ts.map +1 -0
  103. package/dist/dto/get-suspicious-activity.dto.js +13 -0
  104. package/dist/dto/get-suspicious-activity.dto.js.map +1 -0
  105. package/dist/dto/get-user-agent-response.dto.d.ts +4 -0
  106. package/dist/dto/get-user-agent-response.dto.d.ts.map +1 -0
  107. package/dist/dto/get-user-agent-response.dto.js +8 -0
  108. package/dist/dto/get-user-agent-response.dto.js.map +1 -0
  109. package/dist/dto/get-user-auth-history.dto.d.ts +20 -0
  110. package/dist/dto/get-user-auth-history.dto.d.ts.map +1 -0
  111. package/dist/dto/get-user-auth-history.dto.js +22 -0
  112. package/dist/dto/get-user-auth-history.dto.js.map +1 -0
  113. package/dist/dto/get-user-by-email.dto.d.ts +5 -0
  114. package/dist/dto/get-user-by-email.dto.d.ts.map +1 -0
  115. package/dist/dto/get-user-by-email.dto.js +36 -0
  116. package/dist/dto/get-user-by-email.dto.js.map +1 -0
  117. package/dist/dto/get-user-by-id.dto.d.ts +4 -0
  118. package/dist/dto/get-user-by-id.dto.d.ts.map +1 -0
  119. package/dist/dto/get-user-by-id.dto.js +29 -0
  120. package/dist/dto/get-user-by-id.dto.js.map +1 -0
  121. package/dist/dto/get-user-devices.dto.d.ts +8 -0
  122. package/dist/dto/get-user-devices.dto.d.ts.map +1 -0
  123. package/dist/dto/get-user-devices.dto.js +33 -0
  124. package/dist/dto/get-user-devices.dto.js.map +1 -0
  125. package/dist/dto/get-user-response.dto.d.ts +2 -0
  126. package/dist/dto/get-user-response.dto.d.ts.map +1 -0
  127. package/dist/dto/get-user-response.dto.js +6 -0
  128. package/dist/dto/get-user-response.dto.js.map +1 -0
  129. package/dist/dto/has-provider.dto.d.ts +7 -0
  130. package/dist/dto/has-provider.dto.d.ts.map +1 -0
  131. package/dist/dto/has-provider.dto.js +38 -0
  132. package/dist/dto/has-provider.dto.js.map +1 -0
  133. package/dist/dto/index.d.ts +51 -0
  134. package/dist/dto/index.d.ts.map +1 -0
  135. package/dist/dto/index.js +67 -0
  136. package/dist/dto/index.js.map +1 -0
  137. package/dist/dto/is-trusted-device-response.dto.d.ts +4 -0
  138. package/dist/dto/is-trusted-device-response.dto.d.ts.map +1 -0
  139. package/dist/dto/is-trusted-device-response.dto.js +8 -0
  140. package/dist/dto/is-trusted-device-response.dto.js.map +1 -0
  141. package/dist/dto/list-providers-response.dto.d.ts +4 -0
  142. package/dist/dto/list-providers-response.dto.d.ts.map +1 -0
  143. package/dist/dto/list-providers-response.dto.js +8 -0
  144. package/dist/dto/list-providers-response.dto.js.map +1 -0
  145. package/dist/dto/login.dto.d.ts +7 -0
  146. package/dist/dto/login.dto.d.ts.map +1 -0
  147. package/dist/dto/login.dto.js +68 -0
  148. package/dist/dto/login.dto.js.map +1 -0
  149. package/dist/dto/logout-all-response.dto.d.ts +4 -0
  150. package/dist/dto/logout-all-response.dto.d.ts.map +1 -0
  151. package/dist/dto/logout-all-response.dto.js +8 -0
  152. package/dist/dto/logout-all-response.dto.js.map +1 -0
  153. package/dist/dto/logout-all.dto.d.ts +5 -0
  154. package/dist/dto/logout-all.dto.d.ts.map +1 -0
  155. package/dist/dto/logout-all.dto.js +42 -0
  156. package/dist/dto/logout-all.dto.js.map +1 -0
  157. package/dist/dto/logout-response.dto.d.ts +4 -0
  158. package/dist/dto/logout-response.dto.d.ts.map +1 -0
  159. package/dist/dto/logout-response.dto.js +8 -0
  160. package/dist/dto/logout-response.dto.js.map +1 -0
  161. package/dist/dto/logout.dto.d.ts +5 -0
  162. package/dist/dto/logout.dto.d.ts.map +1 -0
  163. package/dist/dto/logout.dto.js +36 -0
  164. package/dist/dto/logout.dto.js.map +1 -0
  165. package/dist/dto/refresh-token.dto.d.ts +4 -0
  166. package/dist/dto/refresh-token.dto.d.ts.map +1 -0
  167. package/dist/dto/refresh-token.dto.js +24 -0
  168. package/dist/dto/refresh-token.dto.js.map +1 -0
  169. package/dist/dto/remove-devices.dto.d.ts +9 -0
  170. package/dist/dto/remove-devices.dto.d.ts.map +1 -0
  171. package/dist/dto/remove-devices.dto.js +50 -0
  172. package/dist/dto/remove-devices.dto.js.map +1 -0
  173. package/dist/dto/resend-code-response.dto.d.ts +4 -0
  174. package/dist/dto/resend-code-response.dto.d.ts.map +1 -0
  175. package/dist/dto/resend-code-response.dto.js +8 -0
  176. package/dist/dto/resend-code-response.dto.js.map +1 -0
  177. package/dist/dto/resend-code.dto.d.ts +4 -0
  178. package/dist/dto/resend-code.dto.d.ts.map +1 -0
  179. package/dist/dto/resend-code.dto.js +29 -0
  180. package/dist/dto/resend-code.dto.js.map +1 -0
  181. package/dist/dto/reset-password.dto.d.ts +8 -0
  182. package/dist/dto/reset-password.dto.d.ts.map +1 -0
  183. package/dist/dto/reset-password.dto.js +61 -0
  184. package/dist/dto/reset-password.dto.js.map +1 -0
  185. package/dist/dto/respond-challenge.dto.d.ts +33 -0
  186. package/dist/dto/respond-challenge.dto.d.ts.map +1 -0
  187. package/dist/dto/respond-challenge.dto.js +131 -0
  188. package/dist/dto/respond-challenge.dto.js.map +1 -0
  189. package/dist/dto/set-mfa-exemption.dto.d.ts +12 -0
  190. package/dist/dto/set-mfa-exemption.dto.d.ts.map +1 -0
  191. package/dist/dto/set-mfa-exemption.dto.js +66 -0
  192. package/dist/dto/set-mfa-exemption.dto.js.map +1 -0
  193. package/dist/dto/set-must-change-password-response.dto.d.ts +4 -0
  194. package/dist/dto/set-must-change-password-response.dto.d.ts.map +1 -0
  195. package/dist/dto/set-must-change-password-response.dto.js +8 -0
  196. package/dist/dto/set-must-change-password-response.dto.js.map +1 -0
  197. package/dist/dto/set-must-change-password.dto.d.ts +4 -0
  198. package/dist/dto/set-must-change-password.dto.d.ts.map +1 -0
  199. package/dist/dto/set-must-change-password.dto.js +29 -0
  200. package/dist/dto/set-must-change-password.dto.js.map +1 -0
  201. package/dist/dto/set-preferred-method.dto.d.ts +8 -0
  202. package/dist/dto/set-preferred-method.dto.d.ts.map +1 -0
  203. package/dist/dto/set-preferred-method.dto.js +49 -0
  204. package/dist/dto/set-preferred-method.dto.js.map +1 -0
  205. package/dist/dto/setup-mfa.dto.d.ts +9 -0
  206. package/dist/dto/setup-mfa.dto.d.ts.map +1 -0
  207. package/dist/dto/setup-mfa.dto.js +55 -0
  208. package/dist/dto/setup-mfa.dto.js.map +1 -0
  209. package/dist/dto/signup.dto.d.ts +10 -0
  210. package/dist/dto/signup.dto.d.ts.map +1 -0
  211. package/dist/dto/signup.dto.js +109 -0
  212. package/dist/dto/signup.dto.js.map +1 -0
  213. package/dist/dto/social-auth.dto.d.ts +54 -0
  214. package/dist/dto/social-auth.dto.d.ts.map +1 -0
  215. package/dist/dto/social-auth.dto.js +232 -0
  216. package/dist/dto/social-auth.dto.js.map +1 -0
  217. package/dist/dto/trust-device-response.dto.d.ts +4 -0
  218. package/dist/dto/trust-device-response.dto.d.ts.map +1 -0
  219. package/dist/dto/trust-device-response.dto.js +8 -0
  220. package/dist/dto/trust-device-response.dto.js.map +1 -0
  221. package/dist/dto/trust-device.dto.d.ts +1 -0
  222. package/dist/dto/trust-device.dto.d.ts.map +1 -0
  223. package/dist/dto/trust-device.dto.js +2 -0
  224. package/dist/dto/trust-device.dto.js.map +1 -0
  225. package/dist/dto/update-user-attributes-request.dto.d.ts +5 -0
  226. package/dist/dto/update-user-attributes-request.dto.d.ts.map +1 -0
  227. package/dist/dto/update-user-attributes-request.dto.js +30 -0
  228. package/dist/dto/update-user-attributes-request.dto.js.map +1 -0
  229. package/dist/dto/user-response.dto.d.ts +20 -0
  230. package/dist/dto/user-response.dto.d.ts.map +1 -0
  231. package/dist/dto/user-response.dto.js +42 -0
  232. package/dist/dto/user-response.dto.js.map +1 -0
  233. package/dist/dto/user-update.dto.d.ts +12 -0
  234. package/dist/dto/user-update.dto.d.ts.map +1 -0
  235. package/dist/dto/user-update.dto.js +119 -0
  236. package/dist/dto/user-update.dto.js.map +1 -0
  237. package/dist/dto/verify-email.dto.d.ts +29 -0
  238. package/dist/dto/verify-email.dto.d.ts.map +1 -0
  239. package/dist/dto/verify-email.dto.js +161 -0
  240. package/dist/dto/verify-email.dto.js.map +1 -0
  241. package/dist/dto/verify-mfa-code.dto.d.ts +10 -0
  242. package/dist/dto/verify-mfa-code.dto.d.ts.map +1 -0
  243. package/dist/dto/verify-mfa-code.dto.js +56 -0
  244. package/dist/dto/verify-mfa-code.dto.js.map +1 -0
  245. package/dist/dto/verify-phone-by-sub.dto.d.ts +6 -0
  246. package/dist/dto/verify-phone-by-sub.dto.d.ts.map +1 -0
  247. package/dist/dto/verify-phone-by-sub.dto.js +49 -0
  248. package/dist/dto/verify-phone-by-sub.dto.js.map +1 -0
  249. package/dist/dto/verify-phone.dto.d.ts +24 -0
  250. package/dist/dto/verify-phone.dto.d.ts.map +1 -0
  251. package/dist/dto/verify-phone.dto.js +124 -0
  252. package/dist/dto/verify-phone.dto.js.map +1 -0
  253. package/dist/entities/auth-audit.entity.d.ts +31 -0
  254. package/dist/entities/auth-audit.entity.d.ts.map +1 -0
  255. package/dist/entities/auth-audit.entity.js +33 -0
  256. package/dist/entities/auth-audit.entity.js.map +1 -0
  257. package/dist/entities/challenge-session.entity.d.ts +17 -0
  258. package/dist/entities/challenge-session.entity.d.ts.map +1 -0
  259. package/dist/entities/challenge-session.entity.js +21 -0
  260. package/dist/entities/challenge-session.entity.js.map +1 -0
  261. package/dist/entities/index.d.ts +12 -0
  262. package/dist/entities/index.d.ts.map +1 -0
  263. package/dist/entities/index.js +26 -0
  264. package/dist/entities/index.js.map +1 -0
  265. package/dist/entities/login-attempt.entity.d.ts +13 -0
  266. package/dist/entities/login-attempt.entity.d.ts.map +1 -0
  267. package/dist/entities/login-attempt.entity.js +17 -0
  268. package/dist/entities/login-attempt.entity.js.map +1 -0
  269. package/dist/entities/mfa-device.entity.d.ts +22 -0
  270. package/dist/entities/mfa-device.entity.d.ts.map +1 -0
  271. package/dist/entities/mfa-device.entity.js +25 -0
  272. package/dist/entities/mfa-device.entity.js.map +1 -0
  273. package/dist/entities/rate-limit.entity.d.ts +9 -0
  274. package/dist/entities/rate-limit.entity.d.ts.map +1 -0
  275. package/dist/entities/rate-limit.entity.js +13 -0
  276. package/dist/entities/rate-limit.entity.js.map +1 -0
  277. package/dist/entities/session.entity.d.ts +32 -0
  278. package/dist/entities/session.entity.d.ts.map +1 -0
  279. package/dist/entities/session.entity.js +36 -0
  280. package/dist/entities/session.entity.js.map +1 -0
  281. package/dist/entities/social-account.entity.d.ts +13 -0
  282. package/dist/entities/social-account.entity.d.ts.map +1 -0
  283. package/dist/entities/social-account.entity.js +17 -0
  284. package/dist/entities/social-account.entity.js.map +1 -0
  285. package/dist/entities/storage-lock.entity.d.ts +8 -0
  286. package/dist/entities/storage-lock.entity.d.ts.map +1 -0
  287. package/dist/entities/storage-lock.entity.js +12 -0
  288. package/dist/entities/storage-lock.entity.js.map +1 -0
  289. package/dist/entities/trusted-device.entity.d.ts +17 -0
  290. package/dist/entities/trusted-device.entity.d.ts.map +1 -0
  291. package/dist/entities/trusted-device.entity.js +21 -0
  292. package/dist/entities/trusted-device.entity.js.map +1 -0
  293. package/dist/entities/user.entity.d.ts +41 -0
  294. package/dist/entities/user.entity.d.ts.map +1 -0
  295. package/dist/entities/user.entity.js +45 -0
  296. package/dist/entities/user.entity.js.map +1 -0
  297. package/dist/entities/verification-token.entity.d.ts +19 -0
  298. package/dist/entities/verification-token.entity.d.ts.map +1 -0
  299. package/dist/entities/verification-token.entity.js +29 -0
  300. package/dist/entities/verification-token.entity.js.map +1 -0
  301. package/dist/enums/auth-audit-event-type.enum.d.ts +55 -0
  302. package/dist/enums/auth-audit-event-type.enum.d.ts.map +1 -0
  303. package/dist/enums/auth-audit-event-type.enum.js +59 -0
  304. package/dist/enums/auth-audit-event-type.enum.js.map +1 -0
  305. package/dist/enums/error-codes.enum.d.ts +53 -0
  306. package/dist/enums/error-codes.enum.d.ts.map +1 -0
  307. package/dist/enums/error-codes.enum.js +57 -0
  308. package/dist/enums/error-codes.enum.js.map +1 -0
  309. package/dist/enums/mfa-method.enum.d.ts +11 -0
  310. package/dist/enums/mfa-method.enum.d.ts.map +1 -0
  311. package/dist/enums/mfa-method.enum.js +18 -0
  312. package/dist/enums/mfa-method.enum.js.map +1 -0
  313. package/dist/enums/risk-factor.enum.d.ts +14 -0
  314. package/dist/enums/risk-factor.enum.d.ts.map +1 -0
  315. package/dist/enums/risk-factor.enum.js +18 -0
  316. package/dist/enums/risk-factor.enum.js.map +1 -0
  317. package/dist/exceptions/nauth.exception.d.ts +18 -0
  318. package/dist/exceptions/nauth.exception.d.ts.map +1 -0
  319. package/dist/exceptions/nauth.exception.js +64 -0
  320. package/dist/exceptions/nauth.exception.js.map +1 -0
  321. package/dist/handlers/auth.handler.d.ts +18 -0
  322. package/dist/handlers/auth.handler.d.ts.map +1 -0
  323. package/dist/handlers/auth.handler.js +173 -0
  324. package/dist/handlers/auth.handler.js.map +1 -0
  325. package/dist/handlers/client-info.handler.d.ts +12 -0
  326. package/dist/handlers/client-info.handler.d.ts.map +1 -0
  327. package/dist/handlers/client-info.handler.js +61 -0
  328. package/dist/handlers/client-info.handler.js.map +1 -0
  329. package/dist/handlers/csrf.handler.d.ts +13 -0
  330. package/dist/handlers/csrf.handler.d.ts.map +1 -0
  331. package/dist/handlers/csrf.handler.js +84 -0
  332. package/dist/handlers/csrf.handler.js.map +1 -0
  333. package/dist/handlers/token-delivery.handler.d.ts +12 -0
  334. package/dist/handlers/token-delivery.handler.d.ts.map +1 -0
  335. package/dist/handlers/token-delivery.handler.js +86 -0
  336. package/dist/handlers/token-delivery.handler.js.map +1 -0
  337. package/dist/index.d.ts +27 -0
  338. package/dist/index.d.ts.map +1 -0
  339. package/dist/index.js +51 -0
  340. package/dist/index.js.map +1 -0
  341. package/dist/interfaces/client-info.interface.d.ts +16 -0
  342. package/dist/interfaces/client-info.interface.d.ts.map +1 -0
  343. package/dist/interfaces/client-info.interface.js +3 -0
  344. package/dist/interfaces/client-info.interface.js.map +1 -0
  345. package/dist/interfaces/config.interface.d.ts +279 -0
  346. package/dist/interfaces/config.interface.d.ts.map +1 -0
  347. package/dist/interfaces/config.interface.js +3 -0
  348. package/dist/interfaces/config.interface.js.map +1 -0
  349. package/dist/interfaces/entities.interface.d.ts +169 -0
  350. package/dist/interfaces/entities.interface.d.ts.map +1 -0
  351. package/dist/interfaces/entities.interface.js +3 -0
  352. package/dist/interfaces/entities.interface.js.map +1 -0
  353. package/dist/interfaces/index.d.ts +11 -0
  354. package/dist/interfaces/index.d.ts.map +1 -0
  355. package/dist/interfaces/index.js +27 -0
  356. package/dist/interfaces/index.js.map +1 -0
  357. package/dist/interfaces/logger.interface.d.ts +43 -0
  358. package/dist/interfaces/logger.interface.d.ts.map +1 -0
  359. package/dist/interfaces/logger.interface.js +12 -0
  360. package/dist/interfaces/logger.interface.js.map +1 -0
  361. package/dist/interfaces/mfa-provider.interface.d.ts +12 -0
  362. package/dist/interfaces/mfa-provider.interface.d.ts.map +1 -0
  363. package/dist/interfaces/mfa-provider.interface.js +3 -0
  364. package/dist/interfaces/mfa-provider.interface.js.map +1 -0
  365. package/dist/interfaces/oauth.interface.d.ts +24 -0
  366. package/dist/interfaces/oauth.interface.d.ts.map +1 -0
  367. package/dist/interfaces/oauth.interface.js +3 -0
  368. package/dist/interfaces/oauth.interface.js.map +1 -0
  369. package/dist/interfaces/provider.interface.d.ts +12 -0
  370. package/dist/interfaces/provider.interface.d.ts.map +1 -0
  371. package/dist/interfaces/provider.interface.js +3 -0
  372. package/dist/interfaces/provider.interface.js.map +1 -0
  373. package/dist/interfaces/social-auth-provider.interface.d.ts +13 -0
  374. package/dist/interfaces/social-auth-provider.interface.d.ts.map +1 -0
  375. package/dist/interfaces/social-auth-provider.interface.js +3 -0
  376. package/dist/interfaces/social-auth-provider.interface.js.map +1 -0
  377. package/dist/interfaces/storage-adapter.interface.d.ts +39 -0
  378. package/dist/interfaces/storage-adapter.interface.d.ts.map +1 -0
  379. package/dist/interfaces/storage-adapter.interface.js +3 -0
  380. package/dist/interfaces/storage-adapter.interface.js.map +1 -0
  381. package/dist/interfaces/template.interface.d.ts +99 -0
  382. package/dist/interfaces/template.interface.d.ts.map +1 -0
  383. package/dist/interfaces/template.interface.js +15 -0
  384. package/dist/interfaces/template.interface.js.map +1 -0
  385. package/dist/interfaces/token-verifier.interface.d.ts +7 -0
  386. package/dist/interfaces/token-verifier.interface.d.ts.map +1 -0
  387. package/dist/interfaces/token-verifier.interface.js +3 -0
  388. package/dist/interfaces/token-verifier.interface.js.map +1 -0
  389. package/dist/internal.d.ts +20 -0
  390. package/dist/internal.d.ts.map +1 -0
  391. package/dist/internal.js +53 -0
  392. package/dist/internal.js.map +1 -0
  393. package/dist/platform/interfaces.d.ts +56 -0
  394. package/dist/platform/interfaces.d.ts.map +1 -0
  395. package/dist/platform/interfaces.js +3 -0
  396. package/dist/platform/interfaces.js.map +1 -0
  397. package/dist/schemas/auth-config.schema.d.ts +3411 -0
  398. package/dist/schemas/auth-config.schema.d.ts.map +1 -0
  399. package/dist/schemas/auth-config.schema.js +428 -0
  400. package/dist/schemas/auth-config.schema.js.map +1 -0
  401. package/dist/services/adaptive-mfa-decision.service.d.ts +39 -0
  402. package/dist/services/adaptive-mfa-decision.service.d.ts.map +1 -0
  403. package/dist/services/adaptive-mfa-decision.service.js +223 -0
  404. package/dist/services/adaptive-mfa-decision.service.js.map +1 -0
  405. package/dist/services/auth-audit.service.d.ts +44 -0
  406. package/dist/services/auth-audit.service.d.ts.map +1 -0
  407. package/dist/services/auth-audit.service.js +241 -0
  408. package/dist/services/auth-audit.service.js.map +1 -0
  409. package/dist/services/auth-challenge-helper.service.d.ts +48 -0
  410. package/dist/services/auth-challenge-helper.service.d.ts.map +1 -0
  411. package/dist/services/auth-challenge-helper.service.js +425 -0
  412. package/dist/services/auth-challenge-helper.service.js.map +1 -0
  413. package/dist/services/auth-flow-context-builder.service.d.ts +31 -0
  414. package/dist/services/auth-flow-context-builder.service.d.ts.map +1 -0
  415. package/dist/services/auth-flow-context-builder.service.js +253 -0
  416. package/dist/services/auth-flow-context-builder.service.js.map +1 -0
  417. package/dist/services/auth-flow-rules.d.ts +18 -0
  418. package/dist/services/auth-flow-rules.d.ts.map +1 -0
  419. package/dist/services/auth-flow-rules.js +55 -0
  420. package/dist/services/auth-flow-rules.js.map +1 -0
  421. package/dist/services/auth-flow-state-definitions.d.ts +5 -0
  422. package/dist/services/auth-flow-state-definitions.d.ts.map +1 -0
  423. package/dist/services/auth-flow-state-definitions.js +87 -0
  424. package/dist/services/auth-flow-state-definitions.js.map +1 -0
  425. package/dist/services/auth-flow-state-machine.service.d.ts +17 -0
  426. package/dist/services/auth-flow-state-machine.service.d.ts.map +1 -0
  427. package/dist/services/auth-flow-state-machine.service.js +91 -0
  428. package/dist/services/auth-flow-state-machine.service.js.map +1 -0
  429. package/dist/services/auth-flow-state-machine.types.d.ts +55 -0
  430. package/dist/services/auth-flow-state-machine.types.d.ts.map +1 -0
  431. package/dist/services/auth-flow-state-machine.types.js +16 -0
  432. package/dist/services/auth-flow-state-machine.types.js.map +1 -0
  433. package/dist/services/auth.service.d.ts +87 -0
  434. package/dist/services/auth.service.d.ts.map +1 -0
  435. package/dist/services/auth.service.js +2356 -0
  436. package/dist/services/auth.service.js.map +1 -0
  437. package/dist/services/challenge.service.d.ts +32 -0
  438. package/dist/services/challenge.service.d.ts.map +1 -0
  439. package/dist/services/challenge.service.js +293 -0
  440. package/dist/services/challenge.service.js.map +1 -0
  441. package/dist/services/client-info.service.d.ts +20 -0
  442. package/dist/services/client-info.service.d.ts.map +1 -0
  443. package/dist/services/client-info.service.js +202 -0
  444. package/dist/services/client-info.service.js.map +1 -0
  445. package/dist/services/csrf.service.d.ts +13 -0
  446. package/dist/services/csrf.service.d.ts.map +1 -0
  447. package/dist/services/csrf.service.js +67 -0
  448. package/dist/services/csrf.service.js.map +1 -0
  449. package/dist/services/email-verification.service.d.ts +30 -0
  450. package/dist/services/email-verification.service.d.ts.map +1 -0
  451. package/dist/services/email-verification.service.js +373 -0
  452. package/dist/services/email-verification.service.js.map +1 -0
  453. package/dist/services/geo-location.service.d.ts +85 -0
  454. package/dist/services/geo-location.service.d.ts.map +1 -0
  455. package/dist/services/geo-location.service.js +338 -0
  456. package/dist/services/geo-location.service.js.map +1 -0
  457. package/dist/services/index.d.ts +14 -0
  458. package/dist/services/index.d.ts.map +1 -0
  459. package/dist/services/index.js +30 -0
  460. package/dist/services/index.js.map +1 -0
  461. package/dist/services/jwt.service.d.ts +62 -0
  462. package/dist/services/jwt.service.d.ts.map +1 -0
  463. package/dist/services/jwt.service.js +261 -0
  464. package/dist/services/jwt.service.js.map +1 -0
  465. package/dist/services/mfa-base.service.d.ts +37 -0
  466. package/dist/services/mfa-base.service.d.ts.map +1 -0
  467. package/dist/services/mfa-base.service.js +297 -0
  468. package/dist/services/mfa-base.service.js.map +1 -0
  469. package/dist/services/mfa.service.d.ts +35 -0
  470. package/dist/services/mfa.service.d.ts.map +1 -0
  471. package/dist/services/mfa.service.js +449 -0
  472. package/dist/services/mfa.service.js.map +1 -0
  473. package/dist/services/password.service.d.ts +19 -0
  474. package/dist/services/password.service.d.ts.map +1 -0
  475. package/dist/services/password.service.js +150 -0
  476. package/dist/services/password.service.js.map +1 -0
  477. package/dist/services/phone-verification.service.d.ts +32 -0
  478. package/dist/services/phone-verification.service.d.ts.map +1 -0
  479. package/dist/services/phone-verification.service.js +474 -0
  480. package/dist/services/phone-verification.service.js.map +1 -0
  481. package/dist/services/risk-detection.service.d.ts +30 -0
  482. package/dist/services/risk-detection.service.d.ts.map +1 -0
  483. package/dist/services/risk-detection.service.js +518 -0
  484. package/dist/services/risk-detection.service.js.map +1 -0
  485. package/dist/services/risk-scoring.service.d.ts +12 -0
  486. package/dist/services/risk-scoring.service.d.ts.map +1 -0
  487. package/dist/services/risk-scoring.service.js +44 -0
  488. package/dist/services/risk-scoring.service.js.map +1 -0
  489. package/dist/services/session.service.d.ts +64 -0
  490. package/dist/services/session.service.d.ts.map +1 -0
  491. package/dist/services/session.service.js +455 -0
  492. package/dist/services/session.service.js.map +1 -0
  493. package/dist/services/social-auth-base.service.d.ts +57 -0
  494. package/dist/services/social-auth-base.service.d.ts.map +1 -0
  495. package/dist/services/social-auth-base.service.js +340 -0
  496. package/dist/services/social-auth-base.service.js.map +1 -0
  497. package/dist/services/social-auth.service.d.ts +31 -0
  498. package/dist/services/social-auth.service.d.ts.map +1 -0
  499. package/dist/services/social-auth.service.js +172 -0
  500. package/dist/services/social-auth.service.js.map +1 -0
  501. package/dist/services/social-provider-registry.service.d.ts +9 -0
  502. package/dist/services/social-provider-registry.service.d.ts.map +1 -0
  503. package/dist/services/social-provider-registry.service.js +30 -0
  504. package/dist/services/social-provider-registry.service.js.map +1 -0
  505. package/dist/services/trusted-device.service.d.ts +29 -0
  506. package/dist/services/trusted-device.service.d.ts.map +1 -0
  507. package/dist/services/trusted-device.service.js +190 -0
  508. package/dist/services/trusted-device.service.js.map +1 -0
  509. package/dist/storage/account-lockout-storage.service.d.ts +16 -0
  510. package/dist/storage/account-lockout-storage.service.d.ts.map +1 -0
  511. package/dist/storage/account-lockout-storage.service.js +50 -0
  512. package/dist/storage/account-lockout-storage.service.js.map +1 -0
  513. package/dist/storage/index.d.ts +4 -0
  514. package/dist/storage/index.d.ts.map +1 -0
  515. package/dist/storage/index.js +20 -0
  516. package/dist/storage/index.js.map +1 -0
  517. package/dist/storage/memory-storage.adapter.d.ts +33 -0
  518. package/dist/storage/memory-storage.adapter.d.ts.map +1 -0
  519. package/dist/storage/memory-storage.adapter.js +195 -0
  520. package/dist/storage/memory-storage.adapter.js.map +1 -0
  521. package/dist/storage/rate-limit-storage.service.d.ts +11 -0
  522. package/dist/storage/rate-limit-storage.service.d.ts.map +1 -0
  523. package/dist/storage/rate-limit-storage.service.js +33 -0
  524. package/dist/storage/rate-limit-storage.service.js.map +1 -0
  525. package/dist/templates/html-template.engine.d.ts +16 -0
  526. package/dist/templates/html-template.engine.d.ts.map +1 -0
  527. package/dist/templates/html-template.engine.js +502 -0
  528. package/dist/templates/html-template.engine.js.map +1 -0
  529. package/dist/templates/index.d.ts +2 -0
  530. package/dist/templates/index.d.ts.map +1 -0
  531. package/dist/templates/index.js +18 -0
  532. package/dist/templates/index.js.map +1 -0
  533. package/dist/utils/common-passwords.d.ts +4 -0
  534. package/dist/utils/common-passwords.d.ts.map +1 -0
  535. package/dist/utils/common-passwords.js +108 -0
  536. package/dist/utils/common-passwords.js.map +1 -0
  537. package/dist/utils/context-storage.d.ts +13 -0
  538. package/dist/utils/context-storage.d.ts.map +1 -0
  539. package/dist/utils/context-storage.js +54 -0
  540. package/dist/utils/context-storage.js.map +1 -0
  541. package/dist/utils/cookie-names.util.d.ts +7 -0
  542. package/dist/utils/cookie-names.util.d.ts.map +1 -0
  543. package/dist/utils/cookie-names.util.js +30 -0
  544. package/dist/utils/cookie-names.util.js.map +1 -0
  545. package/dist/utils/cookies.util.d.ts +12 -0
  546. package/dist/utils/cookies.util.d.ts.map +1 -0
  547. package/dist/utils/cookies.util.js +48 -0
  548. package/dist/utils/cookies.util.js.map +1 -0
  549. package/dist/utils/index.d.ts +8 -0
  550. package/dist/utils/index.d.ts.map +1 -0
  551. package/dist/utils/index.js +24 -0
  552. package/dist/utils/index.js.map +1 -0
  553. package/dist/utils/ip-extractor.d.ts +12 -0
  554. package/dist/utils/ip-extractor.d.ts.map +1 -0
  555. package/dist/utils/ip-extractor.js +88 -0
  556. package/dist/utils/ip-extractor.js.map +1 -0
  557. package/dist/utils/nauth-logger.d.ts +20 -0
  558. package/dist/utils/nauth-logger.d.ts.map +1 -0
  559. package/dist/utils/nauth-logger.js +129 -0
  560. package/dist/utils/nauth-logger.js.map +1 -0
  561. package/dist/utils/pii-redactor.d.ts +16 -0
  562. package/dist/utils/pii-redactor.d.ts.map +1 -0
  563. package/dist/utils/pii-redactor.js +147 -0
  564. package/dist/utils/pii-redactor.js.map +1 -0
  565. package/dist/utils/setup/get-repositories.d.ts +16 -0
  566. package/dist/utils/setup/get-repositories.d.ts.map +1 -0
  567. package/dist/utils/setup/get-repositories.js +36 -0
  568. package/dist/utils/setup/get-repositories.js.map +1 -0
  569. package/dist/utils/setup/init-services.d.ts +41 -0
  570. package/dist/utils/setup/init-services.d.ts.map +1 -0
  571. package/dist/utils/setup/init-services.js +107 -0
  572. package/dist/utils/setup/init-services.js.map +1 -0
  573. package/dist/utils/setup/init-social.d.ts +13 -0
  574. package/dist/utils/setup/init-social.d.ts.map +1 -0
  575. package/dist/utils/setup/init-social.js +77 -0
  576. package/dist/utils/setup/init-social.js.map +1 -0
  577. package/dist/utils/setup/init-storage.d.ts +4 -0
  578. package/dist/utils/setup/init-storage.d.ts.map +1 -0
  579. package/dist/utils/setup/init-storage.js +79 -0
  580. package/dist/utils/setup/init-storage.js.map +1 -0
  581. package/dist/utils/setup/register-mfa.d.ts +5 -0
  582. package/dist/utils/setup/register-mfa.d.ts.map +1 -0
  583. package/dist/utils/setup/register-mfa.js +85 -0
  584. package/dist/utils/setup/register-mfa.js.map +1 -0
  585. package/dist/utils/setup/run-nauth-migrations.d.ts +5 -0
  586. package/dist/utils/setup/run-nauth-migrations.d.ts.map +1 -0
  587. package/dist/utils/setup/run-nauth-migrations.js +67 -0
  588. package/dist/utils/setup/run-nauth-migrations.js.map +1 -0
  589. package/dist/utils/token-delivery-policy.d.ts +6 -0
  590. package/dist/utils/token-delivery-policy.d.ts.map +1 -0
  591. package/dist/utils/token-delivery-policy.js +15 -0
  592. package/dist/utils/token-delivery-policy.js.map +1 -0
  593. package/dist/validators/template.validator.d.ts +7 -0
  594. package/dist/validators/template.validator.d.ts.map +1 -0
  595. package/dist/validators/template.validator.js +95 -0
  596. package/dist/validators/template.validator.js.map +1 -0
  597. package/jest.config.js +15 -0
  598. package/jest.setup.ts +6 -0
  599. package/package.json +73 -0
  600. package/src/adapters/database-columns.ts +165 -0
  601. package/src/adapters/express.adapter.ts +385 -0
  602. package/src/adapters/fastify.adapter.ts +416 -0
  603. package/src/adapters/index.ts +16 -0
  604. package/src/adapters/storage.factory.ts +143 -0
  605. package/src/bootstrap.ts +374 -0
  606. package/src/dto/auth-challenge.dto.ts +231 -0
  607. package/src/dto/auth-response.dto.ts +253 -0
  608. package/src/dto/challenge-response.dto.ts +234 -0
  609. package/src/dto/change-password-request.dto.ts +50 -0
  610. package/src/dto/change-password-response.dto.ts +29 -0
  611. package/src/dto/change-password.dto.ts +57 -0
  612. package/src/dto/error-response.dto.ts +136 -0
  613. package/src/dto/get-available-methods.dto.ts +55 -0
  614. package/src/dto/get-challenge-data-response.dto.ts +28 -0
  615. package/src/dto/get-challenge-data.dto.ts +69 -0
  616. package/src/dto/get-client-info.dto.ts +104 -0
  617. package/src/dto/get-device-token-response.dto.ts +25 -0
  618. package/src/dto/get-events-by-type.dto.ts +76 -0
  619. package/src/dto/get-ip-address-response.dto.ts +24 -0
  620. package/src/dto/get-mfa-status.dto.ts +94 -0
  621. package/src/dto/get-risk-assessment-history.dto.ts +39 -0
  622. package/src/dto/get-session-id-response.dto.ts +25 -0
  623. package/src/dto/get-setup-data-response.dto.ts +31 -0
  624. package/src/dto/get-setup-data.dto.ts +75 -0
  625. package/src/dto/get-suspicious-activity.dto.ts +42 -0
  626. package/src/dto/get-user-agent-response.dto.ts +23 -0
  627. package/src/dto/get-user-auth-history.dto.ts +95 -0
  628. package/src/dto/get-user-by-email.dto.ts +61 -0
  629. package/src/dto/get-user-by-id.dto.ts +46 -0
  630. package/src/dto/get-user-devices.dto.ts +53 -0
  631. package/src/dto/get-user-response.dto.ts +17 -0
  632. package/src/dto/has-provider.dto.ts +56 -0
  633. package/src/dto/index.ts +57 -0
  634. package/src/dto/is-trusted-device-response.dto.ts +34 -0
  635. package/src/dto/list-providers-response.dto.ts +23 -0
  636. package/src/dto/login.dto.ts +95 -0
  637. package/src/dto/logout-all-response.dto.ts +24 -0
  638. package/src/dto/logout-all.dto.ts +65 -0
  639. package/src/dto/logout-response.dto.ts +25 -0
  640. package/src/dto/logout.dto.ts +64 -0
  641. package/src/dto/refresh-token.dto.ts +36 -0
  642. package/src/dto/remove-devices.dto.ts +85 -0
  643. package/src/dto/resend-code-response.dto.ts +32 -0
  644. package/src/dto/resend-code.dto.ts +51 -0
  645. package/src/dto/reset-password.dto.ts +115 -0
  646. package/src/dto/respond-challenge.dto.ts +272 -0
  647. package/src/dto/set-mfa-exemption.dto.ts +112 -0
  648. package/src/dto/set-must-change-password-response.dto.ts +27 -0
  649. package/src/dto/set-must-change-password.dto.ts +46 -0
  650. package/src/dto/set-preferred-method.dto.ts +80 -0
  651. package/src/dto/setup-mfa.dto.ts +98 -0
  652. package/src/dto/signup.dto.ts +174 -0
  653. package/src/dto/social-auth.dto.ts +422 -0
  654. package/src/dto/trust-device-response.dto.ts +30 -0
  655. package/src/dto/trust-device.dto.ts +9 -0
  656. package/src/dto/update-user-attributes-request.dto.ts +51 -0
  657. package/src/dto/user-response.dto.ts +138 -0
  658. package/src/dto/user-update.dto.ts +222 -0
  659. package/src/dto/verify-email.dto.ts +313 -0
  660. package/src/dto/verify-mfa-code.dto.ts +103 -0
  661. package/src/dto/verify-phone-by-sub.dto.ts +78 -0
  662. package/src/dto/verify-phone.dto.ts +245 -0
  663. package/src/entities/auth-audit.entity.ts +232 -0
  664. package/src/entities/challenge-session.entity.ts +116 -0
  665. package/src/entities/index.ts +29 -0
  666. package/src/entities/login-attempt.entity.ts +64 -0
  667. package/src/entities/mfa-device.entity.ts +151 -0
  668. package/src/entities/rate-limit.entity.ts +44 -0
  669. package/src/entities/session.entity.ts +180 -0
  670. package/src/entities/social-account.entity.ts +96 -0
  671. package/src/entities/storage-lock.entity.ts +39 -0
  672. package/src/entities/trusted-device.entity.ts +112 -0
  673. package/src/entities/user.entity.ts +243 -0
  674. package/src/entities/verification-token.entity.ts +141 -0
  675. package/src/enums/auth-audit-event-type.enum.ts +360 -0
  676. package/src/enums/error-codes.enum.ts +420 -0
  677. package/src/enums/mfa-method.enum.ts +97 -0
  678. package/src/enums/risk-factor.enum.ts +111 -0
  679. package/src/exceptions/nauth.exception.ts +231 -0
  680. package/src/handlers/auth.handler.ts +260 -0
  681. package/src/handlers/client-info.handler.ts +101 -0
  682. package/src/handlers/csrf.handler.ts +156 -0
  683. package/src/handlers/token-delivery.handler.ts +118 -0
  684. package/src/index.ts +118 -0
  685. package/src/interfaces/client-info.interface.ts +85 -0
  686. package/src/interfaces/config.interface.ts +2135 -0
  687. package/src/interfaces/entities.interface.ts +226 -0
  688. package/src/interfaces/index.ts +15 -0
  689. package/src/interfaces/logger.interface.ts +283 -0
  690. package/src/interfaces/mfa-provider.interface.ts +154 -0
  691. package/src/interfaces/oauth.interface.ts +148 -0
  692. package/src/interfaces/provider.interface.ts +47 -0
  693. package/src/interfaces/social-auth-provider.interface.ts +131 -0
  694. package/src/interfaces/storage-adapter.interface.ts +82 -0
  695. package/src/interfaces/template.interface.ts +510 -0
  696. package/src/interfaces/token-verifier.interface.ts +110 -0
  697. package/src/internal.ts +178 -0
  698. package/src/platform/interfaces.ts +299 -0
  699. package/src/schemas/auth-config.schema.ts +646 -0
  700. package/src/services/adaptive-mfa-decision.service.spec.ts +1058 -0
  701. package/src/services/adaptive-mfa-decision.service.ts +457 -0
  702. package/src/services/auth-audit.service.spec.ts +675 -0
  703. package/src/services/auth-audit.service.ts +558 -0
  704. package/src/services/auth-challenge-helper.service.spec.ts +3227 -0
  705. package/src/services/auth-challenge-helper.service.ts +825 -0
  706. package/src/services/auth-flow-context-builder.service.ts +520 -0
  707. package/src/services/auth-flow-rules.ts +202 -0
  708. package/src/services/auth-flow-state-definitions.ts +190 -0
  709. package/src/services/auth-flow-state-machine.service.ts +207 -0
  710. package/src/services/auth-flow-state-machine.types.ts +316 -0
  711. package/src/services/auth.service.spec.ts +4195 -0
  712. package/src/services/auth.service.ts +3727 -0
  713. package/src/services/challenge.service.spec.ts +1363 -0
  714. package/src/services/challenge.service.ts +696 -0
  715. package/src/services/client-info.service.spec.ts +572 -0
  716. package/src/services/client-info.service.ts +374 -0
  717. package/src/services/csrf.service.ts +54 -0
  718. package/src/services/email-verification.service.spec.ts +1229 -0
  719. package/src/services/email-verification.service.ts +578 -0
  720. package/src/services/geo-location.service.spec.ts +603 -0
  721. package/src/services/geo-location.service.ts +599 -0
  722. package/src/services/index.ts +13 -0
  723. package/src/services/jwt.service.spec.ts +882 -0
  724. package/src/services/jwt.service.ts +621 -0
  725. package/src/services/mfa-base.service.spec.ts +246 -0
  726. package/src/services/mfa-base.service.ts +611 -0
  727. package/src/services/mfa.service.spec.ts +693 -0
  728. package/src/services/mfa.service.ts +960 -0
  729. package/src/services/password.service.spec.ts +166 -0
  730. package/src/services/password.service.ts +309 -0
  731. package/src/services/phone-verification.service.spec.ts +1120 -0
  732. package/src/services/phone-verification.service.ts +751 -0
  733. package/src/services/risk-detection.service.spec.ts +1292 -0
  734. package/src/services/risk-detection.service.ts +1012 -0
  735. package/src/services/risk-scoring.service.spec.ts +204 -0
  736. package/src/services/risk-scoring.service.ts +131 -0
  737. package/src/services/session.service.spec.ts +1293 -0
  738. package/src/services/session.service.ts +803 -0
  739. package/src/services/social-account.service.spec.ts +725 -0
  740. package/src/services/social-auth-base.service.spec.ts +418 -0
  741. package/src/services/social-auth-base.service.ts +581 -0
  742. package/src/services/social-auth.service.spec.ts +238 -0
  743. package/src/services/social-auth.service.ts +436 -0
  744. package/src/services/social-provider-registry.service.spec.ts +238 -0
  745. package/src/services/social-provider-registry.service.ts +122 -0
  746. package/src/services/trusted-device.service.spec.ts +505 -0
  747. package/src/services/trusted-device.service.ts +339 -0
  748. package/src/storage/account-lockout-storage.service.spec.ts +310 -0
  749. package/src/storage/account-lockout-storage.service.ts +89 -0
  750. package/src/storage/index.ts +3 -0
  751. package/src/storage/memory-storage.adapter.ts +443 -0
  752. package/src/storage/rate-limit-storage.service.spec.ts +247 -0
  753. package/src/storage/rate-limit-storage.service.ts +38 -0
  754. package/src/templates/html-template.engine.spec.ts +161 -0
  755. package/src/templates/html-template.engine.ts +688 -0
  756. package/src/templates/index.ts +7 -0
  757. package/src/utils/common-passwords.spec.ts +230 -0
  758. package/src/utils/common-passwords.ts +170 -0
  759. package/src/utils/context-storage.ts +188 -0
  760. package/src/utils/cookie-names.util.ts +67 -0
  761. package/src/utils/cookies.util.ts +94 -0
  762. package/src/utils/index.ts +12 -0
  763. package/src/utils/ip-extractor.spec.ts +330 -0
  764. package/src/utils/ip-extractor.ts +220 -0
  765. package/src/utils/nauth-logger.spec.ts +388 -0
  766. package/src/utils/nauth-logger.ts +215 -0
  767. package/src/utils/pii-redactor.spec.ts +130 -0
  768. package/src/utils/pii-redactor.ts +288 -0
  769. package/src/utils/setup/get-repositories.ts +140 -0
  770. package/src/utils/setup/init-services.ts +422 -0
  771. package/src/utils/setup/init-social.ts +189 -0
  772. package/src/utils/setup/init-storage.ts +94 -0
  773. package/src/utils/setup/register-mfa.ts +165 -0
  774. package/src/utils/setup/run-nauth-migrations.ts +61 -0
  775. package/src/utils/token-delivery-policy.ts +38 -0
  776. package/src/validators/template.validator.ts +219 -0
  777. package/tsconfig.json +37 -0
  778. package/tsconfig.lint.json +6 -0
@@ -0,0 +1,696 @@
1
+ import { IUser, IChallengeSession } from '../interfaces/entities.interface';
2
+ import { Repository, LessThan } from 'typeorm';
3
+ import { BaseChallengeSession } from '../entities';
4
+ import { randomUUID } from 'crypto';
5
+ import { AuthChallenge } from '../dto/auth-challenge.dto';
6
+ import { NAuthLogger } from '../utils/nauth-logger';
7
+ import { InternalAuthAuditService as AuthAuditService } from './auth-audit.service';
8
+ import { AuthAuditEventType } from '../enums/auth-audit-event-type.enum';
9
+ import { NAuthException } from '../exceptions/nauth.exception';
10
+ import { AuthErrorCode } from '../enums/error-codes.enum';
11
+ import { ClientInfoService } from './client-info.service';
12
+ import { NAuthConfig } from '../interfaces/config.interface';
13
+
14
+ /**
15
+ * Challenge Session Service
16
+ *
17
+ * Manages authentication challenge sessions for the challenge-response flow.
18
+ * Challenge sessions are temporary, short-lived sessions (typically 15 minutes)
19
+ * that track pending authentication challenges similar to AWS Cognito.
20
+ *
21
+ * Handles:
22
+ * - Challenge session creation and validation
23
+ * - Session expiration and cleanup
24
+ * - Attempt tracking and rate limiting
25
+ * - Secure session token generation
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * // Create a challenge session
30
+ * const session = await challengeService.createChallengeSession(
31
+ * user,
32
+ * AuthChallenge.VERIFY_EMAIL,
33
+ * { email: user.email }
34
+ * );
35
+ *
36
+ * // Validate and consume a challenge session
37
+ * const validSession = await challengeService.validateAndConsumeSession(
38
+ * sessionToken,
39
+ * AuthChallenge.VERIFY_EMAIL
40
+ * );
41
+ * ```
42
+ */
43
+ export class ChallengeService {
44
+ /**
45
+ * Default challenge session expiration time (15 minutes)
46
+ */
47
+ private readonly DEFAULT_EXPIRATION_MINUTES = 15;
48
+
49
+ /**
50
+ * Default maximum attempts per challenge session
51
+ */
52
+ private readonly DEFAULT_MAX_ATTEMPTS = 3;
53
+
54
+ constructor(
55
+ private readonly challengeSessionRepository: Repository<BaseChallengeSession>,
56
+ private readonly clientInfoService: ClientInfoService,
57
+ private readonly logger: NAuthLogger,
58
+ private readonly auditService?: AuthAuditService, // Optional - audit trail service (enabled via config.auditLogs.enabled)
59
+ private readonly config?: NAuthConfig, // Optional - config for maxAttempts
60
+ ) {}
61
+
62
+ /**
63
+ * Per-user cleanup throttle map to avoid frequent cleanup writes
64
+ */
65
+ private readonly lastCleanupByUserId: Map<number, number> = new Map();
66
+
67
+ // ============================================================================
68
+ // Challenge Session Creation
69
+ // ============================================================================
70
+
71
+ /**
72
+ * Create a new challenge session
73
+ *
74
+ * Generates a unique session token and stores challenge metadata.
75
+ * The session token is returned to the client and must be submitted
76
+ * when responding to the challenge.
77
+ *
78
+ * **Deduplication:**
79
+ * If an active (non-completed, non-expired) session already exists for the same user
80
+ * and challenge type, this method returns the existing session instead of creating
81
+ * a duplicate. This prevents:
82
+ * - Excessive `CHALLENGE_CREATED` audit events
83
+ * - Database bloat from duplicate sessions
84
+ * - User confusion from multiple active sessions for the same challenge
85
+ *
86
+ * @param user - User the challenge session belongs to
87
+ * @param challengeName - Type of challenge (VERIFY_EMAIL, VERIFY_PHONE, etc.)
88
+ * @param metadata - Challenge-specific data
89
+ * @returns Challenge session with session token (new or existing)
90
+ * @remarks Client info (ipAddress, userAgent) is automatically extracted from ClientInfoService context
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * const session = await challengeService.createChallengeSession(
95
+ * user,
96
+ * AuthChallenge.VERIFY_EMAIL,
97
+ * { email: user.email, verificationTokenId: tokenId }
98
+ * );
99
+ * // Returns: { sessionToken: 'uuid-here', expiresAt: Date, ... }
100
+ * // If called again before completion, returns same session (no duplicate audit event)
101
+ * ```
102
+ */
103
+ async createChallengeSession(
104
+ user: IUser,
105
+ challengeName: AuthChallenge,
106
+ metadata?: Record<string, unknown>,
107
+ ): Promise<IChallengeSession> {
108
+ // Get client info from context (transparent access)
109
+ const clientInfo = this.clientInfoService.get();
110
+
111
+ // ============================================================================
112
+ // DEDUPLICATION: Check for existing active challenge session
113
+ // ============================================================================
114
+ // If an active (non-completed, non-expired) session already exists for this
115
+ // user and challenge type, return it instead of creating a duplicate.
116
+ // This prevents excessive audit logging and database bloat.
117
+ const existingSession = await this.challengeSessionRepository.findOne({
118
+ where: {
119
+ userId: user.id,
120
+ challengeName,
121
+ isCompleted: false,
122
+ },
123
+ order: { createdAt: 'DESC' },
124
+ relations: ['user'],
125
+ });
126
+
127
+ if (existingSession) {
128
+ const session = existingSession as unknown as IChallengeSession;
129
+ // Get current maxAttempts from config
130
+ const currentMaxAttempts = this.config?.challenge?.maxAttempts ?? this.DEFAULT_MAX_ATTEMPTS;
131
+
132
+ // Check if session is still valid (not expired and not max attempts exceeded)
133
+ const isExpired = session.expiresAt <= new Date();
134
+ const isMaxAttemptsExceeded = session.attempts >= session.maxAttempts;
135
+
136
+ if (!isExpired && !isMaxAttemptsExceeded) {
137
+ // Update maxAttempts to match current config if different
138
+ // This ensures sessions created with old config values are updated
139
+ if (session.maxAttempts !== currentMaxAttempts) {
140
+ session.maxAttempts = currentMaxAttempts;
141
+ await this.challengeSessionRepository.save(session);
142
+ this.logger?.debug?.(
143
+ `Updated maxAttempts for existing session: user=${user.sub}, old=${session.maxAttempts}, new=${currentMaxAttempts}`,
144
+ );
145
+ }
146
+ this.logger?.debug?.(
147
+ `Reusing existing challenge session: user=${user.sub}, challenge=${challengeName}, session=${session.sessionToken}`,
148
+ );
149
+
150
+ // ============================================================================
151
+ // Audit: Record challenge reuse for complete audit trail
152
+ // ============================================================================
153
+ try {
154
+ await this.auditService?.recordEvent({
155
+ userId: user.id,
156
+ eventType: AuthAuditEventType.CHALLENGE_CREATED,
157
+ eventStatus: 'INFO',
158
+ challengeSessionId: session.id,
159
+ metadata: {
160
+ challengeName,
161
+ sessionToken: session.sessionToken,
162
+ reused: true, // Indicate this was an existing session
163
+ },
164
+ });
165
+ } catch (auditError) {
166
+ // Non-blocking: Log but continue
167
+ const errorMessage = auditError instanceof Error ? auditError.message : 'Unknown error';
168
+ this.logger?.error?.(`Failed to record CHALLENGE_CREATED (reused) audit event: ${errorMessage}`, {
169
+ error: auditError,
170
+ userId: user.id,
171
+ challengeName,
172
+ });
173
+ }
174
+
175
+ return session;
176
+ }
177
+ // If expired or max attempts exceeded, delete it and create a new one
178
+ const reason = isExpired ? 'expired' : 'max attempts exceeded';
179
+ this.logger?.debug?.(
180
+ `Existing challenge session ${reason}, creating new one: user=${user.sub}, challenge=${challengeName}`,
181
+ );
182
+ await this.challengeSessionRepository.delete({ id: session.id });
183
+ }
184
+
185
+ // Clean up any expired or completed sessions for this user (throttled)
186
+ const now = Date.now();
187
+ const lastCleanup = this.lastCleanupByUserId.get(user.id) || 0;
188
+ // Run at most once per 5 minutes per user to reduce write load
189
+ if (now - lastCleanup > 5 * 60 * 1000) {
190
+ await this.cleanupExpiredSessions(user.id);
191
+ this.lastCleanupByUserId.set(user.id, now);
192
+ }
193
+
194
+ const sessionToken = randomUUID();
195
+ const expiresAt = new Date(Date.now() + this.DEFAULT_EXPIRATION_MINUTES * 60 * 1000);
196
+
197
+ // Get maxAttempts from config or use default
198
+ const maxAttempts = this.config?.challenge?.maxAttempts ?? this.DEFAULT_MAX_ATTEMPTS;
199
+
200
+ const challengeSession = this.challengeSessionRepository.create({
201
+ userId: user.id,
202
+ challengeName,
203
+ sessionToken,
204
+ expiresAt,
205
+ metadata,
206
+ // Client info automatically extracted from ClientInfoService (transparent access)
207
+ ipAddress: clientInfo.ipAddress || null,
208
+ userAgent: clientInfo.userAgent || null,
209
+ attempts: 0, // Explicitly initialize attempts to 0
210
+ maxAttempts,
211
+ });
212
+
213
+ await this.challengeSessionRepository.save(challengeSession);
214
+
215
+ this.logger?.log?.(
216
+ `Challenge session created: user=${user.sub}, challenge=${challengeName}, maxAttempts=${maxAttempts}`,
217
+ );
218
+
219
+ // ============================================================================
220
+ // Audit: Record challenge creation
221
+ // ============================================================================
222
+ try {
223
+ await this.auditService?.recordEvent({
224
+ userId: user.id,
225
+ eventType: AuthAuditEventType.CHALLENGE_CREATED,
226
+ eventStatus: 'INFO',
227
+ challengeSessionId: (challengeSession as unknown as IChallengeSession).id,
228
+ // Client info automatically included from context (no need to pass explicitly)
229
+ metadata: {
230
+ challengeName,
231
+ sessionToken: (challengeSession as unknown as IChallengeSession).sessionToken,
232
+ },
233
+ });
234
+ } catch (auditError) {
235
+ // Non-blocking: Log but continue
236
+ const errorMessage = auditError instanceof Error ? auditError.message : 'Unknown error';
237
+ this.logger?.error?.(`Failed to record CHALLENGE_CREATED audit event: ${errorMessage}`, {
238
+ error: auditError,
239
+ userId: user.id,
240
+ challengeName,
241
+ });
242
+ }
243
+
244
+ return challengeSession as unknown as IChallengeSession;
245
+ }
246
+
247
+ // ============================================================================
248
+ // Challenge Session Validation
249
+ // ============================================================================
250
+
251
+ /**
252
+ * Validate a challenge session token for code requests
253
+ *
254
+ * Validates session for requesting new verification codes (SMS, email, etc.).
255
+ * Skips max attempts check since requesting a new code is not a verification attempt.
256
+ * This method is used internally by nauth when sending verification codes.
257
+ *
258
+ * @param sessionToken - Session token to validate
259
+ * @param expectedChallenge - Expected challenge type (optional, for additional verification)
260
+ * @returns Valid challenge session
261
+ * @throws {UnauthorizedException} If session is invalid, expired, or already completed
262
+ *
263
+ * @example
264
+ * ```typescript
265
+ * // Used internally by nauth when sending verification codes
266
+ * const session = await challengeService.validateSessionForCodeRequest(
267
+ * 'session-token-123',
268
+ * AuthChallenge.MFA_REQUIRED
269
+ * );
270
+ * ```
271
+ */
272
+ async validateSessionForCodeRequest(
273
+ sessionToken: string,
274
+ expectedChallenge?: AuthChallenge,
275
+ ): Promise<IChallengeSession> {
276
+ return this.validateSessionInternal(sessionToken, expectedChallenge, true);
277
+ }
278
+
279
+ /**
280
+ * Validate a challenge session token
281
+ *
282
+ * Checks if the session token is valid, not expired, not completed,
283
+ * and matches the expected challenge type. Does NOT consume the session.
284
+ * Enforces max attempts check for verification attempts.
285
+ *
286
+ * @param sessionToken - Session token to validate
287
+ * @param expectedChallenge - Expected challenge type (optional, for additional verification)
288
+ * @returns Valid challenge session
289
+ * @throws {UnauthorizedException} If session is invalid, expired, or already completed
290
+ *
291
+ * @example
292
+ * ```typescript
293
+ * try {
294
+ * const session = await challengeService.validateSession(
295
+ * 'session-token-123',
296
+ * AuthChallenge.VERIFY_EMAIL
297
+ * );
298
+ * // Session is valid, proceed with verification
299
+ * } catch (error) {
300
+ * // Session is invalid
301
+ * }
302
+ * ```
303
+ */
304
+ async validateSession(sessionToken: string, expectedChallenge?: AuthChallenge): Promise<IChallengeSession> {
305
+ return this.validateSessionInternal(sessionToken, expectedChallenge, false);
306
+ }
307
+
308
+ /**
309
+ * Internal method to validate challenge session
310
+ *
311
+ * @param sessionToken - Session token to validate
312
+ * @param expectedChallenge - Expected challenge type (optional)
313
+ * @param skipMaxAttemptsCheck - If true, skip max attempts check (for code requests)
314
+ * @returns Valid challenge session
315
+ * @private
316
+ */
317
+ private async validateSessionInternal(
318
+ sessionToken: string,
319
+ expectedChallenge?: AuthChallenge,
320
+ skipMaxAttemptsCheck = false,
321
+ ): Promise<IChallengeSession> {
322
+ // Load session with ALL user fields (needed for challenge determination and MFA setup)
323
+ const session = await this.challengeSessionRepository.findOne({
324
+ where: { sessionToken },
325
+ relations: ['user'],
326
+ });
327
+
328
+ if (!session) {
329
+ this.logger?.warn?.('Invalid challenge session token');
330
+ throw new NAuthException(AuthErrorCode.CHALLENGE_INVALID, 'Invalid or expired challenge session');
331
+ }
332
+
333
+ // Check expiration
334
+ const challengeSession = session as unknown as IChallengeSession;
335
+ if (challengeSession.expiresAt < new Date()) {
336
+ this.logger?.warn?.(`Expired challenge session: user=${challengeSession.user?.sub}`);
337
+ throw new NAuthException(AuthErrorCode.CHALLENGE_EXPIRED, 'Challenge session has expired');
338
+ }
339
+
340
+ // Check if already completed
341
+ if (session.isCompleted) {
342
+ this.logger?.warn?.(`Already completed challenge session: user=${challengeSession.user?.sub}`);
343
+ throw new NAuthException(AuthErrorCode.CHALLENGE_ALREADY_COMPLETED, 'Challenge has already been completed');
344
+ }
345
+
346
+ // Check max attempts (skip if requesting new code, but enforce for verification attempts)
347
+ // Ensure attempts is initialized (should be 0, but handle edge cases)
348
+ const currentAttempts = challengeSession.attempts ?? 0;
349
+ if (!skipMaxAttemptsCheck && currentAttempts >= challengeSession.maxAttempts) {
350
+ this.logger?.warn?.(
351
+ `Max attempts exceeded for challenge session: user=${challengeSession.user?.sub}, attempts=${currentAttempts}/${challengeSession.maxAttempts}`,
352
+ );
353
+ throw new NAuthException(AuthErrorCode.CHALLENGE_MAX_ATTEMPTS, 'Maximum challenge attempts exceeded');
354
+ }
355
+
356
+ // Verify challenge type if specified
357
+ if (expectedChallenge && session.challengeName !== expectedChallenge) {
358
+ this.logger?.warn?.(`Challenge type mismatch: expected=${expectedChallenge}, actual=${session.challengeName}`);
359
+ throw new NAuthException(AuthErrorCode.CHALLENGE_TYPE_MISMATCH, 'Invalid challenge type');
360
+ }
361
+
362
+ return session as unknown as IChallengeSession;
363
+ }
364
+
365
+ /**
366
+ * Increment attempt counter for a challenge session
367
+ *
368
+ * Tracks failed attempts to complete a challenge.
369
+ * Used to prevent brute-force attacks on verification codes.
370
+ *
371
+ * @param session - Challenge session to increment
372
+ * @returns Updated session
373
+ *
374
+ * @example
375
+ * ```typescript
376
+ * await challengeService.incrementAttempts(session);
377
+ * ```
378
+ */
379
+ async incrementAttempts(session: IChallengeSession): Promise<IChallengeSession> {
380
+ // ============================================================================
381
+ // CRITICAL: Atomic Increment to Prevent Race Conditions
382
+ // ============================================================================
383
+ // Use TypeORM's increment() for atomic UPDATE attempts = attempts + 1
384
+ // This is concurrency-safe even under high load:
385
+ // - Database executes: UPDATE challenge_session SET attempts = attempts + 1 WHERE id = ?
386
+ // - No read-modify-write race condition
387
+ // - Single database round-trip (better performance than SELECT + UPDATE)
388
+ // - Works across all databases (MySQL, PostgreSQL, SQLite)
389
+ await this.challengeSessionRepository.increment({ id: session.id }, 'attempts', 1);
390
+
391
+ // Reload session to get updated attempts count and user for audit logging
392
+ const freshSession = await this.challengeSessionRepository.findOne({
393
+ where: { id: session.id },
394
+ relations: ['user'],
395
+ });
396
+
397
+ if (!freshSession) {
398
+ this.logger?.warn?.(`Session not found after increment: id=${session.id}`);
399
+ throw new NAuthException(AuthErrorCode.CHALLENGE_INVALID, 'Challenge session not found');
400
+ }
401
+
402
+ const freshChallengeSession = freshSession as unknown as IChallengeSession;
403
+
404
+ this.logger?.debug?.(
405
+ `Challenge attempt incremented: session=${freshChallengeSession.sessionToken}, attempts=${freshChallengeSession.attempts}/${freshChallengeSession.maxAttempts}`,
406
+ );
407
+
408
+ // ============================================================================
409
+ // Audit: Record challenge attempt failure if max attempts exceeded
410
+ // ============================================================================
411
+ if (freshChallengeSession.attempts >= freshChallengeSession.maxAttempts) {
412
+ try {
413
+ const user = freshChallengeSession.user;
414
+ if (user) {
415
+ await this.auditService?.recordEvent({
416
+ userId: user.id,
417
+ eventType: AuthAuditEventType.CHALLENGE_ATTEMPT_FAILED,
418
+ eventStatus: 'FAILURE',
419
+ challengeSessionId: freshChallengeSession.id,
420
+ reason: 'max_attempts_exceeded',
421
+ // Client info (ipAddress, userAgent, etc.) automatically included from context
422
+ description: `Challenge attempt failed - maximum attempts (${freshChallengeSession.maxAttempts}) exceeded`,
423
+ metadata: {
424
+ challengeName: freshChallengeSession.challengeName,
425
+ attempts: freshChallengeSession.attempts,
426
+ maxAttempts: freshChallengeSession.maxAttempts,
427
+ },
428
+ });
429
+ }
430
+ } catch (auditError) {
431
+ // Non-blocking: Log but continue
432
+ const errorMessage = auditError instanceof Error ? auditError.message : 'Unknown error';
433
+ const sessionUser = freshChallengeSession.user;
434
+ this.logger?.error?.(`Failed to record CHALLENGE_ATTEMPT_FAILED audit event: ${errorMessage}`, {
435
+ error: auditError,
436
+ userId: sessionUser?.id,
437
+ challengeName: freshChallengeSession.challengeName,
438
+ });
439
+ }
440
+ }
441
+
442
+ return freshChallengeSession;
443
+ }
444
+
445
+ /**
446
+ * Validate and consume a challenge session
447
+ *
448
+ * Validates the session and marks it as completed if validation succeeds.
449
+ * This method should be called only after successful challenge completion.
450
+ *
451
+ * @param sessionToken - Session token to validate and consume
452
+ * @param expectedChallenge - Expected challenge type
453
+ * @returns Valid, completed challenge session with user
454
+ * @throws {UnauthorizedException} If session is invalid
455
+ *
456
+ * @example
457
+ * ```typescript
458
+ * const session = await challengeService.validateAndConsumeSession(
459
+ * 'session-token-123',
460
+ * AuthChallenge.VERIFY_EMAIL
461
+ * );
462
+ * // Session is now marked complete and cannot be reused
463
+ * ```
464
+ */
465
+ async validateAndConsumeSession(sessionToken: string, expectedChallenge: AuthChallenge): Promise<IChallengeSession> {
466
+ const session = await this.validateSession(sessionToken, expectedChallenge);
467
+
468
+ // Mark session as completed
469
+ session.isCompleted = true;
470
+ session.completedAt = new Date();
471
+ await this.challengeSessionRepository.save(session);
472
+
473
+ const user = session.user;
474
+ if (!user) {
475
+ throw new NAuthException(AuthErrorCode.NOT_FOUND, 'User not found in challenge session');
476
+ }
477
+ this.logger?.log?.(`Challenge session completed: user=${user.sub}, challenge=${session.challengeName}`);
478
+
479
+ // ============================================================================
480
+ // Audit: Record challenge completion
481
+ // ============================================================================
482
+ try {
483
+ // Build metadata with challenge name and MFA method (if applicable)
484
+ const auditMetadata: Record<string, unknown> = {
485
+ // Client info automatically included from context
486
+ challengeName: session.challengeName,
487
+ };
488
+
489
+ // For MFA challenges, include the MFA method used
490
+ if (
491
+ (session.challengeName === AuthChallenge.MFA_REQUIRED ||
492
+ session.challengeName === AuthChallenge.MFA_SETUP_REQUIRED) &&
493
+ session.metadata?.mfaMethod
494
+ ) {
495
+ auditMetadata.mfaMethod = session.metadata.mfaMethod;
496
+ }
497
+
498
+ await this.auditService?.recordEvent({
499
+ userId: user.id,
500
+ eventType: AuthAuditEventType.CHALLENGE_COMPLETED,
501
+ eventStatus: 'SUCCESS',
502
+ challengeSessionId: session.id,
503
+ // Client info (ipAddress, userAgent, etc.) automatically included from context
504
+ metadata: auditMetadata,
505
+ });
506
+ } catch (auditError) {
507
+ // Non-blocking: Log but continue
508
+ const errorMessage = auditError instanceof Error ? auditError.message : 'Unknown error';
509
+ this.logger?.error?.(`Failed to record CHALLENGE_COMPLETED audit event: ${errorMessage}`, {
510
+ error: auditError,
511
+ userId: user.id,
512
+ challengeName: session.challengeName,
513
+ });
514
+ }
515
+
516
+ return session;
517
+ }
518
+
519
+ /**
520
+ * Update challenge session metadata
521
+ *
522
+ * Updates the metadata field of an existing challenge session.
523
+ * Used to store additional challenge-specific data (e.g., passkey challenge).
524
+ *
525
+ * @param sessionToken - Session token to update
526
+ * @param metadata - Metadata to merge into existing metadata
527
+ * @returns Updated challenge session
528
+ * @throws {NAuthException} If session not found or invalid
529
+ *
530
+ * @example
531
+ * ```typescript
532
+ * await challengeService.updateMetadata('session-token-123', {
533
+ * passkeyChallenge: 'base64-challenge-string'
534
+ * });
535
+ * ```
536
+ */
537
+ async updateMetadata(sessionToken: string, metadata: Record<string, unknown>): Promise<IChallengeSession> {
538
+ const session = await this.validateSession(sessionToken);
539
+
540
+ // Merge new metadata with existing metadata
541
+ const existingMetadata = session.metadata || {};
542
+ const updatedMetadata = { ...existingMetadata, ...metadata };
543
+
544
+ // Update session metadata
545
+ await this.challengeSessionRepository.update({ sessionToken }, { metadata: updatedMetadata } as Record<
546
+ string,
547
+ unknown
548
+ >);
549
+
550
+ // Return updated session
551
+ const updatedSession = await this.challengeSessionRepository.findOne({
552
+ where: { sessionToken },
553
+ relations: ['user'],
554
+ });
555
+
556
+ if (!updatedSession) {
557
+ throw new NAuthException(AuthErrorCode.CHALLENGE_INVALID, 'Failed to update challenge session metadata');
558
+ }
559
+
560
+ return updatedSession as unknown as IChallengeSession;
561
+ }
562
+
563
+ // ============================================================================
564
+ // Challenge Session Cleanup
565
+ // ============================================================================
566
+
567
+ /**
568
+ * Clean up expired or completed challenge sessions for a user
569
+ *
570
+ * Removes old sessions to prevent database bloat.
571
+ * Called automatically when creating new challenge sessions.
572
+ *
573
+ * @param userId - User ID to clean up sessions for
574
+ *
575
+ * @example
576
+ * ```typescript
577
+ * await challengeService.cleanupExpiredSessions(user.id);
578
+ * ```
579
+ */
580
+ async cleanupExpiredSessions(userId: number): Promise<void> {
581
+ await this.challengeSessionRepository.delete({
582
+ userId,
583
+ expiresAt: LessThan(new Date()),
584
+ });
585
+
586
+ await this.challengeSessionRepository.delete({
587
+ userId,
588
+ isCompleted: true,
589
+ });
590
+ }
591
+
592
+ /**
593
+ * Clean up all expired challenge sessions (for all users)
594
+ *
595
+ * Should be called periodically (e.g., via cron job) to maintain
596
+ * database health.
597
+ *
598
+ * @returns Number of sessions deleted
599
+ *
600
+ * @example
601
+ * ```typescript
602
+ * // In a scheduled job
603
+ * const deleted = await challengeService.cleanupAllExpiredSessions();
604
+ * logger.log(`Cleaned up ${deleted} expired challenge sessions`);
605
+ * ```
606
+ */
607
+ async cleanupAllExpiredSessions(): Promise<number> {
608
+ const result = await this.challengeSessionRepository.delete({
609
+ expiresAt: LessThan(new Date()),
610
+ });
611
+
612
+ const deletedCount = result.affected || 0;
613
+ this.logger?.log?.(`Cleaned up ${deletedCount} expired challenge sessions`);
614
+
615
+ return deletedCount;
616
+ }
617
+
618
+ /**
619
+ * Delete challenge sessions by challenge name for a user
620
+ *
621
+ * Removes all active (not completed, not expired) challenge sessions
622
+ * of the specified type for a user. Used to clean up phantom challenges
623
+ * when user completes the requirement (e.g., sets up MFA).
624
+ *
625
+ * @param userId - Internal user ID
626
+ * @param challengeName - Challenge type to delete
627
+ * @returns Number of sessions deleted
628
+ *
629
+ * @example
630
+ * ```typescript
631
+ * // Clear MFA_SETUP_REQUIRED challenge when user sets up MFA
632
+ * const deleted = await challengeService.deleteUserChallengeSessions(
633
+ * user.id,
634
+ * AuthChallenge.MFA_SETUP_REQUIRED
635
+ * );
636
+ * ```
637
+ */
638
+ async deleteUserChallengeSessions(userId: number, challengeName: AuthChallenge): Promise<number> {
639
+ const result = await this.challengeSessionRepository.delete({
640
+ userId,
641
+ challengeName,
642
+ isCompleted: false,
643
+ });
644
+
645
+ const deletedCount = result.affected || 0;
646
+ if (deletedCount > 0) {
647
+ this.logger?.log?.(`Deleted ${deletedCount} ${challengeName} challenge session(s) for user ID ${userId}`);
648
+ }
649
+
650
+ return deletedCount;
651
+ }
652
+
653
+ // ============================================================================
654
+ // Helper Methods
655
+ // ============================================================================
656
+
657
+ /**
658
+ * Mask email address for display in challenge parameters
659
+ *
660
+ * Shows first character and domain, hides the rest.
661
+ *
662
+ * @param email - Email to mask
663
+ * @returns Masked email
664
+ *
665
+ * @example
666
+ * ```typescript
667
+ * maskEmail('john.doe@example.com')
668
+ * // Returns: 'j***@example.com'
669
+ * ```
670
+ */
671
+ maskEmail(email: string): string {
672
+ const [localPart, domain] = email.split('@');
673
+ if (!domain) return email;
674
+ return `${localPart[0]}***@${domain}`;
675
+ }
676
+
677
+ /**
678
+ * Mask phone number for display in challenge parameters
679
+ *
680
+ * Shows last 4 digits, hides the rest.
681
+ *
682
+ * @param phone - Phone to mask
683
+ * @returns Masked phone
684
+ *
685
+ * @example
686
+ * ```typescript
687
+ * maskPhone('+1234567890')
688
+ * // Returns: '***-***-7890'
689
+ * ```
690
+ */
691
+ maskPhone(phone: string): string {
692
+ const digits = phone.replace(/\D/g, '');
693
+ if (digits.length < 4) return phone;
694
+ return `***-***-${digits.slice(-4)}`;
695
+ }
696
+ }