@techelusive/nest-auth 0.0.0-stage → 0.2.1
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 +71 -0
- package/LICENSE +21 -0
- package/README.md +204 -2
- package/api/openapi.json +4399 -0
- package/api/techelusive-authentication.postman_collection.json +3178 -0
- package/dist/auth-options.d.ts +156 -0
- package/dist/auth-options.js +3 -0
- package/dist/auth-options.js.map +1 -0
- package/dist/auth-options.validation.d.ts +9 -0
- package/dist/auth-options.validation.js +74 -0
- package/dist/auth-options.validation.js.map +1 -0
- package/dist/auth.module.d.ts +38 -0
- package/dist/auth.module.js +173 -0
- package/dist/auth.module.js.map +1 -0
- package/dist/common/auth-error.d.ts +16 -0
- package/dist/common/auth-error.js +23 -0
- package/dist/common/auth-error.js.map +1 -0
- package/dist/common/auth-exception.filter.d.ts +24 -0
- package/dist/common/auth-exception.filter.js +66 -0
- package/dist/common/auth-exception.filter.js.map +1 -0
- package/dist/common/crypto/jwt.d.ts +89 -0
- package/dist/common/crypto/jwt.js +144 -0
- package/dist/common/crypto/jwt.js.map +1 -0
- package/dist/common/crypto/random-secrets.d.ts +78 -0
- package/dist/common/crypto/random-secrets.js +113 -0
- package/dist/common/crypto/random-secrets.js.map +1 -0
- package/dist/common/crypto/remote-public-keys.d.ts +49 -0
- package/dist/common/crypto/remote-public-keys.js +105 -0
- package/dist/common/crypto/remote-public-keys.js.map +1 -0
- package/dist/common/crypto/totp.d.ts +68 -0
- package/dist/common/crypto/totp.js +148 -0
- package/dist/common/crypto/totp.js.map +1 -0
- package/dist/common/encryption.service.d.ts +36 -0
- package/dist/common/encryption.service.js +111 -0
- package/dist/common/encryption.service.js.map +1 -0
- package/dist/common/identifiers.d.ts +48 -0
- package/dist/common/identifiers.js +89 -0
- package/dist/common/identifiers.js.map +1 -0
- package/dist/common/network-safety.d.ts +19 -0
- package/dist/common/network-safety.js +72 -0
- package/dist/common/network-safety.js.map +1 -0
- package/dist/common/rate-limiter.service.d.ts +63 -0
- package/dist/common/rate-limiter.service.js +158 -0
- package/dist/common/rate-limiter.service.js.map +1 -0
- package/dist/common/refresh-token-cookie.d.ts +78 -0
- package/dist/common/refresh-token-cookie.js +185 -0
- package/dist/common/refresh-token-cookie.js.map +1 -0
- package/dist/common/request-context.d.ts +14 -0
- package/dist/common/request-context.js +22 -0
- package/dist/common/request-context.js.map +1 -0
- package/dist/common/strict-validation.pipe.d.ts +8 -0
- package/dist/common/strict-validation.pipe.js +16 -0
- package/dist/common/strict-validation.pipe.js.map +1 -0
- package/dist/common/time.d.ts +15 -0
- package/dist/common/time.js +34 -0
- package/dist/common/time.js.map +1 -0
- package/dist/constants.d.ts +1326 -0
- package/dist/constants.js +1142 -0
- package/dist/constants.js.map +1 -0
- package/dist/database/create-auth-tables.migration.d.ts +26 -0
- package/dist/database/create-auth-tables.migration.js +291 -0
- package/dist/database/create-auth-tables.migration.js.map +1 -0
- package/dist/database/email-change-and-retention.migration.d.ts +25 -0
- package/dist/database/email-change-and-retention.migration.js +54 -0
- package/dist/database/email-change-and-retention.migration.js.map +1 -0
- package/dist/database/entities/api-key.entity.d.ts +17 -0
- package/dist/database/entities/api-key.entity.js +80 -0
- package/dist/database/entities/api-key.entity.js.map +1 -0
- package/dist/database/entities/audit-log.entity.d.ts +13 -0
- package/dist/database/entities/audit-log.entity.js +64 -0
- package/dist/database/entities/audit-log.entity.js.map +1 -0
- package/dist/database/entities/backup-code.entity.d.ts +9 -0
- package/dist/database/entities/backup-code.entity.js +52 -0
- package/dist/database/entities/backup-code.entity.js.map +1 -0
- package/dist/database/entities/index.d.ts +43 -0
- package/dist/database/entities/index.js +82 -0
- package/dist/database/entities/index.js.map +1 -0
- package/dist/database/entities/json-object.d.ts +12 -0
- package/dist/database/entities/json-object.js +3 -0
- package/dist/database/entities/json-object.js.map +1 -0
- package/dist/database/entities/link-token.entity.d.ts +15 -0
- package/dist/database/entities/link-token.entity.js +64 -0
- package/dist/database/entities/link-token.entity.js.map +1 -0
- package/dist/database/entities/one-time-code.entity.d.ts +16 -0
- package/dist/database/entities/one-time-code.entity.js +69 -0
- package/dist/database/entities/one-time-code.entity.js.map +1 -0
- package/dist/database/entities/organization-invitation.entity.d.ts +14 -0
- package/dist/database/entities/organization-invitation.entity.js +73 -0
- package/dist/database/entities/organization-invitation.entity.js.map +1 -0
- package/dist/database/entities/organization-member.entity.d.ts +9 -0
- package/dist/database/entities/organization-member.entity.js +48 -0
- package/dist/database/entities/organization-member.entity.js.map +1 -0
- package/dist/database/entities/organization.entity.d.ts +12 -0
- package/dist/database/entities/organization.entity.js +58 -0
- package/dist/database/entities/organization.entity.js.map +1 -0
- package/dist/database/entities/passkey.entity.d.ts +19 -0
- package/dist/database/entities/passkey.entity.js +78 -0
- package/dist/database/entities/passkey.entity.js.map +1 -0
- package/dist/database/entities/password.entity.d.ts +6 -0
- package/dist/database/entities/password.entity.js +36 -0
- package/dist/database/entities/password.entity.js.map +1 -0
- package/dist/database/entities/refresh-token.entity.d.ts +9 -0
- package/dist/database/entities/refresh-token.entity.js +53 -0
- package/dist/database/entities/refresh-token.entity.js.map +1 -0
- package/dist/database/entities/session.entity.d.ts +20 -0
- package/dist/database/entities/session.entity.js +87 -0
- package/dist/database/entities/session.entity.js.map +1 -0
- package/dist/database/entities/settings.entity.d.ts +7 -0
- package/dist/database/entities/settings.entity.js +41 -0
- package/dist/database/entities/settings.entity.js.map +1 -0
- package/dist/database/entities/sign-in-challenge.entity.d.ts +23 -0
- package/dist/database/entities/sign-in-challenge.entity.js +80 -0
- package/dist/database/entities/sign-in-challenge.entity.js.map +1 -0
- package/dist/database/entities/signing-key.entity.d.ts +11 -0
- package/dist/database/entities/signing-key.entity.js +54 -0
- package/dist/database/entities/signing-key.entity.js.map +1 -0
- package/dist/database/entities/social-account.entity.d.ts +13 -0
- package/dist/database/entities/social-account.entity.js +54 -0
- package/dist/database/entities/social-account.entity.js.map +1 -0
- package/dist/database/entities/two-factor-secret.entity.d.ts +10 -0
- package/dist/database/entities/two-factor-secret.entity.js +48 -0
- package/dist/database/entities/two-factor-secret.entity.js.map +1 -0
- package/dist/database/entities/user.entity.d.ts +34 -0
- package/dist/database/entities/user.entity.js +129 -0
- package/dist/database/entities/user.entity.js.map +1 -0
- package/dist/database/entities/webhook-delivery.entity.d.ts +17 -0
- package/dist/database/entities/webhook-delivery.entity.js +79 -0
- package/dist/database/entities/webhook-delivery.entity.js.map +1 -0
- package/dist/database/entities/webhook.entity.d.ts +12 -0
- package/dist/database/entities/webhook.entity.js +58 -0
- package/dist/database/entities/webhook.entity.js.map +1 -0
- package/dist/database/typeorm-row.d.ts +21 -0
- package/dist/database/typeorm-row.js +29 -0
- package/dist/database/typeorm-row.js.map +1 -0
- package/dist/features/account/account.controller.d.ts +259 -0
- package/dist/features/account/account.controller.js +372 -0
- package/dist/features/account/account.controller.js.map +1 -0
- package/dist/features/account/account.dto.d.ts +16 -0
- package/dist/features/account/account.dto.js +61 -0
- package/dist/features/account/account.dto.js.map +1 -0
- package/dist/features/account/data-export.service.d.ts +85 -0
- package/dist/features/account/data-export.service.js +125 -0
- package/dist/features/account/data-export.service.js.map +1 -0
- package/dist/features/account/health.service.d.ts +30 -0
- package/dist/features/account/health.service.js +59 -0
- package/dist/features/account/health.service.js.map +1 -0
- package/dist/features/admin/admin.controller.d.ts +382 -0
- package/dist/features/admin/admin.controller.js +623 -0
- package/dist/features/admin/admin.controller.js.map +1 -0
- package/dist/features/admin/admin.dto.d.ts +61 -0
- package/dist/features/admin/admin.dto.js +253 -0
- package/dist/features/admin/admin.dto.js.map +1 -0
- package/dist/features/admin/admin.service.d.ts +142 -0
- package/dist/features/admin/admin.service.js +227 -0
- package/dist/features/admin/admin.service.js.map +1 -0
- package/dist/features/api-keys/api-keys.service.d.ts +67 -0
- package/dist/features/api-keys/api-keys.service.js +144 -0
- package/dist/features/api-keys/api-keys.service.js.map +1 -0
- package/dist/features/email-change/email-change.controller.d.ts +38 -0
- package/dist/features/email-change/email-change.controller.js +85 -0
- package/dist/features/email-change/email-change.controller.js.map +1 -0
- package/dist/features/email-change/email-change.dto.d.ts +10 -0
- package/dist/features/email-change/email-change.dto.js +43 -0
- package/dist/features/email-change/email-change.dto.js.map +1 -0
- package/dist/features/email-change/email-change.service.d.ts +74 -0
- package/dist/features/email-change/email-change.service.js +179 -0
- package/dist/features/email-change/email-change.service.js.map +1 -0
- package/dist/features/email-links/email-verification.service.d.ts +46 -0
- package/dist/features/email-links/email-verification.service.js +94 -0
- package/dist/features/email-links/email-verification.service.js.map +1 -0
- package/dist/features/email-links/link-tokens.service.d.ts +44 -0
- package/dist/features/email-links/link-tokens.service.js +122 -0
- package/dist/features/email-links/link-tokens.service.js.map +1 -0
- package/dist/features/events/auth-events.service.d.ts +52 -0
- package/dist/features/events/auth-events.service.js +117 -0
- package/dist/features/events/auth-events.service.js.map +1 -0
- package/dist/features/maintenance/data-retention.service.d.ts +60 -0
- package/dist/features/maintenance/data-retention.service.js +182 -0
- package/dist/features/maintenance/data-retention.service.js.map +1 -0
- package/dist/features/notifications/notifications.service.d.ts +40 -0
- package/dist/features/notifications/notifications.service.js +94 -0
- package/dist/features/notifications/notifications.service.js.map +1 -0
- package/dist/features/one-time-codes/one-time-codes.service.d.ts +40 -0
- package/dist/features/one-time-codes/one-time-codes.service.js +102 -0
- package/dist/features/one-time-codes/one-time-codes.service.js.map +1 -0
- package/dist/features/organizations/organizations.controller.d.ts +220 -0
- package/dist/features/organizations/organizations.controller.js +337 -0
- package/dist/features/organizations/organizations.controller.js.map +1 -0
- package/dist/features/organizations/organizations.dto.d.ts +31 -0
- package/dist/features/organizations/organizations.dto.js +100 -0
- package/dist/features/organizations/organizations.dto.js.map +1 -0
- package/dist/features/organizations/organizations.service.d.ts +274 -0
- package/dist/features/organizations/organizations.service.js +481 -0
- package/dist/features/organizations/organizations.service.js.map +1 -0
- package/dist/features/passkeys/passkeys.controller.d.ts +92 -0
- package/dist/features/passkeys/passkeys.controller.js +183 -0
- package/dist/features/passkeys/passkeys.controller.js.map +1 -0
- package/dist/features/passkeys/passkeys.dto.d.ts +13 -0
- package/dist/features/passkeys/passkeys.dto.js +50 -0
- package/dist/features/passkeys/passkeys.dto.js.map +1 -0
- package/dist/features/passkeys/passkeys.service.d.ts +159 -0
- package/dist/features/passkeys/passkeys.service.js +350 -0
- package/dist/features/passkeys/passkeys.service.js.map +1 -0
- package/dist/features/passwordless/passwordless-auth.service.d.ts +152 -0
- package/dist/features/passwordless/passwordless-auth.service.js +304 -0
- package/dist/features/passwordless/passwordless-auth.service.js.map +1 -0
- package/dist/features/passwordless/passwordless.controller.d.ts +75 -0
- package/dist/features/passwordless/passwordless.controller.js +163 -0
- package/dist/features/passwordless/passwordless.controller.js.map +1 -0
- package/dist/features/passwordless/passwordless.dto.d.ts +29 -0
- package/dist/features/passwordless/passwordless.dto.js +101 -0
- package/dist/features/passwordless/passwordless.dto.js.map +1 -0
- package/dist/features/passwords/password-auth.service.d.ts +154 -0
- package/dist/features/passwords/password-auth.service.js +317 -0
- package/dist/features/passwords/password-auth.service.js.map +1 -0
- package/dist/features/passwords/password-policy.service.d.ts +63 -0
- package/dist/features/passwords/password-policy.service.js +175 -0
- package/dist/features/passwords/password-policy.service.js.map +1 -0
- package/dist/features/passwords/password.controller.d.ts +95 -0
- package/dist/features/passwords/password.controller.js +193 -0
- package/dist/features/passwords/password.controller.js.map +1 -0
- package/dist/features/passwords/password.dto.d.ts +36 -0
- package/dist/features/passwords/password.dto.js +140 -0
- package/dist/features/passwords/password.dto.js.map +1 -0
- package/dist/features/sessions/session.service.d.ts +132 -0
- package/dist/features/sessions/session.service.js +308 -0
- package/dist/features/sessions/session.service.js.map +1 -0
- package/dist/features/sessions/session.types.d.ts +34 -0
- package/dist/features/sessions/session.types.js +3 -0
- package/dist/features/sessions/session.types.js.map +1 -0
- package/dist/features/settings/settings.defaults.d.ts +2 -0
- package/dist/features/settings/settings.defaults.js +7 -0
- package/dist/features/settings/settings.defaults.js.map +1 -0
- package/dist/features/settings/settings.service.d.ts +44 -0
- package/dist/features/settings/settings.service.js +112 -0
- package/dist/features/settings/settings.service.js.map +1 -0
- package/dist/features/settings/settings.types.d.ts +133 -0
- package/dist/features/settings/settings.types.js +3 -0
- package/dist/features/settings/settings.types.js.map +1 -0
- package/dist/features/settings/settings.validation.d.ts +33 -0
- package/dist/features/settings/settings.validation.js +614 -0
- package/dist/features/settings/settings.validation.js.map +1 -0
- package/dist/features/sign-in/sign-in-challenges.service.d.ts +54 -0
- package/dist/features/sign-in/sign-in-challenges.service.js +104 -0
- package/dist/features/sign-in/sign-in-challenges.service.js.map +1 -0
- package/dist/features/sign-in/sign-in.service.d.ts +127 -0
- package/dist/features/sign-in/sign-in.service.js +248 -0
- package/dist/features/sign-in/sign-in.service.js.map +1 -0
- package/dist/features/sign-in/sign-in.types.d.ts +22 -0
- package/dist/features/sign-in/sign-in.types.js +3 -0
- package/dist/features/sign-in/sign-in.types.js.map +1 -0
- package/dist/features/signing-keys/jwks.controller.d.ts +17 -0
- package/dist/features/signing-keys/jwks.controller.js +51 -0
- package/dist/features/signing-keys/jwks.controller.js.map +1 -0
- package/dist/features/signing-keys/signing-keys.service.d.ts +67 -0
- package/dist/features/signing-keys/signing-keys.service.js +142 -0
- package/dist/features/signing-keys/signing-keys.service.js.map +1 -0
- package/dist/features/social/social-auth.service.d.ts +100 -0
- package/dist/features/social/social-auth.service.js +232 -0
- package/dist/features/social/social-auth.service.js.map +1 -0
- package/dist/features/social/social-providers.service.d.ts +97 -0
- package/dist/features/social/social-providers.service.js +214 -0
- package/dist/features/social/social-providers.service.js.map +1 -0
- package/dist/features/social/social.controller.d.ts +54 -0
- package/dist/features/social/social.controller.js +124 -0
- package/dist/features/social/social.controller.js.map +1 -0
- package/dist/features/social/social.dto.d.ts +11 -0
- package/dist/features/social/social.dto.js +38 -0
- package/dist/features/social/social.dto.js.map +1 -0
- package/dist/features/two-factor/two-factor.controller.d.ts +84 -0
- package/dist/features/two-factor/two-factor.controller.js +174 -0
- package/dist/features/two-factor/two-factor.controller.js.map +1 -0
- package/dist/features/two-factor/two-factor.dto.d.ts +10 -0
- package/dist/features/two-factor/two-factor.dto.js +37 -0
- package/dist/features/two-factor/two-factor.dto.js.map +1 -0
- package/dist/features/two-factor/two-factor.service.d.ts +171 -0
- package/dist/features/two-factor/two-factor.service.js +348 -0
- package/dist/features/two-factor/two-factor.service.js.map +1 -0
- package/dist/features/users/sign-in-methods.service.d.ts +40 -0
- package/dist/features/users/sign-in-methods.service.js +81 -0
- package/dist/features/users/sign-in-methods.service.js.map +1 -0
- package/dist/features/users/sign-up-rules.d.ts +12 -0
- package/dist/features/users/sign-up-rules.js +29 -0
- package/dist/features/users/sign-up-rules.js.map +1 -0
- package/dist/features/users/users.service.d.ts +246 -0
- package/dist/features/users/users.service.js +509 -0
- package/dist/features/users/users.service.js.map +1 -0
- package/dist/features/users/users.types.d.ts +24 -0
- package/dist/features/users/users.types.js +3 -0
- package/dist/features/users/users.types.js.map +1 -0
- package/dist/features/webhooks/webhook-delivery.worker.d.ts +55 -0
- package/dist/features/webhooks/webhook-delivery.worker.js +175 -0
- package/dist/features/webhooks/webhook-delivery.worker.js.map +1 -0
- package/dist/features/webhooks/webhook-signature.d.ts +28 -0
- package/dist/features/webhooks/webhook-signature.js +85 -0
- package/dist/features/webhooks/webhook-signature.js.map +1 -0
- package/dist/features/webhooks/webhooks.service.d.ts +144 -0
- package/dist/features/webhooks/webhooks.service.js +238 -0
- package/dist/features/webhooks/webhooks.service.js.map +1 -0
- package/dist/guards/auth.decorators.d.ts +65 -0
- package/dist/guards/auth.decorators.js +68 -0
- package/dist/guards/auth.decorators.js.map +1 -0
- package/dist/guards/auth.guard.d.ts +47 -0
- package/dist/guards/auth.guard.js +132 -0
- package/dist/guards/auth.guard.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +95 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/console-email-sender.d.ts +15 -0
- package/dist/integrations/console-email-sender.js +26 -0
- package/dist/integrations/console-email-sender.js.map +1 -0
- package/dist/integrations/msg91-sms-sender.d.ts +28 -0
- package/dist/integrations/msg91-sms-sender.js +46 -0
- package/dist/integrations/msg91-sms-sender.js.map +1 -0
- package/docs/README.md +39 -0
- package/docs/admin-api-keys-webhooks.md +147 -0
- package/docs/api-reference.md +175 -0
- package/docs/architecture.md +119 -0
- package/docs/client-integration.md +192 -0
- package/docs/code-walkthrough.md +273 -0
- package/docs/configuration.md +229 -0
- package/docs/endpoints/README.md +151 -0
- package/docs/endpoints/account.md +363 -0
- package/docs/endpoints/admin.md +422 -0
- package/docs/endpoints/email-password.md +261 -0
- package/docs/endpoints/organizations.md +192 -0
- package/docs/endpoints/passkeys.md +195 -0
- package/docs/endpoints/passwordless.md +214 -0
- package/docs/endpoints/social.md +116 -0
- package/docs/endpoints/two-factor.md +146 -0
- package/docs/error-codes.md +100 -0
- package/docs/events.md +83 -0
- package/docs/getting-started.md +139 -0
- package/docs/manual-testing.md +215 -0
- package/docs/organizations.md +86 -0
- package/docs/production-checklist.md +60 -0
- package/docs/protecting-routes.md +147 -0
- package/docs/security.md +61 -0
- package/docs/sign-in-flows.md +294 -0
- package/package.json +92 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes are listed here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions follow [Semantic Versioning](https://semver.org/).
|
|
4
|
+
|
|
5
|
+
Until 1.0, minor versions (0.x.0) may contain breaking changes. They will always be listed here with upgrade steps.
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.2.1] - 2026-10-20
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- Apps can use TypeORM 0.3 or 1.x (`peerDependencies.typeorm` is now `^0.3.20 || ^1.0.0`). CI runs every check against both.
|
|
13
|
+
- The Redis client loads whichever way the installed `ioredis` version exports it.
|
|
14
|
+
- Dependabot groups small updates into one pull request and skips major updates of `typescript` and `@types/node`.
|
|
15
|
+
|
|
16
|
+
## [0.2.0] - 2026-10-20
|
|
17
|
+
|
|
18
|
+
Production hardening.
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
- **Email change:** `POST /auth/email/change` (current password, or a sign-in from the last 10 minutes for accounts without one) sends a link to the new address; `POST /auth/email/change/confirm` switches it and notifies the old address. Events `user.email_change_requested` and `user.email_changed`.
|
|
22
|
+
- **Data retention:** an hourly cleanup removes ended sessions, used or expired codes, links, 2FA challenges and invitations, finished webhook deliveries and old audit entries. New `retention` settings, `DataRetentionService.runCleanup()` and `POST /auth/admin/maintenance/cleanup`.
|
|
23
|
+
- **Cookie mode for web apps:** `refreshTokenCookie` puts the refresh token in an HttpOnly, Secure, SameSite cookie for requests from the listed origins, with an Origin check on cookie refreshes. Mobile apps on the same API are unaffected.
|
|
24
|
+
- **Download my data:** `GET /auth/me/export` (profile, sign-in methods, linked accounts, passkeys, devices, organizations, security history; never secrets).
|
|
25
|
+
- **Operations:** `GET /auth/health` (PostgreSQL and Redis, 503 when down) and `GET /auth/admin/stats`.
|
|
26
|
+
- **CI:** every flow tested over HTTP against the playground (also in cookie mode), `npm audit`, CodeQL, Dependabot, and a release workflow that publishes to npm with provenance.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
- **Breaking:** `redisUrl` is required when `NODE_ENV=production`, unless `singleServer: true`.
|
|
30
|
+
- **Breaking:** two new email types for your `emailSender`: `confirm_email_change` (`token`) and `email_changed` (`newEmail`, masked).
|
|
31
|
+
- **Timings are now settings**, each with a safe range: `emailVerification.linkExpiresInHours`, `passwordReset.linkExpiresInMinutes`, `emailChange.linkExpiresInMinutes`, `magicLink.expiresInMinutes`, `emailOtp/phoneOtp.resendAfterSeconds`, `twoFactor.challengeExpiresInMinutes`, `organizations.invitationExpiresInDays`. Defaults are unchanged. Rate limits stay fixed in code.
|
|
32
|
+
- `POST /auth/refresh`: `refreshToken` is optional when it comes from the cookie.
|
|
33
|
+
- `rxjs` is now a peer dependency (every NestJS app already has it).
|
|
34
|
+
- Removed the error codes `ACCOUNT_DELETED` and `EMAIL_ALREADY_VERIFIED` (and `AUTH_ERRORS.accountDeleted` / `emailAlreadyVerified`): the API never returned them. Deleted accounts get `INVALID_CREDENTIALS` and already-verified emails get the normal answer, so neither reveals whether an account exists.
|
|
35
|
+
|
|
36
|
+
### Upgrade from 0.1.0
|
|
37
|
+
1. Run migrations: the new `EmailChangeAndRetention1792700000000` is included in `AUTH_MIGRATIONS` (adds the `change_email` link type and indexes for the cleanup). On very large tables, see the note in the migration about building the indexes `CONCURRENTLY` first.
|
|
38
|
+
2. Handle `confirm_email_change` and `email_changed` in your `emailSender`.
|
|
39
|
+
3. In production, set `redisUrl` (or `singleServer: true` for a single process).
|
|
40
|
+
4. The first cleanup runs a minute after start. If you must keep audit entries longer than a year, set `retention.auditLogDays` first.
|
|
41
|
+
|
|
42
|
+
## [0.1.0] - 2026-10-20
|
|
43
|
+
|
|
44
|
+
First release.
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
- **Sign-in methods:** email + password, email OTP, magic link, phone OTP (SMS), Google, Apple, Facebook, passkeys (WebAuthn).
|
|
48
|
+
- **Two-factor authentication:** authenticator apps (TOTP) plus backup codes, and an admin reset.
|
|
49
|
+
- **Sessions:**
|
|
50
|
+
- one session per device
|
|
51
|
+
- ES256 access tokens and a public JWKS endpoint
|
|
52
|
+
- rotating single-use refresh tokens with reuse detection
|
|
53
|
+
- signing-key rotation
|
|
54
|
+
- **Account life cycle:** verification-based activation, suspend, deactivate / reactivate, and deletion with personal data wiped.
|
|
55
|
+
- **Roles and admin API:** user search and management, runtime settings, audit log.
|
|
56
|
+
- **Organizations:** owner / admin / member roles, email invitations, and the active organization carried in tokens.
|
|
57
|
+
- **Server access and integrations:**
|
|
58
|
+
- API keys with scopes
|
|
59
|
+
- signed webhooks with retries and SSRF protection
|
|
60
|
+
- an `onEvent` hook
|
|
61
|
+
- **Security:**
|
|
62
|
+
- Argon2id password hashing
|
|
63
|
+
- breached-password check
|
|
64
|
+
- rate limits (Redis or memory, failing closed)
|
|
65
|
+
- AWS KMS envelope encryption
|
|
66
|
+
- protection against account enumeration, account pre-hijacking and social account takeover
|
|
67
|
+
- **Ready-made senders:** MSG91 for SMS, and a console email sender for development.
|
|
68
|
+
- `@CurrentUserId()` decorator, and exported named constants (`ROUTES`, `SIGN_IN_STATUS`, `ACCOUNT_STATUS`, `SIGN_IN_METHOD`...) so clients never type raw strings.
|
|
69
|
+
- `encryption.legacyLocalKey` for moving an existing database from the development key to AWS KMS.
|
|
70
|
+
- Full request/response documentation for every endpoint (`docs/endpoints/`).
|
|
71
|
+
- A test that fails the build when a hardcoded value appears outside `src/constants.ts`.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Techelusive
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,205 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @techelusive/nest-auth
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Reusable, production-grade authentication for NestJS apps. Write it once, plug it into every product.
|
|
4
|
+
|
|
5
|
+
- **Headless:** pure JSON API. Each app builds its own screens (web, iOS, Android).
|
|
6
|
+
- **Your database:** the auth tables live in each app's own PostgreSQL database, through its TypeORM `DataSource`.
|
|
7
|
+
- **Configurable:** every feature can be switched on or off in code, and changed at runtime by an admin through the API.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
| Area | What you get |
|
|
12
|
+
|---|---|
|
|
13
|
+
| Sign in | Email + password, email OTP, magic link, phone OTP (SMS), Google, Apple, Facebook, passkeys |
|
|
14
|
+
| Security | 2FA with authenticator apps + backup codes, breached-password check, rate limits (shared through Redis), refresh-token reuse detection, HttpOnly cookie mode for web apps, new-device emails, audit log |
|
|
15
|
+
| Accounts | Verification and activation rules, verified email change, "download my data", suspend / deactivate / reactivate / delete (personal data wiped), onboarding flag, roles |
|
|
16
|
+
| Teams | Organizations with owner / admin / member roles, email invitations, active organization in the token |
|
|
17
|
+
| Servers | API keys with scopes, signed webhooks with retries, public JWKS so any service can verify tokens |
|
|
18
|
+
| Admin and operations | User search and management, runtime settings, audit log, stats, key rotation, health check, automatic data retention |
|
|
19
|
+
|
|
20
|
+
## Documentation
|
|
21
|
+
|
|
22
|
+
| Guide | |
|
|
23
|
+
|---|---|
|
|
24
|
+
| [Getting started](docs/getting-started.md) | Add auth to a NestJS app in 15 minutes |
|
|
25
|
+
| [Configuration](docs/configuration.md) | Every option and runtime setting |
|
|
26
|
+
| [Sign-in flows](docs/sign-in-flows.md) | Each flow, request by request, for app developers |
|
|
27
|
+
| [Client integration](docs/client-integration.md) | Token storage, refresh, email links, social SDKs, passkeys |
|
|
28
|
+
| [Endpoints](docs/endpoints/README.md) | Every endpoint with its request and response JSON |
|
|
29
|
+
| [API reference](docs/api-reference.md) · [Error codes](docs/error-codes.md) · [Events](docs/events.md) | Look-ups |
|
|
30
|
+
| [Protecting routes](docs/protecting-routes.md) | Decorators, token claims, verifying tokens in other services |
|
|
31
|
+
| [Organizations](docs/organizations.md) · [Admin, API keys, webhooks](docs/admin-api-keys-webhooks.md) | Teams and operations |
|
|
32
|
+
| [Manual testing](docs/manual-testing.md) | Local playground with Swagger, Postman and a dev dashboard |
|
|
33
|
+
| [Code walkthrough](docs/code-walkthrough.md) | How each flow runs through the code, with a study plan |
|
|
34
|
+
| [Production checklist](docs/production-checklist.md) · [Security](docs/security.md) · [Architecture](docs/architecture.md) | Going live and internals |
|
|
35
|
+
|
|
36
|
+
## Install
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install @techelusive/nest-auth
|
|
40
|
+
# peer dependencies your NestJS app already has:
|
|
41
|
+
npm install @nestjs/common @nestjs/core typeorm pg class-validator class-transformer reflect-metadata
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Set up in 3 steps
|
|
45
|
+
|
|
46
|
+
**1. Add the tables to your DataSource and run the migration**
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { AUTH_ENTITIES, AUTH_MIGRATIONS } from '@techelusive/nest-auth';
|
|
50
|
+
|
|
51
|
+
export const appDataSource = new DataSource({
|
|
52
|
+
type: 'postgres',
|
|
53
|
+
url: process.env.DATABASE_URL,
|
|
54
|
+
entities: [...AUTH_ENTITIES, ...yourEntities],
|
|
55
|
+
migrations: [...AUTH_MIGRATIONS, ...yourMigrations],
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx typeorm migration:run -d dist/data-source.js
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**2. Import the module**
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
AuthModule.forRoot({
|
|
67
|
+
useFactory: async () => ({
|
|
68
|
+
dataSource: await appDataSource.initialize(),
|
|
69
|
+
issuer: 'https://api.myapp.com',
|
|
70
|
+
appName: 'MyApp',
|
|
71
|
+
encryption: { awsKmsKeyId: process.env.KMS_KEY_ID!, awsRegion: 'ap-south-1' },
|
|
72
|
+
emailSender: myEmailSender, // { send(email) } - SES, Resend, SMTP...
|
|
73
|
+
smsSender: new Msg91SmsSender({ authKey, templateId }), // only for phone OTP
|
|
74
|
+
redisUrl: process.env.REDIS_URL, // required in production (or singleServer: true)
|
|
75
|
+
settings: {
|
|
76
|
+
registration: { defaultRoles: ['customer'] },
|
|
77
|
+
emailOtp: { enabled: true },
|
|
78
|
+
google: { enabled: true, clientIds: ['...apps.googleusercontent.com'] },
|
|
79
|
+
},
|
|
80
|
+
}),
|
|
81
|
+
})
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**3. Trust your load balancer** (so rate limits see real client IPs)
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
app.set('trust proxy', 1);
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Every route in your app is now protected. A full working example is in [`example/`](example/).
|
|
91
|
+
|
|
92
|
+
## Protecting your own routes
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
@Get('popular') @Public() // anyone
|
|
96
|
+
@Get('mine') // any signed-in user (the default)
|
|
97
|
+
@Post() @Roles('seller', 'admin') // users with one of these roles
|
|
98
|
+
@Post('payout') @CheckSession() // also re-check the session is still active
|
|
99
|
+
@Get('export') @ApiKeyScopes('orders:read') // other servers with an API key ("x-api-key" header)
|
|
100
|
+
|
|
101
|
+
myRoute(@CurrentUser() user: AccessTokenClaims) { user.sub; user.roles; user.org_id; }
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Other services (in any language) can verify access tokens with a standard JWT library pointed at `GET /.well-known/jwks.json`. The algorithm is ES256, and `iss` and `aud` are both your issuer URL.
|
|
105
|
+
|
|
106
|
+
## Endpoints
|
|
107
|
+
|
|
108
|
+
Every response has `success: true` or `success: false`. Errors look like this:
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{ "success": false, "code": "INVALID_CREDENTIALS", "message": "Invalid email or password." }
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
| Method & path | Purpose |
|
|
115
|
+
|---|---|
|
|
116
|
+
| `POST /auth/register` | Create account (email, password, firstName, lastName, phoneNumber, acceptTerms, acceptPrivacyPolicy) |
|
|
117
|
+
| `POST /auth/login` | Email + password |
|
|
118
|
+
| `POST /auth/email/send-verification` · `/auth/email/verify` | Verification link |
|
|
119
|
+
| `POST /auth/email/send-otp` · `/auth/email/verify-otp` | Email code (signs in and verifies) |
|
|
120
|
+
| `POST /auth/magic-link/send` · `/auth/magic-link/verify` | Magic link |
|
|
121
|
+
| `POST /auth/phone/send-otp` · `/auth/phone/verify-otp` | SMS code |
|
|
122
|
+
| `POST /auth/social/:provider` | `google`, `apple`, `facebook` (send the provider's token) |
|
|
123
|
+
| `POST /auth/social/:provider/link` · `DELETE /auth/social/:provider` | Connect or disconnect a provider |
|
|
124
|
+
| `POST /auth/passkeys/register/options` · `register/verify` | Add a passkey |
|
|
125
|
+
| `POST /auth/passkeys/sign-in/options` · `sign-in/verify` | Sign in with a passkey |
|
|
126
|
+
| `GET /auth/passkeys` · `PATCH/DELETE /auth/passkeys/:id` | Manage passkeys |
|
|
127
|
+
| `POST /auth/2fa/setup` · `enable` · `disable` · `backup-codes` · `verify` | Two-factor |
|
|
128
|
+
| `POST /auth/password/forgot` · `reset` · `change` | Passwords |
|
|
129
|
+
| `POST /auth/refresh` · `logout` · `logout-all` | Tokens and sessions |
|
|
130
|
+
| `GET/PATCH/DELETE /auth/me` · `GET /auth/me/export` | Profile, delete account, download my data |
|
|
131
|
+
| `POST /auth/email/change` · `/auth/email/change/confirm` | Change email (confirmed by a link to the new address) |
|
|
132
|
+
| `GET /auth/health` | Database and Redis reachable (for load balancers) |
|
|
133
|
+
| `GET /auth/sessions` · `DELETE /auth/sessions/:id` | Devices |
|
|
134
|
+
| `GET /auth/sign-in-methods` | How the user can sign in |
|
|
135
|
+
| `POST /auth/deactivate` · `/auth/reactivate` | Pause and resume the account |
|
|
136
|
+
| `/auth/organizations/...` | Organizations, members, invitations, switch |
|
|
137
|
+
| `/auth/admin/...` | Users, settings, audit log, stats, data cleanup, API keys, webhooks, key rotation |
|
|
138
|
+
|
|
139
|
+
## Sign-in responses
|
|
140
|
+
|
|
141
|
+
Every sign-in endpoint returns one of these:
|
|
142
|
+
|
|
143
|
+
```jsonc
|
|
144
|
+
{ "success": true, "status": "signed_in", "accessToken": "...", "refreshToken": "rt_...", "expiresIn": 900, "user": { ... } }
|
|
145
|
+
{ "success": true, "status": "two_factor_required", "challengeToken": "ch_...", "expiresIn": 300 } // then POST /auth/2fa/verify
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Or an error the app can act on:
|
|
149
|
+
|
|
150
|
+
| Code | What the app should do |
|
|
151
|
+
|---|---|
|
|
152
|
+
| `ACCOUNT_NOT_VERIFIED` | Send the user to verification. `pendingVerifications` says which: `["email"]`, `["phone"]` |
|
|
153
|
+
| `ACCOUNT_DEACTIVATED` | Offer reactivation: `POST /auth/reactivate` with the `reactivationToken` |
|
|
154
|
+
| `ACCOUNT_SUSPENDED` | Show "contact support" |
|
|
155
|
+
| `VALIDATION_ERROR` with `missingSignUpDetails` | New social / code user: ask for names or consent, then retry |
|
|
156
|
+
| `TOO_MANY_REQUESTS` | Wait `retryAfterSeconds` |
|
|
157
|
+
|
|
158
|
+
## Settings
|
|
159
|
+
|
|
160
|
+
Defaults are in `src/features/settings/settings.defaults.ts`. They are secure and have only email + password turned on.
|
|
161
|
+
|
|
162
|
+
The final settings are built in three layers:
|
|
163
|
+
|
|
164
|
+
1. **Defaults:** shipped with the library.
|
|
165
|
+
2. **Your code:** whatever you pass in `settings` overrides the defaults.
|
|
166
|
+
3. **Admin changes:** `PATCH /auth/admin/settings` overrides both. Changes reach every server within 10 seconds. `DELETE /auth/admin/settings` goes back to the code settings.
|
|
167
|
+
|
|
168
|
+
## Webhooks
|
|
169
|
+
|
|
170
|
+
`POST /auth/admin/webhooks` registers a URL and returns its signing secret **once**. Each delivery is a signed POST. Verify it in the receiving service:
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
import { verifyWebhookSignature } from '@techelusive/nest-auth';
|
|
174
|
+
verifyWebhookSignature(secret, rawBody, req.headers['x-techelusive-signature']);
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Failed deliveries are retried for up to about a day. Private and internal addresses are always refused.
|
|
178
|
+
|
|
179
|
+
## Security notes
|
|
180
|
+
|
|
181
|
+
- **Hashing and encryption:**
|
|
182
|
+
- Passwords use Argon2id.
|
|
183
|
+
- Tokens, codes and API keys are stored only as hashes.
|
|
184
|
+
- Signing keys, 2FA secrets and webhook secrets are encrypted with AWS KMS (or a local key in development only).
|
|
185
|
+
- **No account enumeration:** "send" and "forgot" endpoints answer the same whether or not an account exists, and sign-in takes the same time for unknown emails.
|
|
186
|
+
- **Single-use refresh tokens:** a reused refresh token ends that session.
|
|
187
|
+
- **Fast revocation:** signing out or suspending takes effect within seconds on routes marked `@CheckSession()`, and within one access-token lifetime (15 minutes by default) everywhere else.
|
|
188
|
+
- **Account pre-hijacking protection:** when the real owner first proves an email, any password set earlier by someone else is removed.
|
|
189
|
+
- **Social account takeover protection:** an unverified social email is never linked to an existing account.
|
|
190
|
+
|
|
191
|
+
## Development
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
npm install
|
|
195
|
+
npm test # unit tests (crypto, TOTP RFC vectors, SSRF guard, webhook signatures, input rules)
|
|
196
|
+
npm run build
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
All tunable numbers, limits, patterns, error codes and messages live in [`src/constants.ts`](src/constants.ts).
|
|
200
|
+
|
|
201
|
+
## Contributing, security and license
|
|
202
|
+
|
|
203
|
+
- Contributions are welcome. Read [CONTRIBUTING.md](CONTRIBUTING.md) first.
|
|
204
|
+
- Report vulnerabilities privately as described in [SECURITY.md](SECURITY.md), never in public issues.
|
|
205
|
+
- Released under the [MIT License](LICENSE).
|