@nauth-toolkit/core 0.1.13 → 0.1.17
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/dist/adapters/database-columns.d.ts +70 -0
- package/dist/adapters/database-columns.d.ts.map +1 -1
- package/dist/adapters/database-columns.js +76 -2
- package/dist/adapters/database-columns.js.map +1 -1
- package/dist/adapters/express.adapter.d.ts +66 -0
- package/dist/adapters/express.adapter.d.ts.map +1 -1
- package/dist/adapters/express.adapter.js +80 -0
- package/dist/adapters/express.adapter.js.map +1 -1
- package/dist/adapters/fastify.adapter.d.ts +42 -0
- package/dist/adapters/fastify.adapter.d.ts.map +1 -1
- package/dist/adapters/fastify.adapter.js +86 -0
- package/dist/adapters/fastify.adapter.js.map +1 -1
- package/dist/adapters/index.d.ts +5 -0
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +9 -0
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/storage.factory.d.ts +107 -0
- package/dist/adapters/storage.factory.d.ts.map +1 -1
- package/dist/adapters/storage.factory.js +114 -0
- package/dist/adapters/storage.factory.js.map +1 -1
- package/dist/adapters.d.ts +8 -0
- package/dist/adapters.d.ts.map +1 -1
- package/dist/adapters.js +8 -0
- package/dist/adapters.js.map +1 -1
- package/dist/bootstrap.d.ts +82 -0
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +106 -0
- package/dist/bootstrap.js.map +1 -1
- package/dist/dto/admin-set-password.dto.d.ts +90 -0
- package/dist/dto/admin-set-password.dto.d.ts.map +1 -1
- package/dist/dto/admin-set-password.dto.js +91 -0
- package/dist/dto/admin-set-password.dto.js.map +1 -1
- package/dist/dto/auth-challenge.dto.d.ts +170 -0
- package/dist/dto/auth-challenge.dto.d.ts.map +1 -1
- package/dist/dto/auth-challenge.dto.js +170 -0
- package/dist/dto/auth-challenge.dto.js.map +1 -1
- package/dist/dto/auth-response.dto.d.ts +196 -0
- package/dist/dto/auth-response.dto.d.ts.map +1 -1
- package/dist/dto/auth-response.dto.js +149 -0
- package/dist/dto/auth-response.dto.js.map +1 -1
- package/dist/dto/challenge-response.dto.d.ts +155 -0
- package/dist/dto/challenge-response.dto.d.ts.map +1 -1
- package/dist/dto/challenge-response.dto.js +8 -0
- package/dist/dto/challenge-response.dto.js.map +1 -1
- package/dist/dto/change-password-request.dto.d.ts +35 -0
- package/dist/dto/change-password-request.dto.d.ts.map +1 -1
- package/dist/dto/change-password-request.dto.js +35 -0
- package/dist/dto/change-password-request.dto.js.map +1 -1
- package/dist/dto/change-password-response.dto.d.ts +25 -0
- package/dist/dto/change-password-response.dto.d.ts.map +1 -1
- package/dist/dto/change-password-response.dto.js +25 -0
- package/dist/dto/change-password-response.dto.js.map +1 -1
- package/dist/dto/change-password.dto.d.ts +45 -0
- package/dist/dto/change-password.dto.d.ts.map +1 -1
- package/dist/dto/change-password.dto.js +45 -0
- package/dist/dto/change-password.dto.js.map +1 -1
- package/dist/dto/confirm-forgot-password.dto.d.ts +59 -0
- package/dist/dto/confirm-forgot-password.dto.d.ts.map +1 -1
- package/dist/dto/confirm-forgot-password.dto.js +59 -0
- package/dist/dto/confirm-forgot-password.dto.js.map +1 -1
- package/dist/dto/error-response.dto.d.ts +103 -0
- package/dist/dto/error-response.dto.d.ts.map +1 -1
- package/dist/dto/error-response.dto.js +103 -0
- package/dist/dto/error-response.dto.js.map +1 -1
- package/dist/dto/forgot-password.dto.d.ts +58 -0
- package/dist/dto/forgot-password.dto.d.ts.map +1 -1
- package/dist/dto/forgot-password.dto.js +58 -0
- package/dist/dto/forgot-password.dto.js.map +1 -1
- package/dist/dto/get-available-methods.dto.d.ts +37 -0
- package/dist/dto/get-available-methods.dto.d.ts.map +1 -1
- package/dist/dto/get-available-methods.dto.js +37 -0
- package/dist/dto/get-available-methods.dto.js.map +1 -1
- package/dist/dto/get-challenge-data-response.dto.d.ts +24 -0
- package/dist/dto/get-challenge-data-response.dto.d.ts.map +1 -1
- package/dist/dto/get-challenge-data-response.dto.js +24 -0
- package/dist/dto/get-challenge-data-response.dto.js.map +1 -1
- package/dist/dto/get-challenge-data.dto.d.ts +46 -0
- package/dist/dto/get-challenge-data.dto.d.ts.map +1 -1
- package/dist/dto/get-challenge-data.dto.js +46 -0
- package/dist/dto/get-challenge-data.dto.js.map +1 -1
- package/dist/dto/get-client-info.dto.d.ts +74 -0
- package/dist/dto/get-client-info.dto.d.ts.map +1 -1
- package/dist/dto/get-client-info.dto.js +74 -0
- package/dist/dto/get-client-info.dto.js.map +1 -1
- package/dist/dto/get-device-token-response.dto.d.ts +21 -0
- package/dist/dto/get-device-token-response.dto.d.ts.map +1 -1
- package/dist/dto/get-device-token-response.dto.js +21 -0
- package/dist/dto/get-device-token-response.dto.js.map +1 -1
- package/dist/dto/get-events-by-type.dto.d.ts +50 -0
- package/dist/dto/get-events-by-type.dto.d.ts.map +1 -1
- package/dist/dto/get-events-by-type.dto.js +50 -0
- package/dist/dto/get-events-by-type.dto.js.map +1 -1
- package/dist/dto/get-ip-address-response.dto.d.ts +20 -0
- package/dist/dto/get-ip-address-response.dto.d.ts.map +1 -1
- package/dist/dto/get-ip-address-response.dto.js +20 -0
- package/dist/dto/get-ip-address-response.dto.js.map +1 -1
- package/dist/dto/get-mfa-status.dto.d.ts +59 -0
- package/dist/dto/get-mfa-status.dto.d.ts.map +1 -1
- package/dist/dto/get-mfa-status.dto.js +59 -0
- package/dist/dto/get-mfa-status.dto.js.map +1 -1
- package/dist/dto/get-risk-assessment-history.dto.d.ts +28 -0
- package/dist/dto/get-risk-assessment-history.dto.d.ts.map +1 -1
- package/dist/dto/get-risk-assessment-history.dto.js +28 -0
- package/dist/dto/get-risk-assessment-history.dto.js.map +1 -1
- package/dist/dto/get-session-id-response.dto.d.ts +21 -0
- package/dist/dto/get-session-id-response.dto.d.ts.map +1 -1
- package/dist/dto/get-session-id-response.dto.js +21 -0
- package/dist/dto/get-session-id-response.dto.js.map +1 -1
- package/dist/dto/get-setup-data-response.dto.d.ts +27 -0
- package/dist/dto/get-setup-data-response.dto.d.ts.map +1 -1
- package/dist/dto/get-setup-data-response.dto.js +27 -0
- package/dist/dto/get-setup-data-response.dto.js.map +1 -1
- package/dist/dto/get-setup-data.dto.d.ts +51 -0
- package/dist/dto/get-setup-data.dto.d.ts.map +1 -1
- package/dist/dto/get-setup-data.dto.js +51 -0
- package/dist/dto/get-setup-data.dto.js.map +1 -1
- package/dist/dto/get-suspicious-activity.dto.d.ts +31 -0
- package/dist/dto/get-suspicious-activity.dto.d.ts.map +1 -1
- package/dist/dto/get-suspicious-activity.dto.js +31 -0
- package/dist/dto/get-suspicious-activity.dto.js.map +1 -1
- package/dist/dto/get-user-agent-response.dto.d.ts +19 -0
- package/dist/dto/get-user-agent-response.dto.d.ts.map +1 -1
- package/dist/dto/get-user-agent-response.dto.js +19 -0
- package/dist/dto/get-user-agent-response.dto.js.map +1 -1
- package/dist/dto/get-user-auth-history.dto.d.ts +64 -0
- package/dist/dto/get-user-auth-history.dto.d.ts.map +1 -1
- package/dist/dto/get-user-auth-history.dto.js +64 -0
- package/dist/dto/get-user-auth-history.dto.js.map +1 -1
- package/dist/dto/get-user-by-email.dto.d.ts +42 -0
- package/dist/dto/get-user-by-email.dto.d.ts.map +1 -1
- package/dist/dto/get-user-by-email.dto.js +42 -0
- package/dist/dto/get-user-by-email.dto.js.map +1 -1
- package/dist/dto/get-user-by-id.dto.d.ts +32 -0
- package/dist/dto/get-user-by-id.dto.d.ts.map +1 -1
- package/dist/dto/get-user-by-id.dto.js +32 -0
- package/dist/dto/get-user-by-id.dto.js.map +1 -1
- package/dist/dto/get-user-devices.dto.d.ts +34 -0
- package/dist/dto/get-user-devices.dto.d.ts.map +1 -1
- package/dist/dto/get-user-devices.dto.js +34 -0
- package/dist/dto/get-user-devices.dto.js.map +1 -1
- package/dist/dto/get-user-response.dto.d.ts +14 -0
- package/dist/dto/get-user-response.dto.d.ts.map +1 -1
- package/dist/dto/get-user-response.dto.js +15 -0
- package/dist/dto/get-user-response.dto.js.map +1 -1
- package/dist/dto/has-provider.dto.d.ts +33 -0
- package/dist/dto/has-provider.dto.d.ts.map +1 -1
- package/dist/dto/has-provider.dto.js +33 -0
- package/dist/dto/has-provider.dto.js.map +1 -1
- package/dist/dto/index.js +5 -0
- package/dist/dto/index.js.map +1 -1
- package/dist/dto/is-trusted-device-response.dto.d.ts +28 -0
- package/dist/dto/is-trusted-device-response.dto.d.ts.map +1 -1
- package/dist/dto/is-trusted-device-response.dto.js +28 -0
- package/dist/dto/is-trusted-device-response.dto.js.map +1 -1
- package/dist/dto/list-providers-response.dto.d.ts +19 -0
- package/dist/dto/list-providers-response.dto.d.ts.map +1 -1
- package/dist/dto/list-providers-response.dto.js +19 -0
- package/dist/dto/list-providers-response.dto.js.map +1 -1
- package/dist/dto/login.dto.d.ts +48 -0
- package/dist/dto/login.dto.d.ts.map +1 -1
- package/dist/dto/login.dto.js +50 -1
- package/dist/dto/login.dto.js.map +1 -1
- package/dist/dto/logout-all-response.dto.d.ts +20 -0
- package/dist/dto/logout-all-response.dto.d.ts.map +1 -1
- package/dist/dto/logout-all-response.dto.js +20 -0
- package/dist/dto/logout-all-response.dto.js.map +1 -1
- package/dist/dto/logout-all.dto.d.ts +42 -0
- package/dist/dto/logout-all.dto.d.ts.map +1 -1
- package/dist/dto/logout-all.dto.js +42 -0
- package/dist/dto/logout-all.dto.js.map +1 -1
- package/dist/dto/logout-response.dto.d.ts +21 -0
- package/dist/dto/logout-response.dto.d.ts.map +1 -1
- package/dist/dto/logout-response.dto.js +21 -0
- package/dist/dto/logout-response.dto.js.map +1 -1
- package/dist/dto/logout.dto.d.ts +45 -0
- package/dist/dto/logout.dto.d.ts.map +1 -1
- package/dist/dto/logout.dto.js +45 -0
- package/dist/dto/logout.dto.js.map +1 -1
- package/dist/dto/refresh-token.dto.d.ts +28 -0
- package/dist/dto/refresh-token.dto.d.ts.map +1 -1
- package/dist/dto/refresh-token.dto.js +28 -0
- package/dist/dto/refresh-token.dto.js.map +1 -1
- package/dist/dto/remove-devices.dto.d.ts +51 -0
- package/dist/dto/remove-devices.dto.d.ts.map +1 -1
- package/dist/dto/remove-devices.dto.js +51 -0
- package/dist/dto/remove-devices.dto.js.map +1 -1
- package/dist/dto/resend-code-response.dto.d.ts +28 -0
- package/dist/dto/resend-code-response.dto.d.ts.map +1 -1
- package/dist/dto/resend-code-response.dto.js +28 -0
- package/dist/dto/resend-code-response.dto.js.map +1 -1
- package/dist/dto/resend-code.dto.d.ts +37 -0
- package/dist/dto/resend-code.dto.d.ts.map +1 -1
- package/dist/dto/resend-code.dto.js +37 -0
- package/dist/dto/resend-code.dto.js.map +1 -1
- package/dist/dto/reset-password.dto.d.ts +74 -0
- package/dist/dto/reset-password.dto.d.ts.map +1 -1
- package/dist/dto/reset-password.dto.js +76 -1
- package/dist/dto/reset-password.dto.js.map +1 -1
- package/dist/dto/respond-challenge.dto.d.ts +147 -0
- package/dist/dto/respond-challenge.dto.d.ts.map +1 -1
- package/dist/dto/respond-challenge.dto.js +162 -0
- package/dist/dto/respond-challenge.dto.js.map +1 -1
- package/dist/dto/set-mfa-exemption.dto.d.ts +65 -0
- package/dist/dto/set-mfa-exemption.dto.d.ts.map +1 -1
- package/dist/dto/set-mfa-exemption.dto.js +65 -0
- package/dist/dto/set-mfa-exemption.dto.js.map +1 -1
- package/dist/dto/set-must-change-password-response.dto.d.ts +23 -0
- package/dist/dto/set-must-change-password-response.dto.d.ts.map +1 -1
- package/dist/dto/set-must-change-password-response.dto.js +23 -0
- package/dist/dto/set-must-change-password-response.dto.js.map +1 -1
- package/dist/dto/set-must-change-password.dto.d.ts +32 -0
- package/dist/dto/set-must-change-password.dto.d.ts.map +1 -1
- package/dist/dto/set-must-change-password.dto.js +32 -0
- package/dist/dto/set-must-change-password.dto.js.map +1 -1
- package/dist/dto/set-preferred-method.dto.d.ts +48 -0
- package/dist/dto/set-preferred-method.dto.d.ts.map +1 -1
- package/dist/dto/set-preferred-method.dto.js +48 -0
- package/dist/dto/set-preferred-method.dto.js.map +1 -1
- package/dist/dto/setup-mfa.dto.d.ts +62 -0
- package/dist/dto/setup-mfa.dto.d.ts.map +1 -1
- package/dist/dto/setup-mfa.dto.js +62 -0
- package/dist/dto/setup-mfa.dto.js.map +1 -1
- package/dist/dto/signup.dto.d.ts +92 -0
- package/dist/dto/signup.dto.d.ts.map +1 -1
- package/dist/dto/signup.dto.js +93 -0
- package/dist/dto/signup.dto.js.map +1 -1
- package/dist/dto/social-auth.dto.d.ts +234 -0
- package/dist/dto/social-auth.dto.d.ts.map +1 -1
- package/dist/dto/social-auth.dto.js +234 -0
- package/dist/dto/social-auth.dto.js.map +1 -1
- package/dist/dto/trust-device-response.dto.d.ts +26 -0
- package/dist/dto/trust-device-response.dto.d.ts.map +1 -1
- package/dist/dto/trust-device-response.dto.js +26 -0
- package/dist/dto/trust-device-response.dto.js.map +1 -1
- package/dist/dto/trust-device.dto.d.ts +9 -0
- package/dist/dto/trust-device.dto.d.ts.map +1 -1
- package/dist/dto/trust-device.dto.js +9 -0
- package/dist/dto/trust-device.dto.js.map +1 -1
- package/dist/dto/update-user-attributes-request.dto.d.ts +36 -0
- package/dist/dto/update-user-attributes-request.dto.d.ts.map +1 -1
- package/dist/dto/update-user-attributes-request.dto.js +36 -0
- package/dist/dto/update-user-attributes-request.dto.js.map +1 -1
- package/dist/dto/user-response.dto.d.ts +81 -0
- package/dist/dto/user-response.dto.d.ts.map +1 -1
- package/dist/dto/user-response.dto.js +84 -2
- package/dist/dto/user-response.dto.js.map +1 -1
- package/dist/dto/user-update.dto.d.ts +132 -0
- package/dist/dto/user-update.dto.d.ts.map +1 -1
- package/dist/dto/user-update.dto.js +133 -0
- package/dist/dto/user-update.dto.js.map +1 -1
- package/dist/dto/verify-email.dto.d.ts +171 -0
- package/dist/dto/verify-email.dto.d.ts.map +1 -1
- package/dist/dto/verify-email.dto.js +173 -1
- package/dist/dto/verify-email.dto.js.map +1 -1
- package/dist/dto/verify-mfa-code.dto.d.ts +65 -0
- package/dist/dto/verify-mfa-code.dto.d.ts.map +1 -1
- package/dist/dto/verify-mfa-code.dto.js +65 -0
- package/dist/dto/verify-mfa-code.dto.js.map +1 -1
- package/dist/dto/verify-phone-by-sub.dto.d.ts +49 -0
- package/dist/dto/verify-phone-by-sub.dto.d.ts.map +1 -1
- package/dist/dto/verify-phone-by-sub.dto.js +49 -0
- package/dist/dto/verify-phone-by-sub.dto.js.map +1 -1
- package/dist/dto/verify-phone.dto.d.ts +139 -0
- package/dist/dto/verify-phone.dto.d.ts.map +1 -1
- package/dist/dto/verify-phone.dto.js +142 -1
- package/dist/dto/verify-phone.dto.js.map +1 -1
- package/dist/dto.d.ts +10 -0
- package/dist/dto.d.ts.map +1 -1
- package/dist/dto.js +10 -0
- package/dist/dto.js.map +1 -1
- package/dist/entities/auth-audit.entity.d.ts +159 -0
- package/dist/entities/auth-audit.entity.d.ts.map +1 -1
- package/dist/entities/auth-audit.entity.js +166 -0
- package/dist/entities/auth-audit.entity.js.map +1 -1
- package/dist/entities/challenge-session.entity.d.ts +87 -0
- package/dist/entities/challenge-session.entity.d.ts.map +1 -1
- package/dist/entities/challenge-session.entity.js +87 -0
- package/dist/entities/challenge-session.entity.js.map +1 -1
- package/dist/entities/index.d.ts +18 -0
- package/dist/entities/index.d.ts.map +1 -1
- package/dist/entities/index.js +18 -0
- package/dist/entities/index.js.map +1 -1
- package/dist/entities/login-attempt.entity.d.ts +43 -0
- package/dist/entities/login-attempt.entity.d.ts.map +1 -1
- package/dist/entities/login-attempt.entity.js +43 -0
- package/dist/entities/login-attempt.entity.js.map +1 -1
- package/dist/entities/mfa-device.entity.d.ts +112 -0
- package/dist/entities/mfa-device.entity.d.ts.map +1 -1
- package/dist/entities/mfa-device.entity.js +112 -0
- package/dist/entities/mfa-device.entity.js.map +1 -1
- package/dist/entities/rate-limit.entity.d.ts +31 -0
- package/dist/entities/rate-limit.entity.d.ts.map +1 -1
- package/dist/entities/rate-limit.entity.js +31 -0
- package/dist/entities/rate-limit.entity.js.map +1 -1
- package/dist/entities/session.entity.d.ts +121 -0
- package/dist/entities/session.entity.d.ts.map +1 -1
- package/dist/entities/session.entity.js +121 -0
- package/dist/entities/session.entity.js.map +1 -1
- package/dist/entities/social-account.entity.d.ts +75 -0
- package/dist/entities/social-account.entity.d.ts.map +1 -1
- package/dist/entities/social-account.entity.js +75 -0
- package/dist/entities/social-account.entity.js.map +1 -1
- package/dist/entities/storage-lock.entity.d.ts +28 -0
- package/dist/entities/storage-lock.entity.d.ts.map +1 -1
- package/dist/entities/storage-lock.entity.js +28 -0
- package/dist/entities/storage-lock.entity.js.map +1 -1
- package/dist/entities/trusted-device.entity.d.ts +83 -0
- package/dist/entities/trusted-device.entity.d.ts.map +1 -1
- package/dist/entities/trusted-device.entity.js +83 -0
- package/dist/entities/trusted-device.entity.js.map +1 -1
- package/dist/entities/user.entity.d.ts +166 -0
- package/dist/entities/user.entity.d.ts.map +1 -1
- package/dist/entities/user.entity.js +166 -0
- package/dist/entities/user.entity.js.map +1 -1
- package/dist/entities/verification-token.entity.d.ts +102 -0
- package/dist/entities/verification-token.entity.d.ts.map +1 -1
- package/dist/entities/verification-token.entity.js +102 -0
- package/dist/entities/verification-token.entity.js.map +1 -1
- package/dist/entities.d.ts +8 -0
- package/dist/entities.d.ts.map +1 -1
- package/dist/entities.js +8 -0
- package/dist/entities.js.map +1 -1
- package/dist/enums/auth-audit-event-type.enum.d.ts +211 -0
- package/dist/enums/auth-audit-event-type.enum.d.ts.map +1 -1
- package/dist/enums/auth-audit-event-type.enum.js +244 -0
- package/dist/enums/auth-audit-event-type.enum.js.map +1 -1
- package/dist/enums/error-codes.enum.d.ts +296 -0
- package/dist/enums/error-codes.enum.d.ts.map +1 -1
- package/dist/enums/error-codes.enum.js +332 -0
- package/dist/enums/error-codes.enum.js.map +1 -1
- package/dist/enums/mfa-method.enum.d.ts +74 -0
- package/dist/enums/mfa-method.enum.d.ts.map +1 -1
- package/dist/enums/mfa-method.enum.js +64 -0
- package/dist/enums/mfa-method.enum.js.map +1 -1
- package/dist/enums/risk-factor.enum.d.ts +91 -0
- package/dist/enums/risk-factor.enum.d.ts.map +1 -1
- package/dist/enums/risk-factor.enum.js +97 -0
- package/dist/enums/risk-factor.enum.js.map +1 -1
- package/dist/exceptions/nauth.exception.d.ts +149 -0
- package/dist/exceptions/nauth.exception.d.ts.map +1 -1
- package/dist/exceptions/nauth.exception.js +159 -0
- package/dist/exceptions/nauth.exception.js.map +1 -1
- package/dist/handlers/auth.handler.d.ts +32 -0
- package/dist/handlers/auth.handler.d.ts.map +1 -1
- package/dist/handlers/auth.handler.js +47 -1
- package/dist/handlers/auth.handler.js.map +1 -1
- package/dist/handlers/client-info.handler.d.ts +25 -0
- package/dist/handlers/client-info.handler.d.ts.map +1 -1
- package/dist/handlers/client-info.handler.js +36 -2
- package/dist/handlers/client-info.handler.js.map +1 -1
- package/dist/handlers/csrf.handler.d.ts +32 -0
- package/dist/handlers/csrf.handler.d.ts.map +1 -1
- package/dist/handlers/csrf.handler.js +49 -1
- package/dist/handlers/csrf.handler.js.map +1 -1
- package/dist/handlers/token-delivery.handler.d.ts +16 -0
- package/dist/handlers/token-delivery.handler.d.ts.map +1 -1
- package/dist/handlers/token-delivery.handler.js +22 -1
- package/dist/handlers/token-delivery.handler.js.map +1 -1
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +67 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces/client-info.interface.d.ts +58 -0
- package/dist/interfaces/client-info.interface.d.ts.map +1 -1
- package/dist/interfaces/config.interface.d.ts +1774 -0
- package/dist/interfaces/config.interface.d.ts.map +1 -1
- package/dist/interfaces/config.interface.js +16 -0
- package/dist/interfaces/config.interface.js.map +1 -1
- package/dist/interfaces/entities.interface.d.ts +48 -0
- package/dist/interfaces/entities.interface.d.ts.map +1 -1
- package/dist/interfaces/entities.interface.js +8 -0
- package/dist/interfaces/entities.interface.js.map +1 -1
- package/dist/interfaces/index.js +5 -0
- package/dist/interfaces/index.js.map +1 -1
- package/dist/interfaces/logger.interface.d.ts +213 -0
- package/dist/interfaces/logger.interface.d.ts.map +1 -1
- package/dist/interfaces/logger.interface.js +35 -0
- package/dist/interfaces/logger.interface.js.map +1 -1
- package/dist/interfaces/mfa-provider.interface.d.ts +134 -0
- package/dist/interfaces/mfa-provider.interface.d.ts.map +1 -1
- package/dist/interfaces/oauth.interface.d.ts +110 -0
- package/dist/interfaces/oauth.interface.d.ts.map +1 -1
- package/dist/interfaces/provider.interface.d.ts +83 -0
- package/dist/interfaces/provider.interface.d.ts.map +1 -1
- package/dist/interfaces/sms-template.interface.d.ts +246 -0
- package/dist/interfaces/sms-template.interface.d.ts.map +1 -1
- package/dist/interfaces/sms-template.interface.js +26 -0
- package/dist/interfaces/sms-template.interface.js.map +1 -1
- package/dist/interfaces/social-auth-provider.interface.d.ts +115 -0
- package/dist/interfaces/social-auth-provider.interface.d.ts.map +1 -1
- package/dist/interfaces/storage-adapter.interface.d.ts +37 -0
- package/dist/interfaces/storage-adapter.interface.d.ts.map +1 -1
- package/dist/interfaces/template.interface.d.ts +351 -0
- package/dist/interfaces/template.interface.d.ts.map +1 -1
- package/dist/interfaces/template.interface.js +13 -0
- package/dist/interfaces/template.interface.js.map +1 -1
- package/dist/interfaces/token-verifier.interface.d.ts +101 -0
- package/dist/interfaces/token-verifier.interface.d.ts.map +1 -1
- package/dist/interfaces.d.ts +8 -0
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js +8 -0
- package/dist/interfaces.js.map +1 -1
- package/dist/internal.d.ts +120 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +138 -0
- package/dist/internal.js.map +1 -1
- package/dist/platform/interfaces.d.ts +187 -0
- package/dist/platform/interfaces.d.ts.map +1 -1
- package/dist/platform/interfaces.js +11 -0
- package/dist/platform/interfaces.js.map +1 -1
- package/dist/schemas/auth-config.schema.d.ts +48 -0
- package/dist/schemas/auth-config.schema.d.ts.map +1 -1
- package/dist/schemas/auth-config.schema.js +188 -9
- package/dist/schemas/auth-config.schema.js.map +1 -1
- package/dist/services/adaptive-mfa-decision.service.d.ts +144 -0
- package/dist/services/adaptive-mfa-decision.service.d.ts.map +1 -1
- package/dist/services/adaptive-mfa-decision.service.js +151 -5
- package/dist/services/adaptive-mfa-decision.service.js.map +1 -1
- package/dist/services/auth-audit.service.d.ts +195 -0
- package/dist/services/auth-audit.service.d.ts.map +1 -1
- package/dist/services/auth-audit.service.js +228 -1
- package/dist/services/auth-audit.service.js.map +1 -1
- package/dist/services/auth-challenge-helper.service.d.ts +144 -1
- package/dist/services/auth-challenge-helper.service.d.ts.map +1 -1
- package/dist/services/auth-challenge-helper.service.js +295 -16
- package/dist/services/auth-challenge-helper.service.js.map +1 -1
- package/dist/services/auth-flow-context-builder.service.d.ts +120 -1
- package/dist/services/auth-flow-context-builder.service.d.ts.map +1 -1
- package/dist/services/auth-flow-context-builder.service.js +184 -5
- package/dist/services/auth-flow-context-builder.service.js.map +1 -1
- package/dist/services/auth-flow-rules.d.ts +136 -0
- package/dist/services/auth-flow-rules.d.ts.map +1 -1
- package/dist/services/auth-flow-rules.js +137 -0
- package/dist/services/auth-flow-rules.js.map +1 -1
- package/dist/services/auth-flow-state-definitions.d.ts +40 -0
- package/dist/services/auth-flow-state-definitions.d.ts.map +1 -1
- package/dist/services/auth-flow-state-definitions.js +98 -0
- package/dist/services/auth-flow-state-definitions.js.map +1 -1
- package/dist/services/auth-flow-state-machine.service.d.ts +91 -0
- package/dist/services/auth-flow-state-machine.service.d.ts.map +1 -1
- package/dist/services/auth-flow-state-machine.service.js +102 -0
- package/dist/services/auth-flow-state-machine.service.js.map +1 -1
- package/dist/services/auth-flow-state-machine.types.d.ts +221 -0
- package/dist/services/auth-flow-state-machine.types.d.ts.map +1 -1
- package/dist/services/auth-flow-state-machine.types.js +47 -0
- package/dist/services/auth-flow-state-machine.types.js.map +1 -1
- package/dist/services/auth.service.d.ts +397 -1
- package/dist/services/auth.service.d.ts.map +1 -1
- package/dist/services/auth.service.js +943 -27
- package/dist/services/auth.service.js.map +1 -1
- package/dist/services/challenge.service.d.ts +255 -1
- package/dist/services/challenge.service.d.ts.map +1 -1
- package/dist/services/challenge.service.js +327 -3
- package/dist/services/challenge.service.js.map +1 -1
- package/dist/services/client-info.service.d.ts +143 -0
- package/dist/services/client-info.service.d.ts.map +1 -1
- package/dist/services/client-info.service.js +161 -0
- package/dist/services/client-info.service.js.map +1 -1
- package/dist/services/csrf.service.d.ts +15 -0
- package/dist/services/csrf.service.d.ts.map +1 -1
- package/dist/services/csrf.service.js +16 -0
- package/dist/services/csrf.service.js.map +1 -1
- package/dist/services/email-verification.service.d.ts +52 -0
- package/dist/services/email-verification.service.d.ts.map +1 -1
- package/dist/services/email-verification.service.js +149 -10
- package/dist/services/email-verification.service.js.map +1 -1
- package/dist/services/geo-location.service.d.ts +105 -0
- package/dist/services/geo-location.service.d.ts.map +1 -1
- package/dist/services/geo-location.service.js +188 -2
- package/dist/services/geo-location.service.js.map +1 -1
- package/dist/services/jwt.service.d.ts +257 -0
- package/dist/services/jwt.service.d.ts.map +1 -1
- package/dist/services/jwt.service.js +284 -1
- package/dist/services/jwt.service.js.map +1 -1
- package/dist/services/mfa-base.service.d.ts +179 -1
- package/dist/services/mfa-base.service.d.ts.map +1 -1
- package/dist/services/mfa-base.service.js +256 -2
- package/dist/services/mfa-base.service.js.map +1 -1
- package/dist/services/mfa.service.d.ts +304 -0
- package/dist/services/mfa.service.d.ts.map +1 -1
- package/dist/services/mfa.service.js +380 -0
- package/dist/services/mfa.service.js.map +1 -1
- package/dist/services/password-reset.service.d.ts +46 -0
- package/dist/services/password-reset.service.d.ts.map +1 -1
- package/dist/services/password-reset.service.js +79 -0
- package/dist/services/password-reset.service.js.map +1 -1
- package/dist/services/password.service.d.ts +139 -0
- package/dist/services/password.service.d.ts.map +1 -1
- package/dist/services/password.service.js +167 -9
- package/dist/services/password.service.js.map +1 -1
- package/dist/services/phone-verification.service.d.ts +75 -0
- package/dist/services/phone-verification.service.d.ts.map +1 -1
- package/dist/services/phone-verification.service.js +188 -6
- package/dist/services/phone-verification.service.js.map +1 -1
- package/dist/services/risk-detection.service.d.ts +198 -0
- package/dist/services/risk-detection.service.d.ts.map +1 -1
- package/dist/services/risk-detection.service.js +358 -11
- package/dist/services/risk-detection.service.js.map +1 -1
- package/dist/services/risk-scoring.service.d.ts +84 -0
- package/dist/services/risk-scoring.service.d.ts.map +1 -1
- package/dist/services/risk-scoring.service.js +87 -0
- package/dist/services/risk-scoring.service.js.map +1 -1
- package/dist/services/session.service.d.ts +204 -0
- package/dist/services/session.service.d.ts.map +1 -1
- package/dist/services/session.service.js +289 -4
- package/dist/services/session.service.js.map +1 -1
- package/dist/services/social-auth-base.service.d.ts +123 -1
- package/dist/services/social-auth-base.service.d.ts.map +1 -1
- package/dist/services/social-auth-base.service.js +155 -2
- package/dist/services/social-auth-base.service.js.map +1 -1
- package/dist/services/social-auth.service.d.ts +191 -0
- package/dist/services/social-auth.service.d.ts.map +1 -1
- package/dist/services/social-auth.service.js +215 -2
- package/dist/services/social-auth.service.js.map +1 -1
- package/dist/services/social-provider-registry.service.d.ts +86 -0
- package/dist/services/social-provider-registry.service.d.ts.map +1 -1
- package/dist/services/social-provider-registry.service.js +86 -0
- package/dist/services/social-provider-registry.service.js.map +1 -1
- package/dist/services/trusted-device.service.d.ts +105 -0
- package/dist/services/trusted-device.service.d.ts.map +1 -1
- package/dist/services/trusted-device.service.js +133 -4
- package/dist/services/trusted-device.service.js.map +1 -1
- package/dist/storage/account-lockout-storage.service.d.ts +35 -0
- package/dist/storage/account-lockout-storage.service.d.ts.map +1 -1
- package/dist/storage/account-lockout-storage.service.js +35 -0
- package/dist/storage/account-lockout-storage.service.js.map +1 -1
- package/dist/storage/memory-storage.adapter.d.ts +148 -0
- package/dist/storage/memory-storage.adapter.d.ts.map +1 -1
- package/dist/storage/memory-storage.adapter.js +201 -6
- package/dist/storage/memory-storage.adapter.js.map +1 -1
- package/dist/storage/rate-limit-storage.service.d.ts +3 -0
- package/dist/storage/rate-limit-storage.service.d.ts.map +1 -1
- package/dist/storage/rate-limit-storage.service.js +4 -0
- package/dist/storage/rate-limit-storage.service.js.map +1 -1
- package/dist/storage.d.ts +8 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +8 -0
- package/dist/storage.js.map +1 -1
- package/dist/templates/html-template.engine.d.ts +110 -0
- package/dist/templates/html-template.engine.d.ts.map +1 -1
- package/dist/templates/html-template.engine.js +147 -0
- package/dist/templates/html-template.engine.js.map +1 -1
- package/dist/templates/index.d.ts +5 -0
- package/dist/templates/index.d.ts.map +1 -1
- package/dist/templates/index.js +5 -0
- package/dist/templates/index.js.map +1 -1
- package/dist/templates/sms-template.engine.d.ts +151 -0
- package/dist/templates/sms-template.engine.d.ts.map +1 -1
- package/dist/templates/sms-template.engine.js +171 -0
- package/dist/templates/sms-template.engine.js.map +1 -1
- package/dist/templates.d.ts +8 -0
- package/dist/templates.d.ts.map +1 -1
- package/dist/templates.js +8 -0
- package/dist/templates.js.map +1 -1
- package/dist/utils/common-passwords.d.ts +42 -0
- package/dist/utils/common-passwords.d.ts.map +1 -1
- package/dist/utils/common-passwords.js +88 -0
- package/dist/utils/common-passwords.js.map +1 -1
- package/dist/utils/context-storage.d.ts +129 -0
- package/dist/utils/context-storage.d.ts.map +1 -1
- package/dist/utils/context-storage.js +129 -0
- package/dist/utils/context-storage.js.map +1 -1
- package/dist/utils/cookie-names.util.d.ts +35 -0
- package/dist/utils/cookie-names.util.d.ts.map +1 -1
- package/dist/utils/cookie-names.util.js +37 -0
- package/dist/utils/cookie-names.util.js.map +1 -1
- package/dist/utils/cookies.util.d.ts +19 -0
- package/dist/utils/cookies.util.d.ts.map +1 -1
- package/dist/utils/cookies.util.js +30 -3
- package/dist/utils/cookies.util.js.map +1 -1
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/ip-extractor.d.ts +88 -0
- package/dist/utils/ip-extractor.d.ts.map +1 -1
- package/dist/utils/ip-extractor.js +109 -16
- package/dist/utils/ip-extractor.js.map +1 -1
- package/dist/utils/nauth-logger.d.ts +70 -0
- package/dist/utils/nauth-logger.d.ts.map +1 -1
- package/dist/utils/nauth-logger.js +82 -4
- package/dist/utils/nauth-logger.js.map +1 -1
- package/dist/utils/pii-redactor.d.ts +70 -0
- package/dist/utils/pii-redactor.d.ts.map +1 -1
- package/dist/utils/pii-redactor.js +102 -0
- package/dist/utils/pii-redactor.js.map +1 -1
- package/dist/utils/setup/get-repositories.d.ts +16 -0
- package/dist/utils/setup/get-repositories.d.ts.map +1 -1
- package/dist/utils/setup/get-repositories.js +21 -0
- package/dist/utils/setup/get-repositories.js.map +1 -1
- package/dist/utils/setup/init-services.d.ts +40 -1
- package/dist/utils/setup/init-services.d.ts.map +1 -1
- package/dist/utils/setup/init-services.js +98 -0
- package/dist/utils/setup/init-services.js.map +1 -1
- package/dist/utils/setup/init-social.d.ts +27 -0
- package/dist/utils/setup/init-social.d.ts.map +1 -1
- package/dist/utils/setup/init-social.js +49 -0
- package/dist/utils/setup/init-social.js.map +1 -1
- package/dist/utils/setup/init-storage.d.ts +22 -0
- package/dist/utils/setup/init-storage.d.ts.map +1 -1
- package/dist/utils/setup/init-storage.js +36 -0
- package/dist/utils/setup/init-storage.js.map +1 -1
- package/dist/utils/setup/register-mfa.d.ts +22 -0
- package/dist/utils/setup/register-mfa.d.ts.map +1 -1
- package/dist/utils/setup/register-mfa.js +41 -0
- package/dist/utils/setup/register-mfa.js.map +1 -1
- package/dist/utils/setup/run-nauth-migrations.d.ts +7 -0
- package/dist/utils/setup/run-nauth-migrations.d.ts.map +1 -1
- package/dist/utils/setup/run-nauth-migrations.js +8 -0
- package/dist/utils/setup/run-nauth-migrations.js.map +1 -1
- package/dist/utils/token-delivery-policy.d.ts +17 -0
- package/dist/utils/token-delivery-policy.d.ts.map +1 -1
- package/dist/utils/token-delivery-policy.js +17 -0
- package/dist/utils/token-delivery-policy.js.map +1 -1
- package/dist/utils.d.ts +8 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +8 -0
- package/dist/utils.js.map +1 -1
- package/dist/validators/template.validator.d.ts +80 -0
- package/dist/validators/template.validator.d.ts.map +1 -1
- package/dist/validators/template.validator.js +94 -0
- package/dist/validators/template.validator.js.map +1 -1
- package/package.json +7 -2
|
@@ -41,6 +41,22 @@ const nauth_exception_1 = require("../exceptions/nauth.exception");
|
|
|
41
41
|
const error_codes_enum_1 = require("../enums/error-codes.enum");
|
|
42
42
|
const mfa_method_enum_1 = require("../enums/mfa-method.enum");
|
|
43
43
|
const auth_flow_state_machine_types_1 = require("./auth-flow-state-machine.types");
|
|
44
|
+
/**
|
|
45
|
+
* Helper service for challenge-response authentication flows
|
|
46
|
+
*
|
|
47
|
+
* This service determines if a user needs to complete challenges
|
|
48
|
+
* before full authentication can be granted, and generates appropriate
|
|
49
|
+
* responses including MFA challenges.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* const response = await challengeHelper.determineAuthResponse(
|
|
54
|
+
* user,
|
|
55
|
+
* 'login',
|
|
56
|
+
* { ipAddress: '1.2.3.4' }
|
|
57
|
+
* );
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
44
60
|
class AuthChallengeHelperService {
|
|
45
61
|
challengeService;
|
|
46
62
|
jwtService;
|
|
@@ -64,20 +80,68 @@ class AuthChallengeHelperService {
|
|
|
64
80
|
this.emailVerificationService = emailVerificationService;
|
|
65
81
|
this.phoneVerificationService = phoneVerificationService;
|
|
66
82
|
}
|
|
83
|
+
// ============================================================================
|
|
84
|
+
// OLD METHODS DELETED - Replaced by state machine
|
|
85
|
+
// ============================================================================
|
|
86
|
+
// determinePendingChallenges() - DELETED (replaced by state machine)
|
|
87
|
+
// isMFASetupRequired() - DELETED (replaced by state machine)
|
|
88
|
+
// checkMFARequirement() - DELETED (replaced by state machine)
|
|
89
|
+
// All challenge determination is now handled by determineAuthResponse() using state machine
|
|
90
|
+
/**
|
|
91
|
+
* Create challenge response for authentication
|
|
92
|
+
*
|
|
93
|
+
* Generates a challenge session and returns challenge details to client.
|
|
94
|
+
* Sends verification codes when challenges are created to ensure sequential flow.
|
|
95
|
+
*
|
|
96
|
+
* @param user - User who needs to complete challenges
|
|
97
|
+
* @param challengeName - Type of challenge
|
|
98
|
+
* @param config - Auth configuration
|
|
99
|
+
* @param authMethod - Authentication method ('password' or 'social')
|
|
100
|
+
* @param authProvider - Provider name for social auth (e.g., 'google', 'facebook')
|
|
101
|
+
* @returns Challenge response DTO
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```typescript
|
|
105
|
+
* const response = await challengeHelper.createChallengeResponse(
|
|
106
|
+
* user,
|
|
107
|
+
* AuthChallenge.VERIFY_EMAIL,
|
|
108
|
+
* config,
|
|
109
|
+
* 'social',
|
|
110
|
+
* 'google'
|
|
111
|
+
* );
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
67
114
|
async createChallengeResponse(user, challengeName, config, authMethod = 'password', authProvider, skipAutoSend) {
|
|
115
|
+
// Client info (ipAddress, userAgent) automatically extracted from ClientInfoService
|
|
116
|
+
// Note: ClientInfoService is used transparently by ChallengeService and AuditService
|
|
117
|
+
// ============================================================================
|
|
118
|
+
// STEP 1: Create challenge session FIRST (before sending codes)
|
|
119
|
+
// ============================================================================
|
|
120
|
+
// This ensures the session exists before any verification codes are sent.
|
|
121
|
+
// Creating the session first is critical for proper audit trail and session tracking.
|
|
68
122
|
this.logger?.debug?.(`Creating challenge with authMethod=${authMethod}, authProvider=${authProvider || 'none'} for user ${user.sub}`);
|
|
123
|
+
// Client info (ipAddress, userAgent) automatically extracted from ClientInfoService
|
|
69
124
|
const challengeSession = await this.challengeService.createChallengeSession(user, challengeName, {
|
|
70
125
|
email: user.email,
|
|
71
126
|
phone: user.phone,
|
|
72
|
-
authMethod,
|
|
73
|
-
authProvider,
|
|
127
|
+
authMethod, // Store auth method for challenge completion flow
|
|
128
|
+
authProvider, // Store provider for social auth (e.g., 'google', 'facebook')
|
|
74
129
|
});
|
|
130
|
+
// ============================================================================
|
|
131
|
+
// STEP 2: Send verification codes AFTER session is created
|
|
132
|
+
// ============================================================================
|
|
133
|
+
// This ensures codes are sent at the right time:
|
|
134
|
+
// - Email code sent when VERIFY_EMAIL challenge is created
|
|
135
|
+
// - Phone code sent when VERIFY_PHONE challenge is created (after email is verified)
|
|
136
|
+
// This prevents sending both codes at once, avoiding user confusion.
|
|
137
|
+
// Challenges are sequential: first VERIFY_EMAIL, then VERIFY_PHONE
|
|
75
138
|
if (challengeName === auth_challenge_dto_1.AuthChallenge.VERIFY_EMAIL && this.emailVerificationService) {
|
|
76
139
|
this.logger?.log?.(`Sending verification email to: ${user.email}`);
|
|
140
|
+
// Fire and forget - don't block challenge response
|
|
77
141
|
const emailDto = Object.assign(new verify_email_dto_1.SendVerificationEmailDTO(), {
|
|
78
142
|
sub: user.sub,
|
|
79
143
|
baseUrl: undefined,
|
|
80
|
-
challengeSessionId: challengeSession.id,
|
|
144
|
+
challengeSessionId: challengeSession.id, // Link verification token to this challenge session
|
|
81
145
|
});
|
|
82
146
|
this.emailVerificationService
|
|
83
147
|
.sendVerificationEmail(emailDto)
|
|
@@ -89,12 +153,14 @@ class AuthChallengeHelperService {
|
|
|
89
153
|
this.logger?.error?.(`Failed to send verification email to ${user.email}: ${errorMessage}`);
|
|
90
154
|
});
|
|
91
155
|
}
|
|
156
|
+
// Skip auto-send if SMS was already sent (e.g., during phone collection)
|
|
92
157
|
if (!skipAutoSend && challengeName === auth_challenge_dto_1.AuthChallenge.VERIFY_PHONE && this.phoneVerificationService && user.phone) {
|
|
93
158
|
this.logger?.log?.(`Sending verification SMS to: ${user.phone}`);
|
|
159
|
+
// Fire and forget - don't block challenge response
|
|
94
160
|
const smsDto = Object.assign(new verify_phone_dto_1.SendVerificationSMSDTO(), {
|
|
95
161
|
sub: user.sub,
|
|
96
|
-
skipAlreadyVerifiedCheck: false,
|
|
97
|
-
challengeSessionId: challengeSession.id,
|
|
162
|
+
skipAlreadyVerifiedCheck: false, // Explicitly set to false for phone verification (not MFA)
|
|
163
|
+
challengeSessionId: challengeSession.id, // Link verification token to this challenge session
|
|
98
164
|
});
|
|
99
165
|
this.phoneVerificationService
|
|
100
166
|
.sendVerificationSMS(smsDto)
|
|
@@ -106,6 +172,17 @@ class AuthChallengeHelperService {
|
|
|
106
172
|
this.logger?.error?.(`Failed to send verification SMS to ${user.phone}: ${errorMessage}`);
|
|
107
173
|
});
|
|
108
174
|
}
|
|
175
|
+
// ============================================================================
|
|
176
|
+
// STEP 3: Send MFA challenge code for MFA_REQUIRED (if SMS is preferred method)
|
|
177
|
+
// ============================================================================
|
|
178
|
+
// When user logs in and MFA verification is required, automatically send SMS code
|
|
179
|
+
// if SMS is their preferred MFA method. This provides better UX by not requiring
|
|
180
|
+
// a separate API call to trigger code sending.
|
|
181
|
+
//
|
|
182
|
+
// Note: MFA_REQUIRED challenges are handled by createMFAChallengeResponse()
|
|
183
|
+
// which includes auto-send SMS logic
|
|
184
|
+
// Build challenge parameters
|
|
185
|
+
// Note: Type is Record<string, unknown> to allow arrays (e.g., allowedMethods for MFA)
|
|
109
186
|
const challengeParameters = {};
|
|
110
187
|
switch (challengeName) {
|
|
111
188
|
case auth_challenge_dto_1.AuthChallenge.VERIFY_EMAIL:
|
|
@@ -117,6 +194,7 @@ class AuthChallengeHelperService {
|
|
|
117
194
|
challengeParameters.codeDeliveryDestination = user.phone
|
|
118
195
|
? this.challengeService.maskPhone(user.phone)
|
|
119
196
|
: undefined;
|
|
197
|
+
// If no phone, indicate user must provide it first
|
|
120
198
|
if (!user.phone) {
|
|
121
199
|
challengeParameters.requiresPhoneCollection = 'true';
|
|
122
200
|
challengeParameters.instructions = 'You must add a phone number and verify it to continue';
|
|
@@ -124,9 +202,11 @@ class AuthChallengeHelperService {
|
|
|
124
202
|
break;
|
|
125
203
|
case auth_challenge_dto_1.AuthChallenge.MFA_REQUIRED:
|
|
126
204
|
challengeParameters.instructions = 'Multi-factor authentication is required';
|
|
205
|
+
// Include masked phone if SMS is preferred method
|
|
127
206
|
if (user.preferredMfaMethod === 'sms' && user.phone) {
|
|
128
207
|
challengeParameters.codeDeliveryDestination = this.challengeService.maskPhone(user.phone);
|
|
129
208
|
}
|
|
209
|
+
// Include masked email if Email is preferred method
|
|
130
210
|
if (user.preferredMfaMethod === 'email' && user.email) {
|
|
131
211
|
challengeParameters.codeDeliveryDestination = this.challengeService.maskEmail(user.email);
|
|
132
212
|
}
|
|
@@ -149,17 +229,50 @@ class AuthChallengeHelperService {
|
|
|
149
229
|
};
|
|
150
230
|
return response;
|
|
151
231
|
}
|
|
232
|
+
// ============================================================================
|
|
233
|
+
// MFA Challenge Support
|
|
234
|
+
// ============================================================================
|
|
235
|
+
// checkMFARequirement() - DELETED (replaced by state machine)
|
|
236
|
+
// All MFA requirement checking is now handled by state machine in determineAuthResponse()
|
|
237
|
+
/**
|
|
238
|
+
* Create MFA setup challenge response
|
|
239
|
+
*
|
|
240
|
+
* Generates challenge session for MFA setup requirement.
|
|
241
|
+
* User must set up MFA before being allowed to login.
|
|
242
|
+
*
|
|
243
|
+
* @param user - User requiring MFA setup
|
|
244
|
+
* @param config - Auth configuration
|
|
245
|
+
* @param authMethod - Authentication method ('password' or 'social')
|
|
246
|
+
* @param authProvider - Provider name for social auth (e.g., 'google', 'facebook')
|
|
247
|
+
* @returns MFA setup challenge response
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* ```typescript
|
|
251
|
+
* const response = await challengeHelper.createMFASetupChallengeResponse(
|
|
252
|
+
* user,
|
|
253
|
+
* config,
|
|
254
|
+
* 'social',
|
|
255
|
+
* 'google'
|
|
256
|
+
* );
|
|
257
|
+
* // Returns: { challengeName: 'MFA_SETUP_REQUIRED', session: '...', challengeParameters: {...} }
|
|
258
|
+
* ```
|
|
259
|
+
*/
|
|
152
260
|
async createMFASetupChallengeResponse(user, config, authMethod = 'password', authProvider) {
|
|
261
|
+
// Client info (ipAddress, userAgent) automatically extracted from ClientInfoService
|
|
262
|
+
// Note: ClientInfoService is used transparently by ChallengeService and AuditService
|
|
153
263
|
this.logger?.log?.(`Creating MFA setup challenge for user: ${user.sub}`);
|
|
154
264
|
const allowedMethods = config.mfa?.allowedMethods || [...mfa_method_enum_1.MFADeviceMethods];
|
|
265
|
+
// Create challenge session with auth context
|
|
155
266
|
this.logger?.debug?.(`Creating MFA setup challenge with authMethod=${authMethod}, authProvider=${authProvider || 'none'} for user ${user.sub}`);
|
|
267
|
+
// Client info (ipAddress, userAgent) automatically extracted from ClientInfoService
|
|
156
268
|
const challengeSession = await this.challengeService.createChallengeSession(user, auth_challenge_dto_1.AuthChallenge.MFA_SETUP_REQUIRED, {
|
|
157
269
|
allowedMethods,
|
|
158
270
|
requiresSetup: true,
|
|
159
|
-
authMethod,
|
|
160
|
-
authProvider,
|
|
271
|
+
authMethod, // Store auth method for challenge completion flow
|
|
272
|
+
authProvider, // Store provider for social auth
|
|
161
273
|
});
|
|
162
274
|
this.logger?.log?.(`MFA setup challenge created for user: ${user.sub}`);
|
|
275
|
+
// Return challenge response
|
|
163
276
|
return {
|
|
164
277
|
challengeName: auth_challenge_dto_1.AuthChallenge.MFA_SETUP_REQUIRED,
|
|
165
278
|
session: challengeSession.sessionToken,
|
|
@@ -170,49 +283,87 @@ class AuthChallengeHelperService {
|
|
|
170
283
|
userSub: user.sub,
|
|
171
284
|
};
|
|
172
285
|
}
|
|
286
|
+
/**
|
|
287
|
+
* Create MFA challenge response
|
|
288
|
+
*
|
|
289
|
+
* Generates challenge session for MFA verification.
|
|
290
|
+
* Returns available MFA methods and challenge parameters.
|
|
291
|
+
*
|
|
292
|
+
* @param user - User requiring MFA
|
|
293
|
+
* @returns MFA challenge response
|
|
294
|
+
* @remarks Client info (ipAddress, userAgent) is automatically extracted from ClientInfoService context
|
|
295
|
+
*
|
|
296
|
+
* @example
|
|
297
|
+
* ```typescript
|
|
298
|
+
* const response = await challengeHelper.createMFAChallengeResponse(
|
|
299
|
+
* user,
|
|
300
|
+
* '1.2.3.4',
|
|
301
|
+
* 'Mozilla/5.0...'
|
|
302
|
+
* );
|
|
303
|
+
* // Returns: { challengeName: 'MFA_REQUIRED', session: '...', challengeParameters: {...} }
|
|
304
|
+
* ```
|
|
305
|
+
*/
|
|
173
306
|
async createMFAChallengeResponse(user) {
|
|
307
|
+
// Client info (ipAddress, userAgent) automatically extracted from ClientInfoService
|
|
308
|
+
// Note: ClientInfoService is used transparently by ChallengeService and AuditService
|
|
174
309
|
this.logger?.log?.(`Creating MFA challenge for user: ${user.sub}`);
|
|
310
|
+
// Get user's active MFA devices
|
|
175
311
|
const devices = (await this.mfaDeviceRepository.find({
|
|
176
312
|
where: { userId: user.id, isActive: true },
|
|
177
313
|
order: { isPrimary: 'DESC', lastUsedAt: 'DESC' },
|
|
178
314
|
}));
|
|
179
315
|
if (devices.length === 0) {
|
|
180
316
|
this.logger?.warn?.(`User has MFA enabled but no active devices: ${user.sub}`);
|
|
317
|
+
// User has MFA enabled but no devices - should not happen
|
|
318
|
+
// Allow login and let them set up MFA
|
|
181
319
|
throw new nauth_exception_1.NAuthException(error_codes_enum_1.AuthErrorCode.INTERNAL_ERROR, 'MFA enabled but no devices configured');
|
|
182
320
|
}
|
|
321
|
+
// Get available methods (device types only - no backup)
|
|
183
322
|
const deviceMethods = [...new Set(devices.map((d) => d.type))];
|
|
323
|
+
// Build full available methods list (including backup if available)
|
|
184
324
|
const availableMethods = [...deviceMethods];
|
|
185
325
|
if (user.backupCodes && user.backupCodes.length > 0) {
|
|
186
326
|
availableMethods.push(mfa_method_enum_1.MFAMethod.BACKUP);
|
|
187
327
|
}
|
|
328
|
+
// Debug logging for troubleshooting
|
|
188
329
|
this.logger?.debug?.(`MFA challenge for user ${user.sub}: preferredMfaMethod=${user.preferredMfaMethod}, deviceMethods=[${deviceMethods.join(', ')}], devices=[${devices.map((d) => `${d.type}${d.isPrimary ? '(primary)' : ''}`).join(', ')}]`);
|
|
330
|
+
// Determine preferred method - prioritize user.preferredMfaMethod over primaryDevice
|
|
331
|
+
// This ensures that when user explicitly sets a preferred method, it's respected
|
|
189
332
|
let preferredMethod;
|
|
333
|
+
// Normalize preferred method to lowercase for comparison (database might store in different case)
|
|
190
334
|
const normalizedPreferredMethod = user.preferredMfaMethod?.toLowerCase();
|
|
335
|
+
// Check if user has a preferred method and it's available
|
|
191
336
|
if (normalizedPreferredMethod &&
|
|
192
337
|
(normalizedPreferredMethod === mfa_method_enum_1.MFAMethod.TOTP ||
|
|
193
338
|
normalizedPreferredMethod === mfa_method_enum_1.MFAMethod.SMS ||
|
|
194
339
|
normalizedPreferredMethod === mfa_method_enum_1.MFAMethod.EMAIL ||
|
|
195
340
|
normalizedPreferredMethod === mfa_method_enum_1.MFAMethod.PASSKEY) &&
|
|
196
341
|
deviceMethods.some((m) => m.toLowerCase() === normalizedPreferredMethod)) {
|
|
342
|
+
// User has explicitly set a preferred method and it's available
|
|
343
|
+
// Find the actual method from deviceMethods to ensure case consistency
|
|
197
344
|
preferredMethod =
|
|
198
345
|
deviceMethods.find((m) => m.toLowerCase() === normalizedPreferredMethod) || normalizedPreferredMethod;
|
|
199
346
|
this.logger?.debug?.(`Using user preferred MFA method: ${preferredMethod} (from user.preferredMfaMethod: ${user.preferredMfaMethod})`);
|
|
200
347
|
}
|
|
201
348
|
else {
|
|
349
|
+
// Fallback to primary device or first available method
|
|
202
350
|
const primaryDevice = devices.find((d) => d.isPrimary);
|
|
203
351
|
preferredMethod = primaryDevice?.type || deviceMethods[0];
|
|
204
352
|
this.logger?.debug?.(`Using fallback MFA method: ${preferredMethod} (preferred: ${user.preferredMfaMethod}, available: ${deviceMethods.join(', ')})`);
|
|
205
353
|
}
|
|
354
|
+
// Get masked phone if SMS is available
|
|
206
355
|
let maskedPhone;
|
|
207
356
|
const smsDevice = devices.find((d) => d.type === mfa_method_enum_1.MFAMethod.SMS && d.phoneNumber);
|
|
208
357
|
if (smsDevice?.phoneNumber) {
|
|
209
358
|
const digits = smsDevice.phoneNumber.replace(/\D/g, '');
|
|
210
359
|
maskedPhone = digits.length >= 4 ? `***-***-${digits.slice(-4)}` : smsDevice.phoneNumber;
|
|
211
360
|
}
|
|
361
|
+
// Get masked email if Email is available
|
|
212
362
|
let maskedEmail;
|
|
213
363
|
const emailDevice = devices.find((d) => d.type === mfa_method_enum_1.MFAMethod.EMAIL && d.email);
|
|
214
|
-
const emailToMask = emailDevice?.email || user.email;
|
|
364
|
+
const emailToMask = emailDevice?.email || user.email; // Fallback to user.email if device doesn't have it
|
|
215
365
|
if (emailToMask) {
|
|
366
|
+
// Mask email: show first char and domain (e.g., u***r@example.com)
|
|
216
367
|
const [localPart, domain] = emailToMask.split('@');
|
|
217
368
|
if (localPart && domain) {
|
|
218
369
|
const firstChar = localPart[0];
|
|
@@ -223,22 +374,36 @@ class AuthChallengeHelperService {
|
|
|
223
374
|
maskedEmail = emailToMask;
|
|
224
375
|
}
|
|
225
376
|
}
|
|
377
|
+
// Create challenge session
|
|
378
|
+
// Client info (ipAddress, userAgent) automatically extracted from ClientInfoService
|
|
379
|
+
// Store preferred method in metadata for resend endpoint to know which method to use
|
|
226
380
|
const challengeSession = await this.challengeService.createChallengeSession(user, auth_challenge_dto_1.AuthChallenge.MFA_REQUIRED, {
|
|
227
381
|
availableMethods,
|
|
228
382
|
preferredMethod,
|
|
229
383
|
maskedPhone,
|
|
230
384
|
maskedEmail,
|
|
231
|
-
method: preferredMethod,
|
|
385
|
+
method: preferredMethod, // Store method in metadata for resend endpoint
|
|
232
386
|
});
|
|
233
387
|
this.logger?.log?.(`MFA challenge created for user: ${user.sub}`);
|
|
388
|
+
// ============================================================================
|
|
389
|
+
// Auto-send SMS code if SMS is the preferred method
|
|
390
|
+
// ============================================================================
|
|
391
|
+
// Automatically send SMS code if:
|
|
392
|
+
// 1. SMS is user's preferred MFA method, OR
|
|
393
|
+
// 2. SMS is the ONLY MFA method they have setup
|
|
394
|
+
//
|
|
395
|
+
// This provides better UX by not requiring a separate API call to trigger code sending.
|
|
234
396
|
const smsIsPreferred = preferredMethod.toLowerCase() === 'sms';
|
|
235
397
|
const smsIsOnly = deviceMethods.length === 1 && deviceMethods[0].toLowerCase() === 'sms';
|
|
236
398
|
if ((smsIsPreferred || smsIsOnly) && this.phoneVerificationService && user.phone) {
|
|
237
399
|
this.logger?.log?.(`Auto-sending MFA SMS code to user ${user.sub} (preferred=${smsIsPreferred}, only=${smsIsOnly})`);
|
|
400
|
+
// Fire and forget - don't block challenge response
|
|
401
|
+
// Use PhoneVerificationService which handles SMS sending, rate limits, and token storage
|
|
402
|
+
// skipAlreadyVerifiedCheck=true because phone is already verified but we need MFA code
|
|
238
403
|
const smsDto = Object.assign(new verify_phone_dto_1.SendVerificationSMSDTO(), {
|
|
239
404
|
sub: user.sub,
|
|
240
405
|
skipAlreadyVerifiedCheck: true,
|
|
241
|
-
challengeSessionId: challengeSession.id,
|
|
406
|
+
challengeSessionId: challengeSession.id, // Link MFA SMS code to this challenge session
|
|
242
407
|
});
|
|
243
408
|
this.phoneVerificationService
|
|
244
409
|
.sendVerificationSMS(smsDto)
|
|
@@ -259,15 +424,26 @@ class AuthChallengeHelperService {
|
|
|
259
424
|
`deviceMethods=[${deviceMethods.join(', ')}], ` +
|
|
260
425
|
`phone=${!!user.phone}`);
|
|
261
426
|
}
|
|
427
|
+
// ============================================================================
|
|
428
|
+
// Auto-send Email code if Email is the preferred method
|
|
429
|
+
// ============================================================================
|
|
430
|
+
// Automatically send Email code if:
|
|
431
|
+
// 1. Email is user's preferred MFA method, OR
|
|
432
|
+
// 2. Email is the ONLY MFA method they have setup
|
|
433
|
+
//
|
|
434
|
+
// This provides better UX by not requiring a separate API call to trigger code sending.
|
|
262
435
|
const emailIsPreferred = preferredMethod.toLowerCase() === 'email';
|
|
263
436
|
const emailIsOnly = deviceMethods.length === 1 && deviceMethods[0].toLowerCase() === 'email';
|
|
264
437
|
if ((emailIsPreferred || emailIsOnly) && this.emailVerificationService && user.email) {
|
|
265
438
|
this.logger?.log?.(`Auto-sending MFA Email code to user ${user.sub} (preferred=${emailIsPreferred}, only=${emailIsOnly})`);
|
|
439
|
+
// Fire and forget - don't block challenge response
|
|
440
|
+
// Use EmailVerificationService which handles email sending, rate limits, and token storage
|
|
441
|
+
// skipAlreadyVerifiedCheck=true because email is already verified but we need MFA code
|
|
266
442
|
const emailDto = Object.assign(new verify_email_dto_1.SendVerificationEmailDTO(), {
|
|
267
443
|
sub: user.sub,
|
|
268
444
|
baseUrl: undefined,
|
|
269
445
|
skipAlreadyVerifiedCheck: true,
|
|
270
|
-
challengeSessionId: challengeSession.id,
|
|
446
|
+
challengeSessionId: challengeSession.id, // Link MFA email code to this challenge session
|
|
271
447
|
});
|
|
272
448
|
this.emailVerificationService
|
|
273
449
|
.sendVerificationEmail(emailDto)
|
|
@@ -288,6 +464,8 @@ class AuthChallengeHelperService {
|
|
|
288
464
|
`deviceMethods=[${deviceMethods.join(', ')}], ` +
|
|
289
465
|
`email=${!!user.email}`);
|
|
290
466
|
}
|
|
467
|
+
// Return challenge response
|
|
468
|
+
// Always include maskedEmail if email is preferred, even if undefined (frontend can use user.email)
|
|
291
469
|
const challengeParams = {
|
|
292
470
|
availableMethods,
|
|
293
471
|
preferredMethod: preferredMethod,
|
|
@@ -296,6 +474,7 @@ class AuthChallengeHelperService {
|
|
|
296
474
|
challengeParams.maskedPhone = maskedPhone;
|
|
297
475
|
}
|
|
298
476
|
if (maskedEmail || preferredMethod.toLowerCase() === 'email') {
|
|
477
|
+
// Include maskedEmail if available, or if email is preferred (frontend will handle display)
|
|
299
478
|
challengeParams.maskedEmail = maskedEmail || user.email || '';
|
|
300
479
|
}
|
|
301
480
|
return {
|
|
@@ -304,37 +483,79 @@ class AuthChallengeHelperService {
|
|
|
304
483
|
challengeParameters: challengeParams,
|
|
305
484
|
};
|
|
306
485
|
}
|
|
307
|
-
|
|
486
|
+
// ============================================================================
|
|
487
|
+
// Success Response
|
|
488
|
+
// ============================================================================
|
|
489
|
+
/**
|
|
490
|
+
* Create successful authentication response with tokens
|
|
491
|
+
*
|
|
492
|
+
* Generates tokens and session for fully authenticated user.
|
|
493
|
+
*
|
|
494
|
+
* @param user - Authenticated user
|
|
495
|
+
* @param deviceToken - Device token (optional)
|
|
496
|
+
* @param isTrusted - Whether device is trusted (optional)
|
|
497
|
+
* @param isSocialLogin - Whether this is a social login (optional)
|
|
498
|
+
* @param metadata - Response metadata (optional)
|
|
499
|
+
* @returns Auth response with tokens
|
|
500
|
+
*
|
|
501
|
+
* @example
|
|
502
|
+
* ```typescript
|
|
503
|
+
* const response = await challengeHelper.createSuccessResponse(
|
|
504
|
+
* user,
|
|
505
|
+
* 'abc123',
|
|
506
|
+
* true,
|
|
507
|
+
* false
|
|
508
|
+
* );
|
|
509
|
+
* ```
|
|
510
|
+
*/
|
|
511
|
+
async createSuccessResponse(user, deviceToken, isTrusted, _isSocialLogin = false, // Reserved for future use
|
|
512
|
+
_metadata) {
|
|
513
|
+
// Get client info from ClientInfoService (for deviceToken only - IP/userAgent come from context automatically)
|
|
308
514
|
const clientInfo = this.clientInfoService.get();
|
|
309
515
|
const finalDeviceToken = clientInfo.deviceToken || deviceToken;
|
|
516
|
+
// ============================================================================
|
|
517
|
+
// SECURITY: Defense-in-depth validation before token issuance
|
|
518
|
+
// ============================================================================
|
|
519
|
+
// Note: Challenge validation is now handled by state machine in determineAuthResponse
|
|
520
|
+
// This method is only called when state is AUTHENTICATED, so no additional check needed
|
|
521
|
+
// Generate token family for rotation tracking
|
|
310
522
|
const tokenFamily = this.jwtService.generateTokenFamily();
|
|
523
|
+
// Generate temporary tokens first (session creation requires token hashes)
|
|
524
|
+
// Note: deviceId not included in token - session.deviceId is source of truth
|
|
311
525
|
const tempTokens = await this.jwtService.generateTokenPair({
|
|
312
|
-
userId: user.sub,
|
|
526
|
+
userId: user.sub, // Use sub in JWT payload (external identifier)
|
|
313
527
|
email: user.email,
|
|
314
|
-
sessionId: 'temp',
|
|
528
|
+
sessionId: 'temp', // Temporary - will be regenerated with real sessionId
|
|
315
529
|
tokenFamily,
|
|
316
530
|
});
|
|
531
|
+
// Generate deviceId if not provided
|
|
317
532
|
let finalDeviceId = finalDeviceToken;
|
|
318
533
|
if (!finalDeviceId) {
|
|
319
534
|
const crypto = await Promise.resolve().then(() => __importStar(require('crypto')));
|
|
320
535
|
finalDeviceId = crypto.randomUUID();
|
|
321
536
|
}
|
|
537
|
+
// Create session
|
|
538
|
+
// Client info (ipAddress, ipCountry, ipCity, userAgent) automatically extracted from ClientInfoService
|
|
322
539
|
const session = await this.sessionService.createSession({
|
|
323
|
-
userId: user.id,
|
|
540
|
+
userId: user.id, // Use internal id for foreign key
|
|
324
541
|
accessTokenHash: this.jwtService.hashToken(tempTokens.accessToken),
|
|
325
542
|
refreshTokenHash: this.jwtService.hashToken(tempTokens.refreshToken),
|
|
326
543
|
tokenFamily,
|
|
327
544
|
deviceId: finalDeviceId,
|
|
328
545
|
expiresAt: this.sessionService.getSessionExpirationDate(),
|
|
329
|
-
authMethod: 'password',
|
|
546
|
+
authMethod: 'password', // Default to password for challenge flows (signup, verification completion)
|
|
330
547
|
});
|
|
548
|
+
// Now regenerate tokens with the actual sessionId
|
|
549
|
+
// Note: deviceId not included in token - session.deviceId is source of truth
|
|
331
550
|
const tokens = await this.jwtService.generateTokenPair({
|
|
332
551
|
userId: user.sub,
|
|
333
552
|
email: user.email,
|
|
334
553
|
sessionId: session.id.toString(),
|
|
335
554
|
tokenFamily,
|
|
336
555
|
});
|
|
556
|
+
// Update session with new token hashes
|
|
337
557
|
await this.sessionService.updateTokens(session.id, this.jwtService.hashToken(tokens.accessToken), this.jwtService.hashToken(tokens.refreshToken));
|
|
558
|
+
// Decode tokens to get expiry times
|
|
338
559
|
const accessTokenValidation = await this.jwtService.validateAccessToken(tokens.accessToken);
|
|
339
560
|
const refreshTokenValidation = await this.jwtService.validateRefreshToken(tokens.refreshToken);
|
|
340
561
|
const response = {
|
|
@@ -343,6 +564,12 @@ class AuthChallengeHelperService {
|
|
|
343
564
|
accessTokenExpiresAt: accessTokenValidation.payload?.exp || 0,
|
|
344
565
|
refreshTokenExpiresAt: refreshTokenValidation.payload?.exp || 0,
|
|
345
566
|
trusted: isTrusted,
|
|
567
|
+
// Expose deviceToken so that:
|
|
568
|
+
// - In cookies mode, CookieTokenInterceptor can set the httpOnly nauth_device_token cookie
|
|
569
|
+
// - In JSON mode, mobile clients can store it securely and send via header
|
|
570
|
+
// NOTE: finalDeviceToken is a logical device identifier derived from:
|
|
571
|
+
// - clientInfo.deviceToken (existing trusted device), OR
|
|
572
|
+
// - deviceToken parameter passed from AuthService / state machine
|
|
346
573
|
deviceToken: finalDeviceToken,
|
|
347
574
|
user: {
|
|
348
575
|
sub: user.sub,
|
|
@@ -359,9 +586,35 @@ class AuthChallengeHelperService {
|
|
|
359
586
|
};
|
|
360
587
|
return response;
|
|
361
588
|
}
|
|
589
|
+
/**
|
|
590
|
+
* Determine and create appropriate auth response
|
|
591
|
+
*
|
|
592
|
+
* Main entry point that decides whether to return challenges or tokens.
|
|
593
|
+
* Uses state machine to evaluate authentication flow state.
|
|
594
|
+
*
|
|
595
|
+
* @param params - Authentication parameters
|
|
596
|
+
* @param params.user - User attempting authentication
|
|
597
|
+
* @param params.config - Auth configuration
|
|
598
|
+
* @param params.deviceToken - Device token (optional)
|
|
599
|
+
* @param params.isSocialLogin - Whether this is a social login (OAuth) authentication (optional)
|
|
600
|
+
* @param params.skipMFAVerification - Skip MFA verification flag (optional)
|
|
601
|
+
* @param params.authProvider - Social auth provider name (optional)
|
|
602
|
+
* @returns Auth response (either challenge or success)
|
|
603
|
+
*
|
|
604
|
+
* @example
|
|
605
|
+
* ```typescript
|
|
606
|
+
* const response = await challengeHelper.determineAuthResponse({
|
|
607
|
+
* user,
|
|
608
|
+
* config,
|
|
609
|
+
* deviceToken: 'abc123',
|
|
610
|
+
* isSocialLogin: false
|
|
611
|
+
* });
|
|
612
|
+
* ```
|
|
613
|
+
*/
|
|
362
614
|
async determineAuthResponse(params) {
|
|
363
615
|
const { user, config, deviceToken, isSocialLogin = false, skipMFAVerification = false, authProvider } = params;
|
|
364
616
|
this.logger?.debug?.(`[ChallengeHelper] determineAuthResponse called for user ${user.sub} (isSocialLogin=${isSocialLogin}, skipMFA=${skipMFAVerification}, deviceToken=${deviceToken ? 'present' : 'none'})`);
|
|
617
|
+
// Build context with pre-computed values
|
|
365
618
|
const context = await this.contextBuilder.build({
|
|
366
619
|
user,
|
|
367
620
|
config,
|
|
@@ -370,33 +623,57 @@ class AuthChallengeHelperService {
|
|
|
370
623
|
deviceToken,
|
|
371
624
|
skipMFAVerification,
|
|
372
625
|
});
|
|
626
|
+
// Evaluate state using state machine
|
|
373
627
|
const state = await this.stateMachine.evaluateState(context);
|
|
628
|
+
// Get state definition
|
|
374
629
|
const stateDefinition = this.stateMachine.getStateDefinition(state);
|
|
375
630
|
if (!stateDefinition) {
|
|
376
631
|
this.logger?.error?.(`No state definition found for state: ${state}`, { state, userId: user.id });
|
|
377
632
|
throw new nauth_exception_1.NAuthException(error_codes_enum_1.AuthErrorCode.INTERNAL_ERROR, 'Invalid authentication state');
|
|
378
633
|
}
|
|
634
|
+
// Build metadata if available
|
|
379
635
|
const metadata = this.stateMachine.buildMetadata(state, context);
|
|
636
|
+
// Convert state to response
|
|
380
637
|
const response = await this.stateToResponse(state, stateDefinition, context, metadata);
|
|
381
638
|
this.logger?.debug?.(`[ChallengeHelper] State ${state} → Challenge: ${response.challengeName || 'SUCCESS'} for user ${user.sub}`);
|
|
382
639
|
return response;
|
|
383
640
|
}
|
|
641
|
+
/**
|
|
642
|
+
* Convert state to authentication response
|
|
643
|
+
*
|
|
644
|
+
* Maps state to appropriate response (challenge or success).
|
|
645
|
+
* Merges state metadata into response.
|
|
646
|
+
*
|
|
647
|
+
* @param state - Authentication flow state
|
|
648
|
+
* @param stateDefinition - State definition
|
|
649
|
+
* @param context - Authentication flow context
|
|
650
|
+
* @param metadata - Response metadata (optional)
|
|
651
|
+
* @returns Authentication response
|
|
652
|
+
*/
|
|
384
653
|
async stateToResponse(state, stateDefinition, context, metadata) {
|
|
654
|
+
// Get client info from ClientInfoService
|
|
385
655
|
const clientInfo = this.clientInfoService.get();
|
|
386
656
|
const deviceToken = clientInfo.deviceToken || context.deviceToken;
|
|
387
657
|
const authMethod = context.authMethod || 'password';
|
|
658
|
+
// Handle challenge states
|
|
388
659
|
if (stateDefinition.challenge) {
|
|
660
|
+
// Handle MFA_SETUP_REQUIRED challenge specially
|
|
389
661
|
if (stateDefinition.challenge === auth_challenge_dto_1.AuthChallenge.MFA_SETUP_REQUIRED) {
|
|
390
662
|
return this.createMFASetupChallengeResponse(context.user, context.config, authMethod, context.authProvider);
|
|
391
663
|
}
|
|
664
|
+
// Handle MFA_REQUIRED challenge specially - needs preferred method logic
|
|
392
665
|
if (stateDefinition.challenge === auth_challenge_dto_1.AuthChallenge.MFA_REQUIRED) {
|
|
393
666
|
return this.createMFAChallengeResponse(context.user);
|
|
394
667
|
}
|
|
668
|
+
// Handle other challenges
|
|
395
669
|
return this.createChallengeResponse(context.user, stateDefinition.challenge, context.config, authMethod, context.authProvider);
|
|
396
670
|
}
|
|
671
|
+
// Handle special states
|
|
397
672
|
if (state === auth_flow_state_machine_types_1.AuthFlowState.GRACE_PERIOD_ACTIVE) {
|
|
673
|
+
// Grace period active - return success with metadata
|
|
398
674
|
const isTrusted = context.computed.isDeviceTrusted;
|
|
399
675
|
const response = await this.createSuccessResponse(context.user, deviceToken, isTrusted, context.authMethod === 'social', metadata);
|
|
676
|
+
// Merge metadata
|
|
400
677
|
if (metadata?.gracePeriodEndsAt) {
|
|
401
678
|
response.gracePeriodEndsAt = metadata.gracePeriodEndsAt;
|
|
402
679
|
}
|
|
@@ -409,6 +686,7 @@ class AuthChallengeHelperService {
|
|
|
409
686
|
return response;
|
|
410
687
|
}
|
|
411
688
|
if (state === auth_flow_state_machine_types_1.AuthFlowState.BLOCKED) {
|
|
689
|
+
// User is blocked - throw exception with metadata
|
|
412
690
|
const errorCode = context.config.mfa?.adaptive?.blockedSignIn?.errorCode ||
|
|
413
691
|
error_codes_enum_1.AuthErrorCode.SIGNIN_BLOCKED_HIGH_RISK;
|
|
414
692
|
const message = metadata?.reason ||
|
|
@@ -418,6 +696,7 @@ class AuthChallengeHelperService {
|
|
|
418
696
|
expiresAt: metadata?.blockedUntil,
|
|
419
697
|
});
|
|
420
698
|
}
|
|
699
|
+
// AUTHENTICATED state - return success
|
|
421
700
|
const isTrusted = context.computed.isDeviceTrusted;
|
|
422
701
|
return this.createSuccessResponse(context.user, deviceToken, isTrusted, context.authMethod === 'social', metadata);
|
|
423
702
|
}
|