@ackplus/nest-auth 0.1.51 → 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,226 @@
1
+ import React from 'react';
2
+ import { User, AlertCircle, Check } from 'lucide-react';
3
+ import { useForm, Controller } from 'react-hook-form';
4
+ import { yupResolver } from '@hookform/resolvers/yup';
5
+ import * as yup from 'yup';
6
+ import { PasswordRequirements } from '../components/PasswordRequirements';
7
+ import { PasswordField } from '../../form/PasswordField';
8
+ import { EmailField } from '../../form/EmailField';
9
+ import { SecretKeyField } from '../../form/SecretKeyField';
10
+ import { FormField } from '../../form/FormField';
11
+
12
+ interface CreateAccountFormData {
13
+ email: string;
14
+ password: string;
15
+ name: string;
16
+ secretKey: string;
17
+ }
18
+
19
+ const createAccountSchema = yup.object({
20
+ email: yup.string().email('Invalid email address').required('Email is required').max(254),
21
+ password: yup
22
+ .string()
23
+ .required('Password is required')
24
+ .min(8, 'Password must be at least 8 characters')
25
+ .max(128, 'Password must be less than 128 characters')
26
+ .matches(/[A-Z]/, 'Password must contain at least one uppercase letter')
27
+ .matches(/[a-z]/, 'Password must contain at least one lowercase letter')
28
+ .matches(/\d/, 'Password must contain at least one number')
29
+ .matches(/[@$!%*?&]/, 'Password must contain at least one special character (@$!%*?&)'),
30
+ name: yup.string().max(100, 'Name must be less than 100 characters').optional(),
31
+ secretKey: yup
32
+ .string()
33
+ .required('Secret key is required')
34
+ .min(8, 'Secret key must be at least 8 characters')
35
+ .max(128, 'Secret key must be less than 128 characters'),
36
+ });
37
+
38
+ interface CreateAccountFormProps {
39
+ onSuccess: () => void;
40
+ onError: (error: string) => void;
41
+ error?: string;
42
+ success?: boolean;
43
+ adminApiBaseUrl: string;
44
+ }
45
+
46
+ export const CreateAccountFormComponent: React.FC<CreateAccountFormProps> = ({
47
+ onSuccess,
48
+ onError,
49
+ error,
50
+ success,
51
+ adminApiBaseUrl,
52
+ }) => {
53
+ const {
54
+ control,
55
+ handleSubmit,
56
+ formState: { errors, isSubmitting },
57
+ reset,
58
+ } = useForm<CreateAccountFormData>({
59
+ resolver: yupResolver(createAccountSchema) as any,
60
+ defaultValues: {
61
+ email: '',
62
+ password: '',
63
+ name: '',
64
+ secretKey: '',
65
+ },
66
+ });
67
+
68
+ const onSubmit = async (data: CreateAccountFormData) => {
69
+ try {
70
+ const response = await fetch(`${adminApiBaseUrl}/signup`, {
71
+ method: 'POST',
72
+ headers: { 'Content-Type': 'application/json' },
73
+ credentials: 'include',
74
+ body: JSON.stringify({
75
+ email: data.email.trim().toLowerCase(),
76
+ password: data.password,
77
+ name: data.name.trim() || undefined,
78
+ secretKey: data.secretKey,
79
+ }),
80
+ });
81
+
82
+ let responseData: any = {};
83
+ const contentType = response.headers.get('content-type');
84
+ if (contentType && contentType.includes('application/json')) {
85
+ try {
86
+ responseData = await response.json();
87
+ } catch {
88
+ // Ignore JSON parse errors
89
+ }
90
+ }
91
+
92
+ if (!response.ok) {
93
+ const errorMessage =
94
+ responseData.message ||
95
+ responseData.error ||
96
+ `Request failed with status ${response.status}`;
97
+ throw new Error(errorMessage);
98
+ }
99
+
100
+ reset();
101
+ onSuccess();
102
+ } catch (err: unknown) {
103
+ const errorMessage = err instanceof Error ? err.message : 'An error occurred. Please try again.';
104
+ onError(errorMessage);
105
+ }
106
+ };
107
+
108
+ return (
109
+ <div className="space-y-4">
110
+ <div className="p-4 bg-amber-50 border border-amber-200 rounded-lg flex items-start gap-3">
111
+ <AlertCircle className="w-5 h-5 text-amber-600 flex-shrink-0 mt-0.5" />
112
+ <div className="text-sm text-amber-800">
113
+ <p className="font-semibold mb-1">Secure Access</p>
114
+ <p>
115
+ Admin accounts can only be created using your <strong>Nest Auth Secret Key</strong> configured
116
+ in <code>adminConsole.secretKey</code>. This key is required for admin console security operations.
117
+ </p>
118
+ </div>
119
+ </div>
120
+
121
+ {success && (
122
+ <div className="p-3 bg-green-50 border border-green-200 rounded-lg flex items-start gap-2">
123
+ <Check className="w-5 h-5 text-green-600 flex-shrink-0 mt-0.5" />
124
+ <p className="text-sm text-green-600">Admin account created successfully! You can now sign in.</p>
125
+ </div>
126
+ )}
127
+
128
+ {error && (
129
+ <div className="p-3 bg-red-50 border border-red-200 rounded-lg flex items-start gap-2">
130
+ <AlertCircle className="w-5 h-5 text-red-600 flex-shrink-0 mt-0.5" />
131
+ <p className="text-sm text-red-600">{error}</p>
132
+ </div>
133
+ )}
134
+
135
+ <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
136
+ <Controller
137
+ name="secretKey"
138
+ control={control}
139
+ render={({ field }) => (
140
+ <SecretKeyField
141
+ id="create-secret-key"
142
+ label="Nest Auth Secret Key *"
143
+ value={field.value}
144
+ onChange={field.onChange}
145
+ disabled={isSubmitting}
146
+ error={errors.secretKey?.message}
147
+ helpText={
148
+ !errors.secretKey ? (
149
+ <>
150
+ Your Nest Auth secret key configured in <code>adminConsole.secretKey</code>{' '}
151
+ (used for admin console security)
152
+ </>
153
+ ) : undefined
154
+ }
155
+ />
156
+ )}
157
+ />
158
+
159
+ <Controller
160
+ name="email"
161
+ control={control}
162
+ render={({ field }) => (
163
+ <EmailField
164
+ id="create-email"
165
+ label="Email Address *"
166
+ value={field.value}
167
+ onChange={field.onChange}
168
+ disabled={isSubmitting}
169
+ error={errors.email?.message}
170
+ autoComplete="username"
171
+ />
172
+ )}
173
+ />
174
+
175
+
176
+ <Controller
177
+ name="name"
178
+ control={control}
179
+ render={({ field }) => (
180
+ <FormField
181
+ startIcon={<User className="h-5 w-5 text-gray-400" />}
182
+ label="Name (Optional)"
183
+ id="create-name"
184
+ value={field.value}
185
+ onChange={field.onChange}
186
+ disabled={isSubmitting}
187
+ placeholder="Admin User"
188
+ error={errors.name?.message}
189
+ />
190
+ )}
191
+ />
192
+
193
+
194
+ <Controller
195
+ name="password"
196
+ control={control}
197
+ render={({ field }) => (
198
+ <PasswordField
199
+ id="create-password"
200
+ label="Password *"
201
+ value={field.value}
202
+ onChange={field.onChange}
203
+ disabled={isSubmitting}
204
+ error={errors.password?.message}
205
+ showGenerateButton={true}
206
+ showStrengthIndicator={true}
207
+ />
208
+ )}
209
+ />
210
+
211
+ <PasswordRequirements />
212
+
213
+ <button type="submit" disabled={isSubmitting} className="w-full btn-primary py-3 text-base">
214
+ {isSubmitting ? (
215
+ <span className="flex items-center justify-center gap-2">
216
+ <div className="animate-spin h-5 w-5 border-2 border-white border-t-transparent rounded-full" />
217
+ Creating account...
218
+ </span>
219
+ ) : (
220
+ 'Create Admin Account'
221
+ )}
222
+ </button>
223
+ </form>
224
+ </div>
225
+ );
226
+ };
@@ -0,0 +1,149 @@
1
+ import React, { useState } from 'react';
2
+ import { AlertCircle } from 'lucide-react';
3
+ import { useForm, Controller } from 'react-hook-form';
4
+ import { yupResolver } from '@hookform/resolvers/yup';
5
+ import * as yup from 'yup';
6
+ import { PasswordField } from '../../form/PasswordField';
7
+ import { EmailField } from '../../form/EmailField';
8
+ import type { LoginForm } from '../types';
9
+
10
+ const loginSchema = yup.object({
11
+ email: yup.string().email('Invalid email address').required('Email is required'),
12
+ password: yup.string().required('Password is required'),
13
+ });
14
+
15
+ interface LoginFormProps {
16
+ onSubmit: (credentials: LoginForm) => Promise<void>;
17
+ error?: string | null;
18
+ onOpenCreateAccount: () => void;
19
+ onOpenForgotPassword: () => void;
20
+ }
21
+
22
+ export const LoginFormComponent: React.FC<LoginFormProps> = ({
23
+ onSubmit: onSubmitProp,
24
+ error: externalError,
25
+ onOpenCreateAccount,
26
+ onOpenForgotPassword,
27
+ }) => {
28
+ const [internalError, setInternalError] = useState('');
29
+
30
+ const {
31
+ control,
32
+ handleSubmit,
33
+ formState: { isSubmitting },
34
+ reset,
35
+ } = useForm<LoginForm>({
36
+ resolver: yupResolver(loginSchema) as any,
37
+ defaultValues: {
38
+ email: '',
39
+ password: '',
40
+ },
41
+ });
42
+
43
+ const onSubmit = async (data: LoginForm) => {
44
+ try {
45
+ setInternalError('');
46
+ await onSubmitProp({
47
+ email: data.email.trim().toLowerCase(),
48
+ password: data.password,
49
+ });
50
+ reset();
51
+ } catch (err: unknown) {
52
+ const errorMessage = err instanceof Error ? err.message : 'An error occurred. Please try again.';
53
+ setInternalError(errorMessage);
54
+ }
55
+ };
56
+
57
+ const error = externalError || internalError;
58
+
59
+ return (
60
+ <div className="bg-white rounded-xl shadow-2xl p-8 animate-slide-up">
61
+ <div className="mb-6">
62
+ <h2 className="text-2xl font-bold text-gray-900">Welcome back</h2>
63
+ <p className="text-gray-600 mt-1">Sign in to your admin account</p>
64
+ </div>
65
+
66
+ {error && (
67
+ <div className="p-3 bg-red-50 border border-red-200 rounded-lg flex items-start gap-2 mb-4">
68
+ <AlertCircle className="w-5 h-5 text-red-600 flex-shrink-0 mt-0.5" />
69
+ <p className="text-sm text-red-600">{error}</p>
70
+ </div>
71
+ )}
72
+
73
+ <form onSubmit={handleSubmit(onSubmit)} className="space-y-5">
74
+ <Controller
75
+ name="email"
76
+ control={control}
77
+ render={({ field }) => (
78
+ <EmailField
79
+ id="email"
80
+ label="Email Address"
81
+ value={field.value}
82
+ onChange={field.onChange}
83
+ disabled={isSubmitting}
84
+ placeholder="admin@example.com"
85
+ autoComplete="username"
86
+ />
87
+ )}
88
+ />
89
+
90
+ <div>
91
+ <Controller
92
+ name="password"
93
+ control={control}
94
+ render={({ field }) => (
95
+ <PasswordField
96
+ id="password"
97
+ label="Password"
98
+ value={field.value}
99
+ onChange={field.onChange}
100
+ disabled={isSubmitting}
101
+ placeholder="••••••••"
102
+ autoComplete="current-password"
103
+ />
104
+ )}
105
+ />
106
+ <div className="mt-2 text-right">
107
+ <button
108
+ type="button"
109
+ onClick={onOpenForgotPassword}
110
+ className="text-sm text-primary-600 hover:text-primary-700 font-medium"
111
+ >
112
+ Forgot password?
113
+ </button>
114
+ </div>
115
+ </div>
116
+
117
+ <button type="submit" disabled={isSubmitting} className="w-full btn-primary py-3 text-base">
118
+ {isSubmitting ? (
119
+ <span className="flex items-center justify-center gap-2">
120
+ <div className="animate-spin h-5 w-5 border-2 border-white border-t-transparent rounded-full" />
121
+ Signing in...
122
+ </span>
123
+ ) : (
124
+ 'Sign In'
125
+ )}
126
+ </button>
127
+ </form>
128
+
129
+ <div className="mt-6">
130
+ <div className="relative">
131
+ <div className="absolute inset-0 flex items-center">
132
+ <div className="w-full border-t border-gray-300" />
133
+ </div>
134
+ <div className="relative flex justify-center text-sm">
135
+ <span className="px-2 bg-white text-gray-500">New to this app?</span>
136
+ </div>
137
+ </div>
138
+
139
+ <button
140
+ type="button"
141
+ onClick={onOpenCreateAccount}
142
+ className="mt-4 w-full btn-secondary py-3 text-base"
143
+ >
144
+ Create Admin Account
145
+ </button>
146
+ </div>
147
+ </div>
148
+ );
149
+ };
@@ -0,0 +1,202 @@
1
+ import React from 'react';
2
+ import { AlertCircle, Check } from 'lucide-react';
3
+ import { useForm, Controller } from 'react-hook-form';
4
+ import { yupResolver } from '@hookform/resolvers/yup';
5
+ import * as yup from 'yup';
6
+ import { PasswordRequirements } from '../components/PasswordRequirements';
7
+ import { PasswordField } from '../../form/PasswordField';
8
+ import { EmailField } from '../../form/EmailField';
9
+ import { SecretKeyField } from '../../form/SecretKeyField';
10
+
11
+ interface ResetPasswordFormData {
12
+ email: string;
13
+ secretKey: string;
14
+ newPassword: string;
15
+ }
16
+
17
+ const resetPasswordSchema = yup.object({
18
+ email: yup.string().email('Invalid email address').required('Email is required').max(254),
19
+ secretKey: yup
20
+ .string()
21
+ .required('Secret key is required')
22
+ .min(8, 'Secret key must be at least 8 characters')
23
+ .max(128, 'Secret key must be less than 128 characters'),
24
+ newPassword: yup
25
+ .string()
26
+ .required('Password is required')
27
+ .min(8, 'Password must be at least 8 characters')
28
+ .max(128, 'Password must be less than 128 characters')
29
+ .matches(/[A-Z]/, 'Password must contain at least one uppercase letter')
30
+ .matches(/[a-z]/, 'Password must contain at least one lowercase letter')
31
+ .matches(/\d/, 'Password must contain at least one number')
32
+ .matches(/[@$!%*?&]/, 'Password must contain at least one special character (@$!%*?&)'),
33
+ });
34
+
35
+ interface ResetPasswordFormProps {
36
+ onSuccess: () => void;
37
+ onError: (error: string) => void;
38
+ error?: string;
39
+ success?: boolean;
40
+ adminApiBaseUrl: string;
41
+ }
42
+
43
+ export const ResetPasswordFormComponent: React.FC<ResetPasswordFormProps> = ({
44
+ onSuccess,
45
+ onError,
46
+ error,
47
+ success,
48
+ adminApiBaseUrl,
49
+ }) => {
50
+ const {
51
+ control,
52
+ handleSubmit,
53
+ formState: { errors, isSubmitting },
54
+ reset,
55
+ } = useForm<ResetPasswordFormData>({
56
+ resolver: yupResolver(resetPasswordSchema) as any,
57
+ defaultValues: {
58
+ email: '',
59
+ secretKey: '',
60
+ newPassword: '',
61
+ },
62
+ });
63
+
64
+ const onSubmit = async (data: ResetPasswordFormData) => {
65
+ try {
66
+ const response = await fetch(`${adminApiBaseUrl}/reset-password`, {
67
+ method: 'POST',
68
+ headers: { 'Content-Type': 'application/json' },
69
+ credentials: 'include',
70
+ body: JSON.stringify({
71
+ email: data.email.trim().toLowerCase(),
72
+ secretKey: data.secretKey,
73
+ newPassword: data.newPassword,
74
+ }),
75
+ });
76
+
77
+ let responseData: any = {};
78
+ const contentType = response.headers.get('content-type');
79
+ if (contentType && contentType.includes('application/json')) {
80
+ try {
81
+ responseData = await response.json();
82
+ } catch {
83
+ // Ignore JSON parse errors
84
+ }
85
+ }
86
+
87
+ if (!response.ok) {
88
+ const errorMessage =
89
+ responseData.message ||
90
+ responseData.error ||
91
+ `Request failed with status ${response.status}`;
92
+ throw new Error(errorMessage);
93
+ }
94
+
95
+ reset();
96
+ onSuccess();
97
+ } catch (err: unknown) {
98
+ const errorMessage = err instanceof Error ? err.message : 'An error occurred. Please try again.';
99
+ onError(errorMessage);
100
+ }
101
+ };
102
+
103
+ return (
104
+ <div className="space-y-4">
105
+ <div className="p-4 bg-amber-50 border border-amber-200 rounded-lg flex items-start gap-3">
106
+ <AlertCircle className="w-5 h-5 text-amber-600 flex-shrink-0 mt-0.5" />
107
+ <div className="text-sm text-amber-800">
108
+ <p className="font-semibold mb-1">Security Required</p>
109
+ <p>
110
+ Password reset requires your <strong>Nest Auth Secret Key</strong> configured in{' '}
111
+ <code>adminConsole.secretKey</code>.
112
+ </p>
113
+ </div>
114
+ </div>
115
+
116
+ {success && (
117
+ <div className="p-3 bg-green-50 border border-green-200 rounded-lg flex items-start gap-2">
118
+ <Check className="w-5 h-5 text-green-600 flex-shrink-0 mt-0.5" />
119
+ <p className="text-sm text-green-600">Password reset successfully! You can now sign in with your new password.</p>
120
+ </div>
121
+ )}
122
+
123
+ {error && (
124
+ <div className="p-3 bg-red-50 border border-red-200 rounded-lg flex items-start gap-2">
125
+ <AlertCircle className="w-5 h-5 text-red-600 flex-shrink-0 mt-0.5" />
126
+ <p className="text-sm text-red-600">{error}</p>
127
+ </div>
128
+ )}
129
+
130
+ <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
131
+ <Controller
132
+ name="email"
133
+ control={control}
134
+ render={({ field }) => (
135
+ <EmailField
136
+ id="reset-email"
137
+ label="Email Address *"
138
+ value={field.value}
139
+ onChange={field.onChange}
140
+ disabled={isSubmitting}
141
+ error={errors.email?.message}
142
+ autoComplete="username"
143
+ />
144
+ )}
145
+ />
146
+
147
+ <Controller
148
+ name="secretKey"
149
+ control={control}
150
+ render={({ field }) => (
151
+ <SecretKeyField
152
+ id="reset-secret-key"
153
+ label="Nest Auth Secret Key *"
154
+ value={field.value}
155
+ onChange={field.onChange}
156
+ disabled={isSubmitting}
157
+ error={errors.secretKey?.message}
158
+ helpText={
159
+ !errors.secretKey ? (
160
+ <>
161
+ Your Nest Auth secret key configured in <code>adminConsole.secretKey</code>{' '}
162
+ (used for admin console security)
163
+ </>
164
+ ) : undefined
165
+ }
166
+ />
167
+ )}
168
+ />
169
+
170
+ <Controller
171
+ name="newPassword"
172
+ control={control}
173
+ render={({ field }) => (
174
+ <PasswordField
175
+ id="reset-new-password"
176
+ label="New Password *"
177
+ value={field.value}
178
+ onChange={field.onChange}
179
+ disabled={isSubmitting}
180
+ error={errors.newPassword?.message}
181
+ showGenerateButton={true}
182
+ showStrengthIndicator={true}
183
+ />
184
+ )}
185
+ />
186
+
187
+ <PasswordRequirements />
188
+
189
+ <button type="submit" disabled={isSubmitting} className="w-full btn-primary py-3 text-base">
190
+ {isSubmitting ? (
191
+ <span className="flex items-center justify-center gap-2">
192
+ <div className="animate-spin h-5 w-5 border-2 border-white border-t-transparent rounded-full" />
193
+ Resetting password...
194
+ </span>
195
+ ) : (
196
+ 'Reset Password'
197
+ )}
198
+ </button>
199
+ </form>
200
+ </div>
201
+ );
202
+ };
@@ -0,0 +1,17 @@
1
+ export interface LoginForm {
2
+ email: string;
3
+ password: string;
4
+ }
5
+
6
+ export interface CreateAccountForm {
7
+ email: string;
8
+ password: string;
9
+ name: string;
10
+ secretKey: string; // Backend field name - UI displays as "Nest Auth Secret Key"
11
+ }
12
+
13
+ export interface ResetPasswordForm {
14
+ email: string;
15
+ secretKey: string; // Backend field name - UI displays as "Nest Auth Secret Key"
16
+ newPassword: string;
17
+ }
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Security utilities for authentication forms
3
+ */
4
+
5
+ /**
6
+ * Calculates password strength for display
7
+ */
8
+ export const calculatePasswordStrength = (password: string): 'weak' | 'medium' | 'strong' | null => {
9
+ if (!password || password.length === 0) {
10
+ return null;
11
+ }
12
+
13
+ // Check for required character types
14
+ const hasUpperCase = /[A-Z]/.test(password);
15
+ const hasLowerCase = /[a-z]/.test(password);
16
+ const hasNumber = /\d/.test(password);
17
+ const hasSpecialChar = /[@$!%*?&]/.test(password);
18
+
19
+ const charVariety = [hasUpperCase, hasLowerCase, hasNumber, hasSpecialChar].filter(Boolean).length;
20
+
21
+ if (password.length >= 12 && charVariety === 4) {
22
+ return 'strong';
23
+ } else if (password.length >= 10 || charVariety >= 3) {
24
+ return 'medium';
25
+ }
26
+
27
+ return 'weak';
28
+ };
29
+
30
+ /**
31
+ * Generates a secure random password that meets validation requirements
32
+ * @param length - Desired password length (default: 16, min: 8, max: 128)
33
+ * @returns A secure random password with uppercase, lowercase, numbers, and special characters
34
+ */
35
+ export const generateRandomPassword = (length: number = 16): string => {
36
+ // Ensure length is within valid range
37
+ const validLength = Math.max(8, Math.min(length, 128));
38
+
39
+ // Character sets
40
+ const uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
41
+ const lowercase = 'abcdefghijklmnopqrstuvwxyz';
42
+ const numbers = '0123456789';
43
+ const special = '@$!%*?&';
44
+ const allChars = uppercase + lowercase + numbers + special;
45
+
46
+ // Use crypto.getRandomValues if available (more secure), fallback to Math.random
47
+ // Use rejection sampling to avoid modulo bias
48
+ const getRandomValue = (max: number): number => {
49
+ if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
50
+ let value: number;
51
+ const maxValid = Math.floor(0xFFFFFFFF / max) * max;
52
+ do {
53
+ const array = new Uint32Array(1);
54
+ crypto.getRandomValues(array);
55
+ value = array[0];
56
+ } while (value >= maxValid);
57
+ return value % max;
58
+ }
59
+ return Math.floor(Math.random() * max);
60
+ };
61
+
62
+ // Ensure at least one character from each required set
63
+ let password = '';
64
+ password += uppercase[getRandomValue(uppercase.length)];
65
+ password += lowercase[getRandomValue(lowercase.length)];
66
+ password += numbers[getRandomValue(numbers.length)];
67
+ password += special[getRandomValue(special.length)];
68
+
69
+ // Fill the rest with random characters
70
+ for (let i = password.length; i < validLength; i++) {
71
+ password += allChars[getRandomValue(allChars.length)];
72
+ }
73
+
74
+ // Shuffle the password to avoid predictable pattern
75
+ const passwordArray = password.split('');
76
+ for (let i = passwordArray.length - 1; i > 0; i--) {
77
+ const j = getRandomValue(i + 1);
78
+ [passwordArray[i], passwordArray[j]] = [passwordArray[j], passwordArray[i]];
79
+ }
80
+
81
+ return passwordArray.join('');
82
+ };