@ackplus/nest-auth 1.1.1 → 1.1.2
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/package.json +2 -2
- package/src/{index.ts → index.d.ts} +2 -18
- package/src/index.d.ts.map +1 -0
- package/src/index.js +24 -0
- package/src/lib/admin-console/admin-console.module.d.ts +3 -0
- package/src/lib/admin-console/admin-console.module.d.ts.map +1 -0
- package/src/lib/admin-console/admin-console.module.js +69 -0
- package/src/lib/admin-console/controllers/admin-auth.controller.d.ts +134 -0
- package/src/lib/admin-console/controllers/admin-auth.controller.d.ts.map +1 -0
- package/src/lib/admin-console/controllers/admin-auth.controller.js +374 -0
- package/src/lib/admin-console/controllers/admin-console.controller.d.ts +14 -0
- package/src/lib/admin-console/controllers/admin-console.controller.d.ts.map +1 -0
- package/src/lib/admin-console/controllers/admin-console.controller.js +87 -0
- package/src/lib/admin-console/controllers/admin-permissions.controller.d.ts +86 -0
- package/src/lib/admin-console/controllers/admin-permissions.controller.d.ts.map +1 -0
- package/src/lib/admin-console/controllers/admin-permissions.controller.js +195 -0
- package/src/lib/admin-console/controllers/admin-roles.controller.d.ts +47 -0
- package/src/lib/admin-console/controllers/admin-roles.controller.d.ts.map +1 -0
- package/src/lib/admin-console/controllers/admin-roles.controller.js +95 -0
- package/src/lib/admin-console/controllers/admin-tenants.controller.d.ts +44 -0
- package/src/lib/admin-console/controllers/admin-tenants.controller.d.ts.map +1 -0
- package/src/lib/admin-console/controllers/admin-tenants.controller.js +86 -0
- package/src/lib/admin-console/controllers/admin-users.controller.d.ts +146 -0
- package/src/lib/admin-console/controllers/admin-users.controller.d.ts.map +1 -0
- package/src/lib/admin-console/controllers/admin-users.controller.js +400 -0
- package/src/lib/admin-console/decorators/current-admin.decorator.d.ts +2 -0
- package/src/lib/admin-console/decorators/current-admin.decorator.d.ts.map +1 -0
- package/src/lib/admin-console/decorators/current-admin.decorator.js +8 -0
- package/src/lib/admin-console/dto/admin-permission.dto.d.ts +16 -0
- package/src/lib/admin-console/dto/admin-permission.dto.d.ts.map +1 -0
- package/src/lib/admin-console/dto/admin-permission.dto.js +123 -0
- package/src/lib/admin-console/dto/admin-role.dto.d.ts +13 -0
- package/src/lib/admin-console/dto/admin-role.dto.d.ts.map +1 -0
- package/src/lib/admin-console/dto/admin-role.dto.js +53 -0
- package/src/lib/admin-console/dto/admin-tenant.dto.d.ts +13 -0
- package/src/lib/admin-console/dto/admin-tenant.dto.d.ts.map +1 -0
- package/src/lib/admin-console/dto/admin-tenant.dto.js +57 -0
- package/src/lib/admin-console/dto/admin-user.dto.d.ts +21 -0
- package/src/lib/admin-console/dto/admin-user.dto.d.ts.map +1 -0
- package/src/lib/admin-console/dto/admin-user.dto.js +94 -0
- package/src/lib/admin-console/dto/create-dashboard-admin.dto.d.ts +10 -0
- package/src/lib/admin-console/dto/create-dashboard-admin.dto.d.ts.map +1 -0
- package/src/lib/admin-console/dto/create-dashboard-admin.dto.js +39 -0
- package/src/lib/admin-console/dto/login.dto.d.ts +5 -0
- package/src/lib/admin-console/dto/login.dto.d.ts.map +1 -0
- package/src/lib/admin-console/dto/login.dto.js +17 -0
- package/src/lib/admin-console/dto/reset-password.dto.d.ts +6 -0
- package/src/lib/admin-console/dto/reset-password.dto.d.ts.map +1 -0
- package/src/lib/admin-console/dto/reset-password.dto.js +26 -0
- package/src/lib/admin-console/dto/setup-admin.dto.d.ts +7 -0
- package/src/lib/admin-console/dto/setup-admin.dto.d.ts.map +1 -0
- package/src/lib/admin-console/dto/setup-admin.dto.js +29 -0
- package/src/lib/admin-console/dto/signup.dto.d.ts +8 -0
- package/src/lib/admin-console/dto/signup.dto.d.ts.map +1 -0
- package/src/lib/admin-console/dto/signup.dto.js +58 -0
- package/src/lib/admin-console/entities/admin-user.entity.d.ts +16 -0
- package/src/lib/admin-console/entities/admin-user.entity.d.ts.map +1 -0
- package/src/lib/admin-console/entities/admin-user.entity.js +86 -0
- package/src/lib/admin-console/guards/admin-session.guard.d.ts +17 -0
- package/src/lib/admin-console/guards/admin-session.guard.d.ts.map +1 -0
- package/src/lib/admin-console/guards/admin-session.guard.js +40 -0
- package/src/lib/admin-console/services/admin-auth.service.d.ts +22 -0
- package/src/lib/admin-console/services/admin-auth.service.d.ts.map +1 -0
- package/src/lib/admin-console/services/admin-auth.service.js +77 -0
- package/src/lib/admin-console/services/admin-console-config.service.d.ts +17 -0
- package/src/lib/admin-console/services/admin-console-config.service.d.ts.map +1 -0
- package/src/lib/admin-console/services/admin-console-config.service.js +58 -0
- package/src/lib/admin-console/services/admin-session.service.d.ts +27 -0
- package/src/lib/admin-console/services/admin-session.service.d.ts.map +1 -0
- package/src/lib/admin-console/services/admin-session.service.js +94 -0
- package/src/lib/admin-console/services/admin-user.service.d.ts +24 -0
- package/src/lib/admin-console/services/admin-user.service.d.ts.map +1 -0
- package/src/lib/admin-console/services/admin-user.service.js +87 -0
- package/src/lib/auth/auth.module.d.ts +3 -0
- package/src/lib/auth/auth.module.d.ts.map +1 -0
- package/src/lib/auth/auth.module.js +64 -0
- package/src/lib/auth/controllers/auth.controller.d.ts +67 -0
- package/src/lib/auth/controllers/auth.controller.d.ts.map +1 -0
- package/src/lib/auth/controllers/auth.controller.js +471 -0
- package/src/lib/auth/controllers/mfa.controller.d.ts +34 -0
- package/src/lib/auth/controllers/mfa.controller.d.ts.map +1 -0
- package/src/lib/auth/controllers/mfa.controller.js +230 -0
- package/src/lib/auth/dto/credentials/email-credentials.dto.d.ts +8 -0
- package/src/lib/auth/dto/credentials/email-credentials.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/credentials/email-credentials.dto.js +31 -0
- package/src/lib/auth/dto/credentials/phone-credentials.dto.d.ts +8 -0
- package/src/lib/auth/dto/credentials/phone-credentials.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/credentials/phone-credentials.dto.js +31 -0
- package/src/lib/auth/dto/credentials/social-credentials.dto.d.ts +7 -0
- package/src/lib/auth/dto/credentials/social-credentials.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/credentials/social-credentials.dto.js +21 -0
- package/src/lib/auth/dto/index.d.ts +1 -0
- package/src/lib/auth/dto/index.d.ts.map +1 -0
- package/src/lib/auth/dto/index.js +0 -0
- package/src/lib/auth/dto/requests/change-password.request.dto.d.ts +5 -0
- package/src/lib/auth/dto/requests/change-password.request.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/requests/change-password.request.dto.js +42 -0
- package/src/lib/auth/dto/requests/forgot-password.request.dto.d.ts +6 -0
- package/src/lib/auth/dto/requests/forgot-password.request.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/requests/forgot-password.request.dto.js +38 -0
- package/src/lib/auth/dto/requests/initialize-admin.request.dto.d.ts +8 -0
- package/src/lib/auth/dto/requests/initialize-admin.request.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/requests/initialize-admin.request.dto.js +58 -0
- package/src/lib/auth/dto/requests/login.request.dto.d.ts +13 -0
- package/src/lib/auth/dto/requests/login.request.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/requests/login.request.dto.js +75 -0
- package/src/lib/auth/dto/requests/refresh-token.request.dto.d.ts +4 -0
- package/src/lib/auth/dto/requests/refresh-token.request.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/requests/refresh-token.request.dto.js +18 -0
- package/src/lib/auth/dto/requests/reset-password-with-token.request.dto.d.ts +5 -0
- package/src/lib/auth/dto/requests/reset-password-with-token.request.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/requests/reset-password-with-token.request.dto.js +29 -0
- package/src/lib/auth/dto/requests/reset-password.request.dto.d.ts +8 -0
- package/src/lib/auth/dto/requests/reset-password.request.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/requests/reset-password.request.dto.js +60 -0
- package/src/lib/auth/dto/requests/send-email-verification.request.dto.d.ts +4 -0
- package/src/lib/auth/dto/requests/send-email-verification.request.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/requests/send-email-verification.request.dto.js +18 -0
- package/src/lib/auth/dto/requests/send-mfa-code.request.dto.d.ts +5 -0
- package/src/lib/auth/dto/requests/send-mfa-code.request.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/requests/send-mfa-code.request.dto.js +25 -0
- package/src/lib/auth/dto/requests/signup.request.dto.d.ts +8 -0
- package/src/lib/auth/dto/requests/signup.request.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/requests/signup.request.dto.js +49 -0
- package/src/lib/auth/dto/requests/toggle-mfa.request.dto.d.ts +4 -0
- package/src/lib/auth/dto/requests/toggle-mfa.request.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/requests/toggle-mfa.request.dto.js +18 -0
- package/src/lib/auth/dto/requests/verify-2fa.request.dto.d.ts +6 -0
- package/src/lib/auth/dto/requests/verify-2fa.request.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/requests/verify-2fa.request.dto.js +31 -0
- package/src/lib/auth/dto/requests/verify-email.request.dto.d.ts +5 -0
- package/src/lib/auth/dto/requests/verify-email.request.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/requests/verify-email.request.dto.js +29 -0
- package/src/lib/auth/dto/requests/verify-forgot-password-otp-request-dto.d.ts +7 -0
- package/src/lib/auth/dto/requests/verify-forgot-password-otp-request-dto.d.ts.map +1 -0
- package/src/lib/auth/dto/requests/verify-forgot-password-otp-request-dto.js +49 -0
- package/src/lib/auth/dto/requests/verify-totp-setup.request.dto.d.ts +5 -0
- package/src/lib/auth/dto/requests/verify-totp-setup.request.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/requests/verify-totp-setup.request.dto.js +29 -0
- package/src/lib/auth/dto/responses/auth-cookie.response.dto.d.ts +41 -0
- package/src/lib/auth/dto/responses/auth-cookie.response.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/responses/{auth-cookie.response.dto.ts → auth-cookie.response.dto.js} +18 -11
- package/src/lib/auth/dto/responses/auth-success.response.dto.d.ts +41 -0
- package/src/lib/auth/dto/responses/auth-success.response.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/responses/{auth-success.response.dto.ts → auth-success.response.dto.js} +18 -11
- package/src/lib/auth/dto/responses/auth.response.dto.d.ts +40 -0
- package/src/lib/auth/dto/responses/auth.response.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/responses/auth.response.dto.js +112 -0
- package/src/lib/auth/dto/responses/client-config.response.dto.d.ts +58 -0
- package/src/lib/auth/dto/responses/client-config.response.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/responses/client-config.response.dto.js +202 -0
- package/src/lib/auth/dto/responses/initialize-admin.response.dto.d.ts +7 -0
- package/src/lib/auth/dto/responses/initialize-admin.response.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/responses/initialize-admin.response.dto.js +30 -0
- package/src/lib/auth/dto/responses/mfa-code-response.dto.d.ts +7 -0
- package/src/lib/auth/dto/responses/mfa-code-response.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/responses/mfa-code-response.dto.js +36 -0
- package/src/lib/auth/dto/responses/mfa-status.response.dto.d.ts +19 -0
- package/src/lib/auth/dto/responses/mfa-status.response.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/responses/mfa-status.response.dto.js +108 -0
- package/src/lib/auth/dto/responses/verify-otp.response.dto.d.ts +5 -0
- package/src/lib/auth/dto/responses/verify-otp.response.dto.d.ts.map +1 -0
- package/src/lib/auth/dto/responses/verify-otp.response.dto.js +16 -0
- package/src/lib/auth/entities/mfa-secret.entity.d.ts +13 -0
- package/src/lib/auth/entities/mfa-secret.entity.d.ts.map +1 -0
- package/src/lib/auth/entities/mfa-secret.entity.js +49 -0
- package/src/lib/auth/entities/otp.entity.d.ts +14 -0
- package/src/lib/auth/entities/otp.entity.d.ts.map +1 -0
- package/src/lib/auth/entities/otp.entity.js +49 -0
- package/src/lib/auth/events/{logged-out-all.event.ts → logged-out-all.event.d.ts} +4 -6
- package/src/lib/auth/events/logged-out-all.event.d.ts.map +1 -0
- package/src/lib/auth/events/logged-out-all.event.js +9 -0
- package/src/lib/auth/events/{logged-out.event.ts → logged-out.event.d.ts} +4 -5
- package/src/lib/auth/events/logged-out.event.d.ts.map +1 -0
- package/src/lib/auth/events/logged-out.event.js +9 -0
- package/src/lib/auth/events/{password-reset-requested.event.ts → password-reset-requested.event.d.ts} +4 -6
- package/src/lib/auth/events/password-reset-requested.event.d.ts.map +1 -0
- package/src/lib/auth/events/password-reset-requested.event.js +9 -0
- package/src/lib/auth/events/{password-reset.event.ts → password-reset.event.d.ts} +4 -6
- package/src/lib/auth/events/password-reset.event.d.ts.map +1 -0
- package/src/lib/auth/events/password-reset.event.js +9 -0
- package/src/lib/auth/events/{user-2fa-verified.event.ts → user-2fa-verified.event.d.ts} +4 -6
- package/src/lib/auth/events/user-2fa-verified.event.d.ts.map +1 -0
- package/src/lib/auth/events/user-2fa-verified.event.js +9 -0
- package/src/lib/auth/events/{user-logged-in.event.ts → user-logged-in.event.d.ts} +4 -7
- package/src/lib/auth/events/user-logged-in.event.d.ts.map +1 -0
- package/src/lib/auth/events/user-logged-in.event.js +10 -0
- package/src/lib/auth/events/{user-refresh-token.event.ts → user-refresh-token.event.d.ts} +4 -6
- package/src/lib/auth/events/user-refresh-token.event.d.ts.map +1 -0
- package/src/lib/auth/events/user-refresh-token.event.js +9 -0
- package/src/lib/auth/events/{user-registered.event.ts → user-registered.event.d.ts} +4 -7
- package/src/lib/auth/events/user-registered.event.d.ts.map +1 -0
- package/src/lib/auth/events/user-registered.event.js +10 -0
- package/src/lib/auth/guards/auth.guard.d.ts +56 -0
- package/src/lib/auth/guards/auth.guard.d.ts.map +1 -0
- package/src/lib/auth/guards/{auth.guard.ts → auth.guard.js} +92 -135
- package/src/lib/auth/{index.ts → index.d.ts} +1 -13
- package/src/lib/auth/index.d.ts.map +1 -0
- package/src/lib/auth/index.js +51 -0
- package/src/lib/auth/interceptors/refresh-token.interceptor.d.ts +43 -0
- package/src/lib/auth/interceptors/refresh-token.interceptor.d.ts.map +1 -0
- package/src/lib/auth/interceptors/{refresh-token.interceptor.ts → refresh-token.interceptor.js} +38 -40
- package/src/lib/auth/services/auth.service.d.ts +67 -0
- package/src/lib/auth/services/auth.service.d.ts.map +1 -0
- package/src/lib/auth/services/{auth.service.ts → auth.service.js} +262 -475
- package/src/lib/auth/services/client-config.service.d.ts +12 -0
- package/src/lib/auth/services/client-config.service.d.ts.map +1 -0
- package/src/lib/auth/services/{client-config.service.ts → client-config.service.js} +28 -33
- package/src/lib/auth/services/cookie.service.d.ts +10 -0
- package/src/lib/auth/services/cookie.service.d.ts.map +1 -0
- package/src/lib/auth/services/cookie.service.js +42 -0
- package/src/lib/auth/services/mfa.service.d.ts +45 -0
- package/src/lib/auth/services/mfa.service.d.ts.map +1 -0
- package/src/lib/auth/services/{mfa.service.ts → mfa.service.js} +105 -184
- package/src/lib/auth.constants.d.ts +43 -0
- package/src/lib/auth.constants.d.ts.map +1 -0
- package/src/lib/auth.constants.js +54 -0
- package/src/lib/core/core.module.d.ts +7 -0
- package/src/lib/core/core.module.d.ts.map +1 -0
- package/src/lib/core/core.module.js +57 -0
- package/src/lib/core/decorators/{auth.decorator.ts → auth.decorator.d.ts} +2 -7
- package/src/lib/core/decorators/auth.decorator.d.ts.map +1 -0
- package/src/lib/core/decorators/auth.decorator.js +38 -0
- package/src/lib/core/decorators/permissions.decorator.d.ts +8 -0
- package/src/lib/core/decorators/permissions.decorator.d.ts.map +1 -0
- package/src/lib/core/decorators/permissions.decorator.js +18 -0
- package/src/lib/core/decorators/{public.decorator.ts → public.decorator.d.ts} +3 -5
- package/src/lib/core/decorators/public.decorator.d.ts.map +1 -0
- package/src/lib/core/decorators/public.decorator.js +35 -0
- package/src/lib/core/decorators/role.decorator.d.ts +4 -0
- package/src/lib/core/decorators/role.decorator.d.ts.map +1 -0
- package/src/lib/core/decorators/role.decorator.js +13 -0
- package/src/lib/core/decorators/skip-mfa.decorator.d.ts +3 -0
- package/src/lib/core/decorators/skip-mfa.decorator.d.ts.map +1 -0
- package/src/lib/core/decorators/skip-mfa.decorator.js +7 -0
- package/src/lib/core/dto/message.response.dto.d.ts +4 -0
- package/src/lib/core/dto/message.response.dto.d.ts.map +1 -0
- package/src/lib/core/dto/message.response.dto.js +12 -0
- package/src/lib/core/{entities.ts → entities.d.ts} +2 -14
- package/src/lib/core/entities.d.ts.map +1 -0
- package/src/lib/core/entities.js +37 -0
- package/src/lib/core/{index.ts → index.d.ts} +1 -15
- package/src/lib/core/index.d.ts.map +1 -0
- package/src/lib/core/index.js +35 -0
- package/src/lib/core/interfaces/{auth-module-options.interface.ts → auth-module-options.interface.d.ts} +13 -16
- package/src/lib/core/interfaces/auth-module-options.interface.d.ts.map +1 -0
- package/src/lib/core/interfaces/auth-module-options.interface.js +2 -0
- package/src/lib/core/interfaces/mfa-options.interface.d.ts +26 -0
- package/src/lib/core/interfaces/mfa-options.interface.d.ts.map +1 -0
- package/src/lib/core/interfaces/mfa-options.interface.js +9 -0
- package/src/lib/core/interfaces/otp.interface.d.ts +6 -0
- package/src/lib/core/interfaces/otp.interface.d.ts.map +1 -0
- package/src/lib/core/interfaces/otp.interface.js +9 -0
- package/src/lib/core/interfaces/session-options.interface.d.ts +16 -0
- package/src/lib/core/interfaces/session-options.interface.d.ts.map +1 -0
- package/src/lib/core/interfaces/session-options.interface.js +9 -0
- package/src/lib/core/interfaces/{token-payload.interface.ts → token-payload.interface.d.ts} +2 -4
- package/src/lib/core/interfaces/token-payload.interface.d.ts.map +1 -0
- package/src/lib/core/interfaces/token-payload.interface.js +2 -0
- package/src/lib/core/providers/apple-auth.provider.d.ts +19 -0
- package/src/lib/core/providers/apple-auth.provider.d.ts.map +1 -0
- package/src/lib/core/providers/apple-auth.provider.js +56 -0
- package/src/lib/core/providers/base-auth.provider.d.ts +33 -0
- package/src/lib/core/providers/base-auth.provider.d.ts.map +1 -0
- package/src/lib/core/providers/base-auth.provider.js +48 -0
- package/src/lib/core/providers/email-auth.provider.d.ts +31 -0
- package/src/lib/core/providers/email-auth.provider.d.ts.map +1 -0
- package/src/lib/core/providers/email-auth.provider.js +66 -0
- package/src/lib/core/providers/facebook-auth.provider.d.ts +19 -0
- package/src/lib/core/providers/facebook-auth.provider.d.ts.map +1 -0
- package/src/lib/core/providers/facebook-auth.provider.js +55 -0
- package/src/lib/core/providers/github-auth.provider.d.ts +24 -0
- package/src/lib/core/providers/github-auth.provider.d.ts.map +1 -0
- package/src/lib/core/providers/{github-auth.provider.ts → github-auth.provider.js} +31 -36
- package/src/lib/core/providers/google-auth.provider.d.ts +22 -0
- package/src/lib/core/providers/google-auth.provider.d.ts.map +1 -0
- package/src/lib/core/providers/google-auth.provider.js +57 -0
- package/src/lib/core/providers/jwt-auth.provider.d.ts +34 -0
- package/src/lib/core/providers/jwt-auth.provider.d.ts.map +1 -0
- package/src/lib/core/providers/jwt-auth.provider.js +49 -0
- package/src/lib/core/providers/phone-auth.provider.d.ts +19 -0
- package/src/lib/core/providers/phone-auth.provider.d.ts.map +1 -0
- package/src/lib/core/providers/phone-auth.provider.js +42 -0
- package/src/lib/core/services/auth-config.service.d.ts +39 -0
- package/src/lib/core/services/auth-config.service.d.ts.map +1 -0
- package/src/lib/core/services/auth-config.service.js +167 -0
- package/src/lib/core/services/auth-provider-registry.service.d.ts +42 -0
- package/src/lib/core/services/auth-provider-registry.service.d.ts.map +1 -0
- package/src/lib/core/services/auth-provider-registry.service.js +91 -0
- package/src/lib/core/services/debug-logger.service.d.ts +39 -0
- package/src/lib/core/services/debug-logger.service.d.ts.map +1 -0
- package/src/lib/core/services/{debug-logger.service.ts → debug-logger.service.js} +57 -88
- package/src/lib/core/services/initialization.service.d.ts +11 -0
- package/src/lib/core/services/initialization.service.d.ts.map +1 -0
- package/src/lib/core/services/initialization.service.js +35 -0
- package/src/lib/core/services/jwt.service.d.ts +23 -0
- package/src/lib/core/services/jwt.service.d.ts.map +1 -0
- package/src/lib/core/services/jwt.service.js +119 -0
- package/src/lib/nest-auth.module.d.ts +11 -0
- package/src/lib/nest-auth.module.d.ts.map +1 -0
- package/src/lib/nest-auth.module.js +144 -0
- package/src/lib/permission/entities/permission.entity.d.ts +27 -0
- package/src/lib/permission/entities/permission.entity.d.ts.map +1 -0
- package/src/lib/permission/entities/permission.entity.js +62 -0
- package/src/lib/permission/{index.ts → index.d.ts} +1 -1
- package/src/lib/permission/index.d.ts.map +1 -0
- package/src/lib/permission/index.js +6 -0
- package/src/lib/permission/permission.module.d.ts +3 -0
- package/src/lib/permission/permission.module.d.ts.map +1 -0
- package/src/lib/permission/permission.module.js +20 -0
- package/src/lib/permission/services/permission.service.d.ts +44 -0
- package/src/lib/permission/services/permission.service.d.ts.map +1 -0
- package/src/lib/permission/services/{permission.service.ts → permission.service.js} +48 -108
- package/src/lib/request-context/{index.ts → index.d.ts} +1 -0
- package/src/lib/request-context/index.d.ts.map +1 -0
- package/src/lib/request-context/index.js +5 -0
- package/src/lib/request-context/request-context.d.ts +23 -0
- package/src/lib/request-context/request-context.d.ts.map +1 -0
- package/src/lib/request-context/{request-context.ts → request-context.js} +26 -44
- package/src/lib/request-context/request-context.middleware.d.ts +5 -0
- package/src/lib/request-context/request-context.middleware.d.ts.map +1 -0
- package/src/lib/request-context/request-context.middleware.js +15 -0
- package/src/lib/role/entities/role.entity.d.ts +21 -0
- package/src/lib/role/entities/role.entity.d.ts.map +1 -0
- package/src/lib/role/entities/role.entity.js +110 -0
- package/src/lib/role/{index.ts → index.d.ts} +1 -2
- package/src/lib/role/index.d.ts.map +1 -0
- package/src/lib/role/index.js +5 -0
- package/src/lib/role/role.module.d.ts +3 -0
- package/src/lib/role/role.module.d.ts.map +1 -0
- package/src/lib/role/role.module.js +22 -0
- package/src/lib/role/services/role.service.d.ts +21 -0
- package/src/lib/role/services/role.service.d.ts.map +1 -0
- package/src/lib/role/services/{role.service.ts → role.service.js} +51 -107
- package/src/lib/session/entities/session.entity.d.ts +17 -0
- package/src/lib/session/entities/session.entity.d.ts.map +1 -0
- package/src/lib/session/entities/session.entity.js +62 -0
- package/src/lib/session/{index.ts → index.d.ts} +1 -11
- package/src/lib/session/index.d.ts.map +1 -0
- package/src/lib/session/index.js +18 -0
- package/src/lib/session/interfaces/{session-repository.interface.ts → session-repository.interface.d.ts} +1 -10
- package/src/lib/session/interfaces/session-repository.interface.d.ts.map +1 -0
- package/src/lib/session/interfaces/session-repository.interface.js +2 -0
- package/src/lib/session/repositories/{base-session.repository.ts → base-session.repository.d.ts} +7 -41
- package/src/lib/session/repositories/base-session.repository.d.ts.map +1 -0
- package/src/lib/session/repositories/base-session.repository.js +59 -0
- package/src/lib/session/repositories/memory-session.repository.d.ts +27 -0
- package/src/lib/session/repositories/memory-session.repository.d.ts.map +1 -0
- package/src/lib/session/repositories/{memory-session.repository.ts → memory-session.repository.js} +41 -61
- package/src/lib/session/repositories/redis-session.repository.d.ts +30 -0
- package/src/lib/session/repositories/redis-session.repository.d.ts.map +1 -0
- package/src/lib/session/repositories/{redis-session.repository.ts → redis-session.repository.js} +45 -75
- package/src/lib/session/repositories/typeorm-session.repository.d.ts +23 -0
- package/src/lib/session/repositories/typeorm-session.repository.d.ts.map +1 -0
- package/src/lib/session/repositories/typeorm-session.repository.js +79 -0
- package/src/lib/session/services/session-manager.service.d.ts +100 -0
- package/src/lib/session/services/session-manager.service.d.ts.map +1 -0
- package/src/lib/session/services/{session-manager.service.ts → session-manager.service.js} +54 -94
- package/src/lib/session/session.module.d.ts +14 -0
- package/src/lib/session/session.module.d.ts.map +1 -0
- package/src/lib/session/session.module.js +96 -0
- package/src/lib/session/utils/session.util.d.ts +73 -0
- package/src/lib/session/utils/session.util.d.ts.map +1 -0
- package/src/lib/session/utils/{session.util.ts → session.util.js} +24 -63
- package/src/lib/tenant/entities/{tenant.entity.ts → tenant.entity.d.ts} +2 -21
- package/src/lib/tenant/entities/tenant.entity.d.ts.map +1 -0
- package/src/lib/tenant/entities/tenant.entity.js +47 -0
- package/src/lib/tenant/events/tenant-created.event.d.ts +9 -0
- package/src/lib/tenant/events/tenant-created.event.d.ts.map +1 -0
- package/src/lib/tenant/events/tenant-created.event.js +9 -0
- package/src/lib/tenant/events/tenant-deleted.event.d.ts +9 -0
- package/src/lib/tenant/events/tenant-deleted.event.d.ts.map +1 -0
- package/src/lib/tenant/events/tenant-deleted.event.js +9 -0
- package/src/lib/tenant/events/tenant-updated.event.d.ts +10 -0
- package/src/lib/tenant/events/tenant-updated.event.d.ts.map +1 -0
- package/src/lib/tenant/events/tenant-updated.event.js +9 -0
- package/src/lib/tenant/{index.ts → index.d.ts} +1 -2
- package/src/lib/tenant/index.d.ts.map +1 -0
- package/src/lib/tenant/index.js +14 -0
- package/src/lib/tenant/services/tenant.service.d.ts +35 -0
- package/src/lib/tenant/services/tenant.service.d.ts.map +1 -0
- package/src/lib/tenant/services/{tenant.service.ts → tenant.service.js} +83 -137
- package/src/lib/tenant/tenant.module.d.ts +3 -0
- package/src/lib/tenant/tenant.module.d.ts.map +1 -0
- package/src/lib/tenant/tenant.module.js +26 -0
- package/src/lib/user/dto/requests/update-user.dto.d.ts +6 -0
- package/src/lib/user/dto/requests/update-user.dto.d.ts.map +1 -0
- package/src/lib/user/dto/requests/update-user.dto.js +23 -0
- package/src/lib/user/entities/access-key.entity.d.ts +17 -0
- package/src/lib/user/entities/access-key.entity.d.ts.map +1 -0
- package/src/lib/user/entities/access-key.entity.js +62 -0
- package/src/lib/user/entities/identity.entity.d.ts +13 -0
- package/src/lib/user/entities/identity.entity.d.ts.map +1 -0
- package/src/lib/user/entities/identity.entity.js +46 -0
- package/src/lib/user/entities/user.entity.d.ts +40 -0
- package/src/lib/user/entities/user.entity.d.ts.map +1 -0
- package/src/lib/user/entities/user.entity.js +218 -0
- package/src/lib/user/events/user-created.event.d.ts +10 -0
- package/src/lib/user/events/user-created.event.d.ts.map +1 -0
- package/src/lib/user/events/user-created.event.js +9 -0
- package/src/lib/user/events/user-deleted.event.d.ts +10 -0
- package/src/lib/user/events/user-deleted.event.d.ts.map +1 -0
- package/src/lib/user/events/user-deleted.event.js +9 -0
- package/src/lib/user/events/user-updated.event.d.ts +11 -0
- package/src/lib/user/events/user-updated.event.d.ts.map +1 -0
- package/src/lib/user/events/user-updated.event.js +9 -0
- package/src/lib/user/{index.ts → index.d.ts} +1 -5
- package/src/lib/user/index.d.ts.map +1 -0
- package/src/lib/user/index.js +12 -0
- package/src/lib/user/services/access-key.service.d.ts +20 -0
- package/src/lib/user/services/access-key.service.d.ts.map +1 -0
- package/src/lib/user/services/access-key.service.js +121 -0
- package/src/lib/user/services/user.service.d.ts +28 -0
- package/src/lib/user/services/user.service.d.ts.map +1 -0
- package/src/lib/user/services/{user.service.ts → user.service.js} +92 -164
- package/src/lib/user/user.module.d.ts +3 -0
- package/src/lib/user/user.module.d.ts.map +1 -0
- package/src/lib/user/user.module.js +33 -0
- package/src/lib/utils/database.utils.d.ts +3 -0
- package/src/lib/utils/database.utils.d.ts.map +1 -0
- package/src/lib/utils/database.utils.js +7 -0
- package/src/lib/utils/date.util.d.ts +41 -0
- package/src/lib/utils/date.util.d.ts.map +1 -0
- package/src/lib/utils/{date.util.ts → date.util.js} +28 -35
- package/src/lib/utils/device.util.d.ts +50 -0
- package/src/lib/utils/device.util.d.ts.map +1 -0
- package/src/lib/utils/device.util.js +114 -0
- package/src/lib/utils/{index.ts → index.d.ts} +1 -0
- package/src/lib/utils/index.d.ts.map +1 -0
- package/src/lib/utils/index.js +9 -0
- package/src/lib/utils/otp.d.ts +2 -0
- package/src/lib/utils/otp.d.ts.map +1 -0
- package/src/lib/utils/otp.js +6 -0
- package/src/lib/utils/security.util.d.ts +11 -0
- package/src/lib/utils/security.util.d.ts.map +1 -0
- package/src/lib/utils/{security.util.ts → security.util.js} +10 -9
- package/src/lib/utils/slug.util.d.ts +38 -0
- package/src/lib/utils/slug.util.d.ts.map +1 -0
- package/src/lib/utils/{slug.util.ts → slug.util.js} +10 -9
- package/eslint.config.mjs +0 -59
- package/jest.config.ts +0 -10
- package/project.json +0 -86
- package/src/lib/admin-console/admin-console.module.ts +0 -62
- package/src/lib/admin-console/controllers/admin-auth.controller.ts +0 -339
- package/src/lib/admin-console/controllers/admin-console.controller.ts +0 -82
- package/src/lib/admin-console/controllers/admin-permissions.controller.ts +0 -180
- package/src/lib/admin-console/controllers/admin-roles.controller.ts +0 -89
- package/src/lib/admin-console/controllers/admin-tenants.controller.ts +0 -68
- package/src/lib/admin-console/controllers/admin-users.controller.ts +0 -379
- package/src/lib/admin-console/decorators/current-admin.decorator.ts +0 -9
- package/src/lib/admin-console/dto/admin-permission.dto.ts +0 -106
- package/src/lib/admin-console/dto/admin-role.dto.ts +0 -45
- package/src/lib/admin-console/dto/admin-tenant.dto.ts +0 -43
- package/src/lib/admin-console/dto/admin-user.dto.ts +0 -87
- package/src/lib/admin-console/dto/create-dashboard-admin.dto.ts +0 -34
- package/src/lib/admin-console/dto/login.dto.ts +0 -10
- package/src/lib/admin-console/dto/reset-password.dto.ts +0 -21
- package/src/lib/admin-console/dto/setup-admin.dto.ts +0 -23
- package/src/lib/admin-console/dto/signup.dto.ts +0 -51
- package/src/lib/admin-console/entities/admin-user.entity.ts +0 -74
- package/src/lib/admin-console/guards/admin-session.guard.ts +0 -47
- package/src/lib/admin-console/services/admin-auth.service.ts +0 -82
- package/src/lib/admin-console/services/admin-console-config.service.ts +0 -62
- package/src/lib/admin-console/services/admin-session.service.ts +0 -106
- package/src/lib/admin-console/services/admin-user.service.ts +0 -96
- package/src/lib/auth/auth.module.ts +0 -58
- package/src/lib/auth/controllers/auth.controller.ts +0 -393
- package/src/lib/auth/controllers/mfa.controller.ts +0 -200
- package/src/lib/auth/dto/credentials/email-credentials.dto.ts +0 -24
- package/src/lib/auth/dto/credentials/phone-credentials.dto.ts +0 -24
- package/src/lib/auth/dto/credentials/social-credentials.dto.ts +0 -15
- package/src/lib/auth/dto/index.ts +0 -1
- package/src/lib/auth/dto/requests/change-password.request.dto.ts +0 -34
- package/src/lib/auth/dto/requests/forgot-password.request.dto.ts +0 -30
- package/src/lib/auth/dto/requests/initialize-admin.request.dto.ts +0 -51
- package/src/lib/auth/dto/requests/login.request.dto.ts +0 -65
- package/src/lib/auth/dto/requests/refresh-token.request.dto.ts +0 -12
- package/src/lib/auth/dto/requests/reset-password-with-token.request.dto.ts +0 -22
- package/src/lib/auth/dto/requests/reset-password.request.dto.ts +0 -50
- package/src/lib/auth/dto/requests/send-email-verification.request.dto.ts +0 -12
- package/src/lib/auth/dto/requests/send-mfa-code.request.dto.ts +0 -19
- package/src/lib/auth/dto/requests/signup.request.dto.ts +0 -42
- package/src/lib/auth/dto/requests/toggle-mfa.request.dto.ts +0 -12
- package/src/lib/auth/dto/requests/verify-2fa.request.dto.ts +0 -24
- package/src/lib/auth/dto/requests/verify-email.request.dto.ts +0 -22
- package/src/lib/auth/dto/requests/verify-forgot-password-otp-request-dto.ts +0 -41
- package/src/lib/auth/dto/requests/verify-totp-setup.request.dto.ts +0 -22
- package/src/lib/auth/dto/responses/auth.response.dto.ts +0 -99
- package/src/lib/auth/dto/responses/client-config.response.dto.ts +0 -153
- package/src/lib/auth/dto/responses/initialize-admin.response.dto.ts +0 -22
- package/src/lib/auth/dto/responses/mfa-code-response.dto.ts +0 -27
- package/src/lib/auth/dto/responses/mfa-status.response.dto.ts +0 -89
- package/src/lib/auth/dto/responses/verify-otp.response.dto.ts +0 -9
- package/src/lib/auth/entities/mfa-secret.entity.ts +0 -33
- package/src/lib/auth/entities/otp.entity.ts +0 -33
- package/src/lib/auth/services/cookie.service.ts +0 -43
- package/src/lib/auth.constants.ts +0 -63
- package/src/lib/core/core.module.ts +0 -50
- package/src/lib/core/decorators/permissions.decorator.ts +0 -17
- package/src/lib/core/decorators/role.decorator.ts +0 -12
- package/src/lib/core/decorators/skip-mfa.decorator.ts +0 -4
- package/src/lib/core/dto/message.response.dto.ts +0 -6
- package/src/lib/core/interfaces/mfa-options.interface.ts +0 -46
- package/src/lib/core/interfaces/otp.interface.ts +0 -6
- package/src/lib/core/interfaces/session-options.interface.ts +0 -19
- package/src/lib/core/providers/apple-auth.provider.ts +0 -61
- package/src/lib/core/providers/base-auth.provider.ts +0 -74
- package/src/lib/core/providers/email-auth.provider.ts +0 -71
- package/src/lib/core/providers/facebook-auth.provider.ts +0 -55
- package/src/lib/core/providers/google-auth.provider.ts +0 -61
- package/src/lib/core/providers/jwt-auth.provider.ts +0 -50
- package/src/lib/core/providers/phone-auth.provider.ts +0 -45
- package/src/lib/core/services/auth-config.service.ts +0 -184
- package/src/lib/core/services/auth-provider-registry.service.ts +0 -93
- package/src/lib/core/services/initialization.service.ts +0 -29
- package/src/lib/core/services/jwt.service.ts +0 -137
- package/src/lib/nest-auth.module.ts +0 -152
- package/src/lib/permission/entities/permission.entity.ts +0 -56
- package/src/lib/permission/permission.module.ts +0 -14
- package/src/lib/request-context/request-context.middleware.ts +0 -13
- package/src/lib/role/entities/role.entity.ts +0 -103
- package/src/lib/role/role.module.ts +0 -15
- package/src/lib/session/entities/session.entity.ts +0 -54
- package/src/lib/session/repositories/typeorm-session.repository.ts +0 -86
- package/src/lib/session/session.module.ts +0 -102
- package/src/lib/tenant/events/tenant-created.event.ts +0 -9
- package/src/lib/tenant/events/tenant-deleted.event.ts +0 -11
- package/src/lib/tenant/events/tenant-updated.event.ts +0 -12
- package/src/lib/tenant/tenant.module.ts +0 -19
- package/src/lib/types/express.d.ts +0 -14
- package/src/lib/user/dto/requests/update-user.dto.ts +0 -15
- package/src/lib/user/entities/access-key.entity.ts +0 -53
- package/src/lib/user/entities/identity.entity.ts +0 -31
- package/src/lib/user/entities/user.entity.ts +0 -212
- package/src/lib/user/events/user-created.event.ts +0 -10
- package/src/lib/user/events/user-deleted.event.ts +0 -12
- package/src/lib/user/events/user-updated.event.ts +0 -13
- package/src/lib/user/services/access-key.service.ts +0 -145
- package/src/lib/user/user.module.ts +0 -26
- package/src/lib/utils/database.utils.ts +0 -6
- package/src/lib/utils/device.util.ts +0 -111
- package/src/lib/utils/otp.ts +0 -3
- package/src/types/ms.d.ts +0 -1
- package/test/access-key.service.spec.ts +0 -204
- package/test/auth.service.spec.ts +0 -541
- package/test/mfa.service.spec.ts +0 -359
- package/test/role.service.spec.ts +0 -418
- package/test/tenant.service.spec.ts +0 -218
- package/test/test.setup.ts +0 -66
- package/test/user.service.spec.ts +0 -374
- package/tsconfig.json +0 -17
- package/tsconfig.lib.json +0 -15
- package/tsconfig.spec.json +0 -15
- package/tsconfig.tsbuildinfo +0 -1
- package/ui/.env +0 -1
- package/ui/.env.example +0 -1
- package/ui/.eslintignore +0 -7
- package/ui/README.md +0 -288
- package/ui/index.html +0 -17
- package/ui/package.json +0 -34
- package/ui/postcss.config.js +0 -6
- package/ui/src/App.tsx +0 -245
- package/ui/src/components/AuthGuard.tsx +0 -59
- package/ui/src/components/AuthProvider.tsx +0 -76
- package/ui/src/components/Button.tsx +0 -37
- package/ui/src/components/Card.tsx +0 -37
- package/ui/src/components/ErrorMessage.tsx +0 -15
- package/ui/src/components/FormDialog.tsx +0 -61
- package/ui/src/components/FormFooter.tsx +0 -37
- package/ui/src/components/Layout.tsx +0 -112
- package/ui/src/components/LoadingMessage.tsx +0 -11
- package/ui/src/components/Modal.tsx +0 -97
- package/ui/src/components/MultiSelect.tsx +0 -145
- package/ui/src/components/PageHeader.tsx +0 -42
- package/ui/src/components/PanelHeader.tsx +0 -28
- package/ui/src/components/PermissionInput.tsx +0 -473
- package/ui/src/components/SearchInput.tsx +0 -69
- package/ui/src/components/Select.tsx +0 -51
- package/ui/src/components/SwaggerUIWrapper.tsx +0 -316
- package/ui/src/components/Table.tsx +0 -207
- package/ui/src/components/Tag.tsx +0 -9
- package/ui/src/components/TagsInput.tsx +0 -96
- package/ui/src/components/admin/AdminForm.tsx +0 -170
- package/ui/src/components/admin/CreateAdminDialog.tsx +0 -38
- package/ui/src/components/auth/LoginFooter.tsx +0 -17
- package/ui/src/components/auth/LoginHeader.tsx +0 -14
- package/ui/src/components/auth/components/CodeBlock.tsx +0 -43
- package/ui/src/components/auth/components/CreateAccountCodeExamples.tsx +0 -60
- package/ui/src/components/auth/components/PasswordRequirements.tsx +0 -16
- package/ui/src/components/auth/components/PasswordStrengthIndicator.tsx +0 -48
- package/ui/src/components/auth/components/ResetPasswordCodeExamples.tsx +0 -76
- package/ui/src/components/auth/components/Tabs.tsx +0 -32
- package/ui/src/components/auth/dialogs/CreateAccountDialog.tsx +0 -79
- package/ui/src/components/auth/dialogs/ForgotPasswordDialog.tsx +0 -79
- package/ui/src/components/auth/forms/CreateAccountForm.tsx +0 -226
- package/ui/src/components/auth/forms/LoginForm.tsx +0 -149
- package/ui/src/components/auth/forms/ResetPasswordForm.tsx +0 -202
- package/ui/src/components/auth/types.ts +0 -17
- package/ui/src/components/auth/utils/security.ts +0 -82
- package/ui/src/components/auth/utils/utils.ts +0 -25
- package/ui/src/components/form/EmailField.tsx +0 -25
- package/ui/src/components/form/FormField.tsx +0 -102
- package/ui/src/components/form/FormMultiSelect.tsx +0 -46
- package/ui/src/components/form/FormSelect.tsx +0 -60
- package/ui/src/components/form/FormTagsInput.tsx +0 -42
- package/ui/src/components/form/FormTextarea.tsx +0 -42
- package/ui/src/components/form/PasswordField.tsx +0 -93
- package/ui/src/components/form/SecretKeyField.tsx +0 -49
- package/ui/src/components/permission/CreatePermissionDialog.tsx +0 -44
- package/ui/src/components/permission/EditPermissionDialog.tsx +0 -55
- package/ui/src/components/permission/PermissionForm.tsx +0 -251
- package/ui/src/components/role/CreateRoleDialog.tsx +0 -45
- package/ui/src/components/role/EditRoleDialog.tsx +0 -55
- package/ui/src/components/role/RoleDialog.tsx +0 -252
- package/ui/src/components/role/RoleForm.tsx +0 -246
- package/ui/src/components/tenant/CreateTenantDialog.tsx +0 -41
- package/ui/src/components/tenant/EditTenantDialog.tsx +0 -52
- package/ui/src/components/tenant/TenantForm.tsx +0 -160
- package/ui/src/components/user/CreateUserDialog.tsx +0 -45
- package/ui/src/components/user/UserDetailModal.tsx +0 -815
- package/ui/src/components/user/UserForm.tsx +0 -191
- package/ui/src/data/nest-auth.json +0 -1687
- package/ui/src/hooks/useApi.ts +0 -69
- package/ui/src/hooks/useAuth.ts +0 -100
- package/ui/src/hooks/useConfirm.tsx +0 -105
- package/ui/src/hooks/useFormFooter.tsx +0 -42
- package/ui/src/hooks/usePagination.ts +0 -69
- package/ui/src/index.css +0 -59
- package/ui/src/main.tsx +0 -13
- package/ui/src/pages/AdminsPage.tsx +0 -178
- package/ui/src/pages/ApiPage.tsx +0 -89
- package/ui/src/pages/DashboardPage.tsx +0 -281
- package/ui/src/pages/LoginPage.tsx +0 -39
- package/ui/src/pages/PermissionsPage.tsx +0 -376
- package/ui/src/pages/RolesPage.tsx +0 -274
- package/ui/src/pages/TenantsPage.tsx +0 -221
- package/ui/src/pages/UsersPage.tsx +0 -387
- package/ui/src/services/api.ts +0 -115
- package/ui/src/types/index.ts +0 -136
- package/ui/src/vite-env.d.ts +0 -9
- package/ui/tailwind.config.js +0 -45
- package/ui/tsconfig.json +0 -24
- package/ui/tsconfig.node.json +0 -10
- package/ui/vite.config.ts +0 -37
- package/ui/yarn.lock +0 -3137
|
@@ -1,815 +0,0 @@
|
|
|
1
|
-
import React, { useState, useEffect } from 'react';
|
|
2
|
-
import { X, Mail, Phone, Building2, Shield, CheckCircle, XCircle, Calendar, Edit2, Save, Lock, Key, Smartphone, Trash2, AlertCircle } from 'lucide-react';
|
|
3
|
-
import { Button } from '../Button';
|
|
4
|
-
import { MultiSelect } from '../MultiSelect';
|
|
5
|
-
import { PasswordField } from '../form/PasswordField';
|
|
6
|
-
import { EmailField } from '../form/EmailField';
|
|
7
|
-
import { FormField } from '../form/FormField';
|
|
8
|
-
import type { User, Role, UserDetails, TotpDevice } from '../../types';
|
|
9
|
-
import { api } from '../../services/api';
|
|
10
|
-
import { useConfirm } from '../../hooks/useConfirm';
|
|
11
|
-
|
|
12
|
-
const MFA_METHOD_LABELS: Record<string, string> = {
|
|
13
|
-
totp: 'Authenticator App (TOTP)',
|
|
14
|
-
sms: 'SMS',
|
|
15
|
-
email: 'Email',
|
|
16
|
-
backup_code: 'Backup Code',
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const formatMfaMethod = (method?: string) => {
|
|
20
|
-
if (!method) {
|
|
21
|
-
return 'Unknown';
|
|
22
|
-
}
|
|
23
|
-
return MFA_METHOD_LABELS[method] || method.toUpperCase();
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
interface UserDetailModalProps {
|
|
27
|
-
user: User;
|
|
28
|
-
onClose: () => void;
|
|
29
|
-
onUpdate: (id: string, updates: Partial<User>) => Promise<void>;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export const UserDetailModal: React.FC<UserDetailModalProps> = ({ user: initialUser, onClose, onUpdate }) => {
|
|
33
|
-
const [isEditing, setIsEditing] = useState(false);
|
|
34
|
-
const [saving, setSaving] = useState(false);
|
|
35
|
-
const [loading, setLoading] = useState(true);
|
|
36
|
-
const [roles, setRoles] = useState<Role[]>([]);
|
|
37
|
-
const [userDetails, setUserDetails] = useState<UserDetails | null>(null);
|
|
38
|
-
const [selectedRoles, setSelectedRoles] = useState<string[]>(initialUser.roles);
|
|
39
|
-
const [metadataError, setMetadataError] = useState<string>('');
|
|
40
|
-
const [passwordError, setPasswordError] = useState<string>('');
|
|
41
|
-
const [sessionError, setSessionError] = useState<string>('');
|
|
42
|
-
const [sessionActionId, setSessionActionId] = useState<string | null>(null);
|
|
43
|
-
const [formData, setFormData] = useState({
|
|
44
|
-
email: initialUser.email,
|
|
45
|
-
phone: initialUser.phone || '',
|
|
46
|
-
isActive: initialUser.isActive,
|
|
47
|
-
isVerified: initialUser.isVerified,
|
|
48
|
-
metadata: JSON.stringify(initialUser.metadata || {}, null, 2),
|
|
49
|
-
password: '',
|
|
50
|
-
emailLoginEnabled: true,
|
|
51
|
-
phoneLoginEnabled: false,
|
|
52
|
-
isMfaEnabled: false,
|
|
53
|
-
});
|
|
54
|
-
const confirm = useConfirm();
|
|
55
|
-
|
|
56
|
-
const loadUserDetails = async () => {
|
|
57
|
-
const detailsResponse = await api.get<UserDetails>(`/api/users/${initialUser.id}`);
|
|
58
|
-
setUserDetails(detailsResponse);
|
|
59
|
-
return detailsResponse;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
useEffect(() => {
|
|
63
|
-
const loadData = async () => {
|
|
64
|
-
setLoading(true);
|
|
65
|
-
try {
|
|
66
|
-
// Load user details
|
|
67
|
-
const detailsResponse = await loadUserDetails();
|
|
68
|
-
if (detailsResponse) {
|
|
69
|
-
setFormData(prev => ({
|
|
70
|
-
...prev,
|
|
71
|
-
emailLoginEnabled: detailsResponse.loginMethods.emailEnabled,
|
|
72
|
-
phoneLoginEnabled: detailsResponse.loginMethods.phoneEnabled,
|
|
73
|
-
isMfaEnabled: detailsResponse.mfa?.isEnabled ?? detailsResponse.user.isMfaEnabled,
|
|
74
|
-
}));
|
|
75
|
-
setSelectedRoles(detailsResponse.user.roles);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Load roles
|
|
79
|
-
const rolesResponse = await api.get<{ data: Role[] }>('/api/roles');
|
|
80
|
-
const rolesData = Array.isArray(rolesResponse.data?.data) ? rolesResponse.data.data : [];
|
|
81
|
-
setRoles(rolesData);
|
|
82
|
-
} catch (err) {
|
|
83
|
-
console.error('Failed to load data:', err);
|
|
84
|
-
} finally {
|
|
85
|
-
setLoading(false);
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
loadData();
|
|
89
|
-
}, [initialUser.id]);
|
|
90
|
-
|
|
91
|
-
const handleSave = async () => {
|
|
92
|
-
if (metadataError || passwordError) {
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
setSaving(true);
|
|
97
|
-
try {
|
|
98
|
-
let parsedMetadata;
|
|
99
|
-
try {
|
|
100
|
-
parsedMetadata = JSON.parse(formData.metadata);
|
|
101
|
-
} catch (parseError) {
|
|
102
|
-
setMetadataError('Invalid JSON format');
|
|
103
|
-
setSaving(false);
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const updates: any = {
|
|
108
|
-
email: formData.email,
|
|
109
|
-
phone: formData.phone,
|
|
110
|
-
isActive: formData.isActive,
|
|
111
|
-
isVerified: formData.isVerified,
|
|
112
|
-
roles: selectedRoles,
|
|
113
|
-
metadata: parsedMetadata,
|
|
114
|
-
emailLoginEnabled: formData.emailLoginEnabled,
|
|
115
|
-
phoneLoginEnabled: formData.phoneLoginEnabled,
|
|
116
|
-
isMfaEnabled: formData.isMfaEnabled,
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
if (formData.password) {
|
|
120
|
-
updates.password = formData.password;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
await onUpdate(initialUser.id, updates);
|
|
124
|
-
setIsEditing(false);
|
|
125
|
-
setFormData(prev => ({ ...prev, password: '' }));
|
|
126
|
-
|
|
127
|
-
// Reload user details
|
|
128
|
-
const detailsResponse = await loadUserDetails();
|
|
129
|
-
if (detailsResponse) {
|
|
130
|
-
setSelectedRoles(detailsResponse.user.roles);
|
|
131
|
-
setFormData(prev => ({
|
|
132
|
-
...prev,
|
|
133
|
-
email: detailsResponse.user.email,
|
|
134
|
-
phone: detailsResponse.user.phone || '',
|
|
135
|
-
isActive: detailsResponse.user.isActive,
|
|
136
|
-
isVerified: detailsResponse.user.isVerified,
|
|
137
|
-
metadata: JSON.stringify(detailsResponse.user.metadata || {}, null, 2),
|
|
138
|
-
password: '',
|
|
139
|
-
emailLoginEnabled: detailsResponse.loginMethods.emailEnabled,
|
|
140
|
-
phoneLoginEnabled: detailsResponse.loginMethods.phoneEnabled,
|
|
141
|
-
isMfaEnabled: detailsResponse.mfa?.isEnabled ?? detailsResponse.user.isMfaEnabled,
|
|
142
|
-
}));
|
|
143
|
-
}
|
|
144
|
-
} catch (error: any) {
|
|
145
|
-
if (error.message?.includes('Password')) {
|
|
146
|
-
setPasswordError(error.message);
|
|
147
|
-
}
|
|
148
|
-
console.error('Failed to update user:', error);
|
|
149
|
-
} finally {
|
|
150
|
-
setSaving(false);
|
|
151
|
-
}
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
const handleDeleteTotpDevice = async (deviceId: string, deviceName: string) => {
|
|
155
|
-
const confirmed = await confirm(`Are you sure you want to delete the TOTP device "${deviceName}"? This action cannot be undone.`);
|
|
156
|
-
if (!confirmed) {
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
try {
|
|
161
|
-
await api.delete(`/api/users/${initialUser.id}/totp-devices/${deviceId}`);
|
|
162
|
-
// Reload user details
|
|
163
|
-
await loadUserDetails();
|
|
164
|
-
} catch (error) {
|
|
165
|
-
console.error('Failed to delete TOTP device:', error);
|
|
166
|
-
}
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
const handleRevokeSession = async (sessionId: string) => {
|
|
170
|
-
const confirmed = await confirm('Revoke this session? The user will be signed out on that device.');
|
|
171
|
-
if (!confirmed) {
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
try {
|
|
176
|
-
setSessionError('');
|
|
177
|
-
setSessionActionId(sessionId);
|
|
178
|
-
await api.delete(`/api/users/${initialUser.id}/sessions/${sessionId}`);
|
|
179
|
-
await loadUserDetails();
|
|
180
|
-
} catch (error: any) {
|
|
181
|
-
setSessionError(error?.message || 'Failed to revoke session');
|
|
182
|
-
} finally {
|
|
183
|
-
setSessionActionId(null);
|
|
184
|
-
}
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
const handleRevokeAllSessions = async () => {
|
|
188
|
-
if (!userDetails?.sessions?.length) {
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
const confirmed = await confirm('Revoke all sessions for this user? They will be signed out everywhere.');
|
|
193
|
-
if (!confirmed) {
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
try {
|
|
198
|
-
setSessionError('');
|
|
199
|
-
setSessionActionId('all');
|
|
200
|
-
await api.delete(`/api/users/${initialUser.id}/sessions`);
|
|
201
|
-
await loadUserDetails();
|
|
202
|
-
} catch (error: any) {
|
|
203
|
-
setSessionError(error?.message || 'Failed to revoke sessions');
|
|
204
|
-
} finally {
|
|
205
|
-
setSessionActionId(null);
|
|
206
|
-
}
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
const currentUser = userDetails?.user || initialUser;
|
|
210
|
-
const loginMethods = userDetails?.loginMethods || {
|
|
211
|
-
emailEnabled: !!currentUser.emailVerifiedAt,
|
|
212
|
-
phoneEnabled: !!currentUser.phoneVerifiedAt,
|
|
213
|
-
hasPassword: false,
|
|
214
|
-
};
|
|
215
|
-
const mfaDetails = userDetails?.mfa;
|
|
216
|
-
const totpDevices = mfaDetails?.totpDevices || [];
|
|
217
|
-
const sessions = userDetails?.sessions || [];
|
|
218
|
-
const availableMfaMethods = mfaDetails?.availableMethods || [];
|
|
219
|
-
const enabledMfaMethods = mfaDetails?.enabledMethods || [];
|
|
220
|
-
|
|
221
|
-
if (loading) {
|
|
222
|
-
return (
|
|
223
|
-
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
|
|
224
|
-
<div className="bg-white rounded-xl shadow-2xl p-4">
|
|
225
|
-
<div className="text-center">Loading user details...</div>
|
|
226
|
-
</div>
|
|
227
|
-
</div>
|
|
228
|
-
);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
return (
|
|
232
|
-
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
|
|
233
|
-
<div className="bg-white rounded-xl shadow-2xl max-w-5xl w-full h-[90vh] flex flex-col">
|
|
234
|
-
{/* Header */}
|
|
235
|
-
<div className="bg-gradient-to-r from-primary-600 to-primary-700 text-white p-4 flex items-center justify-between flex-shrink-0">
|
|
236
|
-
<div className="flex items-center gap-3">
|
|
237
|
-
<div className="w-12 h-12 bg-white/20 rounded-full flex items-center justify-center text-xl font-bold">
|
|
238
|
-
{currentUser.email.charAt(0).toUpperCase()}
|
|
239
|
-
</div>
|
|
240
|
-
<div>
|
|
241
|
-
<h2 className="text-xl font-bold">{currentUser.email}</h2>
|
|
242
|
-
<p className="text-primary-100 text-xs">User Details & Management</p>
|
|
243
|
-
</div>
|
|
244
|
-
</div>
|
|
245
|
-
<button
|
|
246
|
-
type="button"
|
|
247
|
-
onClick={onClose}
|
|
248
|
-
className="text-white hover:bg-white/20 p-1.5 rounded-lg transition-colors"
|
|
249
|
-
>
|
|
250
|
-
<X className="w-5 h-5" />
|
|
251
|
-
</button>
|
|
252
|
-
</div>
|
|
253
|
-
|
|
254
|
-
{/* Content */}
|
|
255
|
-
<div className="flex-1 overflow-y-auto">
|
|
256
|
-
<div className="p-4">
|
|
257
|
-
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
|
258
|
-
{/* Basic Information */}
|
|
259
|
-
<div className="space-y-3">
|
|
260
|
-
<h3 className="text-base font-semibold text-gray-900 flex items-center gap-2">
|
|
261
|
-
<Mail className="w-4 h-4 text-primary-600" />
|
|
262
|
-
Basic Information
|
|
263
|
-
</h3>
|
|
264
|
-
|
|
265
|
-
<div className="space-y-2">
|
|
266
|
-
{isEditing ? (
|
|
267
|
-
<>
|
|
268
|
-
<EmailField
|
|
269
|
-
id="edit-email"
|
|
270
|
-
label="Email Address"
|
|
271
|
-
value={formData.email}
|
|
272
|
-
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
|
|
273
|
-
disabled={saving}
|
|
274
|
-
placeholder="user@example.com"
|
|
275
|
-
required
|
|
276
|
-
/>
|
|
277
|
-
<FormField
|
|
278
|
-
id="edit-phone"
|
|
279
|
-
label="Phone Number"
|
|
280
|
-
type="tel"
|
|
281
|
-
value={formData.phone}
|
|
282
|
-
onChange={(e) => setFormData({ ...formData, phone: e.target.value })}
|
|
283
|
-
disabled={saving}
|
|
284
|
-
placeholder="+1234567890"
|
|
285
|
-
startIcon={<Phone className="w-5 h-5 text-gray-400" />}
|
|
286
|
-
/>
|
|
287
|
-
</>
|
|
288
|
-
) : (
|
|
289
|
-
<>
|
|
290
|
-
<div className="p-2.5 bg-gray-50 rounded-lg">
|
|
291
|
-
<label className="text-xs font-medium text-gray-600">Email Address</label>
|
|
292
|
-
<p className="text-sm text-gray-900 font-medium mt-0.5">{currentUser.email}</p>
|
|
293
|
-
</div>
|
|
294
|
-
|
|
295
|
-
<div className="p-2.5 bg-gray-50 rounded-lg">
|
|
296
|
-
<label className="text-xs font-medium text-gray-600">Phone Number</label>
|
|
297
|
-
<p className="text-sm text-gray-900 font-medium mt-0.5">{currentUser.phone || '—'}</p>
|
|
298
|
-
</div>
|
|
299
|
-
</>
|
|
300
|
-
)}
|
|
301
|
-
<div className="p-2.5 bg-gray-50 rounded-lg">
|
|
302
|
-
<label className="text-xs font-medium text-gray-600">User ID</label>
|
|
303
|
-
<p className="text-xs text-gray-600 font-mono mt-0.5">{currentUser.id}</p>
|
|
304
|
-
</div>
|
|
305
|
-
|
|
306
|
-
<div className="p-2.5 bg-gray-50 rounded-lg">
|
|
307
|
-
<label className="text-xs font-medium text-gray-600 flex items-center gap-2">
|
|
308
|
-
<Building2 className="w-3.5 h-3.5" />
|
|
309
|
-
Tenant ID
|
|
310
|
-
</label>
|
|
311
|
-
<p className="text-sm text-gray-900 font-medium mt-0.5">{currentUser.tenantId || '—'}</p>
|
|
312
|
-
</div>
|
|
313
|
-
</div>
|
|
314
|
-
</div>
|
|
315
|
-
|
|
316
|
-
{/* Status & Verification */}
|
|
317
|
-
<div className="space-y-3">
|
|
318
|
-
<h3 className="text-base font-semibold text-gray-900 flex items-center gap-2">
|
|
319
|
-
<Shield className="w-4 h-4 text-primary-600" />
|
|
320
|
-
Status & Security
|
|
321
|
-
</h3>
|
|
322
|
-
|
|
323
|
-
{isEditing ? (
|
|
324
|
-
<div className="space-y-2">
|
|
325
|
-
<div className="p-2.5 bg-gray-50 rounded-lg">
|
|
326
|
-
<label className="flex items-center gap-2 cursor-pointer">
|
|
327
|
-
<input
|
|
328
|
-
type="checkbox"
|
|
329
|
-
checked={formData.isActive}
|
|
330
|
-
onChange={(e) => setFormData({ ...formData, isActive: e.target.checked })}
|
|
331
|
-
className="w-4 h-4 text-primary-600 rounded focus:ring-2 focus:ring-primary-500"
|
|
332
|
-
/>
|
|
333
|
-
<span className="text-sm font-medium text-gray-700">Account Active</span>
|
|
334
|
-
</label>
|
|
335
|
-
</div>
|
|
336
|
-
|
|
337
|
-
<div className="p-2.5 bg-gray-50 rounded-lg">
|
|
338
|
-
<label className="flex items-center gap-2 cursor-pointer">
|
|
339
|
-
<input
|
|
340
|
-
type="checkbox"
|
|
341
|
-
checked={formData.isVerified}
|
|
342
|
-
onChange={(e) => setFormData({ ...formData, isVerified: e.target.checked })}
|
|
343
|
-
className="w-4 h-4 text-primary-600 rounded focus:ring-2 focus:ring-primary-500"
|
|
344
|
-
/>
|
|
345
|
-
<span className="text-sm font-medium text-gray-700">Email Verified</span>
|
|
346
|
-
</label>
|
|
347
|
-
</div>
|
|
348
|
-
|
|
349
|
-
<div className="p-2.5 bg-gray-50 rounded-lg">
|
|
350
|
-
<label className="flex items-center gap-2 cursor-pointer">
|
|
351
|
-
<input
|
|
352
|
-
type="checkbox"
|
|
353
|
-
checked={formData.isMfaEnabled}
|
|
354
|
-
onChange={(e) => setFormData({ ...formData, isMfaEnabled: e.target.checked })}
|
|
355
|
-
className="w-4 h-4 text-primary-600 rounded focus:ring-2 focus:ring-primary-500"
|
|
356
|
-
/>
|
|
357
|
-
<span className="text-sm font-medium text-gray-700">MFA Enabled</span>
|
|
358
|
-
</label>
|
|
359
|
-
</div>
|
|
360
|
-
</div>
|
|
361
|
-
) : (
|
|
362
|
-
<div className="space-y-2">
|
|
363
|
-
<div className="p-2.5 bg-gray-50 rounded-lg flex items-center justify-between">
|
|
364
|
-
<span className="text-xs font-medium text-gray-600">Account Status</span>
|
|
365
|
-
{currentUser.isActive ? (
|
|
366
|
-
<span className="badge-success flex items-center gap-1">
|
|
367
|
-
<CheckCircle className="w-3 h-3" />
|
|
368
|
-
Active
|
|
369
|
-
</span>
|
|
370
|
-
) : (
|
|
371
|
-
<span className="badge-danger flex items-center gap-1">
|
|
372
|
-
<XCircle className="w-3 h-3" />
|
|
373
|
-
Inactive
|
|
374
|
-
</span>
|
|
375
|
-
)}
|
|
376
|
-
</div>
|
|
377
|
-
|
|
378
|
-
<div className="p-2.5 bg-gray-50 rounded-lg flex items-center justify-between">
|
|
379
|
-
<span className="text-xs font-medium text-gray-600">Email Verification</span>
|
|
380
|
-
{currentUser.isVerified ? (
|
|
381
|
-
<span className="badge-success flex items-center gap-1">
|
|
382
|
-
<CheckCircle className="w-3 h-3" />
|
|
383
|
-
Verified
|
|
384
|
-
</span>
|
|
385
|
-
) : (
|
|
386
|
-
<span className="badge-warning flex items-center gap-1">
|
|
387
|
-
<XCircle className="w-3 h-3" />
|
|
388
|
-
Not Verified
|
|
389
|
-
</span>
|
|
390
|
-
)}
|
|
391
|
-
</div>
|
|
392
|
-
|
|
393
|
-
<div className="p-2.5 bg-gray-50 rounded-lg flex items-center justify-between">
|
|
394
|
-
<span className="text-xs font-medium text-gray-600">MFA Status</span>
|
|
395
|
-
{currentUser.isMfaEnabled ? (
|
|
396
|
-
<span className="badge-success flex items-center gap-1">
|
|
397
|
-
<CheckCircle className="w-3 h-3" />
|
|
398
|
-
Enabled
|
|
399
|
-
</span>
|
|
400
|
-
) : (
|
|
401
|
-
<span className="badge-secondary flex items-center gap-1">
|
|
402
|
-
<XCircle className="w-3 h-3" />
|
|
403
|
-
Disabled
|
|
404
|
-
</span>
|
|
405
|
-
)}
|
|
406
|
-
</div>
|
|
407
|
-
</div>
|
|
408
|
-
)}
|
|
409
|
-
|
|
410
|
-
<div className="p-2.5 bg-gray-50 rounded-lg">
|
|
411
|
-
<label className="text-xs font-medium text-gray-600 flex items-center gap-2">
|
|
412
|
-
<Calendar className="w-3.5 h-3.5" />
|
|
413
|
-
Created At
|
|
414
|
-
</label>
|
|
415
|
-
<p className="text-sm text-gray-900 mt-0.5">{new Date(currentUser.createdAt).toLocaleString()}</p>
|
|
416
|
-
</div>
|
|
417
|
-
|
|
418
|
-
<div className="p-2.5 bg-gray-50 rounded-lg">
|
|
419
|
-
<label className="text-xs font-medium text-gray-600 flex items-center gap-2">
|
|
420
|
-
<Calendar className="w-3.5 h-3.5" />
|
|
421
|
-
Last Updated
|
|
422
|
-
</label>
|
|
423
|
-
<p className="text-sm text-gray-900 mt-0.5">{new Date(currentUser.updatedAt).toLocaleString()}</p>
|
|
424
|
-
</div>
|
|
425
|
-
</div>
|
|
426
|
-
</div>
|
|
427
|
-
|
|
428
|
-
{/* MFA Methods Overview */}
|
|
429
|
-
<div className="mt-4">
|
|
430
|
-
<h3 className="text-base font-semibold text-gray-900 mb-2 flex items-center gap-2">
|
|
431
|
-
<Smartphone className="w-4 h-4 text-primary-600" />
|
|
432
|
-
MFA Methods
|
|
433
|
-
</h3>
|
|
434
|
-
{availableMfaMethods.length > 0 ? (
|
|
435
|
-
<div className="flex flex-wrap gap-2">
|
|
436
|
-
{availableMfaMethods.map((method) => {
|
|
437
|
-
const isEnabled = enabledMfaMethods.includes(method);
|
|
438
|
-
return (
|
|
439
|
-
<span
|
|
440
|
-
key={method}
|
|
441
|
-
className={`${isEnabled ? 'badge-success' : 'badge-secondary'} text-xs flex items-center gap-1`}
|
|
442
|
-
>
|
|
443
|
-
{formatMfaMethod(method)}
|
|
444
|
-
{isEnabled ? <CheckCircle className="w-3 h-3" /> : <XCircle className="w-3 h-3" />}
|
|
445
|
-
</span>
|
|
446
|
-
);
|
|
447
|
-
})}
|
|
448
|
-
</div>
|
|
449
|
-
) : (
|
|
450
|
-
<p className="text-sm text-gray-500">MFA is disabled in the global configuration.</p>
|
|
451
|
-
)}
|
|
452
|
-
<div className="mt-2 flex flex-col gap-1">
|
|
453
|
-
<span className="text-xs text-gray-600">
|
|
454
|
-
Recovery code: {mfaDetails?.hasRecoveryCode ? 'Generated' : 'Not generated'}
|
|
455
|
-
</span>
|
|
456
|
-
{mfaDetails && !mfaDetails.allowUserToggle && (
|
|
457
|
-
<span className="text-xs text-amber-600">
|
|
458
|
-
Users cannot toggle MFA themselves for this application.
|
|
459
|
-
</span>
|
|
460
|
-
)}
|
|
461
|
-
</div>
|
|
462
|
-
</div>
|
|
463
|
-
|
|
464
|
-
{/* Password Management */}
|
|
465
|
-
{isEditing && (
|
|
466
|
-
<div className="mt-4">
|
|
467
|
-
<h3 className="text-base font-semibold text-gray-900 mb-2 flex items-center gap-2">
|
|
468
|
-
<Lock className="w-4 h-4 text-primary-600" />
|
|
469
|
-
Password Management
|
|
470
|
-
</h3>
|
|
471
|
-
<div className="p-2.5 bg-amber-50 border border-amber-200 rounded-lg mb-2">
|
|
472
|
-
<div className="flex items-start gap-2">
|
|
473
|
-
<AlertCircle className="w-4 h-4 text-amber-600 flex-shrink-0 mt-0.5" />
|
|
474
|
-
<p className="text-xs text-amber-800">
|
|
475
|
-
Leave password empty to keep current password. Password must contain uppercase, lowercase, number, and special character.
|
|
476
|
-
</p>
|
|
477
|
-
</div>
|
|
478
|
-
</div>
|
|
479
|
-
<PasswordField
|
|
480
|
-
id="change-password"
|
|
481
|
-
label="New Password (optional)"
|
|
482
|
-
value={formData.password}
|
|
483
|
-
onChange={(e) => {
|
|
484
|
-
setFormData({ ...formData, password: e.target.value });
|
|
485
|
-
setPasswordError('');
|
|
486
|
-
}}
|
|
487
|
-
disabled={saving}
|
|
488
|
-
error={passwordError}
|
|
489
|
-
placeholder="Leave empty to keep current password"
|
|
490
|
-
required={false}
|
|
491
|
-
showStrengthIndicator={!!formData.password}
|
|
492
|
-
/>
|
|
493
|
-
</div>
|
|
494
|
-
)}
|
|
495
|
-
|
|
496
|
-
{/* Login Methods */}
|
|
497
|
-
<div className="mt-4">
|
|
498
|
-
<h3 className="text-base font-semibold text-gray-900 mb-2 flex items-center gap-2">
|
|
499
|
-
<Key className="w-4 h-4 text-primary-600" />
|
|
500
|
-
Login Methods
|
|
501
|
-
</h3>
|
|
502
|
-
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
|
503
|
-
{isEditing ? (
|
|
504
|
-
<>
|
|
505
|
-
<div className="p-3 border border-gray-200 rounded-lg">
|
|
506
|
-
<div className="flex items-center justify-between mb-1.5">
|
|
507
|
-
<div className="flex items-center gap-2">
|
|
508
|
-
<Mail className="w-4 h-4 text-gray-600" />
|
|
509
|
-
<span className="text-sm font-medium text-gray-900">Email/Password</span>
|
|
510
|
-
</div>
|
|
511
|
-
<label className="relative inline-flex items-center cursor-pointer">
|
|
512
|
-
<input
|
|
513
|
-
type="checkbox"
|
|
514
|
-
checked={formData.emailLoginEnabled}
|
|
515
|
-
onChange={(e) => setFormData({ ...formData, emailLoginEnabled: e.target.checked })}
|
|
516
|
-
disabled={!currentUser.email}
|
|
517
|
-
className="sr-only peer"
|
|
518
|
-
/>
|
|
519
|
-
<div className="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-primary-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary-600"></div>
|
|
520
|
-
</label>
|
|
521
|
-
</div>
|
|
522
|
-
<p className="text-xs text-gray-500">
|
|
523
|
-
{currentUser.email ? 'User can login with email and password' : 'Email not set'}
|
|
524
|
-
</p>
|
|
525
|
-
</div>
|
|
526
|
-
|
|
527
|
-
<div className="p-3 border border-gray-200 rounded-lg">
|
|
528
|
-
<div className="flex items-center justify-between mb-1.5">
|
|
529
|
-
<div className="flex items-center gap-2">
|
|
530
|
-
<Smartphone className="w-4 h-4 text-gray-600" />
|
|
531
|
-
<span className="text-sm font-medium text-gray-900">Phone/OTP</span>
|
|
532
|
-
</div>
|
|
533
|
-
<label className="relative inline-flex items-center cursor-pointer">
|
|
534
|
-
<input
|
|
535
|
-
type="checkbox"
|
|
536
|
-
checked={formData.phoneLoginEnabled}
|
|
537
|
-
onChange={(e) => setFormData({ ...formData, phoneLoginEnabled: e.target.checked })}
|
|
538
|
-
disabled={!currentUser.phone}
|
|
539
|
-
className="sr-only peer"
|
|
540
|
-
/>
|
|
541
|
-
<div className="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-primary-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary-600"></div>
|
|
542
|
-
</label>
|
|
543
|
-
</div>
|
|
544
|
-
<p className="text-xs text-gray-500">
|
|
545
|
-
{currentUser.phone ? 'User can login with phone and OTP' : 'Phone not set'}
|
|
546
|
-
</p>
|
|
547
|
-
</div>
|
|
548
|
-
</>
|
|
549
|
-
) : (
|
|
550
|
-
<>
|
|
551
|
-
<div className="p-3 border border-gray-200 rounded-lg">
|
|
552
|
-
<div className="flex items-center justify-between">
|
|
553
|
-
<div className="flex items-center gap-2">
|
|
554
|
-
<Mail className="w-4 h-4 text-gray-600" />
|
|
555
|
-
<span className="text-sm font-medium text-gray-900">Email/Password</span>
|
|
556
|
-
</div>
|
|
557
|
-
{loginMethods.emailEnabled ? (
|
|
558
|
-
<span className="badge-success">Enabled</span>
|
|
559
|
-
) : (
|
|
560
|
-
<span className="badge-secondary">Disabled</span>
|
|
561
|
-
)}
|
|
562
|
-
</div>
|
|
563
|
-
<p className="text-xs text-gray-500 mt-1">
|
|
564
|
-
{loginMethods.hasPassword ? 'Password set' : 'No password set'}
|
|
565
|
-
</p>
|
|
566
|
-
</div>
|
|
567
|
-
|
|
568
|
-
<div className="p-3 border border-gray-200 rounded-lg">
|
|
569
|
-
<div className="flex items-center justify-between">
|
|
570
|
-
<div className="flex items-center gap-2">
|
|
571
|
-
<Smartphone className="w-4 h-4 text-gray-600" />
|
|
572
|
-
<span className="text-sm font-medium text-gray-900">Phone/OTP</span>
|
|
573
|
-
</div>
|
|
574
|
-
{loginMethods.phoneEnabled ? (
|
|
575
|
-
<span className="badge-success">Enabled</span>
|
|
576
|
-
) : currentUser.phone ? (
|
|
577
|
-
<span className="badge-secondary">Available</span>
|
|
578
|
-
) : (
|
|
579
|
-
<span className="badge-secondary">Not Set</span>
|
|
580
|
-
)}
|
|
581
|
-
</div>
|
|
582
|
-
</div>
|
|
583
|
-
</>
|
|
584
|
-
)}
|
|
585
|
-
</div>
|
|
586
|
-
</div>
|
|
587
|
-
|
|
588
|
-
{/* TOTP Devices */}
|
|
589
|
-
<div className="mt-4">
|
|
590
|
-
<h3 className="text-base font-semibold text-gray-900 mb-2 flex items-center gap-2">
|
|
591
|
-
<Smartphone className="w-4 h-4 text-primary-600" />
|
|
592
|
-
TOTP Devices ({totpDevices.length})
|
|
593
|
-
</h3>
|
|
594
|
-
{totpDevices.length > 0 ? (
|
|
595
|
-
<div className="space-y-2">
|
|
596
|
-
{totpDevices.map((device) => (
|
|
597
|
-
<div key={device.id} className="p-2.5 border border-gray-200 rounded-lg flex items-center justify-between">
|
|
598
|
-
<div className="flex-1">
|
|
599
|
-
<div className="flex items-center gap-2">
|
|
600
|
-
<span className="text-sm font-medium text-gray-900">{device.deviceName}</span>
|
|
601
|
-
{device.verified ? (
|
|
602
|
-
<span className="badge-success text-xs">Verified</span>
|
|
603
|
-
) : (
|
|
604
|
-
<span className="badge-warning text-xs">Pending</span>
|
|
605
|
-
)}
|
|
606
|
-
</div>
|
|
607
|
-
<div className="text-xs text-gray-500 mt-0.5">
|
|
608
|
-
{device.lastUsedAt
|
|
609
|
-
? `Last used: ${new Date(device.lastUsedAt).toLocaleString()}`
|
|
610
|
-
: `Added: ${new Date(device.createdAt).toLocaleString()}`}
|
|
611
|
-
</div>
|
|
612
|
-
</div>
|
|
613
|
-
<Button
|
|
614
|
-
size="sm"
|
|
615
|
-
variant="danger"
|
|
616
|
-
onClick={() => handleDeleteTotpDevice(device.id, device.deviceName)}
|
|
617
|
-
>
|
|
618
|
-
<Trash2 className="w-4 h-4" />
|
|
619
|
-
</Button>
|
|
620
|
-
</div>
|
|
621
|
-
))}
|
|
622
|
-
</div>
|
|
623
|
-
) : (
|
|
624
|
-
<div className="p-2.5 border border-gray-200 rounded-lg text-center text-xs text-gray-500">
|
|
625
|
-
No TOTP devices configured
|
|
626
|
-
</div>
|
|
627
|
-
)}
|
|
628
|
-
</div>
|
|
629
|
-
|
|
630
|
-
{/* Sessions */}
|
|
631
|
-
<div className="mt-4">
|
|
632
|
-
<h3 className="text-base font-semibold text-gray-900 mb-2 flex items-center gap-2">
|
|
633
|
-
<Lock className="w-4 h-4 text-primary-600" />
|
|
634
|
-
Active Sessions ({sessions.length})
|
|
635
|
-
</h3>
|
|
636
|
-
{sessionError && (
|
|
637
|
-
<div className="bg-red-50 border border-red-200 text-red-600 text-xs px-3 py-2 rounded-lg mb-2">
|
|
638
|
-
{sessionError}
|
|
639
|
-
</div>
|
|
640
|
-
)}
|
|
641
|
-
{sessions.length > 0 ? (
|
|
642
|
-
<div className="space-y-2">
|
|
643
|
-
{sessions.map((session) => (
|
|
644
|
-
<div key={session.id} className="p-2.5 border border-gray-200 rounded-lg flex items-center justify-between gap-4">
|
|
645
|
-
<div>
|
|
646
|
-
<p className="text-sm font-medium text-gray-900">{session.deviceName || 'Unknown device'}</p>
|
|
647
|
-
{session.userAgent && (
|
|
648
|
-
<p className="text-xs text-gray-500 truncate max-w-xs">{session.userAgent}</p>
|
|
649
|
-
)}
|
|
650
|
-
<p className="text-xs text-gray-500">
|
|
651
|
-
Last active:{' '}
|
|
652
|
-
{session.lastActive
|
|
653
|
-
? new Date(session.lastActive).toLocaleString()
|
|
654
|
-
: 'Unknown'}
|
|
655
|
-
</p>
|
|
656
|
-
{session.ipAddress && (
|
|
657
|
-
<p className="text-xs text-gray-500">IP: {session.ipAddress}</p>
|
|
658
|
-
)}
|
|
659
|
-
</div>
|
|
660
|
-
<Button
|
|
661
|
-
size="sm"
|
|
662
|
-
variant="danger"
|
|
663
|
-
onClick={() => handleRevokeSession(session.id)}
|
|
664
|
-
disabled={sessionActionId === session.id}
|
|
665
|
-
>
|
|
666
|
-
{sessionActionId === session.id ? (
|
|
667
|
-
<span className="flex items-center gap-1">
|
|
668
|
-
<span className="animate-spin h-3 w-3 border-2 border-white border-t-transparent rounded-full" />
|
|
669
|
-
Revoking...
|
|
670
|
-
</span>
|
|
671
|
-
) : (
|
|
672
|
-
<>
|
|
673
|
-
<Trash2 className="w-4 h-4" />
|
|
674
|
-
Revoke
|
|
675
|
-
</>
|
|
676
|
-
)}
|
|
677
|
-
</Button>
|
|
678
|
-
</div>
|
|
679
|
-
))}
|
|
680
|
-
<Button
|
|
681
|
-
variant="secondary"
|
|
682
|
-
onClick={handleRevokeAllSessions}
|
|
683
|
-
disabled={sessionActionId === 'all'}
|
|
684
|
-
>
|
|
685
|
-
{sessionActionId === 'all' ? (
|
|
686
|
-
<span className="flex items-center gap-1">
|
|
687
|
-
<span className="animate-spin h-4 w-4 border-2 border-primary-600 border-t-transparent rounded-full" />
|
|
688
|
-
Revoking all...
|
|
689
|
-
</span>
|
|
690
|
-
) : (
|
|
691
|
-
'Revoke All Sessions'
|
|
692
|
-
)}
|
|
693
|
-
</Button>
|
|
694
|
-
</div>
|
|
695
|
-
) : (
|
|
696
|
-
<div className="p-2.5 border border-gray-200 rounded-lg text-center text-xs text-gray-500">
|
|
697
|
-
No active sessions
|
|
698
|
-
</div>
|
|
699
|
-
)}
|
|
700
|
-
</div>
|
|
701
|
-
|
|
702
|
-
{/* Roles */}
|
|
703
|
-
<div className="mt-4">
|
|
704
|
-
<h3 className="text-base font-semibold text-gray-900 mb-2 flex items-center gap-2">
|
|
705
|
-
<Shield className="w-4 h-4 text-primary-600" />
|
|
706
|
-
Assigned Roles
|
|
707
|
-
</h3>
|
|
708
|
-
{isEditing ? (
|
|
709
|
-
<MultiSelect
|
|
710
|
-
value={selectedRoles}
|
|
711
|
-
onChange={setSelectedRoles}
|
|
712
|
-
options={roles.map((r) => ({
|
|
713
|
-
value: r.name,
|
|
714
|
-
label: r.tenantId ? `${r.name} (${r.guard})` : `${r.name} (${r.guard}) - Global`
|
|
715
|
-
}))}
|
|
716
|
-
placeholder="Select roles..."
|
|
717
|
-
/>
|
|
718
|
-
) : (
|
|
719
|
-
<div className="flex flex-wrap gap-2">
|
|
720
|
-
{currentUser.roles.length > 0 ? (
|
|
721
|
-
currentUser.roles.map((role) => (
|
|
722
|
-
<span key={role} className="badge-info">
|
|
723
|
-
{role}
|
|
724
|
-
</span>
|
|
725
|
-
))
|
|
726
|
-
) : (
|
|
727
|
-
<span className="text-gray-500 italic">No roles assigned</span>
|
|
728
|
-
)}
|
|
729
|
-
</div>
|
|
730
|
-
)}
|
|
731
|
-
</div>
|
|
732
|
-
|
|
733
|
-
{/* Metadata */}
|
|
734
|
-
<div className="mt-4">
|
|
735
|
-
<h3 className="text-base font-semibold text-gray-900 mb-2">Custom Metadata</h3>
|
|
736
|
-
{isEditing ? (
|
|
737
|
-
<div>
|
|
738
|
-
<textarea
|
|
739
|
-
value={formData.metadata}
|
|
740
|
-
onChange={(e) => {
|
|
741
|
-
const newValue = e.target.value;
|
|
742
|
-
setFormData({ ...formData, metadata: newValue });
|
|
743
|
-
|
|
744
|
-
// Validate JSON
|
|
745
|
-
try {
|
|
746
|
-
JSON.parse(newValue);
|
|
747
|
-
setMetadataError('');
|
|
748
|
-
} catch (err) {
|
|
749
|
-
setMetadataError('Invalid JSON format');
|
|
750
|
-
}
|
|
751
|
-
}}
|
|
752
|
-
className={`input-field font-mono text-xs ${metadataError ? 'border-red-500' : ''}`}
|
|
753
|
-
rows={6}
|
|
754
|
-
placeholder='{"key": "value"}'
|
|
755
|
-
/>
|
|
756
|
-
{metadataError && (
|
|
757
|
-
<p className="text-xs text-red-600 mt-0.5">{metadataError}</p>
|
|
758
|
-
)}
|
|
759
|
-
</div>
|
|
760
|
-
) : (
|
|
761
|
-
<pre className="bg-gray-50 p-2.5 rounded-lg overflow-x-auto text-xs">
|
|
762
|
-
{JSON.stringify(currentUser.metadata || {}, null, 2)}
|
|
763
|
-
</pre>
|
|
764
|
-
)}
|
|
765
|
-
</div>
|
|
766
|
-
</div>
|
|
767
|
-
</div>
|
|
768
|
-
|
|
769
|
-
{/* Footer Actions */}
|
|
770
|
-
<div className="border-t border-gray-200 p-4 bg-gray-50 flex items-center justify-between flex-shrink-0">
|
|
771
|
-
{isEditing ? (
|
|
772
|
-
<>
|
|
773
|
-
<Button
|
|
774
|
-
variant="secondary"
|
|
775
|
-
onClick={() => {
|
|
776
|
-
setIsEditing(false);
|
|
777
|
-
setSelectedRoles(currentUser.roles);
|
|
778
|
-
setFormData({
|
|
779
|
-
email: currentUser.email,
|
|
780
|
-
phone: currentUser.phone || '',
|
|
781
|
-
isActive: currentUser.isActive,
|
|
782
|
-
isVerified: currentUser.isVerified,
|
|
783
|
-
metadata: JSON.stringify(currentUser.metadata || {}, null, 2),
|
|
784
|
-
password: '',
|
|
785
|
-
emailLoginEnabled: loginMethods.emailEnabled,
|
|
786
|
-
phoneLoginEnabled: loginMethods.phoneEnabled,
|
|
787
|
-
isMfaEnabled: ((mfaDetails as any)?.isEnabled ?? false) || (currentUser.isMfaEnabled ?? false),
|
|
788
|
-
});
|
|
789
|
-
setPasswordError('');
|
|
790
|
-
setMetadataError('');
|
|
791
|
-
}}
|
|
792
|
-
>
|
|
793
|
-
Cancel
|
|
794
|
-
</Button>
|
|
795
|
-
<Button onClick={handleSave} disabled={saving}>
|
|
796
|
-
<Save className="w-4 h-4" />
|
|
797
|
-
{saving ? 'Saving...' : 'Save Changes'}
|
|
798
|
-
</Button>
|
|
799
|
-
</>
|
|
800
|
-
) : (
|
|
801
|
-
<>
|
|
802
|
-
<Button variant="secondary" onClick={onClose}>
|
|
803
|
-
Close
|
|
804
|
-
</Button>
|
|
805
|
-
<Button onClick={() => setIsEditing(true)}>
|
|
806
|
-
<Edit2 className="w-4 h-4" />
|
|
807
|
-
Edit User
|
|
808
|
-
</Button>
|
|
809
|
-
</>
|
|
810
|
-
)}
|
|
811
|
-
</div>
|
|
812
|
-
</div>
|
|
813
|
-
</div>
|
|
814
|
-
);
|
|
815
|
-
};
|