@ackplus/nest-auth 0.1.50 → 1.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 (505) hide show
  1. package/README.md +6 -513
  2. package/eslint.config.mjs +59 -0
  3. package/jest.config.ts +10 -0
  4. package/package.json +14 -44
  5. package/project.json +86 -0
  6. package/src/index.ts +30 -0
  7. package/src/lib/admin-console/admin-console.module.ts +62 -0
  8. package/src/lib/admin-console/controllers/admin-auth.controller.ts +339 -0
  9. package/src/lib/admin-console/controllers/admin-console.controller.ts +82 -0
  10. package/src/lib/admin-console/controllers/admin-permissions.controller.ts +180 -0
  11. package/src/lib/admin-console/controllers/admin-roles.controller.ts +89 -0
  12. package/src/lib/admin-console/controllers/admin-tenants.controller.ts +68 -0
  13. package/src/lib/admin-console/controllers/admin-users.controller.ts +379 -0
  14. package/src/lib/admin-console/decorators/current-admin.decorator.ts +9 -0
  15. package/src/lib/admin-console/dto/admin-permission.dto.ts +106 -0
  16. package/src/lib/admin-console/dto/admin-role.dto.ts +45 -0
  17. package/src/lib/admin-console/dto/admin-tenant.dto.ts +43 -0
  18. package/src/lib/admin-console/dto/admin-user.dto.ts +87 -0
  19. package/src/lib/admin-console/dto/create-dashboard-admin.dto.ts +34 -0
  20. package/src/lib/admin-console/dto/login.dto.ts +10 -0
  21. package/src/lib/admin-console/dto/reset-password.dto.ts +21 -0
  22. package/src/lib/admin-console/dto/setup-admin.dto.ts +23 -0
  23. package/src/lib/admin-console/dto/signup.dto.ts +51 -0
  24. package/src/lib/admin-console/entities/admin-user.entity.ts +74 -0
  25. package/src/lib/admin-console/guards/admin-session.guard.ts +47 -0
  26. package/src/lib/admin-console/services/admin-auth.service.ts +82 -0
  27. package/src/lib/admin-console/services/admin-console-config.service.ts +62 -0
  28. package/src/lib/admin-console/services/admin-session.service.ts +106 -0
  29. package/src/lib/admin-console/services/admin-user.service.ts +96 -0
  30. package/src/lib/admin-console/static/index.html +771 -0
  31. package/src/lib/auth/auth.module.ts +58 -0
  32. package/src/lib/auth/controllers/auth.controller.ts +393 -0
  33. package/src/lib/auth/controllers/mfa.controller.ts +200 -0
  34. package/src/lib/auth/dto/credentials/email-credentials.dto.ts +24 -0
  35. package/src/lib/auth/dto/credentials/phone-credentials.dto.ts +24 -0
  36. package/src/lib/auth/dto/credentials/social-credentials.dto.ts +15 -0
  37. package/src/lib/auth/dto/index.ts +1 -0
  38. package/src/lib/auth/dto/requests/change-password.request.dto.ts +34 -0
  39. package/src/lib/auth/dto/requests/forgot-password.request.dto.ts +30 -0
  40. package/src/lib/auth/dto/requests/initialize-admin.request.dto.ts +51 -0
  41. package/src/lib/auth/dto/requests/login.request.dto.ts +65 -0
  42. package/src/lib/auth/dto/requests/refresh-token.request.dto.ts +12 -0
  43. package/src/lib/auth/dto/requests/reset-password-with-token.request.dto.ts +22 -0
  44. package/src/lib/auth/dto/requests/reset-password.request.dto.ts +50 -0
  45. package/src/lib/auth/dto/requests/send-email-verification.request.dto.ts +12 -0
  46. package/src/lib/auth/dto/requests/send-mfa-code.request.dto.ts +19 -0
  47. package/src/lib/auth/dto/requests/signup.request.dto.ts +42 -0
  48. package/src/lib/auth/dto/requests/toggle-mfa.request.dto.ts +12 -0
  49. package/src/lib/auth/dto/requests/verify-2fa.request.dto.ts +24 -0
  50. package/src/lib/auth/dto/requests/verify-email.request.dto.ts +22 -0
  51. package/src/lib/auth/dto/requests/verify-forgot-password-otp-request-dto.ts +41 -0
  52. package/src/lib/auth/dto/requests/verify-totp-setup.request.dto.ts +22 -0
  53. package/src/lib/auth/dto/responses/auth-cookie.response.dto.ts +58 -0
  54. package/src/lib/auth/dto/responses/auth-success.response.dto.ts +58 -0
  55. package/src/lib/auth/dto/responses/auth.response.dto.ts +99 -0
  56. package/src/lib/auth/dto/responses/client-config.response.dto.ts +153 -0
  57. package/src/lib/auth/dto/responses/initialize-admin.response.dto.ts +22 -0
  58. package/src/lib/auth/dto/responses/mfa-code-response.dto.ts +27 -0
  59. package/src/lib/auth/dto/responses/mfa-status.response.dto.ts +89 -0
  60. package/src/lib/auth/dto/responses/verify-otp.response.dto.ts +9 -0
  61. package/src/lib/auth/entities/mfa-secret.entity.ts +33 -0
  62. package/src/lib/auth/entities/otp.entity.ts +33 -0
  63. package/src/lib/auth/events/{logged-out-all.event.d.ts → logged-out-all.event.ts} +6 -3
  64. package/src/lib/auth/events/{logged-out.event.d.ts → logged-out.event.ts} +5 -3
  65. package/src/lib/auth/events/{password-reset-requested.event.d.ts → password-reset-requested.event.ts} +6 -3
  66. package/src/lib/auth/events/{password-reset.event.d.ts → password-reset.event.ts} +6 -3
  67. package/src/lib/auth/events/{user-2fa-verified.event.d.ts → user-2fa-verified.event.ts} +6 -3
  68. package/src/lib/auth/events/{user-logged-in.event.d.ts → user-logged-in.event.ts} +7 -3
  69. package/src/lib/auth/events/{user-refresh-token.event.d.ts → user-refresh-token.event.ts} +6 -3
  70. package/src/lib/auth/events/{user-registered.event.d.ts → user-registered.event.ts} +7 -3
  71. package/src/lib/auth/guards/auth.guard.ts +386 -0
  72. package/src/lib/auth/{index.d.ts → index.ts} +28 -1
  73. package/src/lib/auth/interceptors/refresh-token.interceptor.ts +117 -0
  74. package/src/lib/auth/services/auth.service.ts +947 -0
  75. package/src/lib/auth/services/client-config.service.ts +157 -0
  76. package/src/lib/auth/services/cookie.service.ts +43 -0
  77. package/src/lib/auth/services/mfa.service.ts +391 -0
  78. package/src/lib/auth.constants.ts +63 -0
  79. package/src/lib/core/core.module.ts +50 -0
  80. package/src/lib/core/decorators/auth.decorator.ts +38 -0
  81. package/src/lib/core/decorators/permissions.decorator.ts +17 -0
  82. package/src/lib/core/decorators/public.decorator.ts +33 -0
  83. package/src/lib/core/decorators/role.decorator.ts +12 -0
  84. package/src/lib/core/decorators/skip-mfa.decorator.ts +4 -0
  85. package/src/lib/core/dto/message.response.dto.ts +6 -0
  86. package/src/lib/core/{entities.d.ts → entities.ts} +18 -1
  87. package/src/lib/core/{index.d.ts → index.ts} +17 -0
  88. package/src/lib/core/interfaces/auth-module-options.interface.ts +211 -0
  89. package/src/lib/core/interfaces/mfa-options.interface.ts +46 -0
  90. package/src/lib/core/interfaces/otp.interface.ts +6 -0
  91. package/src/lib/core/interfaces/session-options.interface.ts +19 -0
  92. package/src/lib/core/interfaces/{token-payload.interface.d.ts → token-payload.interface.ts} +4 -1
  93. package/src/lib/core/providers/apple-auth.provider.ts +61 -0
  94. package/src/lib/core/providers/base-auth.provider.ts +74 -0
  95. package/src/lib/core/providers/email-auth.provider.ts +71 -0
  96. package/src/lib/core/providers/facebook-auth.provider.ts +55 -0
  97. package/src/lib/core/providers/github-auth.provider.ts +79 -0
  98. package/src/lib/core/providers/google-auth.provider.ts +61 -0
  99. package/src/lib/core/providers/jwt-auth.provider.ts +50 -0
  100. package/src/lib/core/providers/phone-auth.provider.ts +45 -0
  101. package/src/lib/core/services/auth-config.service.ts +184 -0
  102. package/src/lib/core/services/auth-provider-registry.service.ts +93 -0
  103. package/src/lib/core/services/{debug-logger.service.js → debug-logger.service.ts} +92 -59
  104. package/src/lib/core/services/initialization.service.ts +29 -0
  105. package/src/lib/core/services/jwt.service.ts +137 -0
  106. package/src/lib/nest-auth.module.ts +152 -0
  107. package/src/lib/permission/entities/permission.entity.ts +56 -0
  108. package/src/lib/permission/index.ts +4 -0
  109. package/src/lib/permission/permission.module.ts +14 -0
  110. package/src/lib/permission/services/permission.service.ts +233 -0
  111. package/src/lib/request-context/index.ts +2 -0
  112. package/src/lib/request-context/request-context.middleware.ts +13 -0
  113. package/src/lib/request-context/{request-context.js → request-context.ts} +51 -27
  114. package/src/lib/role/entities/role.entity.ts +103 -0
  115. package/src/lib/role/{index.d.ts → index.ts} +2 -0
  116. package/src/lib/role/role.module.ts +15 -0
  117. package/src/lib/role/services/{role.service.js → role.service.ts} +117 -52
  118. package/src/lib/session/entities/session.entity.ts +54 -0
  119. package/src/lib/session/index.ts +20 -0
  120. package/src/lib/session/interfaces/session-repository.interface.ts +58 -0
  121. package/src/lib/session/repositories/base-session.repository.ts +74 -0
  122. package/src/lib/session/repositories/memory-session.repository.ts +153 -0
  123. package/src/lib/session/repositories/redis-session.repository.ts +171 -0
  124. package/src/lib/session/repositories/typeorm-session.repository.ts +86 -0
  125. package/src/lib/session/services/session-manager.service.ts +261 -0
  126. package/src/lib/session/session.module.ts +102 -0
  127. package/src/lib/session/utils/session.util.ts +166 -0
  128. package/src/lib/tenant/entities/tenant.entity.ts +40 -0
  129. package/src/lib/tenant/events/tenant-created.event.ts +9 -0
  130. package/src/lib/tenant/events/tenant-deleted.event.ts +11 -0
  131. package/src/lib/tenant/events/{tenant-updated.event.d.ts → tenant-updated.event.ts} +6 -3
  132. package/src/lib/tenant/index.ts +9 -0
  133. package/src/lib/tenant/services/tenant.service.ts +336 -0
  134. package/src/lib/tenant/tenant.module.ts +19 -0
  135. package/src/lib/types/express.d.ts +14 -0
  136. package/src/lib/user/dto/requests/update-user.dto.ts +15 -0
  137. package/src/lib/user/entities/access-key.entity.ts +53 -0
  138. package/src/lib/user/entities/identity.entity.ts +31 -0
  139. package/src/lib/user/entities/user.entity.ts +212 -0
  140. package/src/lib/user/events/{user-created.event.d.ts → user-created.event.ts} +4 -3
  141. package/src/lib/user/events/{user-deleted.event.d.ts → user-deleted.event.ts} +6 -3
  142. package/src/lib/user/events/{user-updated.event.d.ts → user-updated.event.ts} +6 -3
  143. package/src/lib/user/index.ts +11 -0
  144. package/src/lib/user/services/access-key.service.ts +145 -0
  145. package/src/lib/user/services/{user.service.js → user.service.ts} +199 -95
  146. package/src/lib/user/user.module.ts +26 -0
  147. package/src/lib/utils/database.utils.ts +6 -0
  148. package/src/lib/utils/date.util.ts +106 -0
  149. package/src/lib/utils/device.util.ts +111 -0
  150. package/src/lib/utils/index.ts +6 -0
  151. package/src/lib/utils/otp.ts +3 -0
  152. package/src/lib/utils/security.util.ts +27 -0
  153. package/src/lib/utils/slug.util.ts +58 -0
  154. package/src/types/ms.d.ts +1 -0
  155. package/test/access-key.service.spec.ts +204 -0
  156. package/test/auth.service.spec.ts +541 -0
  157. package/test/mfa.service.spec.ts +359 -0
  158. package/test/role.service.spec.ts +418 -0
  159. package/test/tenant.service.spec.ts +218 -0
  160. package/test/test.setup.ts +66 -0
  161. package/test/user.service.spec.ts +374 -0
  162. package/tsconfig.json +17 -0
  163. package/tsconfig.lib.json +15 -0
  164. package/tsconfig.spec.json +15 -0
  165. package/tsconfig.tsbuildinfo +1 -1
  166. package/ui/.env +1 -0
  167. package/ui/.env.example +1 -0
  168. package/ui/.eslintignore +7 -0
  169. package/ui/README.md +288 -0
  170. package/ui/index.html +17 -0
  171. package/ui/package.json +34 -0
  172. package/ui/postcss.config.js +6 -0
  173. package/ui/src/App.tsx +245 -0
  174. package/ui/src/components/AuthGuard.tsx +59 -0
  175. package/ui/src/components/AuthProvider.tsx +76 -0
  176. package/ui/src/components/Button.tsx +37 -0
  177. package/ui/src/components/Card.tsx +37 -0
  178. package/ui/src/components/ErrorMessage.tsx +15 -0
  179. package/ui/src/components/FormDialog.tsx +61 -0
  180. package/ui/src/components/FormFooter.tsx +37 -0
  181. package/ui/src/components/Layout.tsx +112 -0
  182. package/ui/src/components/LoadingMessage.tsx +11 -0
  183. package/ui/src/components/Modal.tsx +97 -0
  184. package/ui/src/components/MultiSelect.tsx +145 -0
  185. package/ui/src/components/PageHeader.tsx +42 -0
  186. package/ui/src/components/PanelHeader.tsx +28 -0
  187. package/ui/src/components/PermissionInput.tsx +473 -0
  188. package/ui/src/components/SearchInput.tsx +69 -0
  189. package/ui/src/components/Select.tsx +51 -0
  190. package/ui/src/components/SwaggerUIWrapper.tsx +316 -0
  191. package/ui/src/components/Table.tsx +207 -0
  192. package/ui/src/components/Tag.tsx +9 -0
  193. package/ui/src/components/TagsInput.tsx +96 -0
  194. package/ui/src/components/admin/AdminForm.tsx +170 -0
  195. package/ui/src/components/admin/CreateAdminDialog.tsx +38 -0
  196. package/ui/src/components/auth/LoginFooter.tsx +17 -0
  197. package/ui/src/components/auth/LoginHeader.tsx +14 -0
  198. package/ui/src/components/auth/components/CodeBlock.tsx +43 -0
  199. package/ui/src/components/auth/components/CreateAccountCodeExamples.tsx +60 -0
  200. package/ui/src/components/auth/components/PasswordRequirements.tsx +16 -0
  201. package/ui/src/components/auth/components/PasswordStrengthIndicator.tsx +48 -0
  202. package/ui/src/components/auth/components/ResetPasswordCodeExamples.tsx +76 -0
  203. package/ui/src/components/auth/components/Tabs.tsx +32 -0
  204. package/ui/src/components/auth/dialogs/CreateAccountDialog.tsx +79 -0
  205. package/ui/src/components/auth/dialogs/ForgotPasswordDialog.tsx +79 -0
  206. package/ui/src/components/auth/forms/CreateAccountForm.tsx +226 -0
  207. package/ui/src/components/auth/forms/LoginForm.tsx +149 -0
  208. package/ui/src/components/auth/forms/ResetPasswordForm.tsx +202 -0
  209. package/ui/src/components/auth/types.ts +17 -0
  210. package/ui/src/components/auth/utils/security.ts +82 -0
  211. package/ui/src/components/auth/utils/utils.ts +25 -0
  212. package/ui/src/components/form/EmailField.tsx +25 -0
  213. package/ui/src/components/form/FormField.tsx +102 -0
  214. package/ui/src/components/form/FormMultiSelect.tsx +46 -0
  215. package/ui/src/components/form/FormSelect.tsx +60 -0
  216. package/ui/src/components/form/FormTagsInput.tsx +42 -0
  217. package/ui/src/components/form/FormTextarea.tsx +42 -0
  218. package/ui/src/components/form/PasswordField.tsx +93 -0
  219. package/ui/src/components/form/SecretKeyField.tsx +49 -0
  220. package/ui/src/components/permission/CreatePermissionDialog.tsx +44 -0
  221. package/ui/src/components/permission/EditPermissionDialog.tsx +55 -0
  222. package/ui/src/components/permission/PermissionForm.tsx +251 -0
  223. package/ui/src/components/role/CreateRoleDialog.tsx +45 -0
  224. package/ui/src/components/role/EditRoleDialog.tsx +55 -0
  225. package/ui/src/components/role/RoleDialog.tsx +252 -0
  226. package/ui/src/components/role/RoleForm.tsx +246 -0
  227. package/ui/src/components/tenant/CreateTenantDialog.tsx +41 -0
  228. package/ui/src/components/tenant/EditTenantDialog.tsx +52 -0
  229. package/ui/src/components/tenant/TenantForm.tsx +160 -0
  230. package/ui/src/components/user/CreateUserDialog.tsx +45 -0
  231. package/ui/src/components/user/UserDetailModal.tsx +815 -0
  232. package/ui/src/components/user/UserForm.tsx +191 -0
  233. package/ui/src/data/nest-auth.json +1687 -0
  234. package/ui/src/hooks/useApi.ts +69 -0
  235. package/ui/src/hooks/useAuth.ts +100 -0
  236. package/ui/src/hooks/useConfirm.tsx +105 -0
  237. package/ui/src/hooks/useFormFooter.tsx +42 -0
  238. package/ui/src/hooks/usePagination.ts +69 -0
  239. package/ui/src/index.css +59 -0
  240. package/ui/src/main.tsx +13 -0
  241. package/ui/src/pages/AdminsPage.tsx +178 -0
  242. package/ui/src/pages/ApiPage.tsx +89 -0
  243. package/ui/src/pages/DashboardPage.tsx +281 -0
  244. package/ui/src/pages/LoginPage.tsx +39 -0
  245. package/ui/src/pages/PermissionsPage.tsx +376 -0
  246. package/ui/src/pages/RolesPage.tsx +274 -0
  247. package/ui/src/pages/TenantsPage.tsx +221 -0
  248. package/ui/src/pages/UsersPage.tsx +387 -0
  249. package/ui/src/services/api.ts +115 -0
  250. package/ui/src/types/index.ts +136 -0
  251. package/ui/src/vite-env.d.ts +9 -0
  252. package/ui/tailwind.config.js +45 -0
  253. package/ui/tsconfig.json +24 -0
  254. package/ui/tsconfig.node.json +10 -0
  255. package/ui/vite.config.ts +37 -0
  256. package/ui/yarn.lock +3137 -0
  257. package/src/index.d.ts +0 -11
  258. package/src/index.js +0 -18
  259. package/src/index.js.map +0 -1
  260. package/src/lib/auth/auth.module.d.ts +0 -2
  261. package/src/lib/auth/auth.module.js +0 -54
  262. package/src/lib/auth/auth.module.js.map +0 -1
  263. package/src/lib/auth/controllers/auth.controller.d.ts +0 -29
  264. package/src/lib/auth/controllers/auth.controller.js +0 -206
  265. package/src/lib/auth/controllers/auth.controller.js.map +0 -1
  266. package/src/lib/auth/controllers/mfa.controller.d.ts +0 -23
  267. package/src/lib/auth/controllers/mfa.controller.js +0 -131
  268. package/src/lib/auth/controllers/mfa.controller.js.map +0 -1
  269. package/src/lib/auth/dto/index.d.ts +0 -0
  270. package/src/lib/auth/dto/index.js +0 -1
  271. package/src/lib/auth/dto/index.js.map +0 -1
  272. package/src/lib/auth/dto/requests/forgot-password.request.dto.d.ts +0 -5
  273. package/src/lib/auth/dto/requests/forgot-password.request.dto.js +0 -30
  274. package/src/lib/auth/dto/requests/forgot-password.request.dto.js.map +0 -1
  275. package/src/lib/auth/dto/requests/login.request.dto.d.ts +0 -6
  276. package/src/lib/auth/dto/requests/login.request.dto.js +0 -38
  277. package/src/lib/auth/dto/requests/login.request.dto.js.map +0 -1
  278. package/src/lib/auth/dto/requests/refresh-token.request.dto.d.ts +0 -3
  279. package/src/lib/auth/dto/requests/refresh-token.request.dto.js +0 -15
  280. package/src/lib/auth/dto/requests/refresh-token.request.dto.js.map +0 -1
  281. package/src/lib/auth/dto/requests/reset-password.request.dto.d.ts +0 -7
  282. package/src/lib/auth/dto/requests/reset-password.request.dto.js +0 -42
  283. package/src/lib/auth/dto/requests/reset-password.request.dto.js.map +0 -1
  284. package/src/lib/auth/dto/requests/send-mfa-code.request.dto.d.ts +0 -4
  285. package/src/lib/auth/dto/requests/send-mfa-code.request.dto.js +0 -16
  286. package/src/lib/auth/dto/requests/send-mfa-code.request.dto.js.map +0 -1
  287. package/src/lib/auth/dto/requests/signup.request.dto.d.ts +0 -7
  288. package/src/lib/auth/dto/requests/signup.request.dto.js +0 -37
  289. package/src/lib/auth/dto/requests/signup.request.dto.js.map +0 -1
  290. package/src/lib/auth/dto/requests/social-login.request.dto.d.ts +0 -3
  291. package/src/lib/auth/dto/requests/social-login.request.dto.js +0 -16
  292. package/src/lib/auth/dto/requests/social-login.request.dto.js.map +0 -1
  293. package/src/lib/auth/dto/requests/verify-2fa.request.dto.d.ts +0 -5
  294. package/src/lib/auth/dto/requests/verify-2fa.request.dto.js +0 -21
  295. package/src/lib/auth/dto/requests/verify-2fa.request.dto.js.map +0 -1
  296. package/src/lib/auth/dto/requests/verify-forgot-password-otp-request-dto.d.ts +0 -6
  297. package/src/lib/auth/dto/requests/verify-forgot-password-otp-request-dto.js +0 -35
  298. package/src/lib/auth/dto/requests/verify-forgot-password-otp-request-dto.js.map +0 -1
  299. package/src/lib/auth/dto/requests/verify-totp-setup.request.dto.d.ts +0 -4
  300. package/src/lib/auth/dto/requests/verify-totp-setup.request.dto.js +0 -20
  301. package/src/lib/auth/dto/requests/verify-totp-setup.request.dto.js.map +0 -1
  302. package/src/lib/auth/dto/responses/auth.response.dto.d.ts +0 -16
  303. package/src/lib/auth/dto/responses/auth.response.dto.js +0 -50
  304. package/src/lib/auth/dto/responses/auth.response.dto.js.map +0 -1
  305. package/src/lib/auth/entities/mfa-secret.entity.d.ts +0 -12
  306. package/src/lib/auth/entities/mfa-secret.entity.js +0 -50
  307. package/src/lib/auth/entities/mfa-secret.entity.js.map +0 -1
  308. package/src/lib/auth/entities/otp.entity.d.ts +0 -13
  309. package/src/lib/auth/entities/otp.entity.js +0 -50
  310. package/src/lib/auth/entities/otp.entity.js.map +0 -1
  311. package/src/lib/auth/events/logged-out-all.event.js +0 -10
  312. package/src/lib/auth/events/logged-out-all.event.js.map +0 -1
  313. package/src/lib/auth/events/logged-out.event.js +0 -10
  314. package/src/lib/auth/events/logged-out.event.js.map +0 -1
  315. package/src/lib/auth/events/password-reset-requested.event.js +0 -10
  316. package/src/lib/auth/events/password-reset-requested.event.js.map +0 -1
  317. package/src/lib/auth/events/password-reset.event.js +0 -10
  318. package/src/lib/auth/events/password-reset.event.js.map +0 -1
  319. package/src/lib/auth/events/user-2fa-verified.event.js +0 -10
  320. package/src/lib/auth/events/user-2fa-verified.event.js.map +0 -1
  321. package/src/lib/auth/events/user-logged-in.event.js +0 -10
  322. package/src/lib/auth/events/user-logged-in.event.js.map +0 -1
  323. package/src/lib/auth/events/user-refresh-token.event.js +0 -10
  324. package/src/lib/auth/events/user-refresh-token.event.js.map +0 -1
  325. package/src/lib/auth/events/user-registered.event.js +0 -10
  326. package/src/lib/auth/events/user-registered.event.js.map +0 -1
  327. package/src/lib/auth/guards/auth.guard.d.ts +0 -28
  328. package/src/lib/auth/guards/auth.guard.js +0 -304
  329. package/src/lib/auth/guards/auth.guard.js.map +0 -1
  330. package/src/lib/auth/index.js +0 -31
  331. package/src/lib/auth/index.js.map +0 -1
  332. package/src/lib/auth/services/auth.service.d.ts +0 -53
  333. package/src/lib/auth/services/auth.service.js +0 -522
  334. package/src/lib/auth/services/auth.service.js.map +0 -1
  335. package/src/lib/auth/services/cookie.service.d.ts +0 -9
  336. package/src/lib/auth/services/cookie.service.js +0 -43
  337. package/src/lib/auth/services/cookie.service.js.map +0 -1
  338. package/src/lib/auth/services/mfa.service.d.ts +0 -38
  339. package/src/lib/auth/services/mfa.service.js +0 -254
  340. package/src/lib/auth/services/mfa.service.js.map +0 -1
  341. package/src/lib/auth.constants.d.ts +0 -39
  342. package/src/lib/auth.constants.js +0 -43
  343. package/src/lib/auth.constants.js.map +0 -1
  344. package/src/lib/core/core.module.d.ts +0 -2
  345. package/src/lib/core/core.module.js +0 -53
  346. package/src/lib/core/core.module.js.map +0 -1
  347. package/src/lib/core/decorators/auth.decorator.d.ts +0 -1
  348. package/src/lib/core/decorators/auth.decorator.js +0 -8
  349. package/src/lib/core/decorators/auth.decorator.js.map +0 -1
  350. package/src/lib/core/decorators/permissions.decorator.d.ts +0 -2
  351. package/src/lib/core/decorators/permissions.decorator.js +0 -14
  352. package/src/lib/core/decorators/permissions.decorator.js.map +0 -1
  353. package/src/lib/core/decorators/role.decorator.d.ts +0 -3
  354. package/src/lib/core/decorators/role.decorator.js +0 -14
  355. package/src/lib/core/decorators/role.decorator.js.map +0 -1
  356. package/src/lib/core/decorators/skip-mfa.decorator.d.ts +0 -2
  357. package/src/lib/core/decorators/skip-mfa.decorator.js +0 -8
  358. package/src/lib/core/decorators/skip-mfa.decorator.js.map +0 -1
  359. package/src/lib/core/dto/message.response.dto.d.ts +0 -3
  360. package/src/lib/core/dto/message.response.dto.js +0 -13
  361. package/src/lib/core/dto/message.response.dto.js.map +0 -1
  362. package/src/lib/core/entities.js +0 -31
  363. package/src/lib/core/entities.js.map +0 -1
  364. package/src/lib/core/index.js +0 -27
  365. package/src/lib/core/index.js.map +0 -1
  366. package/src/lib/core/interfaces/auth-module-options.interface.d.ts +0 -62
  367. package/src/lib/core/interfaces/auth-module-options.interface.js +0 -3
  368. package/src/lib/core/interfaces/auth-module-options.interface.js.map +0 -1
  369. package/src/lib/core/interfaces/mfa-options.interface.d.ts +0 -25
  370. package/src/lib/core/interfaces/mfa-options.interface.js +0 -10
  371. package/src/lib/core/interfaces/mfa-options.interface.js.map +0 -1
  372. package/src/lib/core/interfaces/otp.interface.d.ts +0 -5
  373. package/src/lib/core/interfaces/otp.interface.js +0 -10
  374. package/src/lib/core/interfaces/otp.interface.js.map +0 -1
  375. package/src/lib/core/interfaces/session-options.interface.d.ts +0 -12
  376. package/src/lib/core/interfaces/session-options.interface.js +0 -9
  377. package/src/lib/core/interfaces/session-options.interface.js.map +0 -1
  378. package/src/lib/core/interfaces/token-payload.interface.js +0 -3
  379. package/src/lib/core/interfaces/token-payload.interface.js.map +0 -1
  380. package/src/lib/core/providers/apple-auth.provider.d.ts +0 -18
  381. package/src/lib/core/providers/apple-auth.provider.js +0 -57
  382. package/src/lib/core/providers/apple-auth.provider.js.map +0 -1
  383. package/src/lib/core/providers/base-auth.provider.d.ts +0 -26
  384. package/src/lib/core/providers/base-auth.provider.js +0 -43
  385. package/src/lib/core/providers/base-auth.provider.js.map +0 -1
  386. package/src/lib/core/providers/email-auth.provider.d.ts +0 -17
  387. package/src/lib/core/providers/email-auth.provider.js +0 -40
  388. package/src/lib/core/providers/email-auth.provider.js.map +0 -1
  389. package/src/lib/core/providers/facebook-auth.provider.d.ts +0 -18
  390. package/src/lib/core/providers/facebook-auth.provider.js +0 -56
  391. package/src/lib/core/providers/facebook-auth.provider.js.map +0 -1
  392. package/src/lib/core/providers/google-auth.provider.d.ts +0 -21
  393. package/src/lib/core/providers/google-auth.provider.js +0 -58
  394. package/src/lib/core/providers/google-auth.provider.js.map +0 -1
  395. package/src/lib/core/providers/jwt-auth.provider.d.ts +0 -33
  396. package/src/lib/core/providers/jwt-auth.provider.js +0 -50
  397. package/src/lib/core/providers/jwt-auth.provider.js.map +0 -1
  398. package/src/lib/core/providers/phone-auth.provider.d.ts +0 -18
  399. package/src/lib/core/providers/phone-auth.provider.js +0 -43
  400. package/src/lib/core/providers/phone-auth.provider.js.map +0 -1
  401. package/src/lib/core/services/auth-config.service.d.ts +0 -12
  402. package/src/lib/core/services/auth-config.service.js +0 -79
  403. package/src/lib/core/services/auth-config.service.js.map +0 -1
  404. package/src/lib/core/services/auth-provider-registry.service.d.ts +0 -24
  405. package/src/lib/core/services/auth-provider-registry.service.js +0 -71
  406. package/src/lib/core/services/auth-provider-registry.service.js.map +0 -1
  407. package/src/lib/core/services/debug-logger.service.d.ts +0 -38
  408. package/src/lib/core/services/debug-logger.service.js.map +0 -1
  409. package/src/lib/core/services/initialization.service.d.ts +0 -10
  410. package/src/lib/core/services/initialization.service.js +0 -34
  411. package/src/lib/core/services/initialization.service.js.map +0 -1
  412. package/src/lib/core/services/jwt.service.d.ts +0 -14
  413. package/src/lib/core/services/jwt.service.js +0 -92
  414. package/src/lib/core/services/jwt.service.js.map +0 -1
  415. package/src/lib/nest-auth.module.d.ts +0 -11
  416. package/src/lib/nest-auth.module.js +0 -177
  417. package/src/lib/nest-auth.module.js.map +0 -1
  418. package/src/lib/request-context/request-context.d.ts +0 -22
  419. package/src/lib/request-context/request-context.js.map +0 -1
  420. package/src/lib/request-context/request-context.middleware.d.ts +0 -4
  421. package/src/lib/request-context/request-context.middleware.js +0 -16
  422. package/src/lib/request-context/request-context.middleware.js.map +0 -1
  423. package/src/lib/role/entities/role.entity.d.ts +0 -20
  424. package/src/lib/role/entities/role.entity.js +0 -110
  425. package/src/lib/role/entities/role.entity.js.map +0 -1
  426. package/src/lib/role/index.js +0 -5
  427. package/src/lib/role/index.js.map +0 -1
  428. package/src/lib/role/role.module.d.ts +0 -2
  429. package/src/lib/role/role.module.js +0 -23
  430. package/src/lib/role/role.module.js.map +0 -1
  431. package/src/lib/role/services/role.service.d.ts +0 -20
  432. package/src/lib/role/services/role.service.js.map +0 -1
  433. package/src/lib/session/entities/session.entity.d.ts +0 -16
  434. package/src/lib/session/entities/session.entity.js +0 -63
  435. package/src/lib/session/entities/session.entity.js.map +0 -1
  436. package/src/lib/session/index.d.ts +0 -3
  437. package/src/lib/session/index.js +0 -7
  438. package/src/lib/session/index.js.map +0 -1
  439. package/src/lib/session/services/base-session.service.d.ts +0 -23
  440. package/src/lib/session/services/base-session.service.js +0 -64
  441. package/src/lib/session/services/base-session.service.js.map +0 -1
  442. package/src/lib/session/services/database-session.service.d.ts +0 -17
  443. package/src/lib/session/services/database-session.service.js +0 -51
  444. package/src/lib/session/services/database-session.service.js.map +0 -1
  445. package/src/lib/session/services/redis-session.service.d.ts +0 -20
  446. package/src/lib/session/services/redis-session.service.js +0 -117
  447. package/src/lib/session/services/redis-session.service.js.map +0 -1
  448. package/src/lib/session/session.module.d.ts +0 -2
  449. package/src/lib/session/session.module.js +0 -33
  450. package/src/lib/session/session.module.js.map +0 -1
  451. package/src/lib/tenant/entities/tenant.entity.d.ts +0 -10
  452. package/src/lib/tenant/entities/tenant.entity.js +0 -44
  453. package/src/lib/tenant/entities/tenant.entity.js.map +0 -1
  454. package/src/lib/tenant/events/tenant-created.event.d.ts +0 -8
  455. package/src/lib/tenant/events/tenant-created.event.js +0 -10
  456. package/src/lib/tenant/events/tenant-created.event.js.map +0 -1
  457. package/src/lib/tenant/events/tenant-deleted.event.d.ts +0 -8
  458. package/src/lib/tenant/events/tenant-deleted.event.js +0 -10
  459. package/src/lib/tenant/events/tenant-deleted.event.js.map +0 -1
  460. package/src/lib/tenant/events/tenant-updated.event.js +0 -10
  461. package/src/lib/tenant/events/tenant-updated.event.js.map +0 -1
  462. package/src/lib/tenant/index.d.ts +0 -1
  463. package/src/lib/tenant/index.js +0 -5
  464. package/src/lib/tenant/index.js.map +0 -1
  465. package/src/lib/tenant/services/tenant.service.d.ts +0 -26
  466. package/src/lib/tenant/services/tenant.service.js +0 -200
  467. package/src/lib/tenant/services/tenant.service.js.map +0 -1
  468. package/src/lib/tenant/tenant.module.d.ts +0 -2
  469. package/src/lib/tenant/tenant.module.js +0 -27
  470. package/src/lib/tenant/tenant.module.js.map +0 -1
  471. package/src/lib/user/dto/requests/update-user.dto.d.ts +0 -5
  472. package/src/lib/user/dto/requests/update-user.dto.js +0 -24
  473. package/src/lib/user/dto/requests/update-user.dto.js.map +0 -1
  474. package/src/lib/user/entities/access-key.entity.d.ts +0 -16
  475. package/src/lib/user/entities/access-key.entity.js +0 -63
  476. package/src/lib/user/entities/access-key.entity.js.map +0 -1
  477. package/src/lib/user/entities/identity.entity.d.ts +0 -12
  478. package/src/lib/user/entities/identity.entity.js +0 -47
  479. package/src/lib/user/entities/identity.entity.js.map +0 -1
  480. package/src/lib/user/entities/user.entity.d.ts +0 -39
  481. package/src/lib/user/entities/user.entity.js +0 -201
  482. package/src/lib/user/entities/user.entity.js.map +0 -1
  483. package/src/lib/user/events/user-created.event.js +0 -10
  484. package/src/lib/user/events/user-created.event.js.map +0 -1
  485. package/src/lib/user/events/user-deleted.event.js +0 -10
  486. package/src/lib/user/events/user-deleted.event.js.map +0 -1
  487. package/src/lib/user/events/user-updated.event.js +0 -10
  488. package/src/lib/user/events/user-updated.event.js.map +0 -1
  489. package/src/lib/user/index.d.ts +0 -3
  490. package/src/lib/user/index.js +0 -7
  491. package/src/lib/user/index.js.map +0 -1
  492. package/src/lib/user/services/access-key.service.d.ts +0 -19
  493. package/src/lib/user/services/access-key.service.js +0 -119
  494. package/src/lib/user/services/access-key.service.js.map +0 -1
  495. package/src/lib/user/services/user.service.d.ts +0 -24
  496. package/src/lib/user/services/user.service.js.map +0 -1
  497. package/src/lib/user/user.module.d.ts +0 -2
  498. package/src/lib/user/user.module.js +0 -34
  499. package/src/lib/user/user.module.js.map +0 -1
  500. package/src/lib/utils/database.utils.d.ts +0 -2
  501. package/src/lib/utils/database.utils.js +0 -8
  502. package/src/lib/utils/database.utils.js.map +0 -1
  503. package/src/lib/utils/otp.d.ts +0 -1
  504. package/src/lib/utils/otp.js +0 -7
  505. package/src/lib/utils/otp.js.map +0 -1
