@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.
- package/README.md +6 -513
- package/eslint.config.mjs +59 -0
- package/jest.config.ts +10 -0
- package/package.json +14 -44
- package/project.json +86 -0
- package/src/index.ts +30 -0
- package/src/lib/admin-console/admin-console.module.ts +62 -0
- package/src/lib/admin-console/controllers/admin-auth.controller.ts +339 -0
- package/src/lib/admin-console/controllers/admin-console.controller.ts +82 -0
- package/src/lib/admin-console/controllers/admin-permissions.controller.ts +180 -0
- package/src/lib/admin-console/controllers/admin-roles.controller.ts +89 -0
- package/src/lib/admin-console/controllers/admin-tenants.controller.ts +68 -0
- package/src/lib/admin-console/controllers/admin-users.controller.ts +379 -0
- package/src/lib/admin-console/decorators/current-admin.decorator.ts +9 -0
- package/src/lib/admin-console/dto/admin-permission.dto.ts +106 -0
- package/src/lib/admin-console/dto/admin-role.dto.ts +45 -0
- package/src/lib/admin-console/dto/admin-tenant.dto.ts +43 -0
- package/src/lib/admin-console/dto/admin-user.dto.ts +87 -0
- package/src/lib/admin-console/dto/create-dashboard-admin.dto.ts +34 -0
- package/src/lib/admin-console/dto/login.dto.ts +10 -0
- package/src/lib/admin-console/dto/reset-password.dto.ts +21 -0
- package/src/lib/admin-console/dto/setup-admin.dto.ts +23 -0
- package/src/lib/admin-console/dto/signup.dto.ts +51 -0
- package/src/lib/admin-console/entities/admin-user.entity.ts +74 -0
- package/src/lib/admin-console/guards/admin-session.guard.ts +47 -0
- package/src/lib/admin-console/services/admin-auth.service.ts +82 -0
- package/src/lib/admin-console/services/admin-console-config.service.ts +62 -0
- package/src/lib/admin-console/services/admin-session.service.ts +106 -0
- package/src/lib/admin-console/services/admin-user.service.ts +96 -0
- package/src/lib/admin-console/static/index.html +771 -0
- package/src/lib/auth/auth.module.ts +58 -0
- package/src/lib/auth/controllers/auth.controller.ts +393 -0
- package/src/lib/auth/controllers/mfa.controller.ts +200 -0
- package/src/lib/auth/dto/credentials/email-credentials.dto.ts +24 -0
- package/src/lib/auth/dto/credentials/phone-credentials.dto.ts +24 -0
- package/src/lib/auth/dto/credentials/social-credentials.dto.ts +15 -0
- package/src/lib/auth/dto/index.ts +1 -0
- package/src/lib/auth/dto/requests/change-password.request.dto.ts +34 -0
- package/src/lib/auth/dto/requests/forgot-password.request.dto.ts +30 -0
- package/src/lib/auth/dto/requests/initialize-admin.request.dto.ts +51 -0
- package/src/lib/auth/dto/requests/login.request.dto.ts +65 -0
- package/src/lib/auth/dto/requests/refresh-token.request.dto.ts +12 -0
- package/src/lib/auth/dto/requests/reset-password-with-token.request.dto.ts +22 -0
- package/src/lib/auth/dto/requests/reset-password.request.dto.ts +50 -0
- package/src/lib/auth/dto/requests/send-email-verification.request.dto.ts +12 -0
- package/src/lib/auth/dto/requests/send-mfa-code.request.dto.ts +19 -0
- package/src/lib/auth/dto/requests/signup.request.dto.ts +42 -0
- package/src/lib/auth/dto/requests/toggle-mfa.request.dto.ts +12 -0
- package/src/lib/auth/dto/requests/verify-2fa.request.dto.ts +24 -0
- package/src/lib/auth/dto/requests/verify-email.request.dto.ts +22 -0
- package/src/lib/auth/dto/requests/verify-forgot-password-otp-request-dto.ts +41 -0
- package/src/lib/auth/dto/requests/verify-totp-setup.request.dto.ts +22 -0
- package/src/lib/auth/dto/responses/auth-cookie.response.dto.ts +58 -0
- package/src/lib/auth/dto/responses/auth-success.response.dto.ts +58 -0
- package/src/lib/auth/dto/responses/auth.response.dto.ts +99 -0
- package/src/lib/auth/dto/responses/client-config.response.dto.ts +153 -0
- package/src/lib/auth/dto/responses/initialize-admin.response.dto.ts +22 -0
- package/src/lib/auth/dto/responses/mfa-code-response.dto.ts +27 -0
- package/src/lib/auth/dto/responses/mfa-status.response.dto.ts +89 -0
- package/src/lib/auth/dto/responses/verify-otp.response.dto.ts +9 -0
- package/src/lib/auth/entities/mfa-secret.entity.ts +33 -0
- package/src/lib/auth/entities/otp.entity.ts +33 -0
- package/src/lib/auth/events/{logged-out-all.event.d.ts → logged-out-all.event.ts} +6 -3
- package/src/lib/auth/events/{logged-out.event.d.ts → logged-out.event.ts} +5 -3
- package/src/lib/auth/events/{password-reset-requested.event.d.ts → password-reset-requested.event.ts} +6 -3
- package/src/lib/auth/events/{password-reset.event.d.ts → password-reset.event.ts} +6 -3
- package/src/lib/auth/events/{user-2fa-verified.event.d.ts → user-2fa-verified.event.ts} +6 -3
- package/src/lib/auth/events/{user-logged-in.event.d.ts → user-logged-in.event.ts} +7 -3
- package/src/lib/auth/events/{user-refresh-token.event.d.ts → user-refresh-token.event.ts} +6 -3
- package/src/lib/auth/events/{user-registered.event.d.ts → user-registered.event.ts} +7 -3
- package/src/lib/auth/guards/auth.guard.ts +386 -0
- package/src/lib/auth/{index.d.ts → index.ts} +28 -1
- package/src/lib/auth/interceptors/refresh-token.interceptor.ts +117 -0
- package/src/lib/auth/services/auth.service.ts +947 -0
- package/src/lib/auth/services/client-config.service.ts +157 -0
- package/src/lib/auth/services/cookie.service.ts +43 -0
- package/src/lib/auth/services/mfa.service.ts +391 -0
- package/src/lib/auth.constants.ts +63 -0
- package/src/lib/core/core.module.ts +50 -0
- package/src/lib/core/decorators/auth.decorator.ts +38 -0
- package/src/lib/core/decorators/permissions.decorator.ts +17 -0
- package/src/lib/core/decorators/public.decorator.ts +33 -0
- package/src/lib/core/decorators/role.decorator.ts +12 -0
- package/src/lib/core/decorators/skip-mfa.decorator.ts +4 -0
- package/src/lib/core/dto/message.response.dto.ts +6 -0
- package/src/lib/core/{entities.d.ts → entities.ts} +18 -1
- package/src/lib/core/{index.d.ts → index.ts} +17 -0
- package/src/lib/core/interfaces/auth-module-options.interface.ts +211 -0
- package/src/lib/core/interfaces/mfa-options.interface.ts +46 -0
- package/src/lib/core/interfaces/otp.interface.ts +6 -0
- package/src/lib/core/interfaces/session-options.interface.ts +19 -0
- package/src/lib/core/interfaces/{token-payload.interface.d.ts → token-payload.interface.ts} +4 -1
- package/src/lib/core/providers/apple-auth.provider.ts +61 -0
- package/src/lib/core/providers/base-auth.provider.ts +74 -0
- package/src/lib/core/providers/email-auth.provider.ts +71 -0
- package/src/lib/core/providers/facebook-auth.provider.ts +55 -0
- package/src/lib/core/providers/github-auth.provider.ts +79 -0
- package/src/lib/core/providers/google-auth.provider.ts +61 -0
- package/src/lib/core/providers/jwt-auth.provider.ts +50 -0
- package/src/lib/core/providers/phone-auth.provider.ts +45 -0
- package/src/lib/core/services/auth-config.service.ts +184 -0
- package/src/lib/core/services/auth-provider-registry.service.ts +93 -0
- package/src/lib/core/services/{debug-logger.service.js → debug-logger.service.ts} +92 -59
- package/src/lib/core/services/initialization.service.ts +29 -0
- package/src/lib/core/services/jwt.service.ts +137 -0
- package/src/lib/nest-auth.module.ts +152 -0
- package/src/lib/permission/entities/permission.entity.ts +56 -0
- package/src/lib/permission/index.ts +4 -0
- package/src/lib/permission/permission.module.ts +14 -0
- package/src/lib/permission/services/permission.service.ts +233 -0
- package/src/lib/request-context/index.ts +2 -0
- package/src/lib/request-context/request-context.middleware.ts +13 -0
- package/src/lib/request-context/{request-context.js → request-context.ts} +51 -27
- package/src/lib/role/entities/role.entity.ts +103 -0
- package/src/lib/role/{index.d.ts → index.ts} +2 -0
- package/src/lib/role/role.module.ts +15 -0
- package/src/lib/role/services/{role.service.js → role.service.ts} +117 -52
- package/src/lib/session/entities/session.entity.ts +54 -0
- package/src/lib/session/index.ts +20 -0
- package/src/lib/session/interfaces/session-repository.interface.ts +58 -0
- package/src/lib/session/repositories/base-session.repository.ts +74 -0
- package/src/lib/session/repositories/memory-session.repository.ts +153 -0
- package/src/lib/session/repositories/redis-session.repository.ts +171 -0
- package/src/lib/session/repositories/typeorm-session.repository.ts +86 -0
- package/src/lib/session/services/session-manager.service.ts +261 -0
- package/src/lib/session/session.module.ts +102 -0
- package/src/lib/session/utils/session.util.ts +166 -0
- package/src/lib/tenant/entities/tenant.entity.ts +40 -0
- package/src/lib/tenant/events/tenant-created.event.ts +9 -0
- package/src/lib/tenant/events/tenant-deleted.event.ts +11 -0
- package/src/lib/tenant/events/{tenant-updated.event.d.ts → tenant-updated.event.ts} +6 -3
- package/src/lib/tenant/index.ts +9 -0
- package/src/lib/tenant/services/tenant.service.ts +336 -0
- package/src/lib/tenant/tenant.module.ts +19 -0
- package/src/lib/types/express.d.ts +14 -0
- package/src/lib/user/dto/requests/update-user.dto.ts +15 -0
- package/src/lib/user/entities/access-key.entity.ts +53 -0
- package/src/lib/user/entities/identity.entity.ts +31 -0
- package/src/lib/user/entities/user.entity.ts +212 -0
- package/src/lib/user/events/{user-created.event.d.ts → user-created.event.ts} +4 -3
- package/src/lib/user/events/{user-deleted.event.d.ts → user-deleted.event.ts} +6 -3
- package/src/lib/user/events/{user-updated.event.d.ts → user-updated.event.ts} +6 -3
- package/src/lib/user/index.ts +11 -0
- package/src/lib/user/services/access-key.service.ts +145 -0
- package/src/lib/user/services/{user.service.js → user.service.ts} +199 -95
- package/src/lib/user/user.module.ts +26 -0
- package/src/lib/utils/database.utils.ts +6 -0
- package/src/lib/utils/date.util.ts +106 -0
- package/src/lib/utils/device.util.ts +111 -0
- package/src/lib/utils/index.ts +6 -0
- package/src/lib/utils/otp.ts +3 -0
- package/src/lib/utils/security.util.ts +27 -0
- package/src/lib/utils/slug.util.ts +58 -0
- package/src/types/ms.d.ts +1 -0
- package/test/access-key.service.spec.ts +204 -0
- package/test/auth.service.spec.ts +541 -0
- package/test/mfa.service.spec.ts +359 -0
- package/test/role.service.spec.ts +418 -0
- package/test/tenant.service.spec.ts +218 -0
- package/test/test.setup.ts +66 -0
- package/test/user.service.spec.ts +374 -0
- package/tsconfig.json +17 -0
- package/tsconfig.lib.json +15 -0
- package/tsconfig.spec.json +15 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/ui/.env +1 -0
- package/ui/.env.example +1 -0
- package/ui/.eslintignore +7 -0
- package/ui/README.md +288 -0
- package/ui/index.html +17 -0
- package/ui/package.json +34 -0
- package/ui/postcss.config.js +6 -0
- package/ui/src/App.tsx +245 -0
- package/ui/src/components/AuthGuard.tsx +59 -0
- package/ui/src/components/AuthProvider.tsx +76 -0
- package/ui/src/components/Button.tsx +37 -0
- package/ui/src/components/Card.tsx +37 -0
- package/ui/src/components/ErrorMessage.tsx +15 -0
- package/ui/src/components/FormDialog.tsx +61 -0
- package/ui/src/components/FormFooter.tsx +37 -0
- package/ui/src/components/Layout.tsx +112 -0
- package/ui/src/components/LoadingMessage.tsx +11 -0
- package/ui/src/components/Modal.tsx +97 -0
- package/ui/src/components/MultiSelect.tsx +145 -0
- package/ui/src/components/PageHeader.tsx +42 -0
- package/ui/src/components/PanelHeader.tsx +28 -0
- package/ui/src/components/PermissionInput.tsx +473 -0
- package/ui/src/components/SearchInput.tsx +69 -0
- package/ui/src/components/Select.tsx +51 -0
- package/ui/src/components/SwaggerUIWrapper.tsx +316 -0
- package/ui/src/components/Table.tsx +207 -0
- package/ui/src/components/Tag.tsx +9 -0
- package/ui/src/components/TagsInput.tsx +96 -0
- package/ui/src/components/admin/AdminForm.tsx +170 -0
- package/ui/src/components/admin/CreateAdminDialog.tsx +38 -0
- package/ui/src/components/auth/LoginFooter.tsx +17 -0
- package/ui/src/components/auth/LoginHeader.tsx +14 -0
- package/ui/src/components/auth/components/CodeBlock.tsx +43 -0
- package/ui/src/components/auth/components/CreateAccountCodeExamples.tsx +60 -0
- package/ui/src/components/auth/components/PasswordRequirements.tsx +16 -0
- package/ui/src/components/auth/components/PasswordStrengthIndicator.tsx +48 -0
- package/ui/src/components/auth/components/ResetPasswordCodeExamples.tsx +76 -0
- package/ui/src/components/auth/components/Tabs.tsx +32 -0
- package/ui/src/components/auth/dialogs/CreateAccountDialog.tsx +79 -0
- package/ui/src/components/auth/dialogs/ForgotPasswordDialog.tsx +79 -0
- package/ui/src/components/auth/forms/CreateAccountForm.tsx +226 -0
- package/ui/src/components/auth/forms/LoginForm.tsx +149 -0
- package/ui/src/components/auth/forms/ResetPasswordForm.tsx +202 -0
- package/ui/src/components/auth/types.ts +17 -0
- package/ui/src/components/auth/utils/security.ts +82 -0
- package/ui/src/components/auth/utils/utils.ts +25 -0
- package/ui/src/components/form/EmailField.tsx +25 -0
- package/ui/src/components/form/FormField.tsx +102 -0
- package/ui/src/components/form/FormMultiSelect.tsx +46 -0
- package/ui/src/components/form/FormSelect.tsx +60 -0
- package/ui/src/components/form/FormTagsInput.tsx +42 -0
- package/ui/src/components/form/FormTextarea.tsx +42 -0
- package/ui/src/components/form/PasswordField.tsx +93 -0
- package/ui/src/components/form/SecretKeyField.tsx +49 -0
- package/ui/src/components/permission/CreatePermissionDialog.tsx +44 -0
- package/ui/src/components/permission/EditPermissionDialog.tsx +55 -0
- package/ui/src/components/permission/PermissionForm.tsx +251 -0
- package/ui/src/components/role/CreateRoleDialog.tsx +45 -0
- package/ui/src/components/role/EditRoleDialog.tsx +55 -0
- package/ui/src/components/role/RoleDialog.tsx +252 -0
- package/ui/src/components/role/RoleForm.tsx +246 -0
- package/ui/src/components/tenant/CreateTenantDialog.tsx +41 -0
- package/ui/src/components/tenant/EditTenantDialog.tsx +52 -0
- package/ui/src/components/tenant/TenantForm.tsx +160 -0
- package/ui/src/components/user/CreateUserDialog.tsx +45 -0
- package/ui/src/components/user/UserDetailModal.tsx +815 -0
- package/ui/src/components/user/UserForm.tsx +191 -0
- package/ui/src/data/nest-auth.json +1687 -0
- package/ui/src/hooks/useApi.ts +69 -0
- package/ui/src/hooks/useAuth.ts +100 -0
- package/ui/src/hooks/useConfirm.tsx +105 -0
- package/ui/src/hooks/useFormFooter.tsx +42 -0
- package/ui/src/hooks/usePagination.ts +69 -0
- package/ui/src/index.css +59 -0
- package/ui/src/main.tsx +13 -0
- package/ui/src/pages/AdminsPage.tsx +178 -0
- package/ui/src/pages/ApiPage.tsx +89 -0
- package/ui/src/pages/DashboardPage.tsx +281 -0
- package/ui/src/pages/LoginPage.tsx +39 -0
- package/ui/src/pages/PermissionsPage.tsx +376 -0
- package/ui/src/pages/RolesPage.tsx +274 -0
- package/ui/src/pages/TenantsPage.tsx +221 -0
- package/ui/src/pages/UsersPage.tsx +387 -0
- package/ui/src/services/api.ts +115 -0
- package/ui/src/types/index.ts +136 -0
- package/ui/src/vite-env.d.ts +9 -0
- package/ui/tailwind.config.js +45 -0
- package/ui/tsconfig.json +24 -0
- package/ui/tsconfig.node.json +10 -0
- package/ui/vite.config.ts +37 -0
- package/ui/yarn.lock +3137 -0
- package/src/index.d.ts +0 -11
- package/src/index.js +0 -18
- package/src/index.js.map +0 -1
- package/src/lib/auth/auth.module.d.ts +0 -2
- package/src/lib/auth/auth.module.js +0 -54
- package/src/lib/auth/auth.module.js.map +0 -1
- package/src/lib/auth/controllers/auth.controller.d.ts +0 -29
- package/src/lib/auth/controllers/auth.controller.js +0 -206
- package/src/lib/auth/controllers/auth.controller.js.map +0 -1
- package/src/lib/auth/controllers/mfa.controller.d.ts +0 -23
- package/src/lib/auth/controllers/mfa.controller.js +0 -131
- package/src/lib/auth/controllers/mfa.controller.js.map +0 -1
- package/src/lib/auth/dto/index.d.ts +0 -0
- package/src/lib/auth/dto/index.js +0 -1
- package/src/lib/auth/dto/index.js.map +0 -1
- package/src/lib/auth/dto/requests/forgot-password.request.dto.d.ts +0 -5
- package/src/lib/auth/dto/requests/forgot-password.request.dto.js +0 -30
- package/src/lib/auth/dto/requests/forgot-password.request.dto.js.map +0 -1
- package/src/lib/auth/dto/requests/login.request.dto.d.ts +0 -6
- package/src/lib/auth/dto/requests/login.request.dto.js +0 -38
- package/src/lib/auth/dto/requests/login.request.dto.js.map +0 -1
- package/src/lib/auth/dto/requests/refresh-token.request.dto.d.ts +0 -3
- package/src/lib/auth/dto/requests/refresh-token.request.dto.js +0 -15
- package/src/lib/auth/dto/requests/refresh-token.request.dto.js.map +0 -1
- package/src/lib/auth/dto/requests/reset-password.request.dto.d.ts +0 -7
- package/src/lib/auth/dto/requests/reset-password.request.dto.js +0 -42
- package/src/lib/auth/dto/requests/reset-password.request.dto.js.map +0 -1
- package/src/lib/auth/dto/requests/send-mfa-code.request.dto.d.ts +0 -4
- package/src/lib/auth/dto/requests/send-mfa-code.request.dto.js +0 -16
- package/src/lib/auth/dto/requests/send-mfa-code.request.dto.js.map +0 -1
- package/src/lib/auth/dto/requests/signup.request.dto.d.ts +0 -7
- package/src/lib/auth/dto/requests/signup.request.dto.js +0 -37
- package/src/lib/auth/dto/requests/signup.request.dto.js.map +0 -1
- package/src/lib/auth/dto/requests/social-login.request.dto.d.ts +0 -3
- package/src/lib/auth/dto/requests/social-login.request.dto.js +0 -16
- package/src/lib/auth/dto/requests/social-login.request.dto.js.map +0 -1
- package/src/lib/auth/dto/requests/verify-2fa.request.dto.d.ts +0 -5
- package/src/lib/auth/dto/requests/verify-2fa.request.dto.js +0 -21
- package/src/lib/auth/dto/requests/verify-2fa.request.dto.js.map +0 -1
- package/src/lib/auth/dto/requests/verify-forgot-password-otp-request-dto.d.ts +0 -6
- package/src/lib/auth/dto/requests/verify-forgot-password-otp-request-dto.js +0 -35
- package/src/lib/auth/dto/requests/verify-forgot-password-otp-request-dto.js.map +0 -1
- package/src/lib/auth/dto/requests/verify-totp-setup.request.dto.d.ts +0 -4
- package/src/lib/auth/dto/requests/verify-totp-setup.request.dto.js +0 -20
- package/src/lib/auth/dto/requests/verify-totp-setup.request.dto.js.map +0 -1
- package/src/lib/auth/dto/responses/auth.response.dto.d.ts +0 -16
- package/src/lib/auth/dto/responses/auth.response.dto.js +0 -50
- package/src/lib/auth/dto/responses/auth.response.dto.js.map +0 -1
- package/src/lib/auth/entities/mfa-secret.entity.d.ts +0 -12
- package/src/lib/auth/entities/mfa-secret.entity.js +0 -50
- package/src/lib/auth/entities/mfa-secret.entity.js.map +0 -1
- package/src/lib/auth/entities/otp.entity.d.ts +0 -13
- package/src/lib/auth/entities/otp.entity.js +0 -50
- package/src/lib/auth/entities/otp.entity.js.map +0 -1
- package/src/lib/auth/events/logged-out-all.event.js +0 -10
- package/src/lib/auth/events/logged-out-all.event.js.map +0 -1
- package/src/lib/auth/events/logged-out.event.js +0 -10
- package/src/lib/auth/events/logged-out.event.js.map +0 -1
- package/src/lib/auth/events/password-reset-requested.event.js +0 -10
- package/src/lib/auth/events/password-reset-requested.event.js.map +0 -1
- package/src/lib/auth/events/password-reset.event.js +0 -10
- package/src/lib/auth/events/password-reset.event.js.map +0 -1
- package/src/lib/auth/events/user-2fa-verified.event.js +0 -10
- package/src/lib/auth/events/user-2fa-verified.event.js.map +0 -1
- package/src/lib/auth/events/user-logged-in.event.js +0 -10
- package/src/lib/auth/events/user-logged-in.event.js.map +0 -1
- package/src/lib/auth/events/user-refresh-token.event.js +0 -10
- package/src/lib/auth/events/user-refresh-token.event.js.map +0 -1
- package/src/lib/auth/events/user-registered.event.js +0 -10
- package/src/lib/auth/events/user-registered.event.js.map +0 -1
- package/src/lib/auth/guards/auth.guard.d.ts +0 -28
- package/src/lib/auth/guards/auth.guard.js +0 -304
- package/src/lib/auth/guards/auth.guard.js.map +0 -1
- package/src/lib/auth/index.js +0 -31
- package/src/lib/auth/index.js.map +0 -1
- package/src/lib/auth/services/auth.service.d.ts +0 -53
- package/src/lib/auth/services/auth.service.js +0 -522
- package/src/lib/auth/services/auth.service.js.map +0 -1
- package/src/lib/auth/services/cookie.service.d.ts +0 -9
- package/src/lib/auth/services/cookie.service.js +0 -43
- package/src/lib/auth/services/cookie.service.js.map +0 -1
- package/src/lib/auth/services/mfa.service.d.ts +0 -38
- package/src/lib/auth/services/mfa.service.js +0 -254
- package/src/lib/auth/services/mfa.service.js.map +0 -1
- package/src/lib/auth.constants.d.ts +0 -39
- package/src/lib/auth.constants.js +0 -43
- package/src/lib/auth.constants.js.map +0 -1
- package/src/lib/core/core.module.d.ts +0 -2
- package/src/lib/core/core.module.js +0 -53
- package/src/lib/core/core.module.js.map +0 -1
- package/src/lib/core/decorators/auth.decorator.d.ts +0 -1
- package/src/lib/core/decorators/auth.decorator.js +0 -8
- package/src/lib/core/decorators/auth.decorator.js.map +0 -1
- package/src/lib/core/decorators/permissions.decorator.d.ts +0 -2
- package/src/lib/core/decorators/permissions.decorator.js +0 -14
- package/src/lib/core/decorators/permissions.decorator.js.map +0 -1
- package/src/lib/core/decorators/role.decorator.d.ts +0 -3
- package/src/lib/core/decorators/role.decorator.js +0 -14
- package/src/lib/core/decorators/role.decorator.js.map +0 -1
- package/src/lib/core/decorators/skip-mfa.decorator.d.ts +0 -2
- package/src/lib/core/decorators/skip-mfa.decorator.js +0 -8
- package/src/lib/core/decorators/skip-mfa.decorator.js.map +0 -1
- package/src/lib/core/dto/message.response.dto.d.ts +0 -3
- package/src/lib/core/dto/message.response.dto.js +0 -13
- package/src/lib/core/dto/message.response.dto.js.map +0 -1
- package/src/lib/core/entities.js +0 -31
- package/src/lib/core/entities.js.map +0 -1
- package/src/lib/core/index.js +0 -27
- package/src/lib/core/index.js.map +0 -1
- package/src/lib/core/interfaces/auth-module-options.interface.d.ts +0 -62
- package/src/lib/core/interfaces/auth-module-options.interface.js +0 -3
- package/src/lib/core/interfaces/auth-module-options.interface.js.map +0 -1
- package/src/lib/core/interfaces/mfa-options.interface.d.ts +0 -25
- package/src/lib/core/interfaces/mfa-options.interface.js +0 -10
- package/src/lib/core/interfaces/mfa-options.interface.js.map +0 -1
- package/src/lib/core/interfaces/otp.interface.d.ts +0 -5
- package/src/lib/core/interfaces/otp.interface.js +0 -10
- package/src/lib/core/interfaces/otp.interface.js.map +0 -1
- package/src/lib/core/interfaces/session-options.interface.d.ts +0 -12
- package/src/lib/core/interfaces/session-options.interface.js +0 -9
- package/src/lib/core/interfaces/session-options.interface.js.map +0 -1
- package/src/lib/core/interfaces/token-payload.interface.js +0 -3
- package/src/lib/core/interfaces/token-payload.interface.js.map +0 -1
- package/src/lib/core/providers/apple-auth.provider.d.ts +0 -18
- package/src/lib/core/providers/apple-auth.provider.js +0 -57
- package/src/lib/core/providers/apple-auth.provider.js.map +0 -1
- package/src/lib/core/providers/base-auth.provider.d.ts +0 -26
- package/src/lib/core/providers/base-auth.provider.js +0 -43
- package/src/lib/core/providers/base-auth.provider.js.map +0 -1
- package/src/lib/core/providers/email-auth.provider.d.ts +0 -17
- package/src/lib/core/providers/email-auth.provider.js +0 -40
- package/src/lib/core/providers/email-auth.provider.js.map +0 -1
- package/src/lib/core/providers/facebook-auth.provider.d.ts +0 -18
- package/src/lib/core/providers/facebook-auth.provider.js +0 -56
- package/src/lib/core/providers/facebook-auth.provider.js.map +0 -1
- package/src/lib/core/providers/google-auth.provider.d.ts +0 -21
- package/src/lib/core/providers/google-auth.provider.js +0 -58
- package/src/lib/core/providers/google-auth.provider.js.map +0 -1
- package/src/lib/core/providers/jwt-auth.provider.d.ts +0 -33
- package/src/lib/core/providers/jwt-auth.provider.js +0 -50
- package/src/lib/core/providers/jwt-auth.provider.js.map +0 -1
- package/src/lib/core/providers/phone-auth.provider.d.ts +0 -18
- package/src/lib/core/providers/phone-auth.provider.js +0 -43
- package/src/lib/core/providers/phone-auth.provider.js.map +0 -1
- package/src/lib/core/services/auth-config.service.d.ts +0 -12
- package/src/lib/core/services/auth-config.service.js +0 -79
- package/src/lib/core/services/auth-config.service.js.map +0 -1
- package/src/lib/core/services/auth-provider-registry.service.d.ts +0 -24
- package/src/lib/core/services/auth-provider-registry.service.js +0 -71
- package/src/lib/core/services/auth-provider-registry.service.js.map +0 -1
- package/src/lib/core/services/debug-logger.service.d.ts +0 -38
- package/src/lib/core/services/debug-logger.service.js.map +0 -1
- package/src/lib/core/services/initialization.service.d.ts +0 -10
- package/src/lib/core/services/initialization.service.js +0 -34
- package/src/lib/core/services/initialization.service.js.map +0 -1
- package/src/lib/core/services/jwt.service.d.ts +0 -14
- package/src/lib/core/services/jwt.service.js +0 -92
- package/src/lib/core/services/jwt.service.js.map +0 -1
- package/src/lib/nest-auth.module.d.ts +0 -11
- package/src/lib/nest-auth.module.js +0 -177
- package/src/lib/nest-auth.module.js.map +0 -1
- package/src/lib/request-context/request-context.d.ts +0 -22
- package/src/lib/request-context/request-context.js.map +0 -1
- package/src/lib/request-context/request-context.middleware.d.ts +0 -4
- package/src/lib/request-context/request-context.middleware.js +0 -16
- package/src/lib/request-context/request-context.middleware.js.map +0 -1
- package/src/lib/role/entities/role.entity.d.ts +0 -20
- package/src/lib/role/entities/role.entity.js +0 -110
- package/src/lib/role/entities/role.entity.js.map +0 -1
- package/src/lib/role/index.js +0 -5
- package/src/lib/role/index.js.map +0 -1
- package/src/lib/role/role.module.d.ts +0 -2
- package/src/lib/role/role.module.js +0 -23
- package/src/lib/role/role.module.js.map +0 -1
- package/src/lib/role/services/role.service.d.ts +0 -20
- package/src/lib/role/services/role.service.js.map +0 -1
- package/src/lib/session/entities/session.entity.d.ts +0 -16
- package/src/lib/session/entities/session.entity.js +0 -63
- package/src/lib/session/entities/session.entity.js.map +0 -1
- package/src/lib/session/index.d.ts +0 -3
- package/src/lib/session/index.js +0 -7
- package/src/lib/session/index.js.map +0 -1
- package/src/lib/session/services/base-session.service.d.ts +0 -23
- package/src/lib/session/services/base-session.service.js +0 -64
- package/src/lib/session/services/base-session.service.js.map +0 -1
- package/src/lib/session/services/database-session.service.d.ts +0 -17
- package/src/lib/session/services/database-session.service.js +0 -51
- package/src/lib/session/services/database-session.service.js.map +0 -1
- package/src/lib/session/services/redis-session.service.d.ts +0 -20
- package/src/lib/session/services/redis-session.service.js +0 -117
- package/src/lib/session/services/redis-session.service.js.map +0 -1
- package/src/lib/session/session.module.d.ts +0 -2
- package/src/lib/session/session.module.js +0 -33
- package/src/lib/session/session.module.js.map +0 -1
- package/src/lib/tenant/entities/tenant.entity.d.ts +0 -10
- package/src/lib/tenant/entities/tenant.entity.js +0 -44
- package/src/lib/tenant/entities/tenant.entity.js.map +0 -1
- package/src/lib/tenant/events/tenant-created.event.d.ts +0 -8
- package/src/lib/tenant/events/tenant-created.event.js +0 -10
- package/src/lib/tenant/events/tenant-created.event.js.map +0 -1
- package/src/lib/tenant/events/tenant-deleted.event.d.ts +0 -8
- package/src/lib/tenant/events/tenant-deleted.event.js +0 -10
- package/src/lib/tenant/events/tenant-deleted.event.js.map +0 -1
- package/src/lib/tenant/events/tenant-updated.event.js +0 -10
- package/src/lib/tenant/events/tenant-updated.event.js.map +0 -1
- package/src/lib/tenant/index.d.ts +0 -1
- package/src/lib/tenant/index.js +0 -5
- package/src/lib/tenant/index.js.map +0 -1
- package/src/lib/tenant/services/tenant.service.d.ts +0 -26
- package/src/lib/tenant/services/tenant.service.js +0 -200
- package/src/lib/tenant/services/tenant.service.js.map +0 -1
- package/src/lib/tenant/tenant.module.d.ts +0 -2
- package/src/lib/tenant/tenant.module.js +0 -27
- package/src/lib/tenant/tenant.module.js.map +0 -1
- package/src/lib/user/dto/requests/update-user.dto.d.ts +0 -5
- package/src/lib/user/dto/requests/update-user.dto.js +0 -24
- package/src/lib/user/dto/requests/update-user.dto.js.map +0 -1
- package/src/lib/user/entities/access-key.entity.d.ts +0 -16
- package/src/lib/user/entities/access-key.entity.js +0 -63
- package/src/lib/user/entities/access-key.entity.js.map +0 -1
- package/src/lib/user/entities/identity.entity.d.ts +0 -12
- package/src/lib/user/entities/identity.entity.js +0 -47
- package/src/lib/user/entities/identity.entity.js.map +0 -1
- package/src/lib/user/entities/user.entity.d.ts +0 -39
- package/src/lib/user/entities/user.entity.js +0 -201
- package/src/lib/user/entities/user.entity.js.map +0 -1
- package/src/lib/user/events/user-created.event.js +0 -10
- package/src/lib/user/events/user-created.event.js.map +0 -1
- package/src/lib/user/events/user-deleted.event.js +0 -10
- package/src/lib/user/events/user-deleted.event.js.map +0 -1
- package/src/lib/user/events/user-updated.event.js +0 -10
- package/src/lib/user/events/user-updated.event.js.map +0 -1
- package/src/lib/user/index.d.ts +0 -3
- package/src/lib/user/index.js +0 -7
- package/src/lib/user/index.js.map +0 -1
- package/src/lib/user/services/access-key.service.d.ts +0 -19
- package/src/lib/user/services/access-key.service.js +0 -119
- package/src/lib/user/services/access-key.service.js.map +0 -1
- package/src/lib/user/services/user.service.d.ts +0 -24
- package/src/lib/user/services/user.service.js.map +0 -1
- package/src/lib/user/user.module.d.ts +0 -2
- package/src/lib/user/user.module.js +0 -34
- package/src/lib/user/user.module.js.map +0 -1
- package/src/lib/utils/database.utils.d.ts +0 -2
- package/src/lib/utils/database.utils.js +0 -8
- package/src/lib/utils/database.utils.js.map +0 -1
- package/src/lib/utils/otp.d.ts +0 -1
- package/src/lib/utils/otp.js +0 -7
- package/src/lib/utils/otp.js.map +0 -1
|
@@ -1,151 +1,196 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
async createUser(data) {
|
|
24
|
-
this.debugLogger.logFunctionEntry('createUser', 'UserService', { email: data.email, phone: data.phone, hasPassword: !!data.password });
|
|
1
|
+
import { Injectable, NotFoundException, BadRequestException, ConflictException } from '@nestjs/common';
|
|
2
|
+
import { InjectRepository } from '@nestjs/typeorm';
|
|
3
|
+
import { FindManyOptions, FindOneOptions, IsNull, Not, Repository } from 'typeorm';
|
|
4
|
+
import { NestAuthUser } from '../entities/user.entity';
|
|
5
|
+
import { EventEmitter2 } from '@nestjs/event-emitter';
|
|
6
|
+
import { EMAIL_AUTH_PROVIDER, NestAuthEvents, PHONE_AUTH_PROVIDER } from '../../auth.constants';
|
|
7
|
+
import { UserUpdatedEvent } from '../events/user-updated.event';
|
|
8
|
+
import { UserDeletedEvent } from '../events/user-deleted.event';
|
|
9
|
+
import { UserCreatedEvent } from '../events/user-created.event';
|
|
10
|
+
import { TenantService } from '../../tenant';
|
|
11
|
+
import { DebugLoggerService } from '../../core/services/debug-logger.service';
|
|
12
|
+
|
|
13
|
+
@Injectable()
|
|
14
|
+
export class UserService {
|
|
15
|
+
constructor(
|
|
16
|
+
@InjectRepository(NestAuthUser)
|
|
17
|
+
private userRepository: Repository<NestAuthUser>,
|
|
18
|
+
private eventEmitter: EventEmitter2,
|
|
19
|
+
private tenantService: TenantService,
|
|
20
|
+
private debugLogger: DebugLoggerService
|
|
21
|
+
) { }
|
|
22
|
+
|
|
23
|
+
async createUser(data: Partial<NestAuthUser>): Promise<NestAuthUser> {
|
|
24
|
+
this.debugLogger.logFunctionEntry('createUser', 'UserService', { email: data.email, phone: data.phone, hasPassword: !!(data as any).password });
|
|
25
|
+
|
|
25
26
|
try {
|
|
26
27
|
const { email, phone } = data;
|
|
28
|
+
|
|
27
29
|
const tenantId = await this.tenantService.resolveTenantId(data?.tenantId || null);
|
|
28
30
|
this.debugLogger.logUserOperation('createUser', undefined, { email: !!email, phone: !!phone, resolvedTenantId: tenantId });
|
|
31
|
+
|
|
29
32
|
if (!tenantId) {
|
|
30
33
|
this.debugLogger.error('Tenant ID is required for user creation', 'UserService', { email: !!email, phone: !!phone });
|
|
31
|
-
throw new
|
|
34
|
+
throw new BadRequestException('Tenant ID is required');
|
|
32
35
|
}
|
|
36
|
+
|
|
33
37
|
if (!email && !phone) {
|
|
34
38
|
this.debugLogger.error('Neither email nor phone provided for user creation', 'UserService');
|
|
35
|
-
throw new
|
|
39
|
+
throw new BadRequestException('Either email or phone must be provided');
|
|
36
40
|
}
|
|
41
|
+
|
|
42
|
+
// Check for existing user with same email or phone in the same tenant
|
|
37
43
|
this.debugLogger.debug('Checking for existing user', 'UserService', { email: !!email, phone: !!phone, tenantId });
|
|
38
44
|
let existingUser = null;
|
|
45
|
+
|
|
46
|
+
// Normalize email to lowercase for case-insensitive matching
|
|
47
|
+
const normalizedEmail = email ? email.toLowerCase().trim() : email;
|
|
48
|
+
|
|
39
49
|
if (phone) {
|
|
40
50
|
existingUser = await this.userRepository.findOne({
|
|
41
51
|
where: { phone, tenantId }
|
|
42
52
|
});
|
|
43
53
|
}
|
|
44
|
-
|
|
54
|
+
|
|
55
|
+
if (!existingUser && normalizedEmail) {
|
|
45
56
|
existingUser = await this.userRepository.findOne({
|
|
46
|
-
where: { email, tenantId }
|
|
57
|
+
where: { email: normalizedEmail, tenantId }
|
|
47
58
|
});
|
|
48
59
|
}
|
|
60
|
+
|
|
49
61
|
if (existingUser) {
|
|
50
62
|
this.debugLogger.warn('User already exists', 'UserService', { email: !!email, phone: !!phone, tenantId, existingUserId: existingUser.id });
|
|
51
|
-
throw new
|
|
63
|
+
throw new ConflictException({
|
|
52
64
|
message: `User with ${email ? `email ${email}` : ''}${email && phone ? ' or ' : ''}${phone ? `phone ${phone}` : ''} already exists.`,
|
|
53
65
|
code: 'USER_ALREADY_EXISTS'
|
|
54
66
|
});
|
|
55
67
|
}
|
|
68
|
+
|
|
56
69
|
this.debugLogger.debug('Creating new user', 'UserService', { email: !!email, phone: !!phone, tenantId });
|
|
57
|
-
const user = this.userRepository.create({
|
|
70
|
+
const user = this.userRepository.create({
|
|
71
|
+
...data,
|
|
72
|
+
email: normalizedEmail || data.email,
|
|
73
|
+
tenantId
|
|
74
|
+
});
|
|
75
|
+
|
|
58
76
|
await this.userRepository.save(user);
|
|
59
77
|
this.debugLogger.info('User created successfully', 'UserService', { userId: user.id, tenantId });
|
|
60
|
-
|
|
78
|
+
|
|
79
|
+
// Create authentication identity for login
|
|
80
|
+
if (normalizedEmail) {
|
|
61
81
|
this.debugLogger.debug('Creating email identity', 'UserService', { userId: user.id });
|
|
62
|
-
await user.findOrCreateIdentity(
|
|
82
|
+
await user.findOrCreateIdentity(EMAIL_AUTH_PROVIDER, normalizedEmail);
|
|
63
83
|
}
|
|
64
84
|
if (phone) {
|
|
65
85
|
this.debugLogger.debug('Creating phone identity', 'UserService', { userId: user.id });
|
|
66
|
-
await user.findOrCreateIdentity(
|
|
86
|
+
await user.findOrCreateIdentity(PHONE_AUTH_PROVIDER, phone);
|
|
67
87
|
}
|
|
88
|
+
|
|
89
|
+
// Emit user created event
|
|
68
90
|
this.debugLogger.debug('Emitting user created event', 'UserService', { userId: user.id });
|
|
69
|
-
await this.eventEmitter.emitAsync(
|
|
70
|
-
|
|
71
|
-
|
|
91
|
+
await this.eventEmitter.emitAsync(
|
|
92
|
+
NestAuthEvents.USER_CREATED,
|
|
93
|
+
new UserCreatedEvent({
|
|
94
|
+
user
|
|
95
|
+
})
|
|
96
|
+
);
|
|
97
|
+
|
|
72
98
|
this.debugLogger.logFunctionExit('createUser', 'UserService', { userId: user.id });
|
|
73
99
|
return user;
|
|
74
|
-
|
|
75
|
-
catch (error) {
|
|
100
|
+
|
|
101
|
+
} catch (error) {
|
|
76
102
|
this.debugLogger.logError(error, 'createUser', { email: data.email, phone: data.phone });
|
|
77
103
|
throw error;
|
|
78
104
|
}
|
|
79
105
|
}
|
|
80
|
-
|
|
106
|
+
|
|
107
|
+
async getUserById(id: string, options?: FindOneOptions<NestAuthUser>): Promise<NestAuthUser> {
|
|
81
108
|
this.debugLogger.debug('Getting user by ID', 'UserService', { userId: id });
|
|
109
|
+
|
|
82
110
|
if (!id) {
|
|
83
111
|
this.debugLogger.warn('No user ID provided', 'UserService');
|
|
84
112
|
return null;
|
|
85
113
|
}
|
|
114
|
+
|
|
86
115
|
const user = await this.userRepository.findOne({
|
|
87
116
|
...(options ? options : {}),
|
|
88
117
|
where: { id }
|
|
89
118
|
});
|
|
119
|
+
|
|
90
120
|
if (!user) {
|
|
91
121
|
this.debugLogger.warn('User not found', 'UserService', { userId: id });
|
|
92
122
|
return null;
|
|
93
123
|
}
|
|
124
|
+
|
|
94
125
|
this.debugLogger.debug('User found', 'UserService', { userId: user.id });
|
|
95
126
|
return user;
|
|
96
127
|
}
|
|
97
|
-
|
|
128
|
+
|
|
129
|
+
async getUserByEmail(email: string, tenantId?: string, options?: FindOneOptions<NestAuthUser>): Promise<NestAuthUser> {
|
|
98
130
|
this.debugLogger.debug('Getting user by email', 'UserService', { email: !!email, tenantId });
|
|
131
|
+
|
|
99
132
|
tenantId = await this.tenantService.resolveTenantId(tenantId || null);
|
|
100
133
|
if (!email) {
|
|
101
134
|
this.debugLogger.warn('No email provided for user lookup', 'UserService');
|
|
102
135
|
return null;
|
|
103
136
|
}
|
|
137
|
+
|
|
138
|
+
// Normalize email to lowercase for case-insensitive matching
|
|
139
|
+
const normalizedEmail = email.toLowerCase().trim();
|
|
140
|
+
|
|
104
141
|
const user = await this.userRepository.findOne({
|
|
105
142
|
...(options ? options : {}),
|
|
106
143
|
where: {
|
|
107
|
-
email,
|
|
108
|
-
tenantId: tenantId ||
|
|
144
|
+
email: normalizedEmail,
|
|
145
|
+
tenantId: tenantId || IsNull()
|
|
109
146
|
}
|
|
110
147
|
});
|
|
148
|
+
|
|
111
149
|
if (user) {
|
|
112
150
|
this.debugLogger.debug('User found by email', 'UserService', { userId: user.id, tenantId });
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
151
|
+
} else {
|
|
115
152
|
this.debugLogger.debug('No user found with email', 'UserService', { tenantId });
|
|
116
153
|
}
|
|
154
|
+
|
|
117
155
|
return user;
|
|
118
156
|
}
|
|
119
|
-
|
|
157
|
+
|
|
158
|
+
async getUserByPhone(phone: string, tenantId?: string, options?: FindOneOptions<NestAuthUser>): Promise<NestAuthUser> {
|
|
120
159
|
this.debugLogger.debug('Getting user by phone', 'UserService', { phone: !!phone, tenantId });
|
|
160
|
+
|
|
121
161
|
tenantId = await this.tenantService.resolveTenantId(tenantId || null);
|
|
122
162
|
if (!phone) {
|
|
123
163
|
this.debugLogger.warn('No phone provided for user lookup', 'UserService');
|
|
124
164
|
return null;
|
|
125
165
|
}
|
|
166
|
+
|
|
126
167
|
const user = await this.userRepository.findOne({
|
|
127
168
|
...(options ? options : {}),
|
|
128
169
|
where: {
|
|
129
170
|
phone,
|
|
130
|
-
tenantId: tenantId ||
|
|
171
|
+
tenantId: tenantId || IsNull()
|
|
131
172
|
}
|
|
132
173
|
});
|
|
174
|
+
|
|
133
175
|
if (user) {
|
|
134
176
|
this.debugLogger.debug('User found by phone', 'UserService', { userId: user.id, tenantId });
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
177
|
+
} else {
|
|
137
178
|
this.debugLogger.debug('No user found with phone', 'UserService', { tenantId });
|
|
138
179
|
}
|
|
180
|
+
|
|
139
181
|
return user;
|
|
140
182
|
}
|
|
141
|
-
|
|
183
|
+
|
|
184
|
+
async getUsers(options?: FindManyOptions<NestAuthUser>): Promise<NestAuthUser[]> {
|
|
142
185
|
return this.userRepository.find(options);
|
|
143
186
|
}
|
|
144
|
-
|
|
187
|
+
|
|
188
|
+
async getUsersByTenant(tenantId: string, options?: FindManyOptions<NestAuthUser>): Promise<NestAuthUser[]> {
|
|
145
189
|
tenantId = await this.tenantService.resolveTenantId(tenantId || null);
|
|
146
190
|
if (!tenantId) {
|
|
147
191
|
return [];
|
|
148
192
|
}
|
|
193
|
+
|
|
149
194
|
return this.userRepository.find({
|
|
150
195
|
...(options ? options : {}),
|
|
151
196
|
where: {
|
|
@@ -154,159 +199,218 @@ let UserService = class UserService {
|
|
|
154
199
|
}
|
|
155
200
|
});
|
|
156
201
|
}
|
|
157
|
-
|
|
202
|
+
|
|
203
|
+
async updateUser(id: string, data: Partial<NestAuthUser>): Promise<NestAuthUser> {
|
|
158
204
|
this.debugLogger.logFunctionEntry('updateUser', 'UserService', { userId: id, fields: Object.keys(data) });
|
|
205
|
+
|
|
159
206
|
try {
|
|
160
207
|
const user = await this.getUserById(id);
|
|
208
|
+
|
|
161
209
|
if (!user) {
|
|
162
210
|
this.debugLogger.error('User not found for update', 'UserService', { userId: id });
|
|
163
|
-
throw new
|
|
211
|
+
throw new NotFoundException({
|
|
164
212
|
message: `User with ID ${id} not found`,
|
|
165
213
|
code: 'USER_NOT_FOUND'
|
|
166
214
|
});
|
|
167
215
|
}
|
|
216
|
+
|
|
217
|
+
// If email or phone is being changed, check for conflicts
|
|
168
218
|
if (data.email || data.phone) {
|
|
169
219
|
this.debugLogger.debug('Checking for conflicts during user update', 'UserService', { userId: id, email: !!data.email, phone: !!data.phone });
|
|
220
|
+
|
|
170
221
|
let existingUser = null;
|
|
222
|
+
|
|
171
223
|
if (data.phone) {
|
|
172
224
|
existingUser = await this.userRepository.findOne({
|
|
173
|
-
where: { phone: data.phone, tenantId: user.tenantId, id:
|
|
225
|
+
where: { phone: data.phone, tenantId: user.tenantId, id: Not(user.id) }
|
|
174
226
|
});
|
|
175
227
|
}
|
|
228
|
+
|
|
176
229
|
if (!existingUser && data.email) {
|
|
177
230
|
existingUser = await this.userRepository.findOne({
|
|
178
|
-
where: { email: data.email, tenantId: user.tenantId, id:
|
|
231
|
+
where: { email: data.email, tenantId: user.tenantId, id: Not(user.id) }
|
|
179
232
|
});
|
|
180
233
|
}
|
|
234
|
+
|
|
181
235
|
if (existingUser) {
|
|
182
236
|
this.debugLogger.warn('Conflict detected during user update', 'UserService', { userId: id, conflictingUserId: existingUser.id });
|
|
183
|
-
throw new
|
|
237
|
+
throw new ConflictException({
|
|
184
238
|
message: `User with ${data.email ? `email ${data.email}` : ''}${data.email && data.phone ? ' or ' : ''}${data.phone ? `phone ${data.phone}` : ''} already exists.`,
|
|
185
239
|
code: 'USER_ALREADY_EXISTS'
|
|
186
240
|
});
|
|
187
241
|
}
|
|
188
242
|
}
|
|
243
|
+
|
|
244
|
+
// Prevent changing tenant
|
|
189
245
|
delete data.tenantId;
|
|
246
|
+
|
|
190
247
|
this.debugLogger.debug('Updating user data', 'UserService', { userId: id, fields: Object.keys(data) });
|
|
191
248
|
Object.assign(user, data);
|
|
192
249
|
const updatedUser = await this.userRepository.save(user);
|
|
193
250
|
this.debugLogger.info('User updated successfully', 'UserService', { userId: updatedUser.id });
|
|
251
|
+
|
|
194
252
|
if (data.email) {
|
|
195
253
|
this.debugLogger.debug('Updating email identity', 'UserService', { userId: id });
|
|
196
|
-
await user.updateOrCreateIdentity(
|
|
254
|
+
await user.updateOrCreateIdentity(EMAIL_AUTH_PROVIDER, { providerId: data.email });
|
|
197
255
|
}
|
|
256
|
+
|
|
198
257
|
if (data.phone) {
|
|
199
258
|
this.debugLogger.debug('Updating phone identity', 'UserService', { userId: id });
|
|
200
|
-
await user.updateOrCreateIdentity(
|
|
259
|
+
await user.updateOrCreateIdentity(PHONE_AUTH_PROVIDER, { providerId: data.phone });
|
|
201
260
|
}
|
|
261
|
+
|
|
262
|
+
// Emit user updated event
|
|
202
263
|
this.debugLogger.debug('Emitting user updated event', 'UserService', { userId: updatedUser.id });
|
|
203
|
-
await this.eventEmitter.emitAsync(
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
264
|
+
await this.eventEmitter.emitAsync(
|
|
265
|
+
NestAuthEvents.USER_UPDATED,
|
|
266
|
+
new UserUpdatedEvent({
|
|
267
|
+
user: updatedUser,
|
|
268
|
+
tenantId: updatedUser.tenantId,
|
|
269
|
+
updatedFields: Object.keys(data)
|
|
270
|
+
})
|
|
271
|
+
);
|
|
272
|
+
|
|
208
273
|
this.debugLogger.logFunctionExit('updateUser', 'UserService', { userId: updatedUser.id });
|
|
209
274
|
return updatedUser;
|
|
210
|
-
|
|
211
|
-
catch (error) {
|
|
275
|
+
|
|
276
|
+
} catch (error) {
|
|
212
277
|
this.debugLogger.logError(error, 'updateUser', { userId: id, fields: Object.keys(data) });
|
|
213
278
|
throw error;
|
|
214
279
|
}
|
|
215
280
|
}
|
|
216
|
-
|
|
281
|
+
|
|
282
|
+
async deleteUser(id: string): Promise<void> {
|
|
217
283
|
this.debugLogger.logFunctionEntry('deleteUser', 'UserService', { userId: id });
|
|
284
|
+
|
|
218
285
|
try {
|
|
219
286
|
const user = await this.getUserById(id);
|
|
287
|
+
|
|
220
288
|
if (!user) {
|
|
221
289
|
this.debugLogger.error('User not found for deletion', 'UserService', { userId: id });
|
|
222
|
-
throw new
|
|
290
|
+
throw new NotFoundException({
|
|
223
291
|
message: `User with ID ${id} not found`,
|
|
224
292
|
code: 'USER_NOT_FOUND'
|
|
225
293
|
});
|
|
226
294
|
}
|
|
295
|
+
|
|
296
|
+
// Emit user deleted event before deletion
|
|
227
297
|
this.debugLogger.debug('Emitting user deleted event', 'UserService', { userId: id });
|
|
228
|
-
await this.eventEmitter.emitAsync(
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
298
|
+
await this.eventEmitter.emitAsync(
|
|
299
|
+
NestAuthEvents.USER_DELETED,
|
|
300
|
+
new UserDeletedEvent({
|
|
301
|
+
user,
|
|
302
|
+
tenantId: user.tenantId
|
|
303
|
+
})
|
|
304
|
+
);
|
|
305
|
+
|
|
232
306
|
this.debugLogger.debug('Deleting user from database', 'UserService', { userId: id });
|
|
233
307
|
await this.userRepository.remove(user);
|
|
234
308
|
this.debugLogger.info('User deleted successfully', 'UserService', { userId: id });
|
|
309
|
+
|
|
235
310
|
this.debugLogger.logFunctionExit('deleteUser', 'UserService', { userId: id });
|
|
236
|
-
|
|
237
|
-
catch (error) {
|
|
311
|
+
|
|
312
|
+
} catch (error) {
|
|
238
313
|
this.debugLogger.logError(error, 'deleteUser', { userId: id });
|
|
239
314
|
throw error;
|
|
240
315
|
}
|
|
241
316
|
}
|
|
242
|
-
|
|
317
|
+
|
|
318
|
+
async verifyUser(id: string, verificationType?: 'email' | 'phone' | 'none'): Promise<NestAuthUser> {
|
|
243
319
|
const user = await this.getUserById(id);
|
|
320
|
+
|
|
244
321
|
if (!user) {
|
|
245
|
-
throw new
|
|
322
|
+
throw new NotFoundException({
|
|
246
323
|
message: `User with ID ${id} not found`,
|
|
247
324
|
code: 'USER_NOT_FOUND'
|
|
248
325
|
});
|
|
249
326
|
}
|
|
327
|
+
|
|
250
328
|
if (verificationType === 'email') {
|
|
251
329
|
user.emailVerifiedAt = new Date();
|
|
252
|
-
}
|
|
253
|
-
else if (verificationType === 'phone') {
|
|
330
|
+
} else if (verificationType === 'phone') {
|
|
254
331
|
user.phoneVerifiedAt = new Date();
|
|
255
332
|
}
|
|
333
|
+
|
|
256
334
|
user.isVerified = true;
|
|
335
|
+
|
|
257
336
|
return this.userRepository.save(user);
|
|
258
337
|
}
|
|
259
|
-
|
|
338
|
+
|
|
339
|
+
async unverifyUser(id: string, verificationType?: 'email' | 'phone' | 'none'): Promise<NestAuthUser> {
|
|
260
340
|
const user = await this.getUserById(id);
|
|
341
|
+
|
|
261
342
|
if (!user) {
|
|
262
|
-
throw new
|
|
343
|
+
throw new NotFoundException({
|
|
263
344
|
message: `User with ID ${id} not found`,
|
|
264
345
|
code: 'USER_NOT_FOUND'
|
|
265
346
|
});
|
|
266
347
|
}
|
|
348
|
+
|
|
267
349
|
if (verificationType === 'email') {
|
|
268
350
|
user.emailVerifiedAt = null;
|
|
269
|
-
}
|
|
270
|
-
else if (verificationType === 'phone') {
|
|
351
|
+
} else if (verificationType === 'phone') {
|
|
271
352
|
user.phoneVerifiedAt = null;
|
|
272
353
|
}
|
|
354
|
+
|
|
273
355
|
user.isVerified = false;
|
|
356
|
+
|
|
357
|
+
// Update isVerified flag based on remaining verification status
|
|
274
358
|
user.isVerified = Boolean(user.emailVerifiedAt || user.phoneVerifiedAt);
|
|
359
|
+
|
|
275
360
|
return this.userRepository.save(user);
|
|
276
361
|
}
|
|
277
|
-
|
|
362
|
+
|
|
363
|
+
async updateUserStatus(id: string, isActive: boolean): Promise<NestAuthUser> {
|
|
278
364
|
const user = await this.getUserById(id);
|
|
365
|
+
|
|
279
366
|
if (!user) {
|
|
280
|
-
throw new
|
|
367
|
+
throw new NotFoundException({
|
|
281
368
|
message: `User with ID ${id} not found`,
|
|
282
369
|
code: 'USER_NOT_FOUND'
|
|
283
370
|
});
|
|
284
371
|
}
|
|
372
|
+
|
|
285
373
|
user.isActive = isActive;
|
|
286
374
|
return this.userRepository.save(user);
|
|
287
375
|
}
|
|
288
|
-
|
|
376
|
+
|
|
377
|
+
async updateUserMetadata(id: string, metadata: Record<string, any>): Promise<NestAuthUser> {
|
|
289
378
|
const user = await this.getUserById(id);
|
|
379
|
+
|
|
290
380
|
if (!user) {
|
|
291
|
-
throw new
|
|
381
|
+
throw new NotFoundException({
|
|
292
382
|
message: `User with ID ${id} not found`,
|
|
293
383
|
code: 'USER_NOT_FOUND'
|
|
294
384
|
});
|
|
295
385
|
}
|
|
386
|
+
|
|
296
387
|
user.metadata = {
|
|
297
388
|
...user.metadata,
|
|
298
389
|
...metadata
|
|
299
390
|
};
|
|
391
|
+
|
|
300
392
|
return this.userRepository.save(user);
|
|
301
393
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
394
|
+
|
|
395
|
+
async countUsers(options?: FindManyOptions<NestAuthUser>): Promise<number> {
|
|
396
|
+
return this.userRepository.count(options);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
async getUsersAndCount(options?: FindManyOptions<NestAuthUser>): Promise<[NestAuthUser[], number]> {
|
|
400
|
+
return this.userRepository.findAndCount(options);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
async getUsersByRole(roleName: string, guard: string): Promise<NestAuthUser[]> {
|
|
404
|
+
this.debugLogger.debug('Getting users by role', 'UserService', { roleName, guard });
|
|
405
|
+
|
|
406
|
+
const users = await this.userRepository
|
|
407
|
+
.createQueryBuilder('user')
|
|
408
|
+
.leftJoinAndSelect('user.roles', 'role')
|
|
409
|
+
.where('role.name = :roleName', { roleName })
|
|
410
|
+
.andWhere('role.guard = :guard', { guard })
|
|
411
|
+
.getMany();
|
|
412
|
+
|
|
413
|
+
this.debugLogger.debug('Found users with role', 'UserService', { roleName, count: users.length });
|
|
414
|
+
return users;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { forwardRef, Module } from '@nestjs/common';
|
|
2
|
+
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
3
|
+
import { NestAuthUser } from './entities/user.entity';
|
|
4
|
+
import { UserService } from './services/user.service';
|
|
5
|
+
import { AccessKeyService } from './services/access-key.service';
|
|
6
|
+
import { AuthModule } from '../auth/auth.module';
|
|
7
|
+
import { NestAuthAccessKey } from './entities/access-key.entity';
|
|
8
|
+
import { NestAuthIdentity } from './entities/identity.entity';
|
|
9
|
+
import { TenantModule } from '../tenant/tenant.module';
|
|
10
|
+
|
|
11
|
+
@Module({
|
|
12
|
+
imports: [
|
|
13
|
+
TypeOrmModule.forFeature([NestAuthUser, NestAuthAccessKey, NestAuthIdentity]),
|
|
14
|
+
forwardRef(() => AuthModule),
|
|
15
|
+
forwardRef(() => TenantModule),
|
|
16
|
+
],
|
|
17
|
+
providers: [
|
|
18
|
+
UserService,
|
|
19
|
+
AccessKeyService,
|
|
20
|
+
],
|
|
21
|
+
exports: [
|
|
22
|
+
UserService,
|
|
23
|
+
AccessKeyService,
|
|
24
|
+
],
|
|
25
|
+
})
|
|
26
|
+
export class UserModule { }
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import ms from 'ms';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Date and time utilities
|
|
5
|
+
*/
|
|
6
|
+
export class DateUtil {
|
|
7
|
+
/**
|
|
8
|
+
* Parse duration string to milliseconds
|
|
9
|
+
*/
|
|
10
|
+
static parseDuration(duration: string | number): number {
|
|
11
|
+
if (typeof duration === 'number') {
|
|
12
|
+
return duration;
|
|
13
|
+
}
|
|
14
|
+
return ms(duration);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Add duration to date
|
|
19
|
+
*/
|
|
20
|
+
static addDuration(date: Date, duration: string | number): Date {
|
|
21
|
+
const milliseconds = this.parseDuration(duration);
|
|
22
|
+
return new Date(date.getTime() + milliseconds);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Check if date is in the past
|
|
27
|
+
*/
|
|
28
|
+
static isPast(date: Date): boolean {
|
|
29
|
+
return date < new Date();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Check if date is in the future
|
|
34
|
+
*/
|
|
35
|
+
static isFuture(date: Date): boolean {
|
|
36
|
+
return date > new Date();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Get time remaining until date
|
|
41
|
+
*/
|
|
42
|
+
static getTimeUntil(date: Date): {
|
|
43
|
+
milliseconds: number;
|
|
44
|
+
seconds: number;
|
|
45
|
+
minutes: number;
|
|
46
|
+
hours: number;
|
|
47
|
+
days: number;
|
|
48
|
+
formatted: string;
|
|
49
|
+
} {
|
|
50
|
+
const remaining = Math.max(0, date.getTime() - Date.now());
|
|
51
|
+
const seconds = Math.floor(remaining / 1000);
|
|
52
|
+
const minutes = Math.floor(seconds / 60);
|
|
53
|
+
const hours = Math.floor(minutes / 60);
|
|
54
|
+
const days = Math.floor(hours / 24);
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
milliseconds: remaining,
|
|
58
|
+
seconds,
|
|
59
|
+
minutes,
|
|
60
|
+
hours,
|
|
61
|
+
days,
|
|
62
|
+
formatted: ms(remaining, { long: true }),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Format date for display
|
|
68
|
+
*/
|
|
69
|
+
static format(date: Date, format: 'short' | 'long' | 'iso' = 'short'): string {
|
|
70
|
+
switch (format) {
|
|
71
|
+
case 'long':
|
|
72
|
+
return date.toLocaleString();
|
|
73
|
+
case 'iso':
|
|
74
|
+
return date.toISOString();
|
|
75
|
+
case 'short':
|
|
76
|
+
default:
|
|
77
|
+
return date.toLocaleDateString();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Get relative time (e.g., "2 hours ago")
|
|
83
|
+
*/
|
|
84
|
+
static getRelativeTime(date: Date): string {
|
|
85
|
+
const diff = Date.now() - date.getTime();
|
|
86
|
+
|
|
87
|
+
if (diff < 0) {
|
|
88
|
+
return 'in the future';
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const seconds = Math.floor(diff / 1000);
|
|
92
|
+
const minutes = Math.floor(seconds / 60);
|
|
93
|
+
const hours = Math.floor(minutes / 60);
|
|
94
|
+
const days = Math.floor(hours / 24);
|
|
95
|
+
const months = Math.floor(days / 30);
|
|
96
|
+
const years = Math.floor(days / 365);
|
|
97
|
+
|
|
98
|
+
if (years > 0) return `${years} year${years > 1 ? 's' : ''} ago`;
|
|
99
|
+
if (months > 0) return `${months} month${months > 1 ? 's' : ''} ago`;
|
|
100
|
+
if (days > 0) return `${days} day${days > 1 ? 's' : ''} ago`;
|
|
101
|
+
if (hours > 0) return `${hours} hour${hours > 1 ? 's' : ''} ago`;
|
|
102
|
+
if (minutes > 0) return `${minutes} minute${minutes > 1 ? 's' : ''} ago`;
|
|
103
|
+
if (seconds > 10) return `${seconds} seconds ago`;
|
|
104
|
+
return 'just now';
|
|
105
|
+
}
|
|
106
|
+
}
|