@baseplate-dev/plugin-auth 4.0.0 → 4.0.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/CHANGELOG.md +621 -0
- package/dist/auth/core/common.d.ts +2 -5
- package/dist/auth/core/common.d.ts.map +1 -1
- package/dist/auth/core/common.js +14 -14
- package/dist/auth/core/common.js.map +1 -1
- package/dist/auth/core/node.d.ts +3 -3
- package/dist/auth/core/node.d.ts.map +1 -1
- package/dist/auth/core/node.js +5 -8
- package/dist/auth/core/node.js.map +1 -1
- package/dist/auth/core/web.d.ts +3 -3
- package/dist/auth/core/web.d.ts.map +1 -1
- package/dist/auth/core/web.js +4 -5
- package/dist/auth/core/web.js.map +1 -1
- package/dist/auth0/core/common.d.ts +3 -5
- package/dist/auth0/core/common.d.ts.map +1 -1
- package/dist/auth0/core/common.js +11 -14
- package/dist/auth0/core/common.js.map +1 -1
- package/dist/auth0/core/node.d.ts +3 -3
- package/dist/auth0/core/node.d.ts.map +1 -1
- package/dist/auth0/core/node.js +5 -8
- package/dist/auth0/core/node.js.map +1 -1
- package/dist/auth0/core/schema/plugin-definition.js +1 -1
- package/dist/auth0/core/schema/plugin-definition.js.map +1 -1
- package/dist/auth0/core/web.d.ts +3 -3
- package/dist/auth0/core/web.d.ts.map +1 -1
- package/dist/auth0/core/web.js +4 -5
- package/dist/auth0/core/web.js.map +1 -1
- package/dist/auth0/generators/fastify/auth0-module/templates/module/schema/user-session.queries.ts +1 -1
- package/dist/auth0/generators/react/auth0-hooks/auth0-hooks.generator.js +1 -1
- package/dist/auth0/generators/react/auth0-hooks/auth0-hooks.generator.js.map +1 -1
- package/dist/local-auth/admin/common.d.ts +3 -2
- package/dist/local-auth/admin/common.d.ts.map +1 -1
- package/dist/local-auth/admin/common.js +6 -7
- package/dist/local-auth/admin/common.js.map +1 -1
- package/dist/local-auth/admin/node.d.ts +3 -6
- package/dist/local-auth/admin/node.d.ts.map +1 -1
- package/dist/local-auth/admin/node.js +13 -12
- package/dist/local-auth/admin/node.js.map +1 -1
- package/dist/local-auth/admin/web.d.ts +3 -4
- package/dist/local-auth/admin/web.d.ts.map +1 -1
- package/dist/local-auth/admin/web.js +22 -21
- package/dist/local-auth/admin/web.js.map +1 -1
- package/dist/local-auth/constants/model-names.d.ts +4 -0
- package/dist/local-auth/constants/model-names.d.ts.map +1 -1
- package/dist/local-auth/constants/model-names.js +4 -0
- package/dist/local-auth/constants/model-names.js.map +1 -1
- package/dist/local-auth/core/common.d.ts +3 -5
- package/dist/local-auth/core/common.d.ts.map +1 -1
- package/dist/local-auth/core/common.js +10 -13
- package/dist/local-auth/core/common.js.map +1 -1
- package/dist/local-auth/core/generators/auth-email-password/auth-email-password.generator.d.ts +49 -0
- package/dist/local-auth/core/generators/auth-email-password/auth-email-password.generator.d.ts.map +1 -1
- package/dist/local-auth/core/generators/auth-email-password/auth-email-password.generator.js +17 -6
- package/dist/local-auth/core/generators/auth-email-password/auth-email-password.generator.js.map +1 -1
- package/dist/local-auth/core/generators/auth-email-password/generated/index.d.ts +209 -0
- package/dist/local-auth/core/generators/auth-email-password/generated/index.d.ts.map +1 -1
- package/dist/local-auth/core/generators/auth-email-password/generated/template-paths.d.ts +5 -0
- package/dist/local-auth/core/generators/auth-email-password/generated/template-paths.d.ts.map +1 -1
- package/dist/local-auth/core/generators/auth-email-password/generated/template-paths.js +5 -0
- package/dist/local-auth/core/generators/auth-email-password/generated/template-paths.js.map +1 -1
- package/dist/local-auth/core/generators/auth-email-password/generated/template-renderers.d.ts +47 -1
- package/dist/local-auth/core/generators/auth-email-password/generated/template-renderers.d.ts.map +1 -1
- package/dist/local-auth/core/generators/auth-email-password/generated/template-renderers.js +48 -2
- package/dist/local-auth/core/generators/auth-email-password/generated/template-renderers.js.map +1 -1
- package/dist/local-auth/core/generators/auth-email-password/generated/ts-import-providers.d.ts +18 -0
- package/dist/local-auth/core/generators/auth-email-password/generated/ts-import-providers.d.ts.map +1 -1
- package/dist/local-auth/core/generators/auth-email-password/generated/ts-import-providers.js +12 -0
- package/dist/local-auth/core/generators/auth-email-password/generated/ts-import-providers.js.map +1 -1
- package/dist/local-auth/core/generators/auth-email-password/generated/typed-templates.d.ts +253 -0
- package/dist/local-auth/core/generators/auth-email-password/generated/typed-templates.d.ts.map +1 -1
- package/dist/local-auth/core/generators/auth-email-password/generated/typed-templates.js +102 -4
- package/dist/local-auth/core/generators/auth-email-password/generated/typed-templates.js.map +1 -1
- package/dist/local-auth/core/generators/auth-email-password/templates/module/constants/password.constants.d.ts +15 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/constants/password.constants.d.ts.map +1 -1
- package/dist/local-auth/core/generators/auth-email-password/templates/module/constants/password.constants.js +15 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/constants/password.constants.js.map +1 -1
- package/dist/local-auth/core/generators/auth-email-password/templates/module/constants/password.constants.ts +18 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/schema/email-verification.mutations.d.ts +2 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/schema/email-verification.mutations.d.ts.map +1 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/schema/email-verification.mutations.js +24 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/schema/email-verification.mutations.js.map +1 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/schema/email-verification.mutations.ts +35 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/schema/password-reset.mutations.d.ts +2 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/schema/password-reset.mutations.d.ts.map +1 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/schema/password-reset.mutations.js +38 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/schema/password-reset.mutations.js.map +1 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/schema/password-reset.mutations.ts +54 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/services/auth-verification.service.d.ts +40 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/services/auth-verification.service.d.ts.map +1 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/services/auth-verification.service.js +106 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/services/auth-verification.service.js.map +1 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/services/auth-verification.service.ts +146 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/services/email-verification.service.d.ts +24 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/services/email-verification.service.d.ts.map +1 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/services/email-verification.service.js +88 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/services/email-verification.service.js.map +1 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/services/email-verification.service.ts +141 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/services/password-reset.service.d.ts +35 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/services/password-reset.service.d.ts.map +1 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/services/password-reset.service.js +157 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/services/password-reset.service.js.map +1 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/services/password-reset.service.ts +233 -0
- package/dist/local-auth/core/generators/auth-email-password/templates/module/services/user-password.service.d.ts.map +1 -1
- package/dist/local-auth/core/generators/auth-email-password/templates/module/services/user-password.service.js +48 -14
- package/dist/local-auth/core/generators/auth-email-password/templates/module/services/user-password.service.js.map +1 -1
- package/dist/local-auth/core/generators/auth-email-password/templates/module/services/user-password.service.ts +79 -15
- package/dist/local-auth/core/generators/auth-email-templates/auth-email-templates.generator.d.ts +43 -0
- package/dist/local-auth/core/generators/auth-email-templates/auth-email-templates.generator.d.ts.map +1 -0
- package/dist/local-auth/core/generators/auth-email-templates/auth-email-templates.generator.js +48 -0
- package/dist/local-auth/core/generators/auth-email-templates/auth-email-templates.generator.js.map +1 -0
- package/dist/local-auth/core/generators/auth-email-templates/generated/index.d.ts +96 -0
- package/dist/local-auth/core/generators/auth-email-templates/generated/index.d.ts.map +1 -0
- package/dist/local-auth/core/generators/auth-email-templates/generated/index.js +11 -0
- package/dist/local-auth/core/generators/auth-email-templates/generated/index.js.map +1 -0
- package/dist/local-auth/core/generators/auth-email-templates/generated/template-paths.d.ts +14 -0
- package/dist/local-auth/core/generators/auth-email-templates/generated/template-paths.d.ts.map +1 -0
- package/dist/local-auth/core/generators/auth-email-templates/generated/template-paths.js +26 -0
- package/dist/local-auth/core/generators/auth-email-templates/generated/template-paths.js.map +1 -0
- package/dist/local-auth/core/generators/auth-email-templates/generated/template-renderers.d.ts +41 -0
- package/dist/local-auth/core/generators/auth-email-templates/generated/template-renderers.d.ts.map +1 -0
- package/dist/local-auth/core/generators/auth-email-templates/generated/template-renderers.js +59 -0
- package/dist/local-auth/core/generators/auth-email-templates/generated/template-renderers.js.map +1 -0
- package/dist/local-auth/core/generators/auth-email-templates/generated/typed-templates.d.ts +60 -0
- package/dist/local-auth/core/generators/auth-email-templates/generated/typed-templates.d.ts.map +1 -0
- package/dist/local-auth/core/generators/auth-email-templates/generated/typed-templates.js +42 -0
- package/dist/local-auth/core/generators/auth-email-templates/generated/typed-templates.js.map +1 -0
- package/dist/local-auth/core/generators/auth-email-templates/index.d.ts +2 -0
- package/dist/local-auth/core/generators/auth-email-templates/index.d.ts.map +1 -0
- package/dist/local-auth/core/generators/auth-email-templates/index.js +2 -0
- package/dist/local-auth/core/generators/auth-email-templates/index.js.map +1 -0
- package/dist/local-auth/core/generators/auth-email-templates/templates/src/emails/auth/account-verification.email.d.ts +3 -0
- package/dist/local-auth/core/generators/auth-email-templates/templates/src/emails/auth/account-verification.email.d.ts.map +1 -0
- package/dist/local-auth/core/generators/auth-email-templates/templates/src/emails/auth/account-verification.email.js +14 -0
- package/dist/local-auth/core/generators/auth-email-templates/templates/src/emails/auth/account-verification.email.js.map +1 -0
- package/dist/local-auth/core/generators/auth-email-templates/templates/src/emails/auth/account-verification.email.tsx +55 -0
- package/dist/local-auth/core/generators/auth-email-templates/templates/src/emails/auth/password-changed.email.d.ts +3 -0
- package/dist/local-auth/core/generators/auth-email-templates/templates/src/emails/auth/password-changed.email.d.ts.map +1 -0
- package/dist/local-auth/core/generators/auth-email-templates/templates/src/emails/auth/password-changed.email.js +12 -0
- package/dist/local-auth/core/generators/auth-email-templates/templates/src/emails/auth/password-changed.email.js.map +1 -0
- package/dist/local-auth/core/generators/auth-email-templates/templates/src/emails/auth/password-changed.email.tsx +44 -0
- package/dist/local-auth/core/generators/auth-email-templates/templates/src/emails/auth/password-reset.email.d.ts +3 -0
- package/dist/local-auth/core/generators/auth-email-templates/templates/src/emails/auth/password-reset.email.d.ts.map +1 -0
- package/dist/local-auth/core/generators/auth-email-templates/templates/src/emails/auth/password-reset.email.js +14 -0
- package/dist/local-auth/core/generators/auth-email-templates/templates/src/emails/auth/password-reset.email.js.map +1 -0
- package/dist/local-auth/core/generators/auth-email-templates/templates/src/emails/auth/password-reset.email.tsx +55 -0
- package/dist/local-auth/core/generators/auth-module/auth-module.generator.d.ts +1 -0
- package/dist/local-auth/core/generators/auth-module/auth-module.generator.d.ts.map +1 -1
- package/dist/local-auth/core/generators/auth-module/auth-module.generator.js +1 -1
- package/dist/local-auth/core/generators/auth-module/auth-module.generator.js.map +1 -1
- package/dist/local-auth/core/generators/auth-module/generated/index.d.ts +2 -0
- package/dist/local-auth/core/generators/auth-module/generated/index.d.ts.map +1 -1
- package/dist/local-auth/core/generators/auth-module/generated/template-renderers.d.ts +1 -0
- package/dist/local-auth/core/generators/auth-module/generated/template-renderers.d.ts.map +1 -1
- package/dist/local-auth/core/generators/auth-module/generated/typed-templates.d.ts +1 -0
- package/dist/local-auth/core/generators/auth-module/generated/typed-templates.d.ts.map +1 -1
- package/dist/local-auth/core/generators/auth-module/templates/module/schema/user-session.mutations.js +1 -1
- package/dist/local-auth/core/generators/auth-module/templates/module/schema/user-session.mutations.js.map +1 -1
- package/dist/local-auth/core/generators/auth-module/templates/module/schema/user-session.mutations.ts +1 -1
- package/dist/local-auth/core/generators/auth-module/templates/module/schema/user-session.queries.js +2 -2
- package/dist/local-auth/core/generators/auth-module/templates/module/schema/user-session.queries.js.map +1 -1
- package/dist/local-auth/core/generators/auth-module/templates/module/schema/user-session.queries.ts +2 -2
- package/dist/local-auth/core/generators/auth-routes/auth-routes.generator.d.ts.map +1 -1
- package/dist/local-auth/core/generators/auth-routes/auth-routes.generator.js +1 -0
- package/dist/local-auth/core/generators/auth-routes/auth-routes.generator.js.map +1 -1
- package/dist/local-auth/core/generators/auth-routes/generated/index.d.ts +722 -4
- package/dist/local-auth/core/generators/auth-routes/generated/index.d.ts.map +1 -1
- package/dist/local-auth/core/generators/auth-routes/generated/index.js +2 -0
- package/dist/local-auth/core/generators/auth-routes/generated/index.js.map +1 -1
- package/dist/local-auth/core/generators/auth-routes/generated/template-paths.d.ts +4 -0
- package/dist/local-auth/core/generators/auth-routes/generated/template-paths.d.ts.map +1 -1
- package/dist/local-auth/core/generators/auth-routes/generated/template-paths.js +4 -0
- package/dist/local-auth/core/generators/auth-routes/generated/template-paths.js.map +1 -1
- package/dist/local-auth/core/generators/auth-routes/generated/template-renderers.d.ts +4 -1
- package/dist/local-auth/core/generators/auth-routes/generated/template-renderers.d.ts.map +1 -1
- package/dist/local-auth/core/generators/auth-routes/generated/template-renderers.js +14 -0
- package/dist/local-auth/core/generators/auth-routes/generated/template-renderers.js.map +1 -1
- package/dist/local-auth/core/generators/auth-routes/generated/ts-import-providers.d.ts +21 -0
- package/dist/local-auth/core/generators/auth-routes/generated/ts-import-providers.d.ts.map +1 -0
- package/dist/local-auth/core/generators/auth-routes/generated/ts-import-providers.js +30 -0
- package/dist/local-auth/core/generators/auth-routes/generated/ts-import-providers.js.map +1 -0
- package/dist/local-auth/core/generators/auth-routes/generated/typed-templates.d.ts +1216 -34
- package/dist/local-auth/core/generators/auth-routes/generated/typed-templates.d.ts.map +1 -1
- package/dist/local-auth/core/generators/auth-routes/generated/typed-templates.js +70 -2
- package/dist/local-auth/core/generators/auth-routes/generated/typed-templates.js.map +1 -1
- package/dist/local-auth/core/generators/auth-routes/index.d.ts +2 -0
- package/dist/local-auth/core/generators/auth-routes/index.d.ts.map +1 -1
- package/dist/local-auth/core/generators/auth-routes/index.js +1 -0
- package/dist/local-auth/core/generators/auth-routes/index.js.map +1 -1
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/-constants.d.ts +10 -0
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/-constants.d.ts.map +1 -0
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/-constants.js +11 -0
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/-constants.js.map +1 -0
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/-constants.ts +12 -0
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/forgot-password.d.ts +2 -0
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/forgot-password.d.ts.map +1 -0
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/forgot-password.js +60 -0
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/forgot-password.js.map +1 -0
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/forgot-password.tsx +127 -0
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/login.d.ts +1 -1
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/login.d.ts.map +1 -1
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/login.js +6 -11
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/login.js.map +1 -1
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/login.tsx +20 -19
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/register.d.ts +1 -1
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/register.d.ts.map +1 -1
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/register.js +2 -2
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/register.js.map +1 -1
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/register.tsx +2 -3
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/reset-password.d.ts +7 -0
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/reset-password.d.ts.map +1 -0
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/reset-password.js +131 -0
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/reset-password.js.map +1 -0
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/reset-password.tsx +240 -0
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/verify-email.d.ts +7 -0
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/verify-email.d.ts.map +1 -0
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/verify-email.js +106 -0
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/verify-email.js.map +1 -0
- package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/verify-email.tsx +206 -0
- package/dist/local-auth/core/generators/index.d.ts +1 -0
- package/dist/local-auth/core/generators/index.d.ts.map +1 -1
- package/dist/local-auth/core/generators/index.js +1 -0
- package/dist/local-auth/core/generators/index.js.map +1 -1
- package/dist/local-auth/core/generators/seed-initial-user/generated/index.d.ts +12 -0
- package/dist/local-auth/core/generators/seed-initial-user/generated/index.d.ts.map +1 -1
- package/dist/local-auth/core/generators/seed-initial-user/generated/template-renderers.d.ts +6 -0
- package/dist/local-auth/core/generators/seed-initial-user/generated/template-renderers.d.ts.map +1 -1
- package/dist/local-auth/core/generators/seed-initial-user/generated/typed-templates.d.ts +6 -0
- package/dist/local-auth/core/generators/seed-initial-user/generated/typed-templates.d.ts.map +1 -1
- package/dist/local-auth/core/generators/seed-initial-user/seed-initial-user.generator.d.ts +6 -0
- package/dist/local-auth/core/generators/seed-initial-user/seed-initial-user.generator.d.ts.map +1 -1
- package/dist/local-auth/core/generators/seed-initial-user/seed-initial-user.generator.js +1 -1
- package/dist/local-auth/core/generators/seed-initial-user/seed-initial-user.generator.js.map +1 -1
- package/dist/local-auth/core/node.d.ts +3 -3
- package/dist/local-auth/core/node.d.ts.map +1 -1
- package/dist/local-auth/core/node.js +16 -9
- package/dist/local-auth/core/node.js.map +1 -1
- package/dist/local-auth/core/schema/models.d.ts.map +1 -1
- package/dist/local-auth/core/schema/models.js +60 -0
- package/dist/local-auth/core/schema/models.js.map +1 -1
- package/dist/local-auth/core/web.d.ts +3 -3
- package/dist/local-auth/core/web.d.ts.map +1 -1
- package/dist/local-auth/core/web.js +4 -5
- package/dist/local-auth/core/web.js.map +1 -1
- package/dist/placeholder-auth/core/common.d.ts +2 -5
- package/dist/placeholder-auth/core/common.d.ts.map +1 -1
- package/dist/placeholder-auth/core/common.js +10 -13
- package/dist/placeholder-auth/core/common.js.map +1 -1
- package/dist/placeholder-auth/core/node.d.ts +3 -3
- package/dist/placeholder-auth/core/node.d.ts.map +1 -1
- package/dist/placeholder-auth/core/node.js +5 -8
- package/dist/placeholder-auth/core/node.js.map +1 -1
- package/dist/placeholder-auth/core/schema/plugin-definition.js +1 -1
- package/dist/placeholder-auth/core/schema/plugin-definition.js.map +1 -1
- package/dist/placeholder-auth/core/web.d.ts +3 -3
- package/dist/placeholder-auth/core/web.d.ts.map +1 -1
- package/dist/placeholder-auth/core/web.js +4 -5
- package/dist/placeholder-auth/core/web.js.map +1 -1
- package/dist/web/assets/__federation_expose_auth0CoreCommon-DKJVe6Rd.js +40 -0
- package/dist/web/assets/__federation_expose_auth0CoreCommon-DKJVe6Rd.js.map +1 -0
- package/dist/web/assets/{__federation_expose_auth0CoreWeb-CZueDXPK.js → __federation_expose_auth0CoreWeb-CfhSWZsK.js} +9 -10
- package/dist/web/assets/{__federation_expose_auth0CoreWeb-CZueDXPK.js.map → __federation_expose_auth0CoreWeb-CfhSWZsK.js.map} +1 -1
- package/dist/web/assets/__federation_expose_authCoreCommon-D3-Gk9mI.js +29 -0
- package/dist/web/assets/__federation_expose_authCoreCommon-D3-Gk9mI.js.map +1 -0
- package/dist/web/assets/{__federation_expose_authCoreWeb-C8rgnA2v.js → __federation_expose_authCoreWeb-DZoAij9e.js} +10 -11
- package/dist/web/assets/{__federation_expose_authCoreWeb-C8rgnA2v.js.map → __federation_expose_authCoreWeb-DZoAij9e.js.map} +1 -1
- package/dist/web/assets/{__federation_expose_local-authAdminCommon-C75-DAzO.js → __federation_expose_local-authAdminCommon-BRHnF0Hn.js} +8 -9
- package/dist/web/assets/__federation_expose_local-authAdminCommon-BRHnF0Hn.js.map +1 -0
- package/dist/web/assets/__federation_expose_local-authAdminWeb-dYAIxuqC.js +41 -0
- package/dist/web/assets/__federation_expose_local-authAdminWeb-dYAIxuqC.js.map +1 -0
- package/dist/web/assets/__federation_expose_local-authCoreCommon-CIwvOx0d.js +21 -0
- package/dist/web/assets/__federation_expose_local-authCoreCommon-CIwvOx0d.js.map +1 -0
- package/dist/web/assets/{__federation_expose_local-authCoreWeb-ChyvdsRq.js → __federation_expose_local-authCoreWeb-Bwooi2qZ.js} +70 -11
- package/dist/web/assets/__federation_expose_local-authCoreWeb-Bwooi2qZ.js.map +1 -0
- package/dist/web/assets/__federation_expose_placeholder-authCoreCommon-gFDSzGjB.js +23 -0
- package/dist/web/assets/__federation_expose_placeholder-authCoreCommon-gFDSzGjB.js.map +1 -0
- package/dist/web/assets/{__federation_expose_placeholder-authCoreWeb-CT8JKYLB.js → __federation_expose_placeholder-authCoreWeb-BZLwIkLk.js} +9 -13
- package/dist/web/assets/{__federation_expose_placeholder-authCoreWeb-CT8JKYLB.js.map → __federation_expose_placeholder-authCoreWeb-BZLwIkLk.js.map} +1 -1
- package/dist/web/assets/{__federation_fn_import-C_QCk5FX.js → __federation_fn_import-pxYUpmb_.js} +2 -2
- package/dist/web/assets/{__federation_fn_import-C_QCk5FX.js.map → __federation_fn_import-pxYUpmb_.js.map} +1 -1
- package/dist/web/assets/__federation_shared_@baseplate-dev/project-builder-lib/{web-DtztAtUw.js → web-BXi2UCP-.js} +39 -120
- package/dist/web/assets/__federation_shared_@baseplate-dev/project-builder-lib/web-BXi2UCP-.js.map +1 -0
- package/dist/web/assets/__federation_shared_@baseplate-dev/project-builder-lib-O0clDXMb.js +17445 -0
- package/dist/web/assets/__federation_shared_@baseplate-dev/project-builder-lib-O0clDXMb.js.map +1 -0
- package/dist/web/assets/__federation_shared_@baseplate-dev/ui-components-BpuFQk6s.js +52536 -0
- package/dist/web/assets/__federation_shared_@baseplate-dev/ui-components-BpuFQk6s.js.map +1 -0
- package/dist/web/assets/__federation_shared_@baseplate-dev/{utils-Bxy-1ETU.js → utils-UiZ-8JBg.js} +30 -10
- package/dist/web/assets/__federation_shared_@baseplate-dev/utils-UiZ-8JBg.js.map +1 -0
- package/dist/web/assets/__federation_shared_@tanstack/{react-router-DooFj-IS.js → react-router-BPEAtEJI.js} +1069 -746
- package/dist/web/assets/__federation_shared_@tanstack/react-router-BPEAtEJI.js.map +1 -0
- package/dist/web/assets/{get-auth-plugin-definition-D2XMaoy7.js → get-auth-plugin-definition-DPsrvQbo.js} +2 -2
- package/dist/web/assets/{get-auth-plugin-definition-D2XMaoy7.js.map → get-auth-plugin-definition-DPsrvQbo.js.map} +1 -1
- package/dist/web/assets/{index-DwJT6_Wn.js → index-CSfs0UAV.js} +2 -2
- package/dist/web/assets/{index-DwJT6_Wn.js.map → index-CSfs0UAV.js.map} +1 -1
- package/dist/web/assets/{index.esm-ChwWPPiL.js → index.esm-BoRQu8mM.js} +2 -2
- package/dist/web/assets/{index.esm-ChwWPPiL.js.map → index.esm-BoRQu8mM.js.map} +1 -1
- package/dist/web/assets/{isEqual-DAXqKRba.js → isEqual-BQtm2LNT.js} +5 -5
- package/dist/web/assets/{isEqual-DAXqKRba.js.map → isEqual-BQtm2LNT.js.map} +1 -1
- package/dist/web/assets/{model-merger-gGkFnyaY.js → model-merger-CdjliK9v.js} +266 -101
- package/dist/web/assets/model-merger-CdjliK9v.js.map +1 -0
- package/dist/web/assets/{model-names-CEoSIalq.js → model-names-DrcaRxt1.js} +6 -2
- package/dist/web/assets/{model-names-CEoSIalq.js.map → model-names-DrcaRxt1.js.map} +1 -1
- package/dist/web/assets/{plugin-definition-rpMj4pr8.js → plugin-definition-BG6tu7Hh.js} +3 -3
- package/dist/web/assets/plugin-definition-BG6tu7Hh.js.map +1 -0
- package/dist/web/assets/{plugin-definition-QRBMcFiG.js → plugin-definition-BMYDEj3f.js} +3 -3
- package/dist/web/assets/plugin-definition-BMYDEj3f.js.map +1 -0
- package/dist/web/assets/{plugin-definition-hAzbWO7b.js → plugin-definition-DRhTuQas.js} +2 -2
- package/dist/web/assets/{plugin-definition-hAzbWO7b.js.map → plugin-definition-DRhTuQas.js.map} +1 -1
- package/dist/web/assets/{plugin-definition-_slrOM0G.js → plugin-definition-j1nJ0FFI.js} +2 -2
- package/dist/web/assets/{plugin-definition-_slrOM0G.js.map → plugin-definition-j1nJ0FFI.js.map} +1 -1
- package/dist/web/assets/{react-DbX1FP85.js → react-CBhSWxr_.js} +2 -2
- package/dist/web/assets/{react-DbX1FP85.js.map → react-CBhSWxr_.js.map} +1 -1
- package/dist/web/assets/remoteEntry.js +20 -20
- package/dist/web/assets/{style-DZ-aOCkd.css → style-DiK_rD1L.css} +1 -1
- package/dist/web/assets/{styles-DqLt1Blm.js → styles-BbHyE-2h.js} +3 -3
- package/dist/web/assets/{styles-DqLt1Blm.js.map → styles-BbHyE-2h.js.map} +1 -1
- package/dist/web/index.html +1 -1
- package/package.json +23 -20
- package/dist/web/assets/__federation_expose_auth0CoreCommon-Ga9LD3d6.js +0 -43
- package/dist/web/assets/__federation_expose_auth0CoreCommon-Ga9LD3d6.js.map +0 -1
- package/dist/web/assets/__federation_expose_authCoreCommon-BrTLsuJC.js +0 -29
- package/dist/web/assets/__federation_expose_authCoreCommon-BrTLsuJC.js.map +0 -1
- package/dist/web/assets/__federation_expose_local-authAdminCommon-C75-DAzO.js.map +0 -1
- package/dist/web/assets/__federation_expose_local-authAdminWeb-D2xGvwyL.js +0 -40
- package/dist/web/assets/__federation_expose_local-authAdminWeb-D2xGvwyL.js.map +0 -1
- package/dist/web/assets/__federation_expose_local-authCoreCommon-BFUbyPYg.js +0 -27
- package/dist/web/assets/__federation_expose_local-authCoreCommon-BFUbyPYg.js.map +0 -1
- package/dist/web/assets/__federation_expose_local-authCoreWeb-ChyvdsRq.js.map +0 -1
- package/dist/web/assets/__federation_expose_placeholder-authCoreCommon-DrFV9FSW.js +0 -26
- package/dist/web/assets/__federation_expose_placeholder-authCoreCommon-DrFV9FSW.js.map +0 -1
- package/dist/web/assets/__federation_shared_@baseplate-dev/project-builder-lib/web-DtztAtUw.js.map +0 -1
- package/dist/web/assets/__federation_shared_@baseplate-dev/project-builder-lib-CcNtL_U6.js +0 -10507
- package/dist/web/assets/__federation_shared_@baseplate-dev/project-builder-lib-CcNtL_U6.js.map +0 -1
- package/dist/web/assets/__federation_shared_@baseplate-dev/ui-components-DA_4I2Vy.js +0 -24082
- package/dist/web/assets/__federation_shared_@baseplate-dev/ui-components-DA_4I2Vy.js.map +0 -1
- package/dist/web/assets/__federation_shared_@baseplate-dev/utils-Bxy-1ETU.js.map +0 -1
- package/dist/web/assets/__federation_shared_@tanstack/react-router-DooFj-IS.js.map +0 -1
- package/dist/web/assets/model-merger-gGkFnyaY.js.map +0 -1
- package/dist/web/assets/plugin-definition-QRBMcFiG.js.map +0 -1
- package/dist/web/assets/plugin-definition-rpMj4pr8.js.map +0 -1
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
|
|
3
|
+
import type { RequestServiceContext } from '%requestServiceContextImports';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
PASSWORD_MAX_LENGTH,
|
|
7
|
+
PASSWORD_MIN_LENGTH,
|
|
8
|
+
PASSWORD_RESET_TOKEN_EXPIRY_SEC,
|
|
9
|
+
} from '$constantsPassword';
|
|
10
|
+
import {
|
|
11
|
+
createAuthVerification,
|
|
12
|
+
validateAuthVerification,
|
|
13
|
+
} from '$servicesAuthVerification';
|
|
14
|
+
import { config } from '%configServiceImports';
|
|
15
|
+
import { sendEmail } from '%emailModuleImports';
|
|
16
|
+
import {
|
|
17
|
+
BadRequestError,
|
|
18
|
+
handleZodRequestValidationError,
|
|
19
|
+
} from '%errorHandlerServiceImports';
|
|
20
|
+
import { createPasswordHash } from '%passwordHasherServiceImports';
|
|
21
|
+
import { prisma } from '%prismaImports';
|
|
22
|
+
import { memoizeRateLimiter } from '%rateLimitImports';
|
|
23
|
+
import {
|
|
24
|
+
PasswordChangedEmail,
|
|
25
|
+
PasswordResetEmail,
|
|
26
|
+
} from '@blog-with-auth/transactional';
|
|
27
|
+
import z from 'zod';
|
|
28
|
+
|
|
29
|
+
const PROVIDER_ID = 'email-password';
|
|
30
|
+
const PASSWORD_RESET_TYPE = 'password-reset';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Rate limiters for password reset operations.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
// Per-email rate limit: 3 requests/hour
|
|
37
|
+
const getPasswordResetEmailLimiter = memoizeRateLimiter(
|
|
38
|
+
'password-reset-email',
|
|
39
|
+
{
|
|
40
|
+
points: 3,
|
|
41
|
+
duration: 60 * 60, // 1 hour
|
|
42
|
+
},
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// Per-IP rate limit: 10 requests/hour (prevents email scanning)
|
|
46
|
+
const getPasswordResetIpLimiter = memoizeRateLimiter('password-reset-ip', {
|
|
47
|
+
points: 10,
|
|
48
|
+
duration: 60 * 60, // 1 hour
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// Global rate limit: 100 requests/hour (prevents overloading the email service)
|
|
52
|
+
const getPasswordResetGlobalLimiter = memoizeRateLimiter(
|
|
53
|
+
'password-reset-global',
|
|
54
|
+
{
|
|
55
|
+
points: 100,
|
|
56
|
+
duration: 60 * 60, // 1 hour
|
|
57
|
+
},
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
const requestPasswordResetSchema = z.object({
|
|
61
|
+
email: z
|
|
62
|
+
.email()
|
|
63
|
+
.max(PASSWORD_MAX_LENGTH)
|
|
64
|
+
.transform((value) => value.toLowerCase()),
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Request a password reset for the given email.
|
|
69
|
+
*/
|
|
70
|
+
export async function requestPasswordReset({
|
|
71
|
+
email: rawEmail,
|
|
72
|
+
context,
|
|
73
|
+
}: {
|
|
74
|
+
email: string;
|
|
75
|
+
context: RequestServiceContext;
|
|
76
|
+
}): Promise<{ success: true }> {
|
|
77
|
+
const { email } = await requestPasswordResetSchema
|
|
78
|
+
.parseAsync({ email: rawEmail })
|
|
79
|
+
.catch(handleZodRequestValidationError);
|
|
80
|
+
|
|
81
|
+
await Promise.all([
|
|
82
|
+
getPasswordResetIpLimiter().consumeOrThrow(
|
|
83
|
+
context.reqInfo.ip,
|
|
84
|
+
'Too many password reset attempts. Please try again later.',
|
|
85
|
+
'too-many-requests',
|
|
86
|
+
),
|
|
87
|
+
getPasswordResetEmailLimiter().consumeOrThrow(
|
|
88
|
+
email,
|
|
89
|
+
'Too many password reset attempts. Please try again later.',
|
|
90
|
+
'too-many-requests',
|
|
91
|
+
),
|
|
92
|
+
getPasswordResetGlobalLimiter().consumeOrThrow(
|
|
93
|
+
'global',
|
|
94
|
+
'Too many password reset attempts. Please try again later.',
|
|
95
|
+
'too-many-requests',
|
|
96
|
+
),
|
|
97
|
+
]);
|
|
98
|
+
|
|
99
|
+
// Find user by email - silently handle non-existent users to prevent enumeration
|
|
100
|
+
const user = await prisma.user.findUnique({
|
|
101
|
+
where: { email },
|
|
102
|
+
select: { id: true, email: true },
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
if (user?.email) {
|
|
106
|
+
const { token } = await createAuthVerification({
|
|
107
|
+
type: PASSWORD_RESET_TYPE,
|
|
108
|
+
userId: user.id,
|
|
109
|
+
expiresInSec: PASSWORD_RESET_TOKEN_EXPIRY_SEC,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// Construct reset URL using configured domain
|
|
113
|
+
const resetLink = `${config.AUTH_FRONTEND_URL}/auth/reset-password?token=${encodeURIComponent(token)}`;
|
|
114
|
+
|
|
115
|
+
// Send email asynchronously (queue-based)
|
|
116
|
+
await sendEmail(PasswordResetEmail, {
|
|
117
|
+
to: user.email,
|
|
118
|
+
data: { resetLink },
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Always return success to prevent user enumeration
|
|
123
|
+
return { success: true };
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const validateTokenSchema = z.object({
|
|
127
|
+
token: z.string().min(1).max(PASSWORD_MAX_LENGTH),
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Validates a password reset token without consuming it.
|
|
132
|
+
* Used by the frontend to verify the token is valid before showing the reset form.
|
|
133
|
+
*/
|
|
134
|
+
export async function validatePasswordResetToken({
|
|
135
|
+
token: rawToken,
|
|
136
|
+
}: {
|
|
137
|
+
token: string;
|
|
138
|
+
}): Promise<{ valid: boolean }> {
|
|
139
|
+
const { token } = await validateTokenSchema
|
|
140
|
+
.parseAsync({ token: rawToken })
|
|
141
|
+
.catch(handleZodRequestValidationError);
|
|
142
|
+
|
|
143
|
+
const record = await validateAuthVerification({
|
|
144
|
+
type: PASSWORD_RESET_TYPE,
|
|
145
|
+
token,
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
return { valid: record !== null };
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const completePasswordResetSchema = z.object({
|
|
152
|
+
token: z.string().min(1).max(PASSWORD_MAX_LENGTH),
|
|
153
|
+
newPassword: z.string().min(PASSWORD_MIN_LENGTH).max(PASSWORD_MAX_LENGTH),
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Completes the password reset process by setting a new password.
|
|
158
|
+
*
|
|
159
|
+
* Security notes (OWASP Forgot Password Cheat Sheet):
|
|
160
|
+
* - Token is single-use (deleted after successful reset)
|
|
161
|
+
* - Does not auto-login the user
|
|
162
|
+
* - Always invalidates all existing sessions for security
|
|
163
|
+
* - All remaining password-reset tokens for this user are deleted
|
|
164
|
+
*/
|
|
165
|
+
export async function completePasswordReset({
|
|
166
|
+
token: rawToken,
|
|
167
|
+
newPassword: rawNewPassword,
|
|
168
|
+
}: {
|
|
169
|
+
token: string;
|
|
170
|
+
newPassword: string;
|
|
171
|
+
}): Promise<{ success: true }> {
|
|
172
|
+
const { token, newPassword } = await completePasswordResetSchema
|
|
173
|
+
.parseAsync({
|
|
174
|
+
token: rawToken,
|
|
175
|
+
newPassword: rawNewPassword,
|
|
176
|
+
})
|
|
177
|
+
.catch(handleZodRequestValidationError);
|
|
178
|
+
|
|
179
|
+
const record = await validateAuthVerification({
|
|
180
|
+
type: PASSWORD_RESET_TYPE,
|
|
181
|
+
token,
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
if (!record?.userId) {
|
|
185
|
+
throw new BadRequestError('Invalid or expired token', 'invalid-token');
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const user = await prisma.user.findUniqueOrThrow({
|
|
189
|
+
where: { id: record.userId },
|
|
190
|
+
select: { id: true, email: true },
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
if (!user.email) {
|
|
194
|
+
throw new BadRequestError('User has no email', 'user-has-no-email');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const passwordHash = await createPasswordHash(newPassword);
|
|
198
|
+
|
|
199
|
+
// Delete token + remaining reset tokens + update password + invalidate sessions
|
|
200
|
+
await prisma.$transaction([
|
|
201
|
+
prisma.authVerification.deleteMany({
|
|
202
|
+
where: { type: PASSWORD_RESET_TYPE, userId: user.id },
|
|
203
|
+
}),
|
|
204
|
+
prisma.userAccount.upsert({
|
|
205
|
+
where: {
|
|
206
|
+
accountId_providerId: {
|
|
207
|
+
accountId: user.email,
|
|
208
|
+
providerId: PROVIDER_ID,
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
create: {
|
|
212
|
+
userId: user.id,
|
|
213
|
+
accountId: user.email,
|
|
214
|
+
providerId: PROVIDER_ID,
|
|
215
|
+
password: passwordHash,
|
|
216
|
+
},
|
|
217
|
+
update: {
|
|
218
|
+
password: passwordHash,
|
|
219
|
+
},
|
|
220
|
+
}),
|
|
221
|
+
prisma.userSession.deleteMany({
|
|
222
|
+
where: { userId: user.id },
|
|
223
|
+
}),
|
|
224
|
+
]);
|
|
225
|
+
|
|
226
|
+
// Send password changed confirmation email
|
|
227
|
+
await sendEmail(PasswordChangedEmail, {
|
|
228
|
+
to: user.email,
|
|
229
|
+
data: {},
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
return { success: true };
|
|
233
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-password.service.d.ts","sourceRoot":"","sources":["../../../../../../../../src/local-auth/core/generators/auth-email-password/templates/module/services/user-password.service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"user-password.service.d.ts","sourceRoot":"","sources":["../../../../../../../../src/local-auth/core/generators/auth-email-password/templates/module/services/user-password.service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAuDnE,wBAAsB,8BAA8B,CAAC,EACnD,KAAK,GACN,EAAE;IACD,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,GAAG,OAAO,CAAC,IAAI,CAAC,CAiChB;AAED,wBAAsB,gCAAgC,CAAC,EACrD,KAAK,EACL,OAAO,GACR,EAAE;IACD,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,OAAO,EAAE,qBAAqB,CAAC;CAChC,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,kBAAkB,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC,CAevD;AAED,wBAAsB,oCAAoC,CAAC,EACzD,KAAK,EACL,OAAO,GACR,EAAE;IACD,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,OAAO,EAAE,qBAAqB,CAAC;CAChC,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,kBAAkB,CAAA;CAAE,CAAC,CA6D3C;AAOD;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CAAC,EACvC,MAAM,EACN,KAAK,GACN,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE;QACL,eAAe,EAAE,MAAM,CAAC;QACxB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH,GAAG,OAAO,CAAC,IAAI,CAAC,CAyChB;AAMD;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,MAAM,EACN,KAAK,GACN,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE;QACL,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH,GAAG,OAAO,CAAC,IAAI,CAAC,CA2ChB"}
|
|
@@ -1,18 +1,37 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
|
-
import { PASSWORD_MIN_LENGTH } from '$constantsPassword';
|
|
3
|
-
import {
|
|
2
|
+
import { PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH } from '$constantsPassword';
|
|
3
|
+
import { requestEmailVerification } from '$servicesEmailVerification';
|
|
4
|
+
import { BadRequestError, handleZodRequestValidationError, logError, NotFoundError, TooManyRequestsError, } from '%errorHandlerServiceImports';
|
|
4
5
|
import { createPasswordHash, verifyPasswordHash, } from '%passwordHasherServiceImports';
|
|
5
6
|
import { prisma } from '%prismaImports';
|
|
7
|
+
import { memoizeRateLimiter } from '%rateLimitImports';
|
|
6
8
|
import { userSessionService } from '%userSessionServiceImports';
|
|
7
9
|
import z from 'zod';
|
|
8
10
|
const PROVIDER_ID = 'email-password';
|
|
9
|
-
const MAX_VALUE_LENGTH = 255;
|
|
10
11
|
const emailPasswordSchema = z.object({
|
|
11
12
|
email: z
|
|
12
13
|
.email()
|
|
13
|
-
.max(
|
|
14
|
+
.max(PASSWORD_MAX_LENGTH)
|
|
14
15
|
.transform((value) => value.toLowerCase()),
|
|
15
|
-
password: z.string().min(PASSWORD_MIN_LENGTH).max(
|
|
16
|
+
password: z.string().min(PASSWORD_MIN_LENGTH).max(PASSWORD_MAX_LENGTH),
|
|
17
|
+
});
|
|
18
|
+
/**
|
|
19
|
+
* Rate limiters for authentication operations.
|
|
20
|
+
*/
|
|
21
|
+
const getRegistrationLimiter = memoizeRateLimiter('registration', {
|
|
22
|
+
points: 10,
|
|
23
|
+
duration: 60 * 60, // 1 hour
|
|
24
|
+
blockDuration: 60 * 60, // Block for 1 hour if exceeded
|
|
25
|
+
});
|
|
26
|
+
const getLoginIpLimiter = memoizeRateLimiter('login-ip', {
|
|
27
|
+
points: 10,
|
|
28
|
+
duration: 60 * 60 * 24, // 24 hours
|
|
29
|
+
blockDuration: 60 * 60, // Block for 1 hour if exceeded
|
|
30
|
+
});
|
|
31
|
+
const getLoginConsecutiveFailsLimiter = memoizeRateLimiter('login-consecutive-fails', {
|
|
32
|
+
points: 5,
|
|
33
|
+
duration: 60 * 60 * 24, // 24 hours (duration for tracking)
|
|
34
|
+
blockDuration: 60 * 15, // Block for 15 minutes after 5 consecutive fails
|
|
16
35
|
});
|
|
17
36
|
export async function createUserWithEmailAndPassword({ input, }) {
|
|
18
37
|
const { email, password } = await emailPasswordSchema
|
|
@@ -46,14 +65,28 @@ export async function createUserWithEmailAndPassword({ input, }) {
|
|
|
46
65
|
return user;
|
|
47
66
|
}
|
|
48
67
|
export async function registerUserWithEmailAndPassword({ input, context, }) {
|
|
68
|
+
// Rate limit registration by IP
|
|
69
|
+
await getRegistrationLimiter().consumeOrThrow(context.reqInfo.ip, 'Too many registration attempts. Please try again later.', 'registration-rate-limited');
|
|
49
70
|
const user = await createUserWithEmailAndPassword({ input });
|
|
50
71
|
const session = await userSessionService.createSession(user.id, context);
|
|
72
|
+
// Send verification email (fire-and-forget, don't block registration)
|
|
73
|
+
requestEmailVerification({ userId: user.id, context }).catch(logError);
|
|
51
74
|
return { session, user };
|
|
52
75
|
}
|
|
53
76
|
export async function authenticateUserWithEmailAndPassword({ input, context, }) {
|
|
54
77
|
const { email, password } = await emailPasswordSchema
|
|
55
78
|
.parseAsync(input)
|
|
56
79
|
.catch(handleZodRequestValidationError);
|
|
80
|
+
// Rate limiting setup
|
|
81
|
+
const clientIp = context.reqInfo.ip;
|
|
82
|
+
const emailIpKey = `${email}_${clientIp}`;
|
|
83
|
+
// Check IP-based rate limit (slow brute force protection)
|
|
84
|
+
await getLoginIpLimiter().consumeOrThrow(clientIp, 'Too many login attempts. Please try again later.', 'login-ip-rate-limited');
|
|
85
|
+
// Check consecutive failures rate limit (fast brute force protection)
|
|
86
|
+
const consecutiveFailsResult = await getLoginConsecutiveFailsLimiter().get(emailIpKey);
|
|
87
|
+
if (consecutiveFailsResult && !consecutiveFailsResult.allowed) {
|
|
88
|
+
throw new TooManyRequestsError('Account temporarily locked due to too many failed attempts. Please try again later.', 'login-consecutive-fails-blocked', { retryAfterMs: consecutiveFailsResult.msBeforeNext });
|
|
89
|
+
}
|
|
57
90
|
// check if user with that email exists
|
|
58
91
|
const userAccount = await prisma.userAccount.findUnique({
|
|
59
92
|
where: {
|
|
@@ -63,20 +96,21 @@ export async function authenticateUserWithEmailAndPassword({ input, context, })
|
|
|
63
96
|
},
|
|
64
97
|
},
|
|
65
98
|
});
|
|
66
|
-
if (userAccount === null) {
|
|
67
|
-
throw new BadRequestError('Invalid email', 'invalid-email');
|
|
68
|
-
}
|
|
69
99
|
// check for password match
|
|
70
|
-
const isValid = await verifyPasswordHash(userAccount
|
|
71
|
-
if (!isValid) {
|
|
72
|
-
|
|
100
|
+
const isValid = await verifyPasswordHash(userAccount?.password ?? '', password);
|
|
101
|
+
if (!isValid || !userAccount) {
|
|
102
|
+
// Track failed attempt
|
|
103
|
+
await getLoginConsecutiveFailsLimiter().consume(emailIpKey);
|
|
104
|
+
throw new BadRequestError('Invalid email or password', 'invalid-credentials');
|
|
73
105
|
}
|
|
106
|
+
// Reset consecutive failures on successful login
|
|
107
|
+
await getLoginConsecutiveFailsLimiter().delete(emailIpKey);
|
|
74
108
|
const session = await userSessionService.createSession(userAccount.userId, context);
|
|
75
109
|
return { session };
|
|
76
110
|
}
|
|
77
111
|
const changePasswordSchema = z.object({
|
|
78
|
-
currentPassword: z.string().min(1).max(
|
|
79
|
-
newPassword: z.string().min(PASSWORD_MIN_LENGTH).max(
|
|
112
|
+
currentPassword: z.string().min(1).max(PASSWORD_MAX_LENGTH),
|
|
113
|
+
newPassword: z.string().min(PASSWORD_MIN_LENGTH).max(PASSWORD_MAX_LENGTH),
|
|
80
114
|
});
|
|
81
115
|
/**
|
|
82
116
|
* Change a user's password after validating their current password.
|
|
@@ -120,7 +154,7 @@ export async function changeUserPassword({ userId, input, }) {
|
|
|
120
154
|
});
|
|
121
155
|
}
|
|
122
156
|
const resetPasswordSchema = z.object({
|
|
123
|
-
newPassword: z.string().min(PASSWORD_MIN_LENGTH).max(
|
|
157
|
+
newPassword: z.string().min(PASSWORD_MIN_LENGTH).max(PASSWORD_MAX_LENGTH),
|
|
124
158
|
});
|
|
125
159
|
/**
|
|
126
160
|
* Reset a user's password without requiring the current password.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-password.service.js","sourceRoot":"","sources":["../../../../../../../../src/local-auth/core/generators/auth-email-password/templates/module/services/user-password.service.ts"],"names":[],"mappings":"AAAA,cAAc;AAMd,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"user-password.service.js","sourceRoot":"","sources":["../../../../../../../../src/local-auth/core/generators/auth-email-password/templates/module/services/user-password.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,32 +4,59 @@ import type { User } from '%prismaGeneratedImports';
|
|
|
4
4
|
import type { RequestServiceContext } from '%requestServiceContextImports';
|
|
5
5
|
import type { UserSessionPayload } from '%userSessionTypesImports';
|
|
6
6
|
|
|
7
|
-
import { PASSWORD_MIN_LENGTH } from '$constantsPassword';
|
|
7
|
+
import { PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH } from '$constantsPassword';
|
|
8
|
+
import { requestEmailVerification } from '$servicesEmailVerification';
|
|
8
9
|
import {
|
|
9
10
|
BadRequestError,
|
|
10
11
|
handleZodRequestValidationError,
|
|
12
|
+
logError,
|
|
11
13
|
NotFoundError,
|
|
14
|
+
TooManyRequestsError,
|
|
12
15
|
} from '%errorHandlerServiceImports';
|
|
13
16
|
import {
|
|
14
17
|
createPasswordHash,
|
|
15
18
|
verifyPasswordHash,
|
|
16
19
|
} from '%passwordHasherServiceImports';
|
|
17
20
|
import { prisma } from '%prismaImports';
|
|
21
|
+
import { memoizeRateLimiter } from '%rateLimitImports';
|
|
18
22
|
import { userSessionService } from '%userSessionServiceImports';
|
|
19
23
|
import z from 'zod';
|
|
20
24
|
|
|
21
25
|
const PROVIDER_ID = 'email-password';
|
|
22
26
|
|
|
23
|
-
const MAX_VALUE_LENGTH = 255;
|
|
24
|
-
|
|
25
27
|
const emailPasswordSchema = z.object({
|
|
26
28
|
email: z
|
|
27
29
|
.email()
|
|
28
|
-
.max(
|
|
30
|
+
.max(PASSWORD_MAX_LENGTH)
|
|
29
31
|
.transform((value) => value.toLowerCase()),
|
|
30
|
-
password: z.string().min(PASSWORD_MIN_LENGTH).max(
|
|
32
|
+
password: z.string().min(PASSWORD_MIN_LENGTH).max(PASSWORD_MAX_LENGTH),
|
|
31
33
|
});
|
|
32
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Rate limiters for authentication operations.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
const getRegistrationLimiter = memoizeRateLimiter('registration', {
|
|
40
|
+
points: 10,
|
|
41
|
+
duration: 60 * 60, // 1 hour
|
|
42
|
+
blockDuration: 60 * 60, // Block for 1 hour if exceeded
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const getLoginIpLimiter = memoizeRateLimiter('login-ip', {
|
|
46
|
+
points: 10,
|
|
47
|
+
duration: 60 * 60 * 24, // 24 hours
|
|
48
|
+
blockDuration: 60 * 60, // Block for 1 hour if exceeded
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const getLoginConsecutiveFailsLimiter = memoizeRateLimiter(
|
|
52
|
+
'login-consecutive-fails',
|
|
53
|
+
{
|
|
54
|
+
points: 5,
|
|
55
|
+
duration: 60 * 60 * 24, // 24 hours (duration for tracking)
|
|
56
|
+
blockDuration: 60 * 15, // Block for 15 minutes after 5 consecutive fails
|
|
57
|
+
},
|
|
58
|
+
);
|
|
59
|
+
|
|
33
60
|
export async function createUserWithEmailAndPassword({
|
|
34
61
|
input,
|
|
35
62
|
}: {
|
|
@@ -82,9 +109,19 @@ export async function registerUserWithEmailAndPassword({
|
|
|
82
109
|
};
|
|
83
110
|
context: RequestServiceContext;
|
|
84
111
|
}): Promise<{ session: UserSessionPayload; user: User }> {
|
|
112
|
+
// Rate limit registration by IP
|
|
113
|
+
await getRegistrationLimiter().consumeOrThrow(
|
|
114
|
+
context.reqInfo.ip,
|
|
115
|
+
'Too many registration attempts. Please try again later.',
|
|
116
|
+
'registration-rate-limited',
|
|
117
|
+
);
|
|
118
|
+
|
|
85
119
|
const user = await createUserWithEmailAndPassword({ input });
|
|
86
120
|
const session = await userSessionService.createSession(user.id, context);
|
|
87
121
|
|
|
122
|
+
// Send verification email (fire-and-forget, don't block registration)
|
|
123
|
+
requestEmailVerification({ userId: user.id, context }).catch(logError);
|
|
124
|
+
|
|
88
125
|
return { session, user };
|
|
89
126
|
}
|
|
90
127
|
|
|
@@ -102,6 +139,29 @@ export async function authenticateUserWithEmailAndPassword({
|
|
|
102
139
|
.parseAsync(input)
|
|
103
140
|
.catch(handleZodRequestValidationError);
|
|
104
141
|
|
|
142
|
+
// Rate limiting setup
|
|
143
|
+
const clientIp = context.reqInfo.ip;
|
|
144
|
+
const emailIpKey = `${email}_${clientIp}`;
|
|
145
|
+
|
|
146
|
+
// Check IP-based rate limit (slow brute force protection)
|
|
147
|
+
await getLoginIpLimiter().consumeOrThrow(
|
|
148
|
+
clientIp,
|
|
149
|
+
'Too many login attempts. Please try again later.',
|
|
150
|
+
'login-ip-rate-limited',
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
// Check consecutive failures rate limit (fast brute force protection)
|
|
154
|
+
const consecutiveFailsResult =
|
|
155
|
+
await getLoginConsecutiveFailsLimiter().get(emailIpKey);
|
|
156
|
+
|
|
157
|
+
if (consecutiveFailsResult && !consecutiveFailsResult.allowed) {
|
|
158
|
+
throw new TooManyRequestsError(
|
|
159
|
+
'Account temporarily locked due to too many failed attempts. Please try again later.',
|
|
160
|
+
'login-consecutive-fails-blocked',
|
|
161
|
+
{ retryAfterMs: consecutiveFailsResult.msBeforeNext },
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
105
165
|
// check if user with that email exists
|
|
106
166
|
const userAccount = await prisma.userAccount.findUnique({
|
|
107
167
|
where: {
|
|
@@ -112,19 +172,23 @@ export async function authenticateUserWithEmailAndPassword({
|
|
|
112
172
|
},
|
|
113
173
|
});
|
|
114
174
|
|
|
115
|
-
if (userAccount === null) {
|
|
116
|
-
throw new BadRequestError('Invalid email', 'invalid-email');
|
|
117
|
-
}
|
|
118
|
-
|
|
119
175
|
// check for password match
|
|
120
176
|
const isValid = await verifyPasswordHash(
|
|
121
|
-
userAccount
|
|
177
|
+
userAccount?.password ?? '',
|
|
122
178
|
password,
|
|
123
179
|
);
|
|
124
|
-
if (!isValid) {
|
|
125
|
-
|
|
180
|
+
if (!isValid || !userAccount) {
|
|
181
|
+
// Track failed attempt
|
|
182
|
+
await getLoginConsecutiveFailsLimiter().consume(emailIpKey);
|
|
183
|
+
throw new BadRequestError(
|
|
184
|
+
'Invalid email or password',
|
|
185
|
+
'invalid-credentials',
|
|
186
|
+
);
|
|
126
187
|
}
|
|
127
188
|
|
|
189
|
+
// Reset consecutive failures on successful login
|
|
190
|
+
await getLoginConsecutiveFailsLimiter().delete(emailIpKey);
|
|
191
|
+
|
|
128
192
|
const session = await userSessionService.createSession(
|
|
129
193
|
userAccount.userId,
|
|
130
194
|
context,
|
|
@@ -134,8 +198,8 @@ export async function authenticateUserWithEmailAndPassword({
|
|
|
134
198
|
}
|
|
135
199
|
|
|
136
200
|
const changePasswordSchema = z.object({
|
|
137
|
-
currentPassword: z.string().min(1).max(
|
|
138
|
-
newPassword: z.string().min(PASSWORD_MIN_LENGTH).max(
|
|
201
|
+
currentPassword: z.string().min(1).max(PASSWORD_MAX_LENGTH),
|
|
202
|
+
newPassword: z.string().min(PASSWORD_MIN_LENGTH).max(PASSWORD_MAX_LENGTH),
|
|
139
203
|
});
|
|
140
204
|
|
|
141
205
|
/**
|
|
@@ -200,7 +264,7 @@ export async function changeUserPassword({
|
|
|
200
264
|
}
|
|
201
265
|
|
|
202
266
|
const resetPasswordSchema = z.object({
|
|
203
|
-
newPassword: z.string().min(PASSWORD_MIN_LENGTH).max(
|
|
267
|
+
newPassword: z.string().min(PASSWORD_MIN_LENGTH).max(PASSWORD_MAX_LENGTH),
|
|
204
268
|
});
|
|
205
269
|
|
|
206
270
|
/**
|
package/dist/local-auth/core/generators/auth-email-templates/auth-email-templates.generator.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generator for auth email templates.
|
|
3
|
+
*
|
|
4
|
+
* Registers auth-related email templates (password reset, password changed,
|
|
5
|
+
* account verification) with the transactional email library and generates
|
|
6
|
+
* the corresponding .tsx template files.
|
|
7
|
+
*/
|
|
8
|
+
export declare const authEmailTemplatesGenerator: import("@baseplate-dev/sync").GeneratorBundleCreator<Record<string, never>, {
|
|
9
|
+
paths: import("@baseplate-dev/sync").GeneratorTask<{
|
|
10
|
+
localAuthAuthEmailTemplatesPaths: import("@baseplate-dev/sync").ProviderExport<import("./generated/template-paths.js").LocalAuthAuthEmailTemplatesPaths>;
|
|
11
|
+
}, {
|
|
12
|
+
packageInfo: import("@baseplate-dev/sync").ProviderType<import("@baseplate-dev/core-generators").PackageInfoProvider>;
|
|
13
|
+
}, undefined>;
|
|
14
|
+
renderers: import("@baseplate-dev/sync").GeneratorTask<{
|
|
15
|
+
localAuthAuthEmailTemplatesRenderers: import("@baseplate-dev/sync").ProviderExport<import("./generated/template-renderers.js").LocalAuthAuthEmailTemplatesRenderers>;
|
|
16
|
+
}, {
|
|
17
|
+
paths: import("@baseplate-dev/sync").ProviderType<import("./generated/template-paths.js").LocalAuthAuthEmailTemplatesPaths>;
|
|
18
|
+
transactionalLibImports: import("@baseplate-dev/sync").ProviderType<import("@baseplate-dev/core-generators").InferTsImportMapFromSchema<{
|
|
19
|
+
Button: {};
|
|
20
|
+
defineEmail: {};
|
|
21
|
+
DefineEmailOptions: {
|
|
22
|
+
isTypeOnly: true;
|
|
23
|
+
};
|
|
24
|
+
Divider: {};
|
|
25
|
+
EmailComponent: {
|
|
26
|
+
isTypeOnly: true;
|
|
27
|
+
};
|
|
28
|
+
EmailLayout: {};
|
|
29
|
+
Heading: {};
|
|
30
|
+
renderEmail: {};
|
|
31
|
+
Section: {};
|
|
32
|
+
Text: {};
|
|
33
|
+
theme: {};
|
|
34
|
+
}>>;
|
|
35
|
+
typescriptFile: import("@baseplate-dev/sync").ProviderType<import("@baseplate-dev/core-generators").TypescriptFileProvider>;
|
|
36
|
+
}, undefined>;
|
|
37
|
+
main: import("@baseplate-dev/sync").GeneratorTask<any, {
|
|
38
|
+
emailTemplates: import("@baseplate-dev/sync").ProviderType<import("@baseplate-dev/plugin-email").EmailTemplatesProvider>;
|
|
39
|
+
paths: import("@baseplate-dev/sync").ProviderType<import("./generated/template-paths.js").LocalAuthAuthEmailTemplatesPaths>;
|
|
40
|
+
renderers: import("@baseplate-dev/sync").ProviderType<import("./generated/template-renderers.js").LocalAuthAuthEmailTemplatesRenderers>;
|
|
41
|
+
}, any>;
|
|
42
|
+
}>;
|
|
43
|
+
//# sourceMappingURL=auth-email-templates.generator.d.ts.map
|
package/dist/local-auth/core/generators/auth-email-templates/auth-email-templates.generator.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-email-templates.generator.d.ts","sourceRoot":"","sources":["../../../../../src/local-auth/core/generators/auth-email-templates/auth-email-templates.generator.ts"],"names":[],"mappings":"AAQA;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyCtC,CAAC"}
|
package/dist/local-auth/core/generators/auth-email-templates/auth-email-templates.generator.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { emailTemplatesProvider } from '@baseplate-dev/plugin-email';
|
|
2
|
+
import { createGenerator, createGeneratorTask } from '@baseplate-dev/sync';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { LOCAL_AUTH_AUTH_EMAIL_TEMPLATES_GENERATED as GENERATED_TEMPLATES } from './generated/index.js';
|
|
5
|
+
const descriptorSchema = z.object({});
|
|
6
|
+
/**
|
|
7
|
+
* Generator for auth email templates.
|
|
8
|
+
*
|
|
9
|
+
* Registers auth-related email templates (password reset, password changed,
|
|
10
|
+
* account verification) with the transactional email library and generates
|
|
11
|
+
* the corresponding .tsx template files.
|
|
12
|
+
*/
|
|
13
|
+
export const authEmailTemplatesGenerator = createGenerator({
|
|
14
|
+
name: 'local-auth/auth-email-templates',
|
|
15
|
+
generatorFileUrl: import.meta.url,
|
|
16
|
+
descriptorSchema,
|
|
17
|
+
buildTasks: () => ({
|
|
18
|
+
paths: GENERATED_TEMPLATES.paths.task,
|
|
19
|
+
renderers: GENERATED_TEMPLATES.renderers.task,
|
|
20
|
+
main: createGeneratorTask({
|
|
21
|
+
dependencies: {
|
|
22
|
+
emailTemplates: emailTemplatesProvider,
|
|
23
|
+
paths: GENERATED_TEMPLATES.paths.provider,
|
|
24
|
+
renderers: GENERATED_TEMPLATES.renderers.provider,
|
|
25
|
+
},
|
|
26
|
+
run({ emailTemplates, paths, renderers }) {
|
|
27
|
+
emailTemplates.registerExport({
|
|
28
|
+
exportName: 'AccountVerificationEmail',
|
|
29
|
+
exportPath: paths.accountVerificationEmail,
|
|
30
|
+
});
|
|
31
|
+
emailTemplates.registerExport({
|
|
32
|
+
exportName: 'PasswordChangedEmail',
|
|
33
|
+
exportPath: paths.passwordChangedEmail,
|
|
34
|
+
});
|
|
35
|
+
emailTemplates.registerExport({
|
|
36
|
+
exportName: 'PasswordResetEmail',
|
|
37
|
+
exportPath: paths.passwordResetEmail,
|
|
38
|
+
});
|
|
39
|
+
return {
|
|
40
|
+
build: async (builder) => {
|
|
41
|
+
await builder.apply(renderers.accountVerificationEmail.render({}), renderers.passwordChangedEmail.render({}), renderers.passwordResetEmail.render({}));
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
},
|
|
45
|
+
}),
|
|
46
|
+
}),
|
|
47
|
+
});
|
|
48
|
+
//# sourceMappingURL=auth-email-templates.generator.js.map
|
package/dist/local-auth/core/generators/auth-email-templates/auth-email-templates.generator.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-email-templates.generator.js","sourceRoot":"","sources":["../../../../../src/local-auth/core/generators/auth-email-templates/auth-email-templates.generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,yCAAyC,IAAI,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAExG,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAEtC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,eAAe,CAAC;IACzD,IAAI,EAAE,iCAAiC;IACvC,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG;IACjC,gBAAgB;IAChB,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;QACjB,KAAK,EAAE,mBAAmB,CAAC,KAAK,CAAC,IAAI;QACrC,SAAS,EAAE,mBAAmB,CAAC,SAAS,CAAC,IAAI;QAC7C,IAAI,EAAE,mBAAmB,CAAC;YACxB,YAAY,EAAE;gBACZ,cAAc,EAAE,sBAAsB;gBACtC,KAAK,EAAE,mBAAmB,CAAC,KAAK,CAAC,QAAQ;gBACzC,SAAS,EAAE,mBAAmB,CAAC,SAAS,CAAC,QAAQ;aAClD;YACD,GAAG,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,EAAE;gBACtC,cAAc,CAAC,cAAc,CAAC;oBAC5B,UAAU,EAAE,0BAA0B;oBACtC,UAAU,EAAE,KAAK,CAAC,wBAAwB;iBAC3C,CAAC,CAAC;gBAEH,cAAc,CAAC,cAAc,CAAC;oBAC5B,UAAU,EAAE,sBAAsB;oBAClC,UAAU,EAAE,KAAK,CAAC,oBAAoB;iBACvC,CAAC,CAAC;gBAEH,cAAc,CAAC,cAAc,CAAC;oBAC5B,UAAU,EAAE,oBAAoB;oBAChC,UAAU,EAAE,KAAK,CAAC,kBAAkB;iBACrC,CAAC,CAAC;gBAEH,OAAO;oBACL,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;wBACvB,MAAM,OAAO,CAAC,KAAK,CACjB,SAAS,CAAC,wBAAwB,CAAC,MAAM,CAAC,EAAE,CAAC,EAC7C,SAAS,CAAC,oBAAoB,CAAC,MAAM,CAAC,EAAE,CAAC,EACzC,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC,CACxC,CAAC;oBACJ,CAAC;iBACF,CAAC;YACJ,CAAC;SACF,CAAC;KACH,CAAC;CACH,CAAC,CAAC"}
|