@@ -0,0 +1,171 @@
1
+ import { Injectable, Inject, Optional } from '@nestjs/common';
2
+ import { BaseSessionRepository } from './base-session.repository';
3
+ import { NestAuthSession } from '../entities/session.entity';
4
+ import { SessionPayload } from '../../core/interfaces/token-payload.interface';
5
+ import { v4 as uuidv4 } from 'uuid';
6
+
7
+ // Lazy load Redis to make it optional
8
+ let Redis: any;
9
+ let InjectRedis: any;
10
+
11
+ try {
12
+ Redis = require('ioredis').default || require('ioredis');
13
+ const ioredisModule = require('@nestjs-modules/ioredis');
14
+ InjectRedis = ioredisModule.InjectRedis;
15
+ } catch (e) {
16
+ // Redis is not installed, that's okay if not using Redis sessions
17
+ }
18
+
19
+ /**
20
+ * Redis implementation of session repository
21
+ * Stores sessions in Redis for fast access
22
+ *
23
+ * REQUIREMENTS:
24
+ * - npm install ioredis @nestjs-modules/ioredis
25
+ * - Configure Redis in NestAuthModule
26
+ */
27
+ @Injectable()
28
+ export class RedisSessionRepository extends BaseSessionRepository {
29
+ private readonly prefix = 'nest-auth:session:';
30
+ private readonly userSessionsPrefix = 'nest-auth:user-sessions:';
31
+ private redis: any;
32
+
33
+ constructor(
34
+ @Optional()
35
+ @Inject('REDIS_CLIENT')
36
+ redisClient?: any
37
+ ) {
38
+ super();
39
+
40
+ if (!redisClient) {
41
+ throw new Error(
42
+ 'RedisSessionRepository requires ioredis and @nestjs-modules/ioredis packages. ' +
43
+ 'Install them with: npm install ioredis @nestjs-modules/ioredis'
44
+ );
45
+ }
46
+
47
+ this.redis = redisClient;
48
+ }
49
+
50
+ private getSessionKey(sessionId: string): string {
51
+ return `${this.prefix}${sessionId}`;
52
+ }
53
+
54
+ private getUserSessionsKey(userId: string): string {
55
+ return `${this.userSessionsPrefix}${userId}`;
56
+ }
57
+
58
+ async create(session: SessionPayload): Promise<NestAuthSession> {
59
+ const sessionId = session.id || uuidv4();
60
+ const sessionKey = this.getSessionKey(sessionId);
61
+ const userSessionsKey = this.getUserSessionsKey(session.userId);
62
+
63
+ const sessionData: NestAuthSession = {
64
+ id: sessionId,
65
+ userId: session.userId,
66
+ refreshToken: session.refreshToken,
67
+ data: session.data,
68
+ expiresAt: session.expiresAt,
69
+ userAgent: session.userAgent,
70
+ deviceName: session.deviceName,
71
+ ipAddress: session.ipAddress,
72
+ lastActive: session.lastActive || new Date(),
73
+ } as NestAuthSession;
74
+
75
+ // Store session as hash
76
+ const serialized = this.serializeSession(sessionData);
77
+ await this.redis.hmset(sessionKey, serialized);
78
+
79
+ // Add to user's sessions set
80
+ await this.redis.sadd(userSessionsKey, sessionId);
81
+
82
+ // Set TTL
83
+ const ttl = Math.floor((session.expiresAt.getTime() - Date.now()) / 1000);
84
+ if (ttl > 0) {
85
+ await this.redis.expire(sessionKey, ttl);
86
+ }
87
+
88
+ return sessionData;
89
+ }
90
+
91
+ async findById(sessionId: string): Promise<NestAuthSession | null> {
92
+ const sessionKey = this.getSessionKey(sessionId);
93
+ const data = await this.redis.hgetall(sessionKey);
94
+
95
+ if (!data || Object.keys(data).length === 0) {
96
+ return null;
97
+ }
98
+
99
+ return this.deserializeSession(data);
100
+ }
101
+
102
+ async findByUserId(userId: string): Promise<NestAuthSession[]> {
103
+ const userSessionsKey = this.getUserSessionsKey(userId);
104
+ const sessionIds = await this.redis.smembers(userSessionsKey);
105
+
106
+ const sessions: NestAuthSession[] = [];
107
+ for (const sessionId of sessionIds) {
108
+ const session = await this.findById(sessionId);
109
+ if (session) {
110
+ sessions.push(session);
111
+ }
112
+ }
113
+
114
+ return sessions;
115
+ }
116
+
117
+ async findActiveByUserId(userId: string): Promise<NestAuthSession[]> {
118
+ const allSessions = await this.findByUserId(userId);
119
+ return this.filterActive(allSessions);
120
+ }
121
+
122
+ async update(sessionId: string, updates: Partial<NestAuthSession>): Promise<NestAuthSession> {
123
+ const sessionKey = this.getSessionKey(sessionId);
124
+ const serialized = this.serializeSession(updates as any);
125
+
126
+ await this.redis.hmset(sessionKey, serialized);
127
+
128
+ return await this.findById(sessionId);
129
+ }
130
+
131
+ async delete(sessionId: string): Promise<void> {
132
+ const session = await this.findById(sessionId);
133
+ if (!session) return;
134
+
135
+ const sessionKey = this.getSessionKey(sessionId);
136
+ const userSessionsKey = this.getUserSessionsKey(session.userId);
137
+
138
+ await this.redis.del(sessionKey);
139
+ await this.redis.srem(userSessionsKey, sessionId);
140
+ }
141
+
142
+ async deleteByUserId(userId: string): Promise<void> {
143
+ const userSessionsKey = this.getUserSessionsKey(userId);
144
+ const sessionIds = await this.redis.smembers(userSessionsKey);
145
+
146
+ const pipeline = this.redis.pipeline();
147
+ for (const sessionId of sessionIds) {
148
+ pipeline.del(this.getSessionKey(sessionId));
149
+ }
150
+ pipeline.del(userSessionsKey);
151
+
152
+ await pipeline.exec();
153
+ }
154
+
155
+ async deleteExpired(): Promise<number> {
156
+ // Redis automatically handles expiration via TTL
157
+ // This is a no-op for Redis, but we implement it for interface compliance
158
+ return 0;
159
+ }
160
+
161
+ async countActiveByUserId(userId: string): Promise<number> {
162
+ const activeSessions = await this.findActiveByUserId(userId);
163
+ return activeSessions.length;
164
+ }
165
+
166
+ async updateLastActive(sessionId: string): Promise<void> {
167
+ await this.update(sessionId, {
168
+ lastActive: new Date(),
169
+ } as any);
170
+ }
171
+ }
@@ -0,0 +1,86 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { InjectRepository } from '@nestjs/typeorm';
3
+ import { Repository, MoreThan, LessThan } from 'typeorm';
4
+ import { BaseSessionRepository } from './base-session.repository';
5
+ import { NestAuthSession } from '../entities/session.entity';
6
+ import { SessionPayload } from '../../core/interfaces/token-payload.interface';
7
+ import { v4 as uuidv4 } from 'uuid';
8
+
9
+ /**
10
+ * TypeORM implementation of session repository
11
+ * Stores sessions in PostgreSQL/MySQL database
12
+ */
13
+ @Injectable()
14
+ export class TypeORMSessionRepository extends BaseSessionRepository {
15
+ constructor(
16
+ @InjectRepository(NestAuthSession)
17
+ private readonly repository: Repository<NestAuthSession>,
18
+ ) {
19
+ super();
20
+ }
21
+
22
+ async create(session: SessionPayload): Promise<NestAuthSession> {
23
+ const sessionEntity = this.repository.create(session);
24
+
25
+ return await this.repository.save(sessionEntity);
26
+ }
27
+
28
+ async findById(sessionId: string): Promise<NestAuthSession | null> {
29
+ return await this.repository.findOne({
30
+ where: { id: sessionId },
31
+ relations: ['user'],
32
+ });
33
+ }
34
+
35
+ async findByUserId(userId: string): Promise<NestAuthSession[]> {
36
+ return await this.repository.find({
37
+ where: { userId },
38
+ order: { createdAt: 'DESC' },
39
+ });
40
+ }
41
+
42
+ async findActiveByUserId(userId: string): Promise<NestAuthSession[]> {
43
+ return await this.repository.find({
44
+ where: {
45
+ userId,
46
+ expiresAt: MoreThan(new Date()),
47
+ },
48
+ order: { lastActive: 'DESC' },
49
+ });
50
+ }
51
+
52
+ async update(sessionId: string, updates: Partial<NestAuthSession>): Promise<NestAuthSession> {
53
+ await this.repository.update(sessionId, updates);
54
+ return await this.findById(sessionId);
55
+ }
56
+
57
+ async delete(sessionId: string): Promise<void> {
58
+ await this.repository.delete(sessionId);
59
+ }
60
+
61
+ async deleteByUserId(userId: string): Promise<void> {
62
+ await this.repository.delete({ userId });
63
+ }
64
+
65
+ async deleteExpired(): Promise<number> {
66
+ const result = await this.repository.delete({
67
+ expiresAt: LessThan(new Date()),
68
+ });
69
+ return result.affected || 0;
70
+ }
71
+
72
+ async countActiveByUserId(userId: string): Promise<number> {
73
+ return await this.repository.count({
74
+ where: {
75
+ userId,
76
+ expiresAt: MoreThan(new Date()),
77
+ },
78
+ });
79
+ }
80
+
81
+ async updateLastActive(sessionId: string): Promise<void> {
82
+ await this.repository.update(sessionId, {
83
+ lastActive: new Date(),
84
+ });
85
+ }
86
+ }
@@ -0,0 +1,261 @@
1
+ import { Injectable, UnauthorizedException, Inject } from '@nestjs/common';
2
+ import { ISessionRepository } from '../interfaces/session-repository.interface';
3
+ import { NestAuthSession } from '../entities/session.entity';
4
+ import { SessionPayload } from '../../core/interfaces/token-payload.interface';
5
+ import { AuthModuleOptions } from '../../core/interfaces/auth-module-options.interface';
6
+ import { AuthConfigService } from '../../core/services/auth-config.service';
7
+ import { RequestContext } from '../../request-context/request-context';
8
+ import { NestAuthUser } from '../../user/entities/user.entity';
9
+ import { v4 as uuidv4 } from 'uuid';
10
+ import ms from 'ms';
11
+
12
+ export const SESSION_REPOSITORY = 'SESSION_REPOSITORY';
13
+
14
+ /**
15
+ * High-level session manager
16
+ * Handles session lifecycle using repository pattern
17
+ */
18
+ @Injectable()
19
+ export class SessionManagerService {
20
+ private options: AuthModuleOptions;
21
+ private readonly maxSessionsPerUser: number;
22
+ private readonly slidingExpiration: boolean;
23
+
24
+ constructor(
25
+ @Inject(SESSION_REPOSITORY)
26
+ private readonly repository: ISessionRepository,
27
+ ) {
28
+ this.options = AuthConfigService.getOptions();
29
+ this.maxSessionsPerUser = this.options.session?.maxSessionsPerUser || 10;
30
+ this.slidingExpiration = this.options.session?.slidingExpiration ?? true;
31
+ }
32
+
33
+ /**
34
+ * Create a new session
35
+ */
36
+ async createSession(payload: {
37
+ userId: string;
38
+ refreshToken?: string;
39
+ data?: any;
40
+ userAgent?: string;
41
+ deviceName?: string;
42
+ ipAddress?: string;
43
+ }): Promise<NestAuthSession> {
44
+ const { userId, refreshToken, data, userAgent, deviceName, ipAddress } = payload;
45
+
46
+ // Check max sessions limit
47
+ await this.enforceMaxSessions(userId);
48
+
49
+ const sessionPayload: SessionPayload = {
50
+ id: uuidv4(),
51
+ userId,
52
+ refreshToken: refreshToken || '',
53
+ data: data || {},
54
+ expiresAt: this.calculateExpiration(),
55
+ userAgent: userAgent || RequestContext.currentRequest()?.headers['user-agent'] || 'Unknown',
56
+ deviceName: deviceName || RequestContext.getDeviceInfo().deviceName,
57
+ ipAddress: ipAddress || RequestContext.getDeviceInfo().ipAddress,
58
+ lastActive: new Date(),
59
+ };
60
+
61
+ return await this.repository.create(sessionPayload);
62
+ }
63
+
64
+ /**
65
+ * Get session by ID and optionally refresh it
66
+ */
67
+ async getSession(sessionId: string, refreshSession = true): Promise<NestAuthSession> {
68
+ const session = await this.repository.findById(sessionId);
69
+
70
+ if (!session) {
71
+ throw new UnauthorizedException('Session not found');
72
+ }
73
+
74
+ // Check if expired
75
+ if (this.isExpired(session)) {
76
+ await this.repository.delete(sessionId);
77
+ throw new UnauthorizedException('Session expired');
78
+ }
79
+
80
+ // Update last active if sliding expiration enabled
81
+ if (refreshSession && this.slidingExpiration) {
82
+ await this.repository.updateLastActive(sessionId);
83
+ }
84
+
85
+ return session;
86
+ }
87
+
88
+ /**
89
+ * Get all sessions for a user
90
+ */
91
+ async getUserSessions(userId: string): Promise<NestAuthSession[]> {
92
+ return await this.repository.findByUserId(userId);
93
+ }
94
+
95
+ /**
96
+ * Get active sessions for a user
97
+ */
98
+ async getActiveSessions(userId: string): Promise<NestAuthSession[]> {
99
+ return await this.repository.findActiveByUserId(userId);
100
+ }
101
+
102
+ /**
103
+ * Update session data
104
+ */
105
+ async updateSession(sessionId: string, updates: Partial<NestAuthSession>): Promise<NestAuthSession> {
106
+ return await this.repository.update(sessionId, updates);
107
+ }
108
+
109
+ /**
110
+ * Revoke (delete) a session
111
+ */
112
+ async revokeSession(sessionId: string): Promise<void> {
113
+ await this.repository.delete(sessionId);
114
+ }
115
+
116
+ /**
117
+ * Revoke all sessions for a user
118
+ */
119
+ async revokeAllUserSessions(userId: string): Promise<void> {
120
+ await this.repository.deleteByUserId(userId);
121
+ }
122
+
123
+ /**
124
+ * Revoke all sessions except the current one
125
+ */
126
+ async revokeOtherSessions(userId: string, currentSessionId: string): Promise<void> {
127
+ const sessions = await this.repository.findByUserId(userId);
128
+
129
+ for (const session of sessions) {
130
+ if (session.id !== currentSessionId) {
131
+ await this.repository.delete(session.id);
132
+ }
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Clean up expired sessions
138
+ */
139
+ async cleanupExpiredSessions(): Promise<number> {
140
+ return await this.repository.deleteExpired();
141
+ }
142
+
143
+ /**
144
+ * Extend session expiration
145
+ */
146
+ async extendSession(sessionId: string, duration?: string): Promise<NestAuthSession> {
147
+ const expiresAt = this.calculateExpiration(duration);
148
+ return await this.repository.update(sessionId, { expiresAt } as any);
149
+ }
150
+
151
+ /**
152
+ * Validate session and return it if valid
153
+ */
154
+ async validateSession(sessionId: string): Promise<NestAuthSession | null> {
155
+ try {
156
+ return await this.getSession(sessionId, true);
157
+ } catch {
158
+ return null;
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Check if user has reached max sessions limit
164
+ */
165
+ async hasReachedMaxSessions(userId: string): Promise<boolean> {
166
+ const count = await this.repository.countActiveByUserId(userId);
167
+ return count >= this.maxSessionsPerUser;
168
+ }
169
+
170
+ /**
171
+ * Enforce max sessions per user by removing oldest sessions
172
+ */
173
+ private async enforceMaxSessions(userId: string): Promise<void> {
174
+ const activeSessions = await this.repository.findActiveByUserId(userId);
175
+
176
+ if (activeSessions.length >= this.maxSessionsPerUser) {
177
+ // Sort by lastActive (oldest first)
178
+ const sorted = activeSessions.sort((a, b) => {
179
+ const aTime = a.lastActive?.getTime() || 0;
180
+ const bTime = b.lastActive?.getTime() || 0;
181
+ return aTime - bTime;
182
+ });
183
+
184
+ // Remove oldest session(s)
185
+ const toRemove = sorted.slice(0, activeSessions.length - this.maxSessionsPerUser + 1);
186
+ for (const session of toRemove) {
187
+ await this.repository.delete(session.id);
188
+ }
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Calculate session expiration date
194
+ */
195
+ private calculateExpiration(duration?: string): Date {
196
+ const expiryDuration = duration || this.options.session?.sessionExpiry || '7d';
197
+ const milliseconds = ms(expiryDuration);
198
+ return new Date(Date.now() + milliseconds);
199
+ }
200
+
201
+ /**
202
+ * Check if session is expired
203
+ */
204
+ private isExpired(session: NestAuthSession): boolean {
205
+ if (!session.expiresAt) return false;
206
+ return new Date() > new Date(session.expiresAt);
207
+ }
208
+
209
+ /**
210
+ * Create session from user (helper method from old BaseSessionService)
211
+ * For backward compatibility with AuthService
212
+ */
213
+ async createSessionFromUser(user: NestAuthUser, extraData: { isMfaVerified?: boolean } = {}): Promise<NestAuthSession> {
214
+ const { deviceName, ipAddress, browser } = RequestContext.getDeviceInfo();
215
+ const { isMfaVerified = false } = extraData;
216
+
217
+ if (!user) {
218
+ throw new UnauthorizedException('User not found');
219
+ }
220
+
221
+ const roles = await user.getRoles();
222
+ const permissions = await user.getPermissions();
223
+
224
+ // Create session using createSession method
225
+ return await this.createSession({
226
+ userId: user.id,
227
+ data: {
228
+ user,
229
+ isMfaVerified,
230
+ roles,
231
+ permissions,
232
+ },
233
+ userAgent: [browser, deviceName].join(' - '),
234
+ ipAddress,
235
+ deviceName,
236
+ });
237
+ }
238
+
239
+ /**
240
+ * Create new session from existing session (for refresh)
241
+ * For backward compatibility with AuthService
242
+ */
243
+ async createSessionFromSession(session: NestAuthSession): Promise<NestAuthSession> {
244
+ return await this.createSession({
245
+ userId: session.userId,
246
+ refreshToken: session.refreshToken,
247
+ data: session.data,
248
+ userAgent: session.userAgent,
249
+ deviceName: session.deviceName,
250
+ ipAddress: session.ipAddress,
251
+ });
252
+ }
253
+
254
+ /**
255
+ * Get current active sessions for a user
256
+ * For backward compatibility with AuthService
257
+ */
258
+ async getCurrentSessions(userId: string): Promise<NestAuthSession[]> {
259
+ return await this.getActiveSessions(userId);
260
+ }
261
+ }
@@ -0,0 +1,102 @@
1
+ import { Module, forwardRef } from '@nestjs/common';
2
+ import { TypeOrmModule } from '@nestjs/typeorm';
3
+ import { NestAuthSession } from './entities/session.entity';
4
+ import { SessionManagerService, SESSION_REPOSITORY } from './services/session-manager.service';
5
+ import { TypeORMSessionRepository } from './repositories/typeorm-session.repository';
6
+ import { MemorySessionRepository } from './repositories/memory-session.repository';
7
+ import { CoreModule } from '../core/core.module';
8
+ import { SessionStorageType } from '../core/interfaces/session-options.interface';
9
+ import { AuthConfigService } from '../core/services/auth-config.service';
10
+
11
+ /**
12
+ * Session Module
13
+ *
14
+ * DEFAULT: Uses TypeORM (Database) for session storage
15
+ * OPTIONAL: Can use Redis if configured (requires ioredis packages)
16
+ */
17
+ @Module({
18
+ imports: [
19
+ TypeOrmModule.forFeature([NestAuthSession]),
20
+ forwardRef(() => CoreModule),
21
+ ],
22
+ providers: [
23
+ // Repository implementations
24
+ TypeORMSessionRepository,
25
+ MemorySessionRepository,
26
+
27
+ // Session Repository Provider (dynamically chooses storage)
28
+ {
29
+ provide: SESSION_REPOSITORY,
30
+ useFactory: (typeormRepo: TypeORMSessionRepository) => {
31
+ const config = AuthConfigService.getOptions();
32
+ const storageType = config.session?.storageType || SessionStorageType.DATABASE;
33
+
34
+ // Handle Redis storage
35
+ if (storageType === SessionStorageType.REDIS) {
36
+ return SessionModule.createRedisRepository(config.session?.redisUrl);
37
+ }
38
+
39
+ if (storageType === SessionStorageType.MEMORY) {
40
+ return new MemorySessionRepository();
41
+ }
42
+
43
+ // Default to database storage
44
+ return typeormRepo;
45
+ },
46
+ inject: [TypeORMSessionRepository],
47
+ },
48
+
49
+ // Session Manager
50
+ SessionManagerService,
51
+ ],
52
+ exports: [
53
+ SESSION_REPOSITORY,
54
+ SessionManagerService,
55
+ TypeORMSessionRepository,
56
+ MemorySessionRepository,
57
+ ],
58
+ })
59
+ export class SessionModule {
60
+ /**
61
+ * Create Redis repository instance
62
+ * Only called if Redis storage is configured
63
+ */
64
+ private static createRedisRepository(redisUrl?: string): any {
65
+ let RedisSessionRepository: any;
66
+ let ioredisModule: any;
67
+ let redisClient: any;
68
+
69
+ // Try to load Redis modules
70
+ try {
71
+ // Lazy load Redis repository
72
+ RedisSessionRepository = require('./repositories/redis-session.repository').RedisSessionRepository;
73
+ ioredisModule = require('@nestjs-modules/ioredis');
74
+ const Redis = require('ioredis').default || require('ioredis');
75
+
76
+ // Create Redis client
77
+ if (redisUrl) {
78
+ redisClient = new Redis(redisUrl);
79
+ } else {
80
+ redisClient = new Redis(); // Uses default localhost:6379
81
+ }
82
+
83
+ // Return repository instance
84
+ return new RedisSessionRepository(redisClient);
85
+ } catch (error) {
86
+ const errorMessage = error instanceof Error ? error.message : String(error);
87
+
88
+ if (errorMessage.includes('Cannot find module')) {
89
+ throw new Error(
90
+ '❌ Redis session storage is configured but packages are not installed.\n' +
91
+ ' Install them with: npm install ioredis @nestjs-modules/ioredis\n' +
92
+ ' Or change session.storageType to SessionStorageType.DATABASE'
93
+ );
94
+ }
95
+
96
+ throw new Error(
97
+ `❌ Failed to initialize Redis session storage: ${errorMessage}\n` +
98
+ ' Make sure Redis server is running and accessible.'
99
+ );
100
+ }
101
+ }
102
+ }