@lenne.tech/nest-server 11.13.5 → 11.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -3
- package/dist/core/common/args/filter.args.js +3 -6
- package/dist/core/common/args/filter.args.js.map +1 -1
- package/dist/core/common/args/pagination.args.js +6 -9
- package/dist/core/common/args/pagination.args.js.map +1 -1
- package/dist/core/common/decorators/translatable.decorator.js +1 -1
- package/dist/core/common/decorators/translatable.decorator.js.map +1 -1
- package/dist/core/common/enums/role.enum.js.map +1 -1
- package/dist/core/common/filters/http-exception-log.filter.js +3 -1
- package/dist/core/common/filters/http-exception-log.filter.js.map +1 -1
- package/dist/core/common/helpers/config.helper.js +2 -2
- package/dist/core/common/helpers/config.helper.js.map +1 -1
- package/dist/core/common/helpers/db.helper.js +12 -12
- package/dist/core/common/helpers/db.helper.js.map +1 -1
- package/dist/core/common/helpers/graphql.helper.js +1 -1
- package/dist/core/common/helpers/graphql.helper.js.map +1 -1
- package/dist/core/common/helpers/input.helper.js +7 -4
- package/dist/core/common/helpers/input.helper.js.map +1 -1
- package/dist/core/common/helpers/scim.helper.js +2 -2
- package/dist/core/common/helpers/scim.helper.js.map +1 -1
- package/dist/core/common/helpers/service.helper.js +1 -1
- package/dist/core/common/helpers/service.helper.js.map +1 -1
- package/dist/core/common/inputs/combined-filter.input.js +3 -6
- package/dist/core/common/inputs/combined-filter.input.js.map +1 -1
- package/dist/core/common/inputs/core-input.input.js +1 -1
- package/dist/core/common/inputs/core-input.input.js.map +1 -1
- package/dist/core/common/inputs/filter.input.js +3 -6
- package/dist/core/common/inputs/filter.input.js.map +1 -1
- package/dist/core/common/inputs/single-filter.input.js +9 -12
- package/dist/core/common/inputs/single-filter.input.js.map +1 -1
- package/dist/core/common/inputs/sort.input.js +2 -5
- package/dist/core/common/inputs/sort.input.js.map +1 -1
- package/dist/core/common/interceptors/check-response.interceptor.js +12 -11
- package/dist/core/common/interceptors/check-response.interceptor.js.map +1 -1
- package/dist/core/common/interceptors/check-security.interceptor.js +5 -4
- package/dist/core/common/interceptors/check-security.interceptor.js.map +1 -1
- package/dist/core/common/models/core-model.model.d.ts +2 -2
- package/dist/core/common/models/core-model.model.js +2 -2
- package/dist/core/common/models/core-model.model.js.map +1 -1
- package/dist/core/common/models/core-persistence.model.js +3 -6
- package/dist/core/common/models/core-persistence.model.js.map +1 -1
- package/dist/core/common/models/pagination-info.model.js +6 -0
- package/dist/core/common/models/pagination-info.model.js.map +1 -1
- package/dist/core/common/pipes/check-input.pipe.js +1 -0
- package/dist/core/common/pipes/check-input.pipe.js.map +1 -1
- package/dist/core/common/plugins/complexity.plugin.js +2 -0
- package/dist/core/common/plugins/complexity.plugin.js.map +1 -1
- package/dist/core/common/scalars/any.scalar.js +2 -4
- package/dist/core/common/scalars/any.scalar.js.map +1 -1
- package/dist/core/common/scalars/date-timestamp.scalar.js +1 -3
- package/dist/core/common/scalars/date-timestamp.scalar.js.map +1 -1
- package/dist/core/common/scalars/date.scalar.js +1 -3
- package/dist/core/common/scalars/date.scalar.js.map +1 -1
- package/dist/core/common/scalars/json.scalar.js +2 -4
- package/dist/core/common/scalars/json.scalar.js.map +1 -1
- package/dist/core/common/services/brevo.service.js +3 -0
- package/dist/core/common/services/brevo.service.js.map +1 -1
- package/dist/core/common/services/config.service.js +15 -8
- package/dist/core/common/services/config.service.js.map +1 -1
- package/dist/core/common/services/core-cron-jobs.service.js +10 -7
- package/dist/core/common/services/core-cron-jobs.service.js.map +1 -1
- package/dist/core/common/services/crud.service.js +1 -9
- package/dist/core/common/services/crud.service.js.map +1 -1
- package/dist/core/common/services/email.service.js +2 -0
- package/dist/core/common/services/email.service.js.map +1 -1
- package/dist/core/common/services/mailjet.service.js +5 -4
- package/dist/core/common/services/mailjet.service.js.map +1 -1
- package/dist/core/common/services/model-doc.service.js +1 -0
- package/dist/core/common/services/model-doc.service.js.map +1 -1
- package/dist/core/common/services/module.service.js +6 -3
- package/dist/core/common/services/module.service.js.map +1 -1
- package/dist/core/common/services/template.service.js +2 -1
- package/dist/core/common/services/template.service.js.map +1 -1
- package/dist/core/common/types/array-element.type.d.ts +1 -1
- package/dist/core/modules/auth/core-auth.controller.js +2 -0
- package/dist/core/modules/auth/core-auth.controller.js.map +1 -1
- package/dist/core/modules/auth/core-auth.model.js +3 -6
- package/dist/core/modules/auth/core-auth.model.js.map +1 -1
- package/dist/core/modules/auth/core-auth.resolver.js +2 -0
- package/dist/core/modules/auth/core-auth.resolver.js.map +1 -1
- package/dist/core/modules/auth/guards/auth.guard.js +6 -4
- package/dist/core/modules/auth/guards/auth.guard.js.map +1 -1
- package/dist/core/modules/auth/guards/legacy-auth-rate-limit.guard.js +1 -0
- package/dist/core/modules/auth/guards/legacy-auth-rate-limit.guard.js.map +1 -1
- package/dist/core/modules/auth/guards/roles-guard-registry.js +3 -3
- package/dist/core/modules/auth/guards/roles-guard-registry.js.map +1 -1
- package/dist/core/modules/auth/guards/roles.guard.js +15 -7
- package/dist/core/modules/auth/guards/roles.guard.js.map +1 -1
- package/dist/core/modules/auth/inputs/core-auth-sign-in.input.js +4 -7
- package/dist/core/modules/auth/inputs/core-auth-sign-in.input.js.map +1 -1
- package/dist/core/modules/auth/services/core-auth.service.js +6 -1
- package/dist/core/modules/auth/services/core-auth.service.js.map +1 -1
- package/dist/core/modules/auth/services/legacy-auth-rate-limiter.service.js +4 -4
- package/dist/core/modules/auth/services/legacy-auth-rate-limiter.service.js.map +1 -1
- package/dist/core/modules/auth/strategies/jwt-refresh.strategy.js +2 -0
- package/dist/core/modules/auth/strategies/jwt-refresh.strategy.js.map +1 -1
- package/dist/core/modules/auth/strategies/jwt.strategy.js +2 -0
- package/dist/core/modules/auth/strategies/jwt.strategy.js.map +1 -1
- package/dist/core/modules/auth/tokens.decorator.js +2 -2
- package/dist/core/modules/auth/tokens.decorator.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth-roles.guard.js +2 -4
- package/dist/core/modules/better-auth/better-auth-roles.guard.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth-token.service.js +3 -1
- package/dist/core/modules/better-auth/better-auth-token.service.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.resolver.js +4 -0
- package/dist/core/modules/better-auth/better-auth.resolver.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.types.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.js +6 -3
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-auth.model.js +7 -0
- package/dist/core/modules/better-auth/core-better-auth-auth.model.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-challenge.service.js +6 -4
- package/dist/core/modules/better-auth/core-better-auth-challenge.service.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-cookie.helper.js +3 -0
- package/dist/core/modules/better-auth/core-better-auth-cookie.helper.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-email-verification.service.js +13 -8
- package/dist/core/modules/better-auth/core-better-auth-email-verification.service.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-migration-status.model.js +8 -0
- package/dist/core/modules/better-auth/core-better-auth-migration-status.model.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-models.js +31 -0
- package/dist/core/modules/better-auth/core-better-auth-models.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-rate-limit.middleware.js +2 -0
- package/dist/core/modules/better-auth/core-better-auth-rate-limit.middleware.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-rate-limiter.service.js +4 -4
- package/dist/core/modules/better-auth/core-better-auth-rate-limiter.service.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-signup-validator.service.js +3 -2
- package/dist/core/modules/better-auth/core-better-auth-signup-validator.service.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.js +2 -1
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.controller.js +27 -1
- package/dist/core/modules/better-auth/core-better-auth.controller.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.middleware.js +3 -1
- package/dist/core/modules/better-auth/core-better-auth.middleware.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.module.js +23 -18
- package/dist/core/modules/better-auth/core-better-auth.module.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.resolver.js +5 -1
- package/dist/core/modules/better-auth/core-better-auth.resolver.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.service.js +6 -1
- package/dist/core/modules/better-auth/core-better-auth.service.js.map +1 -1
- package/dist/core/modules/error-code/core-error-code.controller.js +1 -0
- package/dist/core/modules/error-code/core-error-code.controller.js.map +1 -1
- package/dist/core/modules/error-code/core-error-code.service.js +3 -3
- package/dist/core/modules/error-code/core-error-code.service.js.map +1 -1
- package/dist/core/modules/error-code/error-codes.js.map +1 -1
- package/dist/core/modules/file/core-file-info.model.js +6 -9
- package/dist/core/modules/file/core-file-info.model.js.map +1 -1
- package/dist/core/modules/file/core-file.controller.js +1 -0
- package/dist/core/modules/file/core-file.controller.js.map +1 -1
- package/dist/core/modules/file/core-file.resolver.js +1 -0
- package/dist/core/modules/file/core-file.resolver.js.map +1 -1
- package/dist/core/modules/file/core-file.service.d.ts +1 -1
- package/dist/core/modules/file/core-file.service.js +4 -4
- package/dist/core/modules/file/core-file.service.js.map +1 -1
- package/dist/core/modules/health-check/core-health-check-result.model.js +4 -7
- package/dist/core/modules/health-check/core-health-check-result.model.js.map +1 -1
- package/dist/core/modules/health-check/core-health-check.controller.js +1 -0
- package/dist/core/modules/health-check/core-health-check.controller.js.map +1 -1
- package/dist/core/modules/health-check/core-health-check.resolver.js +1 -0
- package/dist/core/modules/health-check/core-health-check.resolver.js.map +1 -1
- package/dist/core/modules/health-check/core-health-check.service.js +5 -0
- package/dist/core/modules/health-check/core-health-check.service.js.map +1 -1
- package/dist/core/modules/migrate/cli/migrate-cli.js.map +1 -1
- package/dist/core/modules/migrate/helpers/migration.helper.js +11 -19
- package/dist/core/modules/migrate/helpers/migration.helper.js.map +1 -1
- package/dist/core/modules/migrate/migration-runner.js +2 -0
- package/dist/core/modules/migrate/migration-runner.js.map +1 -1
- package/dist/core/modules/migrate/mongo-state-store.js +3 -0
- package/dist/core/modules/migrate/mongo-state-store.js.map +1 -1
- package/dist/core/modules/system-setup/core-system-setup.controller.js +4 -0
- package/dist/core/modules/system-setup/core-system-setup.controller.js.map +1 -1
- package/dist/core/modules/system-setup/core-system-setup.service.js +6 -5
- package/dist/core/modules/system-setup/core-system-setup.service.js.map +1 -1
- package/dist/core/modules/tus/core-tus.controller.js +2 -1
- package/dist/core/modules/tus/core-tus.controller.js.map +1 -1
- package/dist/core/modules/tus/core-tus.service.js +6 -3
- package/dist/core/modules/tus/core-tus.service.js.map +1 -1
- package/dist/core/modules/tus/tus.module.js +7 -5
- package/dist/core/modules/tus/tus.module.js.map +1 -1
- package/dist/core/modules/user/core-user.model.js +15 -18
- package/dist/core/modules/user/core-user.model.js.map +1 -1
- package/dist/core/modules/user/core-user.service.d.ts +1 -1
- package/dist/core/modules/user/core-user.service.js +7 -2
- package/dist/core/modules/user/core-user.service.js.map +1 -1
- package/dist/core/modules/user/inputs/core-user-create.input.js +1 -4
- package/dist/core/modules/user/inputs/core-user-create.input.js.map +1 -1
- package/dist/core/modules/user/inputs/core-user.input.js +6 -9
- package/dist/core/modules/user/inputs/core-user.input.js.map +1 -1
- package/dist/server/common/models/persistence.model.js +2 -5
- package/dist/server/common/models/persistence.model.js.map +1 -1
- package/dist/server/common/services/cron-jobs.service.js +2 -0
- package/dist/server/common/services/cron-jobs.service.js.map +1 -1
- package/dist/server/modules/auth/auth.controller.js +2 -0
- package/dist/server/modules/auth/auth.controller.js.map +1 -1
- package/dist/server/modules/auth/auth.model.js +1 -4
- package/dist/server/modules/auth/auth.model.js.map +1 -1
- package/dist/server/modules/auth/auth.module.js +1 -6
- package/dist/server/modules/auth/auth.module.js.map +1 -1
- package/dist/server/modules/auth/auth.resolver.js +2 -0
- package/dist/server/modules/auth/auth.resolver.js.map +1 -1
- package/dist/server/modules/auth/auth.service.js +4 -0
- package/dist/server/modules/auth/auth.service.js.map +1 -1
- package/dist/server/modules/auth/inputs/auth-sign-up.input.js +2 -5
- package/dist/server/modules/auth/inputs/auth-sign-up.input.js.map +1 -1
- package/dist/server/modules/better-auth/better-auth.controller.js +3 -0
- package/dist/server/modules/better-auth/better-auth.controller.js.map +1 -1
- package/dist/server/modules/better-auth/better-auth.resolver.js +4 -0
- package/dist/server/modules/better-auth/better-auth.resolver.js.map +1 -1
- package/dist/server/modules/error-code/error-code.controller.js +1 -0
- package/dist/server/modules/error-code/error-code.controller.js.map +1 -1
- package/dist/server/modules/file/file-info.model.d.ts +2 -2
- package/dist/server/modules/file/file.controller.js +1 -0
- package/dist/server/modules/file/file.controller.js.map +1 -1
- package/dist/server/modules/file/file.resolver.js +2 -1
- package/dist/server/modules/file/file.resolver.js.map +1 -1
- package/dist/server/modules/file/file.service.js +2 -3
- package/dist/server/modules/file/file.service.js.map +1 -1
- package/dist/server/modules/user/avatar.controller.js +1 -0
- package/dist/server/modules/user/avatar.controller.js.map +1 -1
- package/dist/server/modules/user/inputs/user-create.input.js +1 -4
- package/dist/server/modules/user/inputs/user-create.input.js.map +1 -1
- package/dist/server/modules/user/inputs/user.input.js +1 -4
- package/dist/server/modules/user/inputs/user.input.js.map +1 -1
- package/dist/server/modules/user/outputs/find-and-count-users-result.output.js +3 -0
- package/dist/server/modules/user/outputs/find-and-count-users-result.output.js.map +1 -1
- package/dist/server/modules/user/user.controller.js +1 -0
- package/dist/server/modules/user/user.controller.js.map +1 -1
- package/dist/server/modules/user/user.model.js +7 -10
- package/dist/server/modules/user/user.model.js.map +1 -1
- package/dist/server/modules/user/user.resolver.js +3 -1
- package/dist/server/modules/user/user.resolver.js.map +1 -1
- package/dist/server/modules/user/user.service.js +6 -0
- package/dist/server/modules/user/user.service.js.map +1 -1
- package/dist/server/server.controller.js +1 -0
- package/dist/server/server.controller.js.map +1 -1
- package/dist/test/test.helper.js +18 -10
- package/dist/test/test.helper.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +26 -58
- package/src/core/common/args/filter.args.ts +1 -1
- package/src/core/common/args/pagination.args.ts +1 -1
- package/src/core/common/decorators/translatable.decorator.ts +1 -1
- package/src/core/common/enums/role.enum.ts +0 -1
- package/src/core/common/filters/http-exception-log.filter.ts +3 -3
- package/src/core/common/helpers/config.helper.ts +2 -2
- package/src/core/common/helpers/db.helper.ts +12 -12
- package/src/core/common/helpers/graphql.helper.ts +1 -1
- package/src/core/common/helpers/input.helper.ts +7 -4
- package/src/core/common/helpers/scim.helper.ts +16 -13
- package/src/core/common/helpers/service.helper.ts +1 -1
- package/src/core/common/inputs/combined-filter.input.ts +1 -1
- package/src/core/common/inputs/core-input.input.ts +1 -1
- package/src/core/common/inputs/filter.input.ts +13 -13
- package/src/core/common/inputs/single-filter.input.ts +2 -2
- package/src/core/common/interceptors/check-response.interceptor.ts +2 -2
- package/src/core/common/interfaces/cron-job-config-with-time-zone.interface.ts +4 -2
- package/src/core/common/interfaces/cron-job-config-with-utc-offset.interface.ts +4 -2
- package/src/core/common/interfaces/scim-array-filter-node.interface.ts +1 -1
- package/src/core/common/interfaces/scim-condition-node.interface.ts +1 -1
- package/src/core/common/interfaces/scim-logical-node.interface.ts +1 -1
- package/src/core/common/models/core-model.model.ts +2 -4
- package/src/core/common/scalars/any.scalar.ts +1 -1
- package/src/core/common/scalars/json.scalar.ts +3 -3
- package/src/core/common/services/config.service.ts +17 -11
- package/src/core/common/services/core-cron-jobs.service.ts +6 -6
- package/src/core/common/services/crud.service.ts +3 -12
- package/src/core/common/services/mailjet.service.ts +4 -5
- package/src/core/common/services/module.service.ts +3 -3
- package/src/core/common/types/array-element.type.ts +3 -2
- package/src/core/common/types/require-only-one.type.ts +2 -2
- package/src/core/common/types/required-at-least-one.type.ts +2 -2
- package/src/core/common/types/scim-comparator.type.ts +1 -1
- package/src/core/common/types/scim-logical-operator.type.ts +1 -1
- package/src/core/common/types/scim-node.type.ts +1 -1
- package/src/core/modules/auth/guards/auth.guard.ts +4 -2
- package/src/core/modules/auth/guards/roles.guard.ts +17 -3
- package/src/core/modules/auth/tokens.decorator.ts +3 -3
- package/src/core/modules/better-auth/ARCHITECTURE.md +23 -20
- package/src/core/modules/better-auth/CUSTOMIZATION.md +64 -56
- package/src/core/modules/better-auth/INTEGRATION-CHECKLIST.md +67 -40
- package/src/core/modules/better-auth/README.md +268 -230
- package/src/core/modules/better-auth/better-auth-roles.guard.ts +8 -1
- package/src/core/modules/better-auth/better-auth-token.service.ts +10 -3
- package/src/core/modules/better-auth/better-auth.resolver.ts +3 -1
- package/src/core/modules/better-auth/better-auth.types.ts +3 -1
- package/src/core/modules/better-auth/core-better-auth-api.middleware.ts +3 -1
- package/src/core/modules/better-auth/core-better-auth-challenge.service.ts +3 -1
- package/src/core/modules/better-auth/core-better-auth-email-verification.service.ts +30 -25
- package/src/core/modules/better-auth/core-better-auth-signup-validator.service.ts +3 -1
- package/src/core/modules/better-auth/core-better-auth.middleware.ts +6 -2
- package/src/core/modules/error-code/INTEGRATION-CHECKLIST.md +28 -21
- package/src/core/modules/error-code/error-codes.ts +0 -2
- package/src/core/modules/file/README.md +12 -10
- package/src/core/modules/file/core-file.service.ts +5 -9
- package/src/core/modules/migrate/MIGRATION_FROM_NODEPIT.md +21 -9
- package/src/core/modules/migrate/README.md +30 -28
- package/src/core/modules/migrate/cli/migrate-cli.ts +0 -3
- package/src/core/modules/migrate/helpers/migration.helper.ts +13 -21
- package/src/core/modules/migrate/migration-runner.ts +0 -3
- package/src/core/modules/system-setup/INTEGRATION-CHECKLIST.md +15 -14
- package/src/core/modules/system-setup/README.md +28 -20
- package/src/core/modules/system-setup/core-system-setup.service.ts +4 -5
- package/src/core/modules/tus/INTEGRATION-CHECKLIST.md +15 -14
- package/src/core/modules/tus/README.md +50 -44
- package/src/core/modules/user/core-user.service.ts +1 -2
- package/src/server/modules/auth/auth.module.ts +1 -9
- package/src/server/modules/better-auth/better-auth.resolver.ts +3 -1
- package/src/server/modules/error-code/README.md +19 -16
- package/src/server/modules/error-code/error-code.controller.ts +4 -1
- package/src/server/modules/file/file.resolver.ts +1 -1
- package/src/server/modules/file/file.service.ts +1 -3
- package/src/server/modules/user/user.resolver.ts +1 -1
- package/src/test/README.md +31 -27
- package/src/test/test.helper.ts +18 -10
|
@@ -79,6 +79,7 @@ const config = {
|
|
|
79
79
|
A complete working implementation exists in this package:
|
|
80
80
|
|
|
81
81
|
**Local (in your node_modules):**
|
|
82
|
+
|
|
82
83
|
```
|
|
83
84
|
node_modules/@lenne.tech/nest-server/src/server/modules/better-auth/
|
|
84
85
|
```
|
|
@@ -87,6 +88,7 @@ node_modules/@lenne.tech/nest-server/src/server/modules/better-auth/
|
|
|
87
88
|
https://github.com/lenneTech/nest-server/tree/develop/src/server/modules/better-auth
|
|
88
89
|
|
|
89
90
|
**UserService integration:**
|
|
91
|
+
|
|
90
92
|
- Local: `node_modules/@lenne.tech/nest-server/src/server/modules/user/user.service.ts`
|
|
91
93
|
- GitHub: https://github.com/lenneTech/nest-server/blob/develop/src/server/modules/user/user.service.ts
|
|
92
94
|
|
|
@@ -95,10 +97,12 @@ https://github.com/lenneTech/nest-server/tree/develop/src/server/modules/better-
|
|
|
95
97
|
## Project Integration Guide (Required Steps)
|
|
96
98
|
|
|
97
99
|
### Step 1: Create BetterAuth Module
|
|
100
|
+
|
|
98
101
|
**Create:** `src/server/modules/better-auth/better-auth.module.ts`
|
|
99
102
|
**Copy from:** Reference implementation (see above)
|
|
100
103
|
|
|
101
104
|
### Step 2: Create BetterAuth Resolver (CRITICAL!)
|
|
105
|
+
|
|
102
106
|
**Create:** `src/server/modules/better-auth/better-auth.resolver.ts`
|
|
103
107
|
**Copy from:** Reference implementation
|
|
104
108
|
|
|
@@ -108,21 +112,25 @@ GraphQL schema is built from decorators at compile time. The parent class (`Core
|
|
|
108
112
|
**Note:** `@UseGuards(AuthGuard(JWT))` is NOT needed when using `@Roles(S_USER)` or `@Roles(ADMIN)` because `RolesGuard` already extends `AuthGuard(JWT)` internally.
|
|
109
113
|
|
|
110
114
|
### Step 3: Create BetterAuth Controller
|
|
115
|
+
|
|
111
116
|
**Create:** `src/server/modules/better-auth/better-auth.controller.ts`
|
|
112
117
|
**Copy from:** Reference implementation
|
|
113
118
|
|
|
114
119
|
### Step 4: Inject BetterAuthUserMapper in UserService (CRITICAL!)
|
|
120
|
+
|
|
115
121
|
**Modify:** `src/server/modules/user/user.service.ts`
|
|
116
122
|
**Reference:** See UserService in reference implementation
|
|
117
123
|
|
|
118
124
|
**Required changes:**
|
|
119
125
|
|
|
120
126
|
1. Add import:
|
|
127
|
+
|
|
121
128
|
```typescript
|
|
122
129
|
import { CoreBetterAuthUserMapper } from '@lenne.tech/nest-server';
|
|
123
130
|
```
|
|
124
131
|
|
|
125
132
|
2. Add constructor parameter:
|
|
133
|
+
|
|
126
134
|
```typescript
|
|
127
135
|
@Optional() private readonly betterAuthUserMapper?: CoreBetterAuthUserMapper,
|
|
128
136
|
```
|
|
@@ -134,11 +142,13 @@ GraphQL schema is built from decorators at compile time. The parent class (`Core
|
|
|
134
142
|
|
|
135
143
|
**Why is this critical?**
|
|
136
144
|
The `CoreBetterAuthUserMapper` enables bidirectional password synchronization:
|
|
145
|
+
|
|
137
146
|
- User signs up via BetterAuth → password synced to Legacy Auth (bcrypt hash)
|
|
138
147
|
- User changes password → synced between both systems
|
|
139
148
|
- **Without this, users can only authenticate via ONE system!**
|
|
140
149
|
|
|
141
150
|
### Step 5: Import in ServerModule
|
|
151
|
+
|
|
142
152
|
**Modify:** `src/server/server.module.ts`
|
|
143
153
|
**Reference:** See ServerModule in reference implementation
|
|
144
154
|
|
|
@@ -152,6 +162,7 @@ CoreBetterAuthModule.forRoot({
|
|
|
152
162
|
```
|
|
153
163
|
|
|
154
164
|
### Step 6: Configure in config.env.ts
|
|
165
|
+
|
|
155
166
|
**Modify:** `src/config.env.ts`
|
|
156
167
|
**Reference:** See config.env.ts in reference implementation
|
|
157
168
|
|
|
@@ -162,6 +173,7 @@ Add `betterAuth` configuration block. See reference for all available options in
|
|
|
162
173
|
## Quick Reference
|
|
163
174
|
|
|
164
175
|
**Configuration formats:**
|
|
176
|
+
|
|
165
177
|
```typescript
|
|
166
178
|
betterAuth: true // Enable with all defaults (JWT enabled)
|
|
167
179
|
betterAuth: false // Disable completely
|
|
@@ -183,7 +195,7 @@ To **explicitly disable** Better-Auth:
|
|
|
183
195
|
|
|
184
196
|
```typescript
|
|
185
197
|
const config = {
|
|
186
|
-
betterAuth: false,
|
|
198
|
+
betterAuth: false, // or betterAuth: { enabled: false }
|
|
187
199
|
};
|
|
188
200
|
```
|
|
189
201
|
|
|
@@ -242,11 +254,11 @@ Read the security section below for production deployments.
|
|
|
242
254
|
|
|
243
255
|
### Configuration Summary
|
|
244
256
|
|
|
245
|
-
| Setting
|
|
246
|
-
|
|
|
247
|
-
| `baseUrl`
|
|
248
|
-
| `basePath`
|
|
249
|
-
| `passkey.origin`
|
|
257
|
+
| Setting | Technical Purpose | Impact of Wrong Value |
|
|
258
|
+
| ---------------- | ------------------ | --------------------------- |
|
|
259
|
+
| `baseUrl` | Email links, OAuth | Links point to wrong server |
|
|
260
|
+
| `basePath` | Endpoint routing | 404 on API calls |
|
|
261
|
+
| `passkey.origin` | WebAuthn security | Passkey auth fails |
|
|
250
262
|
|
|
251
263
|
**For Development:** The defaults (`http://localhost:3000`, `/iam`) are correct.
|
|
252
264
|
|
|
@@ -267,11 +279,12 @@ const config = {
|
|
|
267
279
|
|
|
268
280
|
// OR for local development - env: 'local' uses localhost defaults:
|
|
269
281
|
const localConfig = {
|
|
270
|
-
env: 'local',
|
|
282
|
+
env: 'local', // Uses API=localhost:3000, App=localhost:3001
|
|
271
283
|
};
|
|
272
284
|
```
|
|
273
285
|
|
|
274
286
|
**Benefits:**
|
|
287
|
+
|
|
275
288
|
- **One config per stage**: Only set `BASE_URL` in your environment
|
|
276
289
|
- **No duplication**: Passkey values derived automatically
|
|
277
290
|
- **Graceful Degradation**: If auto-detection fails (no baseUrl), Passkey is disabled with a warning - other auth methods (Email/Password, 2FA) continue to work
|
|
@@ -291,7 +304,7 @@ For production scenarios where you need full control:
|
|
|
291
304
|
|
|
292
305
|
```typescript
|
|
293
306
|
const config = {
|
|
294
|
-
baseUrl: 'https://api.your-domain.com',
|
|
307
|
+
baseUrl: 'https://api.your-domain.com', // Root-level
|
|
295
308
|
betterAuth: {
|
|
296
309
|
passkey: {
|
|
297
310
|
origin: 'https://your-domain.com', // Frontend domain (if different from API)
|
|
@@ -352,11 +365,11 @@ export BETTER_AUTH_SECRET="your-generated-secret-here"
|
|
|
352
365
|
|
|
353
366
|
### Secret Requirements
|
|
354
367
|
|
|
355
|
-
| Requirement
|
|
356
|
-
|
|
|
357
|
-
| Minimum length
|
|
358
|
-
| Recommended
|
|
359
|
-
| Character types
|
|
368
|
+
| Requirement | Value |
|
|
369
|
+
| --------------- | ----------------------------------------------------- |
|
|
370
|
+
| Minimum length | 32 characters |
|
|
371
|
+
| Recommended | 44+ characters (32 bytes base64) |
|
|
372
|
+
| Character types | At least 2 of: lowercase, uppercase, numbers, special |
|
|
360
373
|
|
|
361
374
|
### Configuration Examples
|
|
362
375
|
|
|
@@ -385,16 +398,17 @@ const config = {
|
|
|
385
398
|
|
|
386
399
|
The following table shows which features are active based on your configuration:
|
|
387
400
|
|
|
388
|
-
| Configuration
|
|
389
|
-
|
|
390
|
-
|
|
|
391
|
-
| `env: 'local'/'ci'/'e2e'` (auto URLs) |
|
|
392
|
-
| `baseUrl` set
|
|
393
|
-
| `betterAuth: false`
|
|
394
|
-
| `{ passkey: false }`
|
|
395
|
-
| `{ twoFactor: false }`
|
|
401
|
+
| Configuration | BetterAuth | JWT | 2FA | Passkey |
|
|
402
|
+
| ------------------------------------- | :--------: | :-: | :-: | :---------: |
|
|
403
|
+
| _not set_ (no URLs) | ✅ | ✅ | ✅ | ⚠️ disabled |
|
|
404
|
+
| `env: 'local'/'ci'/'e2e'` (auto URLs) | ✅ | ✅ | ✅ | ✅ auto |
|
|
405
|
+
| `baseUrl` set | ✅ | ✅ | ✅ | ✅ auto |
|
|
406
|
+
| `betterAuth: false` | ❌ | ❌ | ❌ | ❌ |
|
|
407
|
+
| `{ passkey: false }` | ✅ | ✅ | ✅ | ❌ |
|
|
408
|
+
| `{ twoFactor: false }` | ✅ | ✅ | ❌ | ✅ auto |
|
|
396
409
|
|
|
397
410
|
**Key points:**
|
|
411
|
+
|
|
398
412
|
- **BetterAuth** is enabled by default (zero-config)
|
|
399
413
|
- **JWT** is enabled by default (stateless authentication)
|
|
400
414
|
- **2FA/TOTP** is enabled by default (users can optionally set up 2FA)
|
|
@@ -406,20 +420,22 @@ The following table shows which features are active based on your configuration:
|
|
|
406
420
|
### URL Configuration (Important for Passkey!)
|
|
407
421
|
|
|
408
422
|
**Typical Architecture:**
|
|
423
|
+
|
|
409
424
|
- **API**: `https://api.example.com` (NestJS server)
|
|
410
425
|
- **App**: `https://example.com` (Frontend where browser runs)
|
|
411
426
|
|
|
412
427
|
**URL Resolution:**
|
|
413
428
|
|
|
414
|
-
| Config
|
|
415
|
-
|
|
416
|
-
| `env: 'local'/'ci'/'e2e'`
|
|
417
|
-
| `baseUrl: 'https://api.example.com'` | as set
|
|
418
|
-
| `baseUrl: 'https://example.com'`
|
|
419
|
-
| `appUrl: 'https://app.example.com'`
|
|
420
|
-
| Neither set
|
|
429
|
+
| Config | `baseUrl` (API) | `appUrl` (Frontend) | Passkey |
|
|
430
|
+
| ------------------------------------ | ----------------------- | ------------------------------------ | ----------- |
|
|
431
|
+
| `env: 'local'/'ci'/'e2e'` | `http://localhost:3000` | `http://localhost:3001` | ✅ auto |
|
|
432
|
+
| `baseUrl: 'https://api.example.com'` | as set | `https://example.com` (auto-derived) | ✅ auto |
|
|
433
|
+
| `baseUrl: 'https://example.com'` | as set | `https://example.com` (same) | ✅ auto |
|
|
434
|
+
| `appUrl: 'https://app.example.com'` | - | as set | ✅ auto |
|
|
435
|
+
| Neither set | - | - | ⚠️ disabled |
|
|
421
436
|
|
|
422
437
|
**Auto-Detection Logic:**
|
|
438
|
+
|
|
423
439
|
1. `appUrl` is derived from `baseUrl` by removing `api.` prefix
|
|
424
440
|
2. `rpId` is extracted from `appUrl` (e.g., `example.com`)
|
|
425
441
|
3. `origin` = `appUrl` (e.g., `https://example.com`)
|
|
@@ -445,14 +461,14 @@ export default {
|
|
|
445
461
|
// JWT Plugin - ENABLED BY DEFAULT (no config needed)
|
|
446
462
|
// Only add this block to customize or explicitly disable
|
|
447
463
|
jwt: {
|
|
448
|
-
expiresIn: '30m',
|
|
464
|
+
expiresIn: '30m', // Default: '15m'
|
|
449
465
|
// enabled: false, // Uncomment to disable JWT
|
|
450
466
|
},
|
|
451
467
|
|
|
452
468
|
// Two-Factor Authentication - ENABLED BY DEFAULT
|
|
453
469
|
// Only add this block to customize or explicitly disable
|
|
454
470
|
twoFactor: {
|
|
455
|
-
appName: 'My Application',
|
|
471
|
+
appName: 'My Application', // Default: 'Nest Server'
|
|
456
472
|
// enabled: false, // Uncomment to disable 2FA
|
|
457
473
|
},
|
|
458
474
|
|
|
@@ -510,10 +526,10 @@ const config = {
|
|
|
510
526
|
// Email verification is enabled by default
|
|
511
527
|
// To customize:
|
|
512
528
|
emailVerification: {
|
|
513
|
-
expiresIn: 86400,
|
|
514
|
-
template: 'custom-verify',
|
|
515
|
-
locale: 'en',
|
|
516
|
-
brevoTemplateId: 42,
|
|
529
|
+
expiresIn: 86400, // Token expiration in seconds (default: 24h)
|
|
530
|
+
template: 'custom-verify', // Custom template name
|
|
531
|
+
locale: 'en', // Template locale (default: 'de')
|
|
532
|
+
brevoTemplateId: 42, // Send via Brevo transactional API (optional)
|
|
517
533
|
},
|
|
518
534
|
// To disable:
|
|
519
535
|
emailVerification: false,
|
|
@@ -546,16 +562,20 @@ const config = {
|
|
|
546
562
|
When `termsAndPrivacyAccepted: true` is provided, `termsAndPrivacyAcceptedAt` is automatically stored in the user record.
|
|
547
563
|
|
|
548
564
|
**GraphQL Example:**
|
|
565
|
+
|
|
549
566
|
```graphql
|
|
550
567
|
mutation {
|
|
551
568
|
betterAuthSignUp(
|
|
552
569
|
email: "user@example.com"
|
|
553
570
|
password: "hashedPassword"
|
|
554
571
|
name: "User"
|
|
555
|
-
termsAndPrivacyAccepted: true
|
|
572
|
+
termsAndPrivacyAccepted: true # Required by default
|
|
556
573
|
) {
|
|
557
574
|
success
|
|
558
|
-
user {
|
|
575
|
+
user {
|
|
576
|
+
id
|
|
577
|
+
email
|
|
578
|
+
}
|
|
559
579
|
}
|
|
560
580
|
}
|
|
561
581
|
```
|
|
@@ -589,13 +609,15 @@ const config = {
|
|
|
589
609
|
```
|
|
590
610
|
|
|
591
611
|
When disabled:
|
|
612
|
+
|
|
592
613
|
- REST `POST /iam/sign-up/email` returns `400 Bad Request` with error `LTNS_0026`
|
|
593
614
|
- GraphQL `betterAuthSignUp` mutation returns error `LTNS_0026`
|
|
594
615
|
- `betterAuthFeatures` reports `signUpEnabled: false`
|
|
595
616
|
- Sign-in continues to work for existing users
|
|
596
617
|
|
|
597
618
|
**Defense in Depth:** The flag is enforced at two layers:
|
|
598
|
-
|
|
619
|
+
|
|
620
|
+
1. **Custom check** (`CoreBetterAuthService.ensureSignUpEnabled()`) runs in Controller/Resolver _before_ any BetterAuth API call and returns a structured `LTNS_0026` error.
|
|
599
621
|
2. **Native BetterAuth** `emailAndPassword.disableSignUp` acts as a safety net for any direct API access that bypasses the custom check.
|
|
600
622
|
|
|
601
623
|
**Default:** `false` (sign-up enabled) - fully backward compatible.
|
|
@@ -714,11 +736,11 @@ Better-Auth provides a rich plugin ecosystem. This module uses a **hybrid approa
|
|
|
714
736
|
|
|
715
737
|
### Built-in Plugins
|
|
716
738
|
|
|
717
|
-
| Plugin
|
|
718
|
-
|
|
|
719
|
-
| **JWT**
|
|
720
|
-
| **Two-Factor**
|
|
721
|
-
| **Passkey**
|
|
739
|
+
| Plugin | Default State | Config to Disable | Default Values |
|
|
740
|
+
| -------------- | ------------- | ------------------ | -------------------------------------------------------------- |
|
|
741
|
+
| **JWT** | **ENABLED** | `jwt: false` | `expiresIn: '15m'` |
|
|
742
|
+
| **Two-Factor** | **ENABLED** | `twoFactor: false` | `appName: 'Nest Server'` |
|
|
743
|
+
| **Passkey** | **ENABLED** | `passkey: false` | Auto-detected from `baseUrl`/`appUrl`, `rpName: 'Nest Server'` |
|
|
722
744
|
|
|
723
745
|
**All three plugins are enabled by default** - no configuration needed. Passkey requires resolvable URLs to function (via `baseUrl`, `appUrl`, or `env: 'local'/'ci'/'e2e'`). If URLs cannot be resolved, Passkey is disabled with a warning (graceful degradation).
|
|
724
746
|
|
|
@@ -727,14 +749,14 @@ Better-Auth provides a rich plugin ecosystem. This module uses a **hybrid approa
|
|
|
727
749
|
```typescript
|
|
728
750
|
const config = {
|
|
729
751
|
// JWT and 2FA are enabled automatically with BetterAuth
|
|
730
|
-
betterAuth: true,
|
|
752
|
+
betterAuth: true, // or betterAuth: {}
|
|
731
753
|
|
|
732
754
|
// Passkey is auto-activated when URLs can be resolved:
|
|
733
755
|
// Option 1: Set root-level baseUrl (production)
|
|
734
|
-
baseUrl: 'https://api.example.com',
|
|
756
|
+
baseUrl: 'https://api.example.com', // Passkey values auto-detected from this
|
|
735
757
|
|
|
736
758
|
// Option 2: Use env: 'local'/'ci'/'e2e' (development)
|
|
737
|
-
env: 'local',
|
|
759
|
+
env: 'local', // Uses localhost defaults: API=:3000, App=:3001
|
|
738
760
|
};
|
|
739
761
|
```
|
|
740
762
|
|
|
@@ -759,9 +781,9 @@ const config = {
|
|
|
759
781
|
```typescript
|
|
760
782
|
const config = {
|
|
761
783
|
betterAuth: {
|
|
762
|
-
jwt: false,
|
|
763
|
-
twoFactor: false,
|
|
764
|
-
passkey: false,
|
|
784
|
+
jwt: false, // Disable JWT (or jwt: { enabled: false })
|
|
785
|
+
twoFactor: false, // Disable 2FA (or twoFactor: { enabled: false })
|
|
786
|
+
passkey: false, // Disable Passkey (or passkey: { enabled: false })
|
|
765
787
|
},
|
|
766
788
|
};
|
|
767
789
|
```
|
|
@@ -803,16 +825,16 @@ const config = {
|
|
|
803
825
|
|
|
804
826
|
### Available Better-Auth Plugins
|
|
805
827
|
|
|
806
|
-
| Plugin
|
|
807
|
-
|
|
|
808
|
-
| **organization**
|
|
809
|
-
| **admin**
|
|
810
|
-
| **multiSession**
|
|
811
|
-
| **apiKey**
|
|
812
|
-
| **sso**
|
|
813
|
-
| **oidcProvider**
|
|
814
|
-
| **genericOAuth**
|
|
815
|
-
| **polar**
|
|
828
|
+
| Plugin | Use Case | Recommendation |
|
|
829
|
+
| ---------------- | -------------------------------------------- | -------------------------- |
|
|
830
|
+
| **organization** | Multi-tenant apps, teams, member management | Common for SaaS/B2B |
|
|
831
|
+
| **admin** | User impersonation, banning, user management | Common for admin panels |
|
|
832
|
+
| **multiSession** | Multiple active sessions per user | Account switching apps |
|
|
833
|
+
| **apiKey** | API key based authentication | Public APIs |
|
|
834
|
+
| **sso** | Single Sign-On (OIDC, SAML 2.0) | Enterprise apps |
|
|
835
|
+
| **oidcProvider** | Build your own identity provider | Identity platforms |
|
|
836
|
+
| **genericOAuth** | Custom OAuth providers | Special OAuth integrations |
|
|
837
|
+
| **polar** | Usage-based billing with Polar | SaaS billing |
|
|
816
838
|
|
|
817
839
|
For the complete list of plugins, see:
|
|
818
840
|
|
|
@@ -885,10 +907,10 @@ const config = {
|
|
|
885
907
|
|
|
886
908
|
### Why This Hybrid Approach?
|
|
887
909
|
|
|
888
|
-
| Approach
|
|
889
|
-
|
|
|
890
|
-
| **Built-in** (jwt, 2fa, passkey)
|
|
891
|
-
| **Dynamic** (plugins array)
|
|
910
|
+
| Approach | Pros | Cons |
|
|
911
|
+
| -------------------------------- | ------------------------------------------------- | --------------------------------- |
|
|
912
|
+
| **Built-in** (jwt, 2fa, passkey) | TypeScript types, IDE autocomplete, documentation | Package update needed for changes |
|
|
913
|
+
| **Dynamic** (plugins array) | Any plugin works immediately, future-proof | No typed config in IBetterAuth |
|
|
892
914
|
|
|
893
915
|
**Best of both worlds:**
|
|
894
916
|
|
|
@@ -936,9 +958,9 @@ To explicitly disable Better-Auth:
|
|
|
936
958
|
|
|
937
959
|
```typescript
|
|
938
960
|
const config = {
|
|
939
|
-
betterAuth: false,
|
|
961
|
+
betterAuth: false, // Simple boolean
|
|
940
962
|
// or
|
|
941
|
-
betterAuth: { enabled: false },
|
|
963
|
+
betterAuth: { enabled: false }, // Allows pre-configuration
|
|
942
964
|
};
|
|
943
965
|
```
|
|
944
966
|
|
|
@@ -946,28 +968,30 @@ const config = {
|
|
|
946
968
|
|
|
947
969
|
When enabled, Better-Auth exposes the following endpoints at the configured `basePath` (default: `/iam`):
|
|
948
970
|
|
|
949
|
-
| Endpoint
|
|
950
|
-
|
|
|
951
|
-
| `/iam/sign-up/email`
|
|
952
|
-
| `/iam/sign-in/email`
|
|
953
|
-
| `/iam/sign-out`
|
|
954
|
-
| `/iam/session`
|
|
955
|
-
| `/iam/token`
|
|
956
|
-
| `/iam/forgot-password`
|
|
957
|
-
| `/iam/reset-password`
|
|
958
|
-
| `/iam/verify-email`
|
|
971
|
+
| Endpoint | Method | Description |
|
|
972
|
+
| ---------------------- | ------ | ----------------------------- |
|
|
973
|
+
| `/iam/sign-up/email` | POST | Register new user |
|
|
974
|
+
| `/iam/sign-in/email` | POST | Sign in with email/password |
|
|
975
|
+
| `/iam/sign-out` | GET | Sign out (invalidate session) |
|
|
976
|
+
| `/iam/session` | GET | Get current session |
|
|
977
|
+
| `/iam/token` | GET | Get fresh JWT token |
|
|
978
|
+
| `/iam/forgot-password` | POST | Request password reset |
|
|
979
|
+
| `/iam/reset-password` | POST | Reset password with token |
|
|
980
|
+
| `/iam/verify-email` | POST | Verify email address |
|
|
959
981
|
|
|
960
982
|
### JWT Token Endpoint
|
|
961
983
|
|
|
962
984
|
The `/iam/token` endpoint returns a fresh JWT token for the current session. Use this when your JWT has expired but your session is still valid.
|
|
963
985
|
|
|
964
986
|
**Request:**
|
|
987
|
+
|
|
965
988
|
```bash
|
|
966
989
|
curl -X GET https://api.example.com/iam/token \
|
|
967
990
|
-H "Cookie: better-auth.session_token=..."
|
|
968
991
|
```
|
|
969
992
|
|
|
970
993
|
**Response:**
|
|
994
|
+
|
|
971
995
|
```json
|
|
972
996
|
{
|
|
973
997
|
"token": "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCIsImtpZCI6Ii4uLiJ9..."
|
|
@@ -978,36 +1002,36 @@ curl -X GET https://api.example.com/iam/token \
|
|
|
978
1002
|
|
|
979
1003
|
### Social Login Endpoints
|
|
980
1004
|
|
|
981
|
-
| Endpoint
|
|
982
|
-
|
|
|
983
|
-
| `/iam/sign-in/social`
|
|
984
|
-
| `/iam/callback/:provider`
|
|
1005
|
+
| Endpoint | Method | Description |
|
|
1006
|
+
| ------------------------- | ------ | --------------------- |
|
|
1007
|
+
| `/iam/sign-in/social` | POST | Initiate social login |
|
|
1008
|
+
| `/iam/callback/:provider` | GET | OAuth callback |
|
|
985
1009
|
|
|
986
1010
|
### Two-Factor Authentication Endpoints (Native Better Auth)
|
|
987
1011
|
|
|
988
1012
|
These endpoints are handled by Better Auth's native `twoFactor` plugin:
|
|
989
1013
|
|
|
990
|
-
| Endpoint
|
|
991
|
-
|
|
|
992
|
-
| `/iam/two-factor/enable`
|
|
993
|
-
| `/iam/two-factor/disable`
|
|
994
|
-
| `/iam/two-factor/verify-totp`
|
|
995
|
-
| `/iam/two-factor/generate-backup-codes` | POST
|
|
996
|
-
| `/iam/two-factor/verify-backup-code
|
|
1014
|
+
| Endpoint | Method | Description |
|
|
1015
|
+
| --------------------------------------- | ------ | ------------------------ |
|
|
1016
|
+
| `/iam/two-factor/enable` | POST | Enable 2FA, get TOTP URI |
|
|
1017
|
+
| `/iam/two-factor/disable` | POST | Disable 2FA |
|
|
1018
|
+
| `/iam/two-factor/verify-totp` | POST | Verify TOTP code |
|
|
1019
|
+
| `/iam/two-factor/generate-backup-codes` | POST | Generate backup codes |
|
|
1020
|
+
| `/iam/two-factor/verify-backup-code` | POST | Verify backup code |
|
|
997
1021
|
|
|
998
1022
|
### Passkey Endpoints (Native Better Auth)
|
|
999
1023
|
|
|
1000
1024
|
These endpoints are handled by Better Auth's native `passkey` plugin:
|
|
1001
1025
|
|
|
1002
|
-
| Endpoint
|
|
1003
|
-
|
|
|
1004
|
-
| `/iam/passkey/generate-register-options`
|
|
1005
|
-
| `/iam/passkey/verify-registration`
|
|
1006
|
-
| `/iam/passkey/generate-authenticate-options` | POST
|
|
1007
|
-
| `/iam/passkey/verify-authentication`
|
|
1008
|
-
| `/iam/passkey/list-user-passkeys`
|
|
1009
|
-
| `/iam/passkey/delete-passkey`
|
|
1010
|
-
| `/iam/passkey/update-passkey`
|
|
1026
|
+
| Endpoint | Method | Description |
|
|
1027
|
+
| -------------------------------------------- | ------ | ----------------------------------- |
|
|
1028
|
+
| `/iam/passkey/generate-register-options` | POST | Get WebAuthn registration options |
|
|
1029
|
+
| `/iam/passkey/verify-registration` | POST | Verify and store passkey |
|
|
1030
|
+
| `/iam/passkey/generate-authenticate-options` | POST | Get WebAuthn authentication options |
|
|
1031
|
+
| `/iam/passkey/verify-authentication` | POST | Verify passkey authentication |
|
|
1032
|
+
| `/iam/passkey/list-user-passkeys` | POST | List user's passkeys |
|
|
1033
|
+
| `/iam/passkey/delete-passkey` | POST | Delete a passkey |
|
|
1034
|
+
| `/iam/passkey/update-passkey` | POST | Update passkey name |
|
|
1011
1035
|
|
|
1012
1036
|
## GraphQL API
|
|
1013
1037
|
|
|
@@ -1015,42 +1039,42 @@ In addition to REST endpoints, Better-Auth provides GraphQL queries and mutation
|
|
|
1015
1039
|
|
|
1016
1040
|
### Queries
|
|
1017
1041
|
|
|
1018
|
-
| Query
|
|
1019
|
-
|
|
|
1020
|
-
| `betterAuthEnabled`
|
|
1021
|
-
| `betterAuthFeatures`
|
|
1022
|
-
| `betterAuthSession`
|
|
1023
|
-
| `betterAuthToken`
|
|
1024
|
-
| `betterAuthListPasskeys`
|
|
1025
|
-
| `betterAuthMigrationStatus` | -
|
|
1042
|
+
| Query | Arguments | Return Type | Description |
|
|
1043
|
+
| --------------------------- | --------- | -------------------------------- | -------------------------------- |
|
|
1044
|
+
| `betterAuthEnabled` | - | `Boolean` | Check if Better-Auth is enabled |
|
|
1045
|
+
| `betterAuthFeatures` | - | `BetterAuthFeaturesModel` | Get enabled features status |
|
|
1046
|
+
| `betterAuthSession` | - | `BetterAuthSessionModel` | Get current session (auth req.) |
|
|
1047
|
+
| `betterAuthToken` | - | `String` | Get fresh JWT token (auth req.) |
|
|
1048
|
+
| `betterAuthListPasskeys` | - | `[BetterAuthPasskeyModel]` | List user's passkeys (auth req.) |
|
|
1049
|
+
| `betterAuthMigrationStatus` | - | `BetterAuthMigrationStatusModel` | Migration status (admin only) |
|
|
1026
1050
|
|
|
1027
1051
|
### Mutations
|
|
1028
1052
|
|
|
1029
1053
|
#### Authentication
|
|
1030
1054
|
|
|
1031
|
-
| Mutation | Arguments
|
|
1032
|
-
| --------------------- |
|
|
1033
|
-
| `betterAuthSignIn` | `email`, `password`
|
|
1034
|
-
| `betterAuthSignUp` | `email`, `password`, `name?`, `termsAndPrivacyAccepted?` | `BetterAuthAuthModel
|
|
1035
|
-
| `betterAuthSignOut` | -
|
|
1036
|
-
| `betterAuthVerify2FA` | `code`
|
|
1055
|
+
| Mutation | Arguments | Return Type | Description |
|
|
1056
|
+
| --------------------- | -------------------------------------------------------- | --------------------- | ------------------------ |
|
|
1057
|
+
| `betterAuthSignIn` | `email`, `password` | `BetterAuthAuthModel` | Sign in with email/pass |
|
|
1058
|
+
| `betterAuthSignUp` | `email`, `password`, `name?`, `termsAndPrivacyAccepted?` | `BetterAuthAuthModel` | Register new account |
|
|
1059
|
+
| `betterAuthSignOut` | - | `Boolean` | Sign out (requires auth) |
|
|
1060
|
+
| `betterAuthVerify2FA` | `code` | `BetterAuthAuthModel` | Verify 2FA code |
|
|
1037
1061
|
|
|
1038
1062
|
**Note (v11.13.0+):** `termsAndPrivacyAccepted` is required by default. Set `signUpChecks: false` to disable.
|
|
1039
1063
|
|
|
1040
1064
|
#### 2FA Management (requires authentication)
|
|
1041
1065
|
|
|
1042
|
-
| Mutation
|
|
1043
|
-
|
|
|
1044
|
-
| `betterAuthEnable2FA`
|
|
1045
|
-
| `betterAuthDisable2FA`
|
|
1046
|
-
| `betterAuthGenerateBackupCodes
|
|
1066
|
+
| Mutation | Arguments | Return Type | Description |
|
|
1067
|
+
| ------------------------------- | ---------- | ------------------------- | ------------------------- |
|
|
1068
|
+
| `betterAuthEnable2FA` | `password` | `BetterAuth2FASetupModel` | Enable 2FA, get TOTP URI |
|
|
1069
|
+
| `betterAuthDisable2FA` | `password` | `Boolean` | Disable 2FA for user |
|
|
1070
|
+
| `betterAuthGenerateBackupCodes` | - | `[String]` | Generate new backup codes |
|
|
1047
1071
|
|
|
1048
1072
|
#### Passkey Management (requires authentication)
|
|
1049
1073
|
|
|
1050
|
-
| Mutation
|
|
1051
|
-
|
|
|
1052
|
-
| `betterAuthGetPasskeyChallenge
|
|
1053
|
-
| `betterAuthDeletePasskey`
|
|
1074
|
+
| Mutation | Arguments | Return Type | Description |
|
|
1075
|
+
| ------------------------------- | ----------- | --------------------------------- | ---------------------- |
|
|
1076
|
+
| `betterAuthGetPasskeyChallenge` | - | `BetterAuthPasskeyChallengeModel` | Get WebAuthn challenge |
|
|
1077
|
+
| `betterAuthDeletePasskey` | `passkeyId` | `Boolean` | Delete a passkey |
|
|
1054
1078
|
|
|
1055
1079
|
### Response Types
|
|
1056
1080
|
|
|
@@ -1266,23 +1290,23 @@ export class MyService {
|
|
|
1266
1290
|
|
|
1267
1291
|
### Available Methods
|
|
1268
1292
|
|
|
1269
|
-
| Method
|
|
1270
|
-
|
|
|
1271
|
-
| `isEnabled()`
|
|
1272
|
-
| `getInstance()`
|
|
1273
|
-
| `getApi()`
|
|
1274
|
-
| `getConfig()`
|
|
1275
|
-
| `isJwtEnabled()`
|
|
1276
|
-
| `isTwoFactorEnabled()`
|
|
1277
|
-
| `isPasskeyEnabled()`
|
|
1278
|
-
| `isSignUpEnabled()`
|
|
1279
|
-
| `getEnabledSocialProviders()`
|
|
1280
|
-
| `getBasePath()`
|
|
1281
|
-
| `getBaseUrl()`
|
|
1282
|
-
| `getSession(req)`
|
|
1283
|
-
| `revokeSession(token)`
|
|
1284
|
-
| `isSessionExpiringSoon(session, t?)
|
|
1285
|
-
| `getSessionTimeRemaining(session)`
|
|
1293
|
+
| Method | Description |
|
|
1294
|
+
| ------------------------------------ | ------------------------------------- |
|
|
1295
|
+
| `isEnabled()` | Check if Better-Auth is enabled |
|
|
1296
|
+
| `getInstance()` | Get the Better-Auth instance |
|
|
1297
|
+
| `getApi()` | Get the Better-Auth API |
|
|
1298
|
+
| `getConfig()` | Get the current configuration |
|
|
1299
|
+
| `isJwtEnabled()` | Check if JWT plugin is enabled |
|
|
1300
|
+
| `isTwoFactorEnabled()` | Check if 2FA is enabled |
|
|
1301
|
+
| `isPasskeyEnabled()` | Check if Passkey is enabled |
|
|
1302
|
+
| `isSignUpEnabled()` | Check if sign-up is enabled |
|
|
1303
|
+
| `getEnabledSocialProviders()` | Get list of enabled social providers |
|
|
1304
|
+
| `getBasePath()` | Get the base path for endpoints |
|
|
1305
|
+
| `getBaseUrl()` | Get the base URL |
|
|
1306
|
+
| `getSession(req)` | Get current session from request |
|
|
1307
|
+
| `revokeSession(token)` | Revoke a session (logout) |
|
|
1308
|
+
| `isSessionExpiringSoon(session, t?)` | Check if session is expiring soon |
|
|
1309
|
+
| `getSessionTimeRemaining(session)` | Get remaining session time in seconds |
|
|
1286
1310
|
|
|
1287
1311
|
## Security Integration
|
|
1288
1312
|
|
|
@@ -1302,12 +1326,12 @@ async findAllUsers() {
|
|
|
1302
1326
|
|
|
1303
1327
|
### Special Roles
|
|
1304
1328
|
|
|
1305
|
-
| Role
|
|
1306
|
-
|
|
|
1307
|
-
| `S_EVERYONE`
|
|
1308
|
-
| `S_USER`
|
|
1309
|
-
| `S_VERIFIED`
|
|
1310
|
-
| `S_NO_ONE`
|
|
1329
|
+
| Role | Description |
|
|
1330
|
+
| ------------ | ------------------------------------- |
|
|
1331
|
+
| `S_EVERYONE` | Accessible by everyone (no auth req.) |
|
|
1332
|
+
| `S_USER` | Any authenticated user |
|
|
1333
|
+
| `S_VERIFIED` | Users with verified email |
|
|
1334
|
+
| `S_NO_ONE` | Never accessible |
|
|
1311
1335
|
|
|
1312
1336
|
### How It Works
|
|
1313
1337
|
|
|
@@ -1348,17 +1372,17 @@ export class MyService {
|
|
|
1348
1372
|
|
|
1349
1373
|
### Mapped User Properties
|
|
1350
1374
|
|
|
1351
|
-
| Property | Type
|
|
1352
|
-
| ----------------------------- |
|
|
1353
|
-
| `id` | string
|
|
1354
|
-
| `iamId` | string
|
|
1355
|
-
| `email` | string
|
|
1356
|
-
| `name` | string
|
|
1357
|
-
| `roles` | string[]
|
|
1358
|
-
| `verified` | boolean
|
|
1359
|
-
| `emailVerified` | boolean
|
|
1360
|
-
| `hasRole(roles)` | function
|
|
1361
|
-
| `_authenticatedViaBetterAuth` | true
|
|
1375
|
+
| Property | Type | Description |
|
|
1376
|
+
| ----------------------------- | -------- | ----------------------------------------------------- |
|
|
1377
|
+
| `id` | string | User ID (from database or Better-Auth ID as fallback) |
|
|
1378
|
+
| `iamId` | string | IAM provider user ID (e.g., Better-Auth) |
|
|
1379
|
+
| `email` | string | User email |
|
|
1380
|
+
| `name` | string | User display name |
|
|
1381
|
+
| `roles` | string[] | User roles from database |
|
|
1382
|
+
| `verified` | boolean | Whether user is verified |
|
|
1383
|
+
| `emailVerified` | boolean | Better-Auth email verification status |
|
|
1384
|
+
| `hasRole(roles)` | function | Check if user has any of the specified roles |
|
|
1385
|
+
| `_authenticatedViaBetterAuth` | true | Marker for Better-Auth authenticated users |
|
|
1362
1386
|
|
|
1363
1387
|
## CoreModule.forRoot() Signatures
|
|
1364
1388
|
|
|
@@ -1381,11 +1405,13 @@ export class ServerModule {}
|
|
|
1381
1405
|
```
|
|
1382
1406
|
|
|
1383
1407
|
**Features:**
|
|
1408
|
+
|
|
1384
1409
|
- Simplified setup - no Legacy Auth overhead
|
|
1385
1410
|
- GraphQL Subscription authentication via BetterAuth sessions
|
|
1386
1411
|
- BetterAuthModule is auto-registered when using this signature
|
|
1387
1412
|
|
|
1388
1413
|
**Requirements:**
|
|
1414
|
+
|
|
1389
1415
|
- Create BetterAuthModule, Resolver, and Controller in your project
|
|
1390
1416
|
- Inject BetterAuthUserMapper in UserService
|
|
1391
1417
|
- Set `auth.legacyEndpoints.enabled: false` in config
|
|
@@ -1410,6 +1436,7 @@ export class ServerModule {}
|
|
|
1410
1436
|
> Use the single-parameter signature for new projects.
|
|
1411
1437
|
|
|
1412
1438
|
**Features:**
|
|
1439
|
+
|
|
1413
1440
|
- Both Legacy Auth and BetterAuth run in parallel
|
|
1414
1441
|
- Bidirectional password synchronization
|
|
1415
1442
|
- Gradual user migration to IAM
|
|
@@ -1430,11 +1457,11 @@ BetterAuth supports extensive customization through inheritance and configuratio
|
|
|
1430
1457
|
|
|
1431
1458
|
### Quick Reference: Registration Patterns
|
|
1432
1459
|
|
|
1433
|
-
| Pattern
|
|
1434
|
-
|
|
1435
|
-
| **Zero-Config**
|
|
1436
|
-
| **Config-based**
|
|
1437
|
-
| **Separate Module** | Full control, additional providers | `betterAuth: { autoRegister: false }`
|
|
1460
|
+
| Pattern | Use When | Configuration |
|
|
1461
|
+
| ------------------- | ---------------------------------- | -------------------------------------- |
|
|
1462
|
+
| **Zero-Config** | No customization | `CoreModule.forRoot(envConfig)` |
|
|
1463
|
+
| **Config-based** | Custom Controller/Resolver | `betterAuth: { controller, resolver }` |
|
|
1464
|
+
| **Separate Module** | Full control, additional providers | `betterAuth: { autoRegister: false }` |
|
|
1438
1465
|
|
|
1439
1466
|
---
|
|
1440
1467
|
|
|
@@ -1444,11 +1471,11 @@ Better-Auth is designed as the successor to Legacy Auth. This section describes
|
|
|
1444
1471
|
|
|
1445
1472
|
### Scenario Overview
|
|
1446
1473
|
|
|
1447
|
-
| Scenario
|
|
1448
|
-
|
|
1474
|
+
| Scenario | Signature | Description |
|
|
1475
|
+
| ------------------ | ----------- | ------------------------------------- |
|
|
1449
1476
|
| **1. Legacy Only** | 3-parameter | Existing projects, no IAM integration |
|
|
1450
|
-
| **2. Migration**
|
|
1451
|
-
| **3. IAM Only**
|
|
1477
|
+
| **2. Migration** | 3-parameter | Legacy + IAM parallel operation |
|
|
1478
|
+
| **3. IAM Only** | 1-parameter | New projects, BetterAuth only |
|
|
1452
1479
|
|
|
1453
1480
|
### Migration Steps (Scenario 2)
|
|
1454
1481
|
|
|
@@ -1457,6 +1484,7 @@ Better-Auth is designed as the successor to Legacy Auth. This section describes
|
|
|
1457
1484
|
- Both systems run in parallel
|
|
1458
1485
|
|
|
1459
1486
|
2. **Monitor Migration Progress**
|
|
1487
|
+
|
|
1460
1488
|
```graphql
|
|
1461
1489
|
query {
|
|
1462
1490
|
betterAuthMigrationStatus {
|
|
@@ -1468,33 +1496,36 @@ Better-Auth is designed as the successor to Legacy Auth. This section describes
|
|
|
1468
1496
|
}
|
|
1469
1497
|
}
|
|
1470
1498
|
```
|
|
1499
|
+
|
|
1471
1500
|
Users migrate automatically when signing in via BetterAuth (IAM).
|
|
1472
1501
|
|
|
1473
1502
|
3. **Disable Legacy Endpoints** (when `canDisableLegacyAuth: true`)
|
|
1503
|
+
|
|
1474
1504
|
```typescript
|
|
1475
1505
|
// config.env.ts
|
|
1476
1506
|
auth: {
|
|
1477
1507
|
legacyEndpoints: {
|
|
1478
|
-
enabled: false
|
|
1508
|
+
enabled: false; // Disables signIn, signUp, logout, refreshToken
|
|
1479
1509
|
}
|
|
1480
1510
|
}
|
|
1481
1511
|
```
|
|
1482
1512
|
|
|
1483
1513
|
4. **Switch to IAM-Only Signature** (optional)
|
|
1514
|
+
|
|
1484
1515
|
```typescript
|
|
1485
1516
|
// Before (deprecated)
|
|
1486
|
-
CoreModule.forRoot(AuthService, AuthModule.forRoot(envConfig.jwt), envConfig)
|
|
1517
|
+
CoreModule.forRoot(AuthService, AuthModule.forRoot(envConfig.jwt), envConfig);
|
|
1487
1518
|
|
|
1488
1519
|
// After (recommended)
|
|
1489
|
-
CoreModule.forRoot(envConfig)
|
|
1520
|
+
CoreModule.forRoot(envConfig);
|
|
1490
1521
|
```
|
|
1491
1522
|
|
|
1492
1523
|
### Why No Automatic Migration Script?
|
|
1493
1524
|
|
|
1494
|
-
| System
|
|
1495
|
-
|
|
1525
|
+
| System | Password Hash Algorithm |
|
|
1526
|
+
| ----------- | -------------------------- |
|
|
1496
1527
|
| Legacy Auth | `bcrypt(sha256(password))` |
|
|
1497
|
-
| BetterAuth
|
|
1528
|
+
| BetterAuth | `scrypt(sha256(password))` |
|
|
1498
1529
|
|
|
1499
1530
|
These are **one-way hashes** - there's no way to convert between them without the plain password.
|
|
1500
1531
|
Users must sign in at least once via BetterAuth to create a compatible hash.
|
|
@@ -1530,19 +1561,19 @@ const legacyToken = await authService.signIn({ email, password });
|
|
|
1530
1561
|
|
|
1531
1562
|
### Compatibility Matrix
|
|
1532
1563
|
|
|
1533
|
-
| Scenario
|
|
1534
|
-
|
|
|
1535
|
-
| Legacy user → Legacy login
|
|
1536
|
-
| Legacy user → Better-Auth login
|
|
1537
|
-
| Better-Auth user → Better-Auth
|
|
1538
|
-
| Better-Auth user → Legacy login
|
|
1539
|
-
| Social-only user → Legacy login
|
|
1564
|
+
| Scenario | Result |
|
|
1565
|
+
| ------------------------------- | -------------------------------- |
|
|
1566
|
+
| Legacy user → Legacy login | Works |
|
|
1567
|
+
| Legacy user → Better-Auth login | Works (bcrypt compatible) |
|
|
1568
|
+
| Better-Auth user → Better-Auth | Works |
|
|
1569
|
+
| Better-Auth user → Legacy login | Works (password field preserved) |
|
|
1570
|
+
| Social-only user → Legacy login | Fails (no password field) |
|
|
1540
1571
|
|
|
1541
1572
|
### User Database Fields
|
|
1542
1573
|
|
|
1543
|
-
| Field | Purpose
|
|
1544
|
-
| ---------- |
|
|
1545
|
-
| `password` | Password hash (bcrypt) - used by both systems
|
|
1574
|
+
| Field | Purpose |
|
|
1575
|
+
| ---------- | ----------------------------------------------------- |
|
|
1576
|
+
| `password` | Password hash (bcrypt) - used by both systems |
|
|
1546
1577
|
| `iamId` | IAM provider user ID (set on first Better-Auth login) |
|
|
1547
1578
|
|
|
1548
1579
|
**No migration is required** - users can authenticate with either system immediately.
|
|
@@ -1555,13 +1586,13 @@ When both Legacy Auth and BetterAuth (IAM) are active, passwords are automatical
|
|
|
1555
1586
|
|
|
1556
1587
|
### How Password Sync Works
|
|
1557
1588
|
|
|
1558
|
-
| Scenario
|
|
1559
|
-
|
|
1560
|
-
| Sign up via BetterAuth
|
|
1561
|
-
| Sign up via Legacy Auth
|
|
1562
|
-
| Password reset via Legacy
|
|
1563
|
-
| Password reset via BetterAuth
|
|
1564
|
-
| Password change via user update | Legacy | IAM
|
|
1589
|
+
| Scenario | Source | Target | Auto-Synced? |
|
|
1590
|
+
| ------------------------------- | ------ | ------ | ----------------------- |
|
|
1591
|
+
| Sign up via BetterAuth | IAM | Legacy | ✅ Yes |
|
|
1592
|
+
| Sign up via Legacy Auth | Legacy | IAM | ⚠️ On first IAM sign-in |
|
|
1593
|
+
| Password reset via Legacy | Legacy | IAM | ✅ Yes |
|
|
1594
|
+
| Password reset via BetterAuth | IAM | Legacy | ⚠️ See below |
|
|
1595
|
+
| Password change via user update | Legacy | IAM | ✅ Yes |
|
|
1565
1596
|
|
|
1566
1597
|
#### IAM Password Reset → Legacy Sync
|
|
1567
1598
|
|
|
@@ -1583,16 +1614,21 @@ When a user resets their password via BetterAuth's native `/iam/reset-password`
|
|
|
1583
1614
|
The following sync operations happen automatically when `CoreBetterAuthUserMapper` is injected in `UserService`:
|
|
1584
1615
|
|
|
1585
1616
|
#### 1. IAM Sign-Up → Legacy
|
|
1617
|
+
|
|
1586
1618
|
When a user signs up via BetterAuth (`/iam/sign-up/email`), the password is hashed with bcrypt and stored in `users.password`, enabling Legacy Auth sign-in.
|
|
1587
1619
|
|
|
1588
1620
|
#### 2. Legacy Password Reset → IAM
|
|
1621
|
+
|
|
1589
1622
|
When a user resets their password via `CoreUserService.resetPassword()`, the new password is synced to the BetterAuth `account` collection (if the user has a credential account).
|
|
1590
1623
|
|
|
1591
1624
|
#### 3. Legacy Password Update → IAM
|
|
1625
|
+
|
|
1592
1626
|
When a user changes their password via `UserService.update()`, the new password is synced to BetterAuth (if the user has a credential account).
|
|
1593
1627
|
|
|
1594
1628
|
#### 4. Legacy → IAM Migration (On First Sign-In)
|
|
1629
|
+
|
|
1595
1630
|
When a legacy user signs in via BetterAuth for the first time, their account is migrated:
|
|
1631
|
+
|
|
1596
1632
|
- Their `iamId` is set
|
|
1597
1633
|
- A credential account is created in the `account` collection with the scrypt hash
|
|
1598
1634
|
|
|
@@ -1630,10 +1666,10 @@ betterAuth: {
|
|
|
1630
1666
|
|
|
1631
1667
|
### Password Hashing Algorithms
|
|
1632
1668
|
|
|
1633
|
-
| System
|
|
1634
|
-
|
|
1635
|
-
| Legacy Auth
|
|
1636
|
-
| BetterAuth (IAM) | scrypt
|
|
1669
|
+
| System | Algorithm | Format |
|
|
1670
|
+
| ---------------- | ------------------------ | ------------------------- |
|
|
1671
|
+
| Legacy Auth | bcrypt(sha256(password)) | `$2b$10$...` (60 chars) |
|
|
1672
|
+
| BetterAuth (IAM) | scrypt | `salt:hash` (hex encoded) |
|
|
1637
1673
|
|
|
1638
1674
|
**Important:** These hashes are NOT interchangeable. Password sync requires re-hashing the plain password with the target algorithm.
|
|
1639
1675
|
|
|
@@ -1641,25 +1677,26 @@ betterAuth: {
|
|
|
1641
1677
|
|
|
1642
1678
|
Email changes are also synchronized bidirectionally:
|
|
1643
1679
|
|
|
1644
|
-
| Scenario
|
|
1645
|
-
|
|
1680
|
+
| Scenario | Effect |
|
|
1681
|
+
| ------------------------------------------------- | ----------------------------------------- |
|
|
1646
1682
|
| Email changed via Legacy (`UserService.update()`) | IAM sessions invalidated (forces re-auth) |
|
|
1647
|
-
| Email changed via IAM
|
|
1683
|
+
| Email changed via IAM | Legacy refresh tokens cleared |
|
|
1648
1684
|
|
|
1649
1685
|
### User Deletion Cleanup
|
|
1650
1686
|
|
|
1651
1687
|
When a user is deleted:
|
|
1652
1688
|
|
|
1653
|
-
| Via
|
|
1654
|
-
|
|
1689
|
+
| Via | Effect |
|
|
1690
|
+
| ------------------------------- | ---------------------------------------- |
|
|
1655
1691
|
| Legacy (`UserService.delete()`) | IAM accounts and sessions are cleaned up |
|
|
1656
|
-
| IAM
|
|
1692
|
+
| IAM | Legacy user record is removed |
|
|
1657
1693
|
|
|
1658
1694
|
### Troubleshooting Password Sync
|
|
1659
1695
|
|
|
1660
1696
|
#### Password not syncing to IAM
|
|
1661
1697
|
|
|
1662
1698
|
1. Verify `CoreBetterAuthUserMapper` is injected in `UserService`:
|
|
1699
|
+
|
|
1663
1700
|
```typescript
|
|
1664
1701
|
constructor(
|
|
1665
1702
|
@Optional() private readonly betterAuthUserMapper?: CoreBetterAuthUserMapper,
|
|
@@ -1669,9 +1706,10 @@ When a user is deleted:
|
|
|
1669
1706
|
```
|
|
1670
1707
|
|
|
1671
1708
|
2. Check if user has an IAM credential account:
|
|
1709
|
+
|
|
1672
1710
|
```javascript
|
|
1673
1711
|
// MongoDB query
|
|
1674
|
-
db.account.findOne({ userId: ObjectId(
|
|
1712
|
+
db.account.findOne({ userId: ObjectId('...'), providerId: 'credential' });
|
|
1675
1713
|
```
|
|
1676
1714
|
|
|
1677
1715
|
3. Check server logs for sync warnings:
|
|
@@ -1840,14 +1878,14 @@ const config = {
|
|
|
1840
1878
|
|
|
1841
1879
|
### Configuration Options
|
|
1842
1880
|
|
|
1843
|
-
| Option | Type | Default
|
|
1844
|
-
| ----------------- | -------- |
|
|
1845
|
-
| `enabled` | boolean | `false`
|
|
1846
|
-
| `max` | number | `10`
|
|
1847
|
-
| `windowSeconds` | number | `60`
|
|
1848
|
-
| `message` | string | `'Too many requests...'`
|
|
1849
|
-
| `strictEndpoints` | string[] | See below
|
|
1850
|
-
| `skipEndpoints` | string[] | See below
|
|
1881
|
+
| Option | Type | Default | Description |
|
|
1882
|
+
| ----------------- | -------- | ------------------------ | ------------------------------------ |
|
|
1883
|
+
| `enabled` | boolean | `false` | Enable/disable rate limiting |
|
|
1884
|
+
| `max` | number | `10` | Maximum requests per time window |
|
|
1885
|
+
| `windowSeconds` | number | `60` | Time window in seconds |
|
|
1886
|
+
| `message` | string | `'Too many requests...'` | Error message when limit exceeded |
|
|
1887
|
+
| `strictEndpoints` | string[] | See below | Endpoints with half the normal limit |
|
|
1888
|
+
| `skipEndpoints` | string[] | See below | Endpoints that skip rate limiting |
|
|
1851
1889
|
|
|
1852
1890
|
### Default Strict Endpoints
|
|
1853
1891
|
|
|
@@ -1869,12 +1907,12 @@ These endpoints bypass rate limiting entirely:
|
|
|
1869
1907
|
|
|
1870
1908
|
When rate limiting is enabled, the following headers are added to responses:
|
|
1871
1909
|
|
|
1872
|
-
| Header
|
|
1873
|
-
|
|
|
1874
|
-
| `X-RateLimit-Limit`
|
|
1875
|
-
| `X-RateLimit-Remaining
|
|
1876
|
-
| `X-RateLimit-Reset`
|
|
1877
|
-
| `Retry-After`
|
|
1910
|
+
| Header | Description |
|
|
1911
|
+
| ----------------------- | --------------------------------------- |
|
|
1912
|
+
| `X-RateLimit-Limit` | Maximum requests allowed in the window |
|
|
1913
|
+
| `X-RateLimit-Remaining` | Remaining requests in current window |
|
|
1914
|
+
| `X-RateLimit-Reset` | Seconds until the rate limit resets |
|
|
1915
|
+
| `Retry-After` | (429 only) Seconds to wait before retry |
|
|
1878
1916
|
|
|
1879
1917
|
### Rate Limit Exceeded Response
|
|
1880
1918
|
|
|
@@ -1975,21 +2013,21 @@ override async betterAuthSignUp(
|
|
|
1975
2013
|
|
|
1976
2014
|
All methods in `CoreBetterAuthResolver` can be overridden:
|
|
1977
2015
|
|
|
1978
|
-
| Method
|
|
1979
|
-
|
|
|
1980
|
-
| `betterAuthSignIn(email, password, ctx)`
|
|
1981
|
-
| `betterAuthSignUp(email, password, name?)` | Register new user
|
|
1982
|
-
| `betterAuthSignOut(ctx)`
|
|
1983
|
-
| `betterAuthVerify2FA(code, ctx)`
|
|
1984
|
-
| `betterAuthEnable2FA(password, ctx)`
|
|
1985
|
-
| `betterAuthDisable2FA(password, ctx)`
|
|
1986
|
-
| `betterAuthGenerateBackupCodes(ctx)`
|
|
1987
|
-
| `betterAuthGetPasskeyChallenge(ctx)`
|
|
1988
|
-
| `betterAuthListPasskeys(ctx)`
|
|
1989
|
-
| `betterAuthDeletePasskey(passkeyId, ctx)`
|
|
1990
|
-
| `betterAuthSession(ctx)`
|
|
1991
|
-
| `betterAuthEnabled()`
|
|
1992
|
-
| `betterAuthFeatures()`
|
|
2016
|
+
| Method | Description |
|
|
2017
|
+
| ------------------------------------------ | ------------------------------- |
|
|
2018
|
+
| `betterAuthSignIn(email, password, ctx)` | Sign in with email/password |
|
|
2019
|
+
| `betterAuthSignUp(email, password, name?)` | Register new user |
|
|
2020
|
+
| `betterAuthSignOut(ctx)` | Sign out current session |
|
|
2021
|
+
| `betterAuthVerify2FA(code, ctx)` | Verify 2FA code |
|
|
2022
|
+
| `betterAuthEnable2FA(password, ctx)` | Enable 2FA for user |
|
|
2023
|
+
| `betterAuthDisable2FA(password, ctx)` | Disable 2FA for user |
|
|
2024
|
+
| `betterAuthGenerateBackupCodes(ctx)` | Generate new backup codes |
|
|
2025
|
+
| `betterAuthGetPasskeyChallenge(ctx)` | Get WebAuthn challenge |
|
|
2026
|
+
| `betterAuthListPasskeys(ctx)` | List user's passkeys |
|
|
2027
|
+
| `betterAuthDeletePasskey(passkeyId, ctx)` | Delete a passkey |
|
|
2028
|
+
| `betterAuthSession(ctx)` | Get current session |
|
|
2029
|
+
| `betterAuthEnabled()` | Check if Better-Auth is enabled |
|
|
2030
|
+
| `betterAuthFeatures()` | Get enabled features |
|
|
1993
2031
|
|
|
1994
2032
|
### Helper Methods (Protected)
|
|
1995
2033
|
|
|
@@ -2025,16 +2063,16 @@ For frontend integration with Better-Auth, see the **[Integration Checklist](./I
|
|
|
2025
2063
|
|
|
2026
2064
|
### Quick Reference
|
|
2027
2065
|
|
|
2028
|
-
| Feature
|
|
2029
|
-
|
|
2030
|
-
| Email Sign-In
|
|
2031
|
-
| Passkey Sign-In
|
|
2032
|
-
| 2FA Verify
|
|
2033
|
-
| Session Validation | `authClient.$fetch('/session')`
|
|
2066
|
+
| Feature | Client Method | Server Endpoint |
|
|
2067
|
+
| ------------------ | ----------------------------------- | ----------------------------------------- |
|
|
2068
|
+
| Email Sign-In | `authClient.signIn.email()` | `POST /iam/sign-in/email` |
|
|
2069
|
+
| Passkey Sign-In | `authClient.signIn.passkey()` | `POST /iam/passkey/verify-authentication` |
|
|
2070
|
+
| 2FA Verify | `authClient.twoFactor.verifyTotp()` | `POST /iam/two-factor/verify-totp` |
|
|
2071
|
+
| Session Validation | `authClient.$fetch('/session')` | `GET /iam/session` |
|
|
2034
2072
|
|
|
2035
2073
|
### Key Points
|
|
2036
2074
|
|
|
2037
2075
|
1. **Password Hashing**: Always hash passwords with SHA256 client-side before sending
|
|
2038
2076
|
2. **2FA Redirect**: Check for `twoFactorRedirect: true` in sign-in response
|
|
2039
2077
|
3. **Passkey Session**: Passkey auth returns session without user - call `validateSession()` to fetch user data
|
|
2040
|
-
4. **Credentials**: Use `credentials: 'include'` for cross-origin cookie handling
|
|
2078
|
+
4. **Credentials**: Use `credentials: 'include'` for cross-origin cookie handling
|