@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
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
Configuration has two parts:
|
|
4
|
+
|
|
5
|
+
- **Options** (`AuthOptions`): wiring and secrets, such as the database, URLs, keys and senders. They are set in code at startup and checked then; a mistake stops the app with a clear message.
|
|
6
|
+
- **Settings** (`AuthSettings`): behavior, such as which sign-in methods are on, token lifetimes and roles. You set defaults in code, and admins can change them at runtime.
|
|
7
|
+
|
|
8
|
+
## Options
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
AuthModule.forRoot({
|
|
12
|
+
imports: [], // modules your factory needs (e.g. ConfigModule)
|
|
13
|
+
inject: [], // providers passed to useFactory
|
|
14
|
+
protectAllRoutes: true, // install AuthGuard app-wide (default true)
|
|
15
|
+
useFactory: (...injected) => ({ /* AuthOptions */ }),
|
|
16
|
+
})
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
| Option | Required | Description |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| `dataSource` | yes | Your TypeORM `DataSource`, already initialized, including `AUTH_ENTITIES`. |
|
|
22
|
+
| `issuer` | yes | Your API's public URL, e.g. `https://api.myapp.com`. Written into every token as `iss` and `aud`. Must be https in production. |
|
|
23
|
+
| `encryption` | yes | `{ awsKmsKeyId, awsRegion, legacyLocalKey? }` in production, or `{ localKey }` (32 random bytes in base64) in development. `legacyLocalKey` is only for [moving an existing database to KMS](production-checklist.md#configuration). |
|
|
24
|
+
| `emailSender` | yes | Object with `send(email: AuthEmail): Promise<void>`. See [below](#email-sender). |
|
|
25
|
+
| `smsSender` | for phone OTP | Object with `sendCode(phoneNumber, code)`. `Msg91SmsSender` is included. |
|
|
26
|
+
| `facebookAppSecret` | for Facebook | Your Facebook app secret. Google and Apple need no secret. |
|
|
27
|
+
| `passkeys` | for passkeys | `{ relyingPartyId: 'myapp.com', relyingPartyName: 'MyApp', allowedOrigins: ['https://myapp.com'] }` |
|
|
28
|
+
| `appName` | no | Shown in authenticator apps next to the 2FA code. Default `Techelusive`. |
|
|
29
|
+
| `settings` | no | Your defaults for behavior (see below). |
|
|
30
|
+
| `redisUrl` | in production | Shares rate limits between servers. Required when `NODE_ENV=production` (the app refuses to start without it), because without it each server counts separately and an attacker gets a full set of attempts per server. |
|
|
31
|
+
| `singleServer` | no | `true` lets production run without Redis. Only when exactly one server process runs; counters then live in its memory and reset on restart. |
|
|
32
|
+
| `refreshTokenCookie` | for web apps | `{ allowedOrigins: ['https://app.myapp.com'], name?, domain?, path?, sameSite? }`. Web requests get the refresh token in an HttpOnly cookie instead of the body. See [Client integration](client-integration.md#web-apps-refresh-token-in-a-cookie). |
|
|
33
|
+
| `onEvent` | no | `(event) => void \| Promise<void>`, called for every [event](events.md). |
|
|
34
|
+
|
|
35
|
+
### Email sender
|
|
36
|
+
|
|
37
|
+
The library never builds email HTML. It hands you the data, and you render your own templates with your own provider (SES, Resend, Postmark, SMTP...).
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import { AuthEmail, EmailSender } from '@techelusive/nest-auth';
|
|
41
|
+
|
|
42
|
+
export class SesEmailSender implements EmailSender {
|
|
43
|
+
async send(email: AuthEmail): Promise<void> {
|
|
44
|
+
switch (email.type) {
|
|
45
|
+
case 'verify_email':
|
|
46
|
+
return sendTemplate(email.to, 'verify-email', { link: `https://myapp.com/verify-email?token=${email.token}` });
|
|
47
|
+
case 'reset_password':
|
|
48
|
+
return sendTemplate(email.to, 'reset-password', { link: `https://myapp.com/reset-password?token=${email.token}` });
|
|
49
|
+
case 'magic_sign_in':
|
|
50
|
+
return sendTemplate(email.to, 'magic-link', { link: `https://myapp.com/magic?token=${email.token}` });
|
|
51
|
+
case 'sign_in_code':
|
|
52
|
+
return sendTemplate(email.to, 'sign-in-code', { code: email.code });
|
|
53
|
+
case 'organization_invitation':
|
|
54
|
+
return sendTemplate(email.to, 'invitation', {
|
|
55
|
+
link: `https://myapp.com/join?token=${email.token}`,
|
|
56
|
+
organizationName: email.organizationName,
|
|
57
|
+
invitedByName: email.invitedByName,
|
|
58
|
+
});
|
|
59
|
+
case 'password_changed':
|
|
60
|
+
return sendTemplate(email.to, 'password-changed', {});
|
|
61
|
+
case 'new_sign_in':
|
|
62
|
+
return sendTemplate(email.to, 'new-sign-in', { ipAddress: email.ipAddress, device: email.userAgent });
|
|
63
|
+
case 'confirm_email_change':
|
|
64
|
+
return sendTemplate(email.to, 'confirm-email-change', { link: `https://myapp.com/confirm-email?token=${email.token}` });
|
|
65
|
+
case 'email_changed':
|
|
66
|
+
return sendTemplate(email.to, 'email-changed', { newEmail: email.newEmail });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
| `type` | Extra fields | When |
|
|
73
|
+
|---|---|---|
|
|
74
|
+
| `verify_email` | `token` | Registration, or `POST /auth/email/send-verification` |
|
|
75
|
+
| `reset_password` | `token` | `POST /auth/password/forgot` |
|
|
76
|
+
| `magic_sign_in` | `token` | `POST /auth/magic-link/send` |
|
|
77
|
+
| `sign_in_code` | `code` | `POST /auth/email/send-otp` |
|
|
78
|
+
| `organization_invitation` | `token`, `organizationName`, `invitedByName` | Organization admin invites someone |
|
|
79
|
+
| `password_changed` | none | Password changed or reset (if `password.notifyOnChange`) |
|
|
80
|
+
| `new_sign_in` | `ipAddress`, `userAgent` | Sign-in from a new device (if `security.notifyOnNewSignIn`) |
|
|
81
|
+
| `confirm_email_change` | `token` | `POST /auth/email/change`; sent to the **new** address. Your link page calls `POST /auth/email/change/confirm` |
|
|
82
|
+
| `email_changed` | `newEmail` (masked, e.g. `a***@mail.com`) | The change was confirmed; sent to the **old** address. Tell the user how to contact support if it wasn't them |
|
|
83
|
+
|
|
84
|
+
If `send` throws for a code or link the user is waiting for, the request fails with `INTERNAL_SERVER_ERROR`, so the user knows to try again. Failures of notice emails (`password_changed`, `new_sign_in`, `email_changed`) are only logged.
|
|
85
|
+
|
|
86
|
+
### SMS sender
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
import { Msg91SmsSender } from '@techelusive/nest-auth';
|
|
90
|
+
|
|
91
|
+
smsSender: new Msg91SmsSender({
|
|
92
|
+
authKey: process.env.MSG91_AUTH_KEY!,
|
|
93
|
+
templateId: process.env.MSG91_TEMPLATE_ID!, // DLT-approved template, e.g. "Your MyApp code is ##otp##"
|
|
94
|
+
codeVariableName: 'otp', // the variable used in your template (default "otp")
|
|
95
|
+
}),
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
For any other provider (Twilio, AWS SNS, Vonage...), implement the interface:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
const twilioSender: SmsSender = {
|
|
102
|
+
async sendCode(phoneNumber, code) {
|
|
103
|
+
await twilio.messages.create({ to: phoneNumber, from: TWILIO_NUMBER, body: `Your MyApp code is ${code}` });
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Phone numbers are always passed in E.164 form (`+919876543210`).
|
|
109
|
+
|
|
110
|
+
## Settings
|
|
111
|
+
|
|
112
|
+
Settings are built in three layers: **defaults**, overridden by **your code**, overridden by **admin changes**. Admin changes are stored in the `auth_settings` table and reach every server within 10 seconds.
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
settings: {
|
|
116
|
+
emailOtp: { enabled: true, expiresInMinutes: 5, resendAfterSeconds: 30 },
|
|
117
|
+
google: { enabled: true, clientIds: ['1234-abc.apps.googleusercontent.com'] },
|
|
118
|
+
tokens: { accessTokenMinutes: 10, sessionDays: 30 },
|
|
119
|
+
magicLink: { enabled: true, expiresInMinutes: 30 },
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
```http
|
|
124
|
+
PATCH /auth/admin/settings
|
|
125
|
+
{ "phoneOtp": { "enabled": true, "allowedCountryCodes": ["+91"] } }
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Every change is validated, both field by field and in combination. For example, the API won't let you turn off every sign-in method or turn on Google without a client id. Invalid changes return `INVALID_SETTINGS` with a `problems` list. If a later code release makes a stored admin change invalid, the library falls back to the code settings instead of breaking sign-in.
|
|
129
|
+
|
|
130
|
+
### Reference
|
|
131
|
+
|
|
132
|
+
| Setting | Default | Notes |
|
|
133
|
+
|---|---|---|
|
|
134
|
+
| **registration** | | |
|
|
135
|
+
| `enabled` | `true` | Allow new accounts with any method. |
|
|
136
|
+
| `defaultRoles` | `["user"]` | Roles every new user gets. Users can never pick their own role. |
|
|
137
|
+
| `requireFirstAndLastName` | `true` | |
|
|
138
|
+
| `requirePhoneNumber` | `false` | Email + password sign-up must include a phone number. |
|
|
139
|
+
| `requireTermsAcceptance` | `true` | Sign-up must send `acceptTerms: true`. The time is stored. |
|
|
140
|
+
| `requirePrivacyPolicyAcceptance` | `true` | Sign-up must send `acceptPrivacyPolicy: true`. |
|
|
141
|
+
| `allowedEmailDomains` | `[]` | e.g. `["mycompany.com"]` for internal tools. Empty means any domain. |
|
|
142
|
+
| **activation** | | Which verifications move `PENDING_VERIFICATION` to `ACTIVE`. |
|
|
143
|
+
| `requireVerifiedEmail` | `true` | |
|
|
144
|
+
| `requireVerifiedPhone` | `false` | |
|
|
145
|
+
| **password** | | |
|
|
146
|
+
| `enabled` | `true` | |
|
|
147
|
+
| `minimumLength` | `10` | 8–128. |
|
|
148
|
+
| `requireUppercaseLetter` / `requireLowercaseLetter` / `requireNumber` / `requireSymbol` | `false` | Length plus the breach check is stronger than character rules (NIST 800-63B). |
|
|
149
|
+
| `rejectBreachedPasswords` | `true` | Uses haveibeenpwned.com k-anonymity; the password never leaves your server. |
|
|
150
|
+
| `notifyOnChange` | `true` | Sends a `password_changed` email. |
|
|
151
|
+
| **emailVerification** | | |
|
|
152
|
+
| `linkExpiresInHours` | `24` | 1–72. How long the "verify your email" link works. |
|
|
153
|
+
| **passwordReset** | | |
|
|
154
|
+
| `linkExpiresInMinutes` | `60` | 10–180. How long the reset link works. |
|
|
155
|
+
| **emailChange** | | |
|
|
156
|
+
| `linkExpiresInMinutes` | `60` | 10–240. How long the link confirming a new email works. |
|
|
157
|
+
| **emailOtp** | | |
|
|
158
|
+
| `enabled` | `false` | |
|
|
159
|
+
| `codeLength` | `6` | 6–8. |
|
|
160
|
+
| `expiresInMinutes` | `10` | 1–15. |
|
|
161
|
+
| `resendAfterSeconds` | `60` | 30–300. Wait before another code can go to the same email. |
|
|
162
|
+
| `allowSignUp` | `true` | An unknown email gets a new account. |
|
|
163
|
+
| **magicLink** | | |
|
|
164
|
+
| `enabled` | `false` | |
|
|
165
|
+
| `expiresInMinutes` | `15` | 5–60. How long the sign-in link works. |
|
|
166
|
+
| `allowSignUp` | `true` | |
|
|
167
|
+
| **phoneOtp** | | Needs `smsSender`. |
|
|
168
|
+
| `enabled` | `false` | |
|
|
169
|
+
| `codeLength` / `expiresInMinutes` / `resendAfterSeconds` / `allowSignUp` | `6` / `10` / `60` / `true` | Same ranges as `emailOtp`. |
|
|
170
|
+
| `allowedCountryCodes` | `[]` | e.g. `["+91"]`. Empty means any country. Limiting countries cuts SMS fraud costs. |
|
|
171
|
+
| **google** / **apple** | | |
|
|
172
|
+
| `enabled` | `false` | |
|
|
173
|
+
| `clientIds` | `[]` | Google: your OAuth client ids (web, Android, iOS). Apple: bundle id and/or Services id. |
|
|
174
|
+
| **facebook** | | Needs `facebookAppSecret`. |
|
|
175
|
+
| `enabled` / `appId` | `false` / `""` | |
|
|
176
|
+
| **passkeys** | | Needs `passkeys` option. |
|
|
177
|
+
| `enabled` | `false` | |
|
|
178
|
+
| **twoFactor** | | |
|
|
179
|
+
| `enabled` | `true` | Users *may* turn on 2FA. It is never forced. |
|
|
180
|
+
| `challengeExpiresInMinutes` | `5` | 2–15. Time to enter the 2FA code after the password (or code) was right. |
|
|
181
|
+
| **organizations** | | |
|
|
182
|
+
| `enabled` | `false` | |
|
|
183
|
+
| `allowUsersToCreate` | `true` | Otherwise only app admins can create organizations. |
|
|
184
|
+
| `invitationExpiresInDays` | `7` | 1–30. How long an emailed invitation can be accepted. |
|
|
185
|
+
| **tokens** | | |
|
|
186
|
+
| `accessTokenMinutes` | `15` | 5–60. |
|
|
187
|
+
| `refreshTokenDays` | `30` | 1–90; can't exceed `sessionDays`. |
|
|
188
|
+
| `sessionDays` | `90` | 1–365. Hard limit: the user must sign in again after this. |
|
|
189
|
+
| **admin** | | |
|
|
190
|
+
| `adminRoles` | `["admin"]` | Roles allowed to use `/auth/admin/*`. |
|
|
191
|
+
| **security** | | |
|
|
192
|
+
| `notifyOnNewSignIn` | `false` | Email the user when a new device signs in. |
|
|
193
|
+
| **retention** | | See [Data retention](#data-retention). |
|
|
194
|
+
| `enabled` | `true` | The hourly automatic cleanup. |
|
|
195
|
+
| `expiredRecordDays` | `7` | 1–90. Ended sessions; used or expired links, codes, 2FA challenges and invitations. |
|
|
196
|
+
| `webhookDeliveryDays` | `30` | 1–365. Delivered or failed webhook deliveries. |
|
|
197
|
+
| `auditLogDays` | `365` | 0–3650. `0` keeps the audit log forever. |
|
|
198
|
+
|
|
199
|
+
### Data retention
|
|
200
|
+
|
|
201
|
+
Without cleanup, tables such as sessions, codes and the audit log grow forever. Every server runs a cleanup once an hour (first run a minute after start) that deletes, in batches of 5,000 rows:
|
|
202
|
+
|
|
203
|
+
| Rows | Deleted after |
|
|
204
|
+
|---|---|
|
|
205
|
+
| Sessions that ended (signed out, expired, revoked) and their refresh tokens | `expiredRecordDays` after they ended |
|
|
206
|
+
| Expired refresh tokens of sessions still in use | `expiredRecordDays` after they expired |
|
|
207
|
+
| Used or expired email links, one-time codes and 2FA challenges | `expiredRecordDays` |
|
|
208
|
+
| Accepted, cancelled or expired organization invitations | `expiredRecordDays` |
|
|
209
|
+
| Delivered or failed webhook deliveries (pending ones are never removed) | `webhookDeliveryDays` |
|
|
210
|
+
| Audit log entries | `auditLogDays` (`0` = never) |
|
|
211
|
+
|
|
212
|
+
Users, organizations, passkeys, API keys and other live data are never touched. Several servers running the cleanup at once is harmless. To run it on your own schedule instead, set `retention.enabled: false` and call `DataRetentionService.runCleanup()` (or `POST /auth/admin/maintenance/cleanup`).
|
|
213
|
+
|
|
214
|
+
Pick `auditLogDays` with your legal team: security logs are often kept for 1 year, but some industries require longer.
|
|
215
|
+
|
|
216
|
+
### Constants (not runtime settings)
|
|
217
|
+
|
|
218
|
+
Rate limits, attempt limits, Argon2 parameters and other security constants live in [`src/constants.ts`](../src/constants.ts). They are deliberately not settings, so they can't be weakened at runtime. (Timings such as link and code lifetimes *are* settings, listed above, each with a safe range.) Notable values:
|
|
219
|
+
|
|
220
|
+
| What | Value |
|
|
221
|
+
|---|---|
|
|
222
|
+
| Sign-in attempts | 30 per IP and 10 per account per 15 minutes |
|
|
223
|
+
| Sign-ups | 10 per IP per hour |
|
|
224
|
+
| Codes sent | 10 per IP and 5 per phone/email per hour (plus `resendAfterSeconds` between codes) |
|
|
225
|
+
| Emailed links | 10 per IP and 3 per email per hour |
|
|
226
|
+
| Wrong code attempts | 5 per code; 5 per 2FA challenge |
|
|
227
|
+
| Passkey prompt | must finish within 5 minutes |
|
|
228
|
+
| Reactivation | 10 minutes to confirm after proving who you are |
|
|
229
|
+
| "Recent sign-in" for email change without a password | 10 minutes |
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Endpoints: requests and responses
|
|
2
|
+
|
|
3
|
+
Every endpoint, with its exact request body, response body and errors, for the backend and frontend developers who integrate with it.
|
|
4
|
+
|
|
5
|
+
| Page | Endpoints |
|
|
6
|
+
|---|---|
|
|
7
|
+
| [Email + password](email-password.md) | register, login, email verification, forgot / reset / change password |
|
|
8
|
+
| [Passwordless](passwordless.md) | email code, magic link, phone code |
|
|
9
|
+
| [Social sign-in](social.md) | Google, Apple, Facebook, link / unlink |
|
|
10
|
+
| [Passkeys](passkeys.md) | add, sign in, list, rename, remove |
|
|
11
|
+
| [Two-factor](two-factor.md) | setup, enable, verify, disable, backup codes |
|
|
12
|
+
| [Account and sessions](account.md) | refresh, logout, me, devices, email change, download my data, health, deactivate / reactivate, delete |
|
|
13
|
+
| [Organizations](organizations.md) | organizations, members, invitations, switch |
|
|
14
|
+
| [Admin](admin.md) | users, settings, audit log, API keys, webhooks, signing keys |
|
|
15
|
+
|
|
16
|
+
## How to call the API
|
|
17
|
+
|
|
18
|
+
```http
|
|
19
|
+
POST /auth/login HTTP/1.1
|
|
20
|
+
Host: api.myapp.com
|
|
21
|
+
Content-Type: application/json
|
|
22
|
+
Authorization: Bearer eyJhbGciOiJFUzI1NiIs... ← only on routes that need a signed-in user
|
|
23
|
+
|
|
24
|
+
{ "email": "asha@example.com", "password": "correct horse battery" }
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
- **Body:** request bodies are JSON. **Unknown fields are rejected** with `VALIDATION_ERROR`, so only send the fields listed.
|
|
28
|
+
- **Success:** every success response contains `"success": true`. Every error contains `"success": false`, `code` and `message`.
|
|
29
|
+
- **Server-to-server:** routes your app marks with `@ApiKeyScopes()` accept an `x-api-key: ak_...` header instead of a bearer token.
|
|
30
|
+
- **Paths:** the paths are defined in `ROUTES` in `src/constants.ts`, and exported, so TypeScript clients can import them instead of typing paths.
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { ROUTES } from '@techelusive/nest-auth';
|
|
34
|
+
const loginUrl = `${API_URL}/${ROUTES.auth.prefix}/${ROUTES.auth.login}`; // https://api.myapp.com/auth/login
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Errors every endpoint can return
|
|
38
|
+
|
|
39
|
+
| Status | `code` | When | Extra fields |
|
|
40
|
+
|---|---|---|---|
|
|
41
|
+
| 400 | `VALIDATION_ERROR` | Missing, wrongly typed, too long or unknown field | `problems: string[]` |
|
|
42
|
+
| 401 | `UNAUTHORIZED` | Route needs a signed-in user and no token was sent | |
|
|
43
|
+
| 401 | `INVALID_TOKEN` | Access token expired or invalid: refresh and retry once | |
|
|
44
|
+
| 429 | `TOO_MANY_REQUESTS` | Rate limit hit (also a `Retry-After` header) | `retryAfterSeconds: number` |
|
|
45
|
+
| 500 | `INTERNAL_SERVER_ERROR` | Unexpected failure, or an email/SMS could not be sent | |
|
|
46
|
+
|
|
47
|
+
Example:
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"success": false,
|
|
52
|
+
"code": "VALIDATION_ERROR",
|
|
53
|
+
"message": "Some fields are missing or invalid.",
|
|
54
|
+
"problems": ["email must be a string", "property role should not exist"]
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Each endpoint page lists only its **own** errors in addition to these. All codes are explained in [Error codes](../error-codes.md).
|
|
59
|
+
|
|
60
|
+
## Shared objects
|
|
61
|
+
|
|
62
|
+
### Sign-in result
|
|
63
|
+
|
|
64
|
+
Every endpoint that signs a user in returns **one of these two**.
|
|
65
|
+
|
|
66
|
+
**Signed in:**
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"success": true,
|
|
71
|
+
"status": "signed_in",
|
|
72
|
+
"accessToken": "eyJhbGciOiJFUzI1NiIsInR5cCI6ImF0K2p3dCIsImtpZCI6Ii4uLiJ9.eyJzdWIiOiI1ZjBj...",
|
|
73
|
+
"expiresIn": 900,
|
|
74
|
+
"refreshToken": "rt_Q2x4bWZkY2V0ZXN0dG9rZW5leGFtcGxlMTIzNDU2Nzg5MDE",
|
|
75
|
+
"refreshTokenExpiresAt": "2026-11-19T06:30:00.000Z",
|
|
76
|
+
"sessionId": "8c1e2f4a-3b6d-4e8f-9a1b-2c3d4e5f6a7b",
|
|
77
|
+
"user": { "...": "the user object below" }
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Two-factor code needed** (then call `POST /auth/2fa/verify`):
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"success": true,
|
|
86
|
+
"status": "two_factor_required",
|
|
87
|
+
"challengeToken": "ch_Zm9vYmFyZXhhbXBsZWNoYWxsZW5nZXRva2VuMTIzNDU2Nzg",
|
|
88
|
+
"expiresIn": 300
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Any sign-in can also fail with these errors, but only **after** the user has proven who they are:
|
|
93
|
+
|
|
94
|
+
| Status | `code` | Extra fields | What the app should do |
|
|
95
|
+
|---|---|---|---|
|
|
96
|
+
| 403 | `ACCOUNT_NOT_VERIFIED` | `pendingVerifications: ("email"\|"phone")[]`, `email?`, `phoneNumber?` | Open the verification screen |
|
|
97
|
+
| 403 | `ACCOUNT_DEACTIVATED` | `reactivationToken: string`, `expiresIn: number` | Offer `POST /auth/reactivate` |
|
|
98
|
+
| 403 | `ACCOUNT_SUSPENDED` | | Show "contact support" |
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"success": false,
|
|
103
|
+
"code": "ACCOUNT_NOT_VERIFIED",
|
|
104
|
+
"message": "Please finish verifying your account.",
|
|
105
|
+
"pendingVerifications": ["email"],
|
|
106
|
+
"email": "asha@example.com"
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### User object
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"id": "5f0c8a2e-1d3b-4c5a-9e7f-0a1b2c3d4e5f",
|
|
115
|
+
"email": "asha@example.com",
|
|
116
|
+
"isEmailVerified": true,
|
|
117
|
+
"phoneNumber": "+919876543210",
|
|
118
|
+
"isPhoneVerified": false,
|
|
119
|
+
"firstName": "Asha",
|
|
120
|
+
"lastName": "Rao",
|
|
121
|
+
"roles": ["user"],
|
|
122
|
+
"status": "ACTIVE",
|
|
123
|
+
"pendingVerifications": [],
|
|
124
|
+
"onboardingCompleted": false,
|
|
125
|
+
"isTwoFactorEnabled": false,
|
|
126
|
+
"metadata": {},
|
|
127
|
+
"lastSignedInAt": "2026-10-20T06:30:00.000Z",
|
|
128
|
+
"createdAt": "2026-10-01T09:00:00.000Z"
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
| Field | Type | Notes |
|
|
133
|
+
|---|---|---|
|
|
134
|
+
| `email`, `phoneNumber` | `string \| null` | At least one is set. Phone numbers are E.164 (`+919876543210`). |
|
|
135
|
+
| `roles` | `string[]` | App-wide roles. Users never set their own. |
|
|
136
|
+
| `status` | `"PENDING_VERIFICATION" \| "ACTIVE" \| "SUSPENDED" \| "DEACTIVATED" \| "DELETED"` | |
|
|
137
|
+
| `pendingVerifications` | `("email" \| "phone")[]` | What is still needed before `ACTIVE`. |
|
|
138
|
+
| `onboardingCompleted` | `boolean` | Set by your app via `UsersService.completeOnboarding`. |
|
|
139
|
+
| `metadata` | `object` | Your app's own fields. |
|
|
140
|
+
| `lastSignedInAt` | `string \| null` | ISO 8601 |
|
|
141
|
+
|
|
142
|
+
### Field formats used on these pages
|
|
143
|
+
|
|
144
|
+
| Format | Meaning |
|
|
145
|
+
|---|---|
|
|
146
|
+
| email | Up to 254 characters; trimmed and lowercased by the server |
|
|
147
|
+
| phone | International number with country code, up to 32 characters typed; spaces, dashes and brackets are removed (`+91 98765-43210` → `+919876543210`) |
|
|
148
|
+
| password | Up to 128 characters; the minimum length and rules come from the settings (default: at least 10 characters, not found in data breaches) |
|
|
149
|
+
| token | The token from an email link or a previous response, up to 128 characters |
|
|
150
|
+
| code | The 6-digit code (or backup code), up to 16 characters |
|
|
151
|
+
| uuid | An id such as `5f0c8a2e-1d3b-4c5a-9e7f-0a1b2c3d4e5f`. A path parameter that isn't a uuid returns `400` |
|