@techelusive/nest-auth 0.0.0-stage → 0.2.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/CHANGELOG.md +64 -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,97 @@
|
|
|
1
|
+
import { AuthOptions } from '../../auth-options.js';
|
|
2
|
+
import { SocialProvider } from '../../database/entities/index.js';
|
|
3
|
+
import { AuthSettings } from '../settings/settings.types.js';
|
|
4
|
+
/** Who the provider says the user is. */
|
|
5
|
+
export interface SocialIdentity {
|
|
6
|
+
provider: SocialProvider;
|
|
7
|
+
/** The provider's permanent id for the user ("sub"). Emails can change; this can't. */
|
|
8
|
+
providerUserId: string;
|
|
9
|
+
email: string | null;
|
|
10
|
+
/** True only when the provider itself confirmed the user owns the email. */
|
|
11
|
+
isEmailVerified: boolean;
|
|
12
|
+
firstName: string | null;
|
|
13
|
+
lastName: string | null;
|
|
14
|
+
}
|
|
15
|
+
/** What the app sends after the user signed in with the provider's own SDK or button. */
|
|
16
|
+
export interface SocialCredential {
|
|
17
|
+
/** Google / Apple: the ID token (a JWT). Facebook: the user access token. */
|
|
18
|
+
token: string;
|
|
19
|
+
/**
|
|
20
|
+
* Optional. If your app put a nonce in the provider request, send the same raw nonce here.
|
|
21
|
+
* It ties the token to this sign-in so a stolen token can't be replayed. Strongly recommended for Apple.
|
|
22
|
+
*/
|
|
23
|
+
nonce?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Checks tokens from Google, Apple and Facebook WITHOUT trusting the app: signatures are verified
|
|
27
|
+
* against the provider's published keys (Google, Apple) or the token is checked with Facebook's API.
|
|
28
|
+
*/
|
|
29
|
+
export declare class SocialProvidersService {
|
|
30
|
+
private readonly options;
|
|
31
|
+
private readonly logger;
|
|
32
|
+
private readonly googleKeys;
|
|
33
|
+
private readonly appleKeys;
|
|
34
|
+
constructor(options: AuthOptions);
|
|
35
|
+
/**
|
|
36
|
+
* Checks a provider token and returns who it belongs to.
|
|
37
|
+
*
|
|
38
|
+
* @param provider - "google", "apple" or "facebook".
|
|
39
|
+
* @param credential - The token (and optional nonce) the app got from the provider.
|
|
40
|
+
* @param settings - The current settings (which providers are on, client ids).
|
|
41
|
+
* @returns The provider's user id, email and names.
|
|
42
|
+
* @throws AuthError SIGN_IN_METHOD_DISABLED when the provider is turned off.
|
|
43
|
+
* @throws AuthError NOT_CONFIGURED when client ids or the Facebook app secret are missing.
|
|
44
|
+
* @throws AuthError INVALID_SOCIAL_TOKEN when the token doesn't check out.
|
|
45
|
+
*/
|
|
46
|
+
verifyCredential(provider: SocialProvider, credential: SocialCredential, settings: AuthSettings): Promise<SocialIdentity>;
|
|
47
|
+
/**
|
|
48
|
+
* @param credential - Google's ID token and optional nonce.
|
|
49
|
+
* @param clientIds - Your Google OAuth client ids (web, iOS, Android).
|
|
50
|
+
* @returns The identity from the token.
|
|
51
|
+
* @throws AuthError INVALID_SOCIAL_TOKEN when the token doesn't check out.
|
|
52
|
+
*/
|
|
53
|
+
private verifyGoogleIdToken;
|
|
54
|
+
/**
|
|
55
|
+
* @param credential - Apple's ID token and optional nonce.
|
|
56
|
+
* @param clientIds - Your Apple Services ID / bundle ids.
|
|
57
|
+
* @returns The identity from the token (names are always null; Apple sends them to the app only).
|
|
58
|
+
* @throws AuthError INVALID_SOCIAL_TOKEN when the token doesn't check out.
|
|
59
|
+
*/
|
|
60
|
+
private verifyAppleIdToken;
|
|
61
|
+
/**
|
|
62
|
+
* Shared ID-token checks: signature, issuer, audience, expiry, and the nonce when given.
|
|
63
|
+
*
|
|
64
|
+
* @param credential - The ID token and optional nonce.
|
|
65
|
+
* @param providerKeys - The provider's public keys.
|
|
66
|
+
* @param issuers - Accepted "iss" values.
|
|
67
|
+
* @param clientIds - Accepted "aud" values (your client ids).
|
|
68
|
+
* @returns The token's claims.
|
|
69
|
+
* @throws AuthError NOT_CONFIGURED when no client ids are set.
|
|
70
|
+
* @throws AuthError INVALID_SOCIAL_TOKEN when any check fails.
|
|
71
|
+
*/
|
|
72
|
+
private verifyProviderIdToken;
|
|
73
|
+
/**
|
|
74
|
+
* Apple puts sha256(rawNonce) in the token; Google puts the raw nonce. Accept either form.
|
|
75
|
+
*
|
|
76
|
+
* @param rawNonce - The nonce the app sent.
|
|
77
|
+
* @param nonceInToken - The "nonce" claim from the token.
|
|
78
|
+
* @returns True when they match.
|
|
79
|
+
*/
|
|
80
|
+
private nonceMatches;
|
|
81
|
+
/**
|
|
82
|
+
* Asks Facebook whether the access token is valid and was issued to OUR app, then reads the profile.
|
|
83
|
+
*
|
|
84
|
+
* @param accessToken - The user access token from the Facebook SDK.
|
|
85
|
+
* @param appId - Your Facebook app id.
|
|
86
|
+
* @returns The identity. The email is never treated as verified.
|
|
87
|
+
* @throws AuthError NOT_CONFIGURED when the app id or secret is missing.
|
|
88
|
+
* @throws AuthError INVALID_SOCIAL_TOKEN when the token is invalid or for another app.
|
|
89
|
+
*/
|
|
90
|
+
private verifyFacebookAccessToken;
|
|
91
|
+
/**
|
|
92
|
+
* @param url - A Facebook Graph API URL.
|
|
93
|
+
* @returns The JSON response, or null for a non-2xx answer.
|
|
94
|
+
* @throws AuthError INTERNAL_SERVER_ERROR when Facebook can't be reached.
|
|
95
|
+
*/
|
|
96
|
+
private fetchFacebookJson;
|
|
97
|
+
}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.SocialProvidersService = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const node_crypto_1 = require("node:crypto");
|
|
18
|
+
const auth_error_1 = require("../../common/auth-error.js");
|
|
19
|
+
const jwt_1 = require("../../common/crypto/jwt.js");
|
|
20
|
+
const remote_public_keys_1 = require("../../common/crypto/remote-public-keys.js");
|
|
21
|
+
const random_secrets_1 = require("../../common/crypto/random-secrets.js");
|
|
22
|
+
const constants_1 = require("../../constants.js");
|
|
23
|
+
/**
|
|
24
|
+
* Checks tokens from Google, Apple and Facebook WITHOUT trusting the app: signatures are verified
|
|
25
|
+
* against the provider's published keys (Google, Apple) or the token is checked with Facebook's API.
|
|
26
|
+
*/
|
|
27
|
+
let SocialProvidersService = class SocialProvidersService {
|
|
28
|
+
options;
|
|
29
|
+
logger = new common_1.Logger(constants_1.LOG_CONTEXT.socialProviders);
|
|
30
|
+
googleKeys = new remote_public_keys_1.RemotePublicKeys(constants_1.GOOGLE_PUBLIC_KEYS_URL);
|
|
31
|
+
appleKeys = new remote_public_keys_1.RemotePublicKeys(constants_1.APPLE_PUBLIC_KEYS_URL);
|
|
32
|
+
constructor(options) {
|
|
33
|
+
this.options = options;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Checks a provider token and returns who it belongs to.
|
|
37
|
+
*
|
|
38
|
+
* @param provider - "google", "apple" or "facebook".
|
|
39
|
+
* @param credential - The token (and optional nonce) the app got from the provider.
|
|
40
|
+
* @param settings - The current settings (which providers are on, client ids).
|
|
41
|
+
* @returns The provider's user id, email and names.
|
|
42
|
+
* @throws AuthError SIGN_IN_METHOD_DISABLED when the provider is turned off.
|
|
43
|
+
* @throws AuthError NOT_CONFIGURED when client ids or the Facebook app secret are missing.
|
|
44
|
+
* @throws AuthError INVALID_SOCIAL_TOKEN when the token doesn't check out.
|
|
45
|
+
*/
|
|
46
|
+
async verifyCredential(provider, credential, settings) {
|
|
47
|
+
switch (provider) {
|
|
48
|
+
case constants_1.SOCIAL_PROVIDER.google:
|
|
49
|
+
if (!settings.google.enabled)
|
|
50
|
+
throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.signInMethodDisabled);
|
|
51
|
+
return this.verifyGoogleIdToken(credential, settings.google.clientIds);
|
|
52
|
+
case constants_1.SOCIAL_PROVIDER.apple:
|
|
53
|
+
if (!settings.apple.enabled)
|
|
54
|
+
throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.signInMethodDisabled);
|
|
55
|
+
return this.verifyAppleIdToken(credential, settings.apple.clientIds);
|
|
56
|
+
case constants_1.SOCIAL_PROVIDER.facebook:
|
|
57
|
+
if (!settings.facebook.enabled)
|
|
58
|
+
throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.signInMethodDisabled);
|
|
59
|
+
return this.verifyFacebookAccessToken(credential.token, settings.facebook.appId);
|
|
60
|
+
default:
|
|
61
|
+
throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.signInMethodDisabled);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// -------------------------------------------------------------------------------------------
|
|
65
|
+
// Google: an RS256 ID token whose "aud" must be one of YOUR client ids.
|
|
66
|
+
// -------------------------------------------------------------------------------------------
|
|
67
|
+
/**
|
|
68
|
+
* @param credential - Google's ID token and optional nonce.
|
|
69
|
+
* @param clientIds - Your Google OAuth client ids (web, iOS, Android).
|
|
70
|
+
* @returns The identity from the token.
|
|
71
|
+
* @throws AuthError INVALID_SOCIAL_TOKEN when the token doesn't check out.
|
|
72
|
+
*/
|
|
73
|
+
async verifyGoogleIdToken(credential, clientIds) {
|
|
74
|
+
const claims = await this.verifyProviderIdToken(credential, this.googleKeys, constants_1.GOOGLE_TOKEN_ISSUERS, clientIds);
|
|
75
|
+
return {
|
|
76
|
+
provider: constants_1.SOCIAL_PROVIDER.google,
|
|
77
|
+
providerUserId: claims.sub,
|
|
78
|
+
email: typeof claims.email === 'string' ? claims.email.toLowerCase() : null,
|
|
79
|
+
isEmailVerified: claims.email_verified === true,
|
|
80
|
+
firstName: typeof claims.given_name === 'string' ? claims.given_name : null,
|
|
81
|
+
lastName: typeof claims.family_name === 'string' ? claims.family_name : null,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
// -------------------------------------------------------------------------------------------
|
|
85
|
+
// Apple: like Google. Apple sends the user's name only to the app, only the first time, so
|
|
86
|
+
// the app passes it in the sign-up details. The email may be a private relay address.
|
|
87
|
+
// -------------------------------------------------------------------------------------------
|
|
88
|
+
/**
|
|
89
|
+
* @param credential - Apple's ID token and optional nonce.
|
|
90
|
+
* @param clientIds - Your Apple Services ID / bundle ids.
|
|
91
|
+
* @returns The identity from the token (names are always null; Apple sends them to the app only).
|
|
92
|
+
* @throws AuthError INVALID_SOCIAL_TOKEN when the token doesn't check out.
|
|
93
|
+
*/
|
|
94
|
+
async verifyAppleIdToken(credential, clientIds) {
|
|
95
|
+
const claims = await this.verifyProviderIdToken(credential, this.appleKeys, [constants_1.APPLE_TOKEN_ISSUER], clientIds);
|
|
96
|
+
return {
|
|
97
|
+
provider: constants_1.SOCIAL_PROVIDER.apple,
|
|
98
|
+
providerUserId: claims.sub,
|
|
99
|
+
email: typeof claims.email === 'string' ? claims.email.toLowerCase() : null,
|
|
100
|
+
// Apple sends this as a boolean or as the string "true".
|
|
101
|
+
isEmailVerified: claims.email_verified === true || claims.email_verified === constants_1.APPLE_TRUE_STRING,
|
|
102
|
+
firstName: null,
|
|
103
|
+
lastName: null,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Shared ID-token checks: signature, issuer, audience, expiry, and the nonce when given.
|
|
108
|
+
*
|
|
109
|
+
* @param credential - The ID token and optional nonce.
|
|
110
|
+
* @param providerKeys - The provider's public keys.
|
|
111
|
+
* @param issuers - Accepted "iss" values.
|
|
112
|
+
* @param clientIds - Accepted "aud" values (your client ids).
|
|
113
|
+
* @returns The token's claims.
|
|
114
|
+
* @throws AuthError NOT_CONFIGURED when no client ids are set.
|
|
115
|
+
* @throws AuthError INVALID_SOCIAL_TOKEN when any check fails.
|
|
116
|
+
*/
|
|
117
|
+
async verifyProviderIdToken(credential, providerKeys, issuers, clientIds) {
|
|
118
|
+
if (clientIds.length === 0)
|
|
119
|
+
throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.notConfigured);
|
|
120
|
+
await providerKeys.ensureLoaded((0, jwt_1.readJwtKeyId)(credential.token));
|
|
121
|
+
const claims = (0, jwt_1.verifyJwt)(credential.token, (keyId) => providerKeys.findLoadedKey(keyId), {
|
|
122
|
+
allowedAlgorithm: constants_1.PROVIDER_ID_TOKEN_ALGORITHM,
|
|
123
|
+
expectedIssuers: issuers,
|
|
124
|
+
expectedAudiences: clientIds,
|
|
125
|
+
});
|
|
126
|
+
if (!claims || typeof claims.sub !== 'string' || claims.sub.length === 0)
|
|
127
|
+
throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.invalidSocialToken);
|
|
128
|
+
if (credential.nonce !== undefined || claims.nonce !== undefined) {
|
|
129
|
+
if (!this.nonceMatches(credential.nonce, claims.nonce))
|
|
130
|
+
throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.invalidSocialToken);
|
|
131
|
+
}
|
|
132
|
+
return claims;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Apple puts sha256(rawNonce) in the token; Google puts the raw nonce. Accept either form.
|
|
136
|
+
*
|
|
137
|
+
* @param rawNonce - The nonce the app sent.
|
|
138
|
+
* @param nonceInToken - The "nonce" claim from the token.
|
|
139
|
+
* @returns True when they match.
|
|
140
|
+
*/
|
|
141
|
+
nonceMatches(rawNonce, nonceInToken) {
|
|
142
|
+
if (typeof rawNonce !== 'string' || typeof nonceInToken !== 'string')
|
|
143
|
+
return false;
|
|
144
|
+
const hashedNonce = (0, node_crypto_1.createHash)(constants_1.HASH_ALGORITHM.sha256).update(rawNonce).digest(constants_1.TEXT_ENCODING.hex);
|
|
145
|
+
return (0, random_secrets_1.constantTimeEquals)(nonceInToken, rawNonce) || (0, random_secrets_1.constantTimeEquals)(nonceInToken, hashedNonce);
|
|
146
|
+
}
|
|
147
|
+
// -------------------------------------------------------------------------------------------
|
|
148
|
+
// Facebook: no ID token for most apps, so we ask Facebook whether the access token is valid
|
|
149
|
+
// and was issued to OUR app (otherwise a token from any other app would be accepted).
|
|
150
|
+
// -------------------------------------------------------------------------------------------
|
|
151
|
+
/**
|
|
152
|
+
* Asks Facebook whether the access token is valid and was issued to OUR app, then reads the profile.
|
|
153
|
+
*
|
|
154
|
+
* @param accessToken - The user access token from the Facebook SDK.
|
|
155
|
+
* @param appId - Your Facebook app id.
|
|
156
|
+
* @returns The identity. The email is never treated as verified.
|
|
157
|
+
* @throws AuthError NOT_CONFIGURED when the app id or secret is missing.
|
|
158
|
+
* @throws AuthError INVALID_SOCIAL_TOKEN when the token is invalid or for another app.
|
|
159
|
+
*/
|
|
160
|
+
async verifyFacebookAccessToken(accessToken, appId) {
|
|
161
|
+
const appSecret = this.options.facebookAppSecret;
|
|
162
|
+
if (!appId || !appSecret)
|
|
163
|
+
throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.notConfigured);
|
|
164
|
+
const tokenCheckUrl = new URL(`${constants_1.FACEBOOK_GRAPH_API_URL}${constants_1.FACEBOOK_API.debugTokenPath}`);
|
|
165
|
+
tokenCheckUrl.searchParams.set(constants_1.FACEBOOK_API.inputTokenParameter, accessToken);
|
|
166
|
+
tokenCheckUrl.searchParams.set(constants_1.FACEBOOK_API.accessTokenParameter, constants_1.FACEBOOK_API.appAccessToken(appId, appSecret));
|
|
167
|
+
const tokenCheck = await this.fetchFacebookJson(tokenCheckUrl);
|
|
168
|
+
const tokenData = tokenCheck?.data;
|
|
169
|
+
const tokenIsForOurApp = tokenData?.is_valid === true && String(tokenData.app_id) === appId && typeof tokenData.user_id === 'string';
|
|
170
|
+
if (!tokenIsForOurApp)
|
|
171
|
+
throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.invalidSocialToken);
|
|
172
|
+
// appsecret_proof proves the call comes from our server, not from someone holding the token.
|
|
173
|
+
const profileUrl = new URL(`${constants_1.FACEBOOK_GRAPH_API_URL}${constants_1.FACEBOOK_API.profilePath}`);
|
|
174
|
+
profileUrl.searchParams.set(constants_1.FACEBOOK_API.fieldsParameter, constants_1.FACEBOOK_PROFILE_FIELDS);
|
|
175
|
+
profileUrl.searchParams.set(constants_1.FACEBOOK_API.accessTokenParameter, accessToken);
|
|
176
|
+
profileUrl.searchParams.set(constants_1.FACEBOOK_API.appSecretProofParameter, (0, node_crypto_1.createHmac)(constants_1.HASH_ALGORITHM.sha256, appSecret).update(accessToken).digest(constants_1.TEXT_ENCODING.hex));
|
|
177
|
+
const profile = await this.fetchFacebookJson(profileUrl);
|
|
178
|
+
if (!profile || profile.id !== tokenData.user_id)
|
|
179
|
+
throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.invalidSocialToken);
|
|
180
|
+
return {
|
|
181
|
+
provider: constants_1.SOCIAL_PROVIDER.facebook,
|
|
182
|
+
providerUserId: profile.id,
|
|
183
|
+
email: typeof profile.email === 'string' ? profile.email.toLowerCase() : null,
|
|
184
|
+
// Facebook does not say whether the email was confirmed, so we never treat it as proven.
|
|
185
|
+
isEmailVerified: false,
|
|
186
|
+
firstName: typeof profile.first_name === 'string' ? profile.first_name : null,
|
|
187
|
+
lastName: typeof profile.last_name === 'string' ? profile.last_name : null,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* @param url - A Facebook Graph API URL.
|
|
192
|
+
* @returns The JSON response, or null for a non-2xx answer.
|
|
193
|
+
* @throws AuthError INTERNAL_SERVER_ERROR when Facebook can't be reached.
|
|
194
|
+
*/
|
|
195
|
+
async fetchFacebookJson(url) {
|
|
196
|
+
try {
|
|
197
|
+
const response = await fetch(url, { signal: AbortSignal.timeout(constants_1.SOCIAL_PROVIDER_TIMEOUT_MS) });
|
|
198
|
+
if (!response.ok)
|
|
199
|
+
return null;
|
|
200
|
+
return (await response.json());
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
this.logger.warn(`Facebook API call failed: ${error.message}`);
|
|
204
|
+
throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.internalError);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
exports.SocialProvidersService = SocialProvidersService;
|
|
209
|
+
exports.SocialProvidersService = SocialProvidersService = __decorate([
|
|
210
|
+
(0, common_1.Injectable)(),
|
|
211
|
+
__param(0, (0, common_1.Inject)(constants_1.AUTH_OPTIONS_TOKEN)),
|
|
212
|
+
__metadata("design:paramtypes", [Object])
|
|
213
|
+
], SocialProvidersService);
|
|
214
|
+
//# sourceMappingURL=social-providers.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"social-providers.service.js","sourceRoot":"","sources":["../../../src/features/social/social-providers.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { RequestContext } from '../../common/request-context.js';
|
|
2
|
+
import { SocialAuthService } from './social-auth.service';
|
|
3
|
+
import { SocialSignInInput } from './social.dto';
|
|
4
|
+
/**
|
|
5
|
+
* Google, Apple and Facebook.
|
|
6
|
+
*
|
|
7
|
+
* POST /auth/social/:provider sign in / sign up with the provider's token
|
|
8
|
+
* POST /auth/social/:provider/link signed in: connect the provider to this account
|
|
9
|
+
* DELETE /auth/social/:provider signed in: disconnect it
|
|
10
|
+
*
|
|
11
|
+
* :provider is "google", "apple" or "facebook".
|
|
12
|
+
*/
|
|
13
|
+
export declare class SocialController {
|
|
14
|
+
private readonly socialAuth;
|
|
15
|
+
constructor(socialAuth: SocialAuthService);
|
|
16
|
+
/**
|
|
17
|
+
* POST /auth/social/:provider — Signs in or signs up with the provider's token. Public.
|
|
18
|
+
*
|
|
19
|
+
* @param provider - From the URL.
|
|
20
|
+
* @param body - `{ token, nonce? }`, plus sign-up details for new accounts.
|
|
21
|
+
* @param request - Who is asking.
|
|
22
|
+
* @returns Tokens, or a 2FA challenge.
|
|
23
|
+
*/
|
|
24
|
+
signIn(provider: string, body: SocialSignInInput, request: RequestContext): Promise<import("../..").SignInResult>;
|
|
25
|
+
/**
|
|
26
|
+
* POST /auth/social/:provider/link — Connects the provider to the signed-in account.
|
|
27
|
+
*
|
|
28
|
+
* @param userId - From the access token.
|
|
29
|
+
* @param provider - From the URL.
|
|
30
|
+
* @param body - `{ token, nonce? }`.
|
|
31
|
+
* @param request - Who is asking.
|
|
32
|
+
* @returns `{ success: true }`.
|
|
33
|
+
*/
|
|
34
|
+
link(userId: string, provider: string, body: SocialSignInInput, request: RequestContext): Promise<{
|
|
35
|
+
success: true;
|
|
36
|
+
}>;
|
|
37
|
+
/**
|
|
38
|
+
* DELETE /auth/social/:provider — Disconnects the provider.
|
|
39
|
+
*
|
|
40
|
+
* @param userId - From the access token.
|
|
41
|
+
* @param provider - From the URL.
|
|
42
|
+
* @param request - Who is asking.
|
|
43
|
+
* @returns `{ success: true }`.
|
|
44
|
+
*/
|
|
45
|
+
unlink(userId: string, provider: string, request: RequestContext): Promise<{
|
|
46
|
+
success: true;
|
|
47
|
+
}>;
|
|
48
|
+
/**
|
|
49
|
+
* @param provider - The :provider part of the URL.
|
|
50
|
+
* @returns The provider name, now known to be supported.
|
|
51
|
+
* @throws AuthError NOT_FOUND for any other value.
|
|
52
|
+
*/
|
|
53
|
+
private parseProvider;
|
|
54
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.SocialController = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const auth_error_1 = require("../../common/auth-error.js");
|
|
18
|
+
const strict_validation_pipe_1 = require("../../common/strict-validation.pipe.js");
|
|
19
|
+
const request_context_1 = require("../../common/request-context.js");
|
|
20
|
+
const constants_1 = require("../../constants.js");
|
|
21
|
+
const auth_decorators_1 = require("../../guards/auth.decorators.js");
|
|
22
|
+
const social_auth_service_1 = require("./social-auth.service");
|
|
23
|
+
const social_dto_1 = require("./social.dto");
|
|
24
|
+
const refresh_token_cookie_1 = require("../../common/refresh-token-cookie.js");
|
|
25
|
+
/**
|
|
26
|
+
* Google, Apple and Facebook.
|
|
27
|
+
*
|
|
28
|
+
* POST /auth/social/:provider sign in / sign up with the provider's token
|
|
29
|
+
* POST /auth/social/:provider/link signed in: connect the provider to this account
|
|
30
|
+
* DELETE /auth/social/:provider signed in: disconnect it
|
|
31
|
+
*
|
|
32
|
+
* :provider is "google", "apple" or "facebook".
|
|
33
|
+
*/
|
|
34
|
+
let SocialController = class SocialController {
|
|
35
|
+
socialAuth;
|
|
36
|
+
constructor(socialAuth) {
|
|
37
|
+
this.socialAuth = socialAuth;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* POST /auth/social/:provider — Signs in or signs up with the provider's token. Public.
|
|
41
|
+
*
|
|
42
|
+
* @param provider - From the URL.
|
|
43
|
+
* @param body - `{ token, nonce? }`, plus sign-up details for new accounts.
|
|
44
|
+
* @param request - Who is asking.
|
|
45
|
+
* @returns Tokens, or a 2FA challenge.
|
|
46
|
+
*/
|
|
47
|
+
signIn(provider, body, request) {
|
|
48
|
+
return this.socialAuth.signInWithProvider(this.parseProvider(provider), body, request);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* POST /auth/social/:provider/link — Connects the provider to the signed-in account.
|
|
52
|
+
*
|
|
53
|
+
* @param userId - From the access token.
|
|
54
|
+
* @param provider - From the URL.
|
|
55
|
+
* @param body - `{ token, nonce? }`.
|
|
56
|
+
* @param request - Who is asking.
|
|
57
|
+
* @returns `{ success: true }`.
|
|
58
|
+
*/
|
|
59
|
+
link(userId, provider, body, request) {
|
|
60
|
+
return this.socialAuth.linkProvider(userId, this.parseProvider(provider), body, request);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* DELETE /auth/social/:provider — Disconnects the provider.
|
|
64
|
+
*
|
|
65
|
+
* @param userId - From the access token.
|
|
66
|
+
* @param provider - From the URL.
|
|
67
|
+
* @param request - Who is asking.
|
|
68
|
+
* @returns `{ success: true }`.
|
|
69
|
+
*/
|
|
70
|
+
unlink(userId, provider, request) {
|
|
71
|
+
return this.socialAuth.unlinkProvider(userId, this.parseProvider(provider), request);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* @param provider - The :provider part of the URL.
|
|
75
|
+
* @returns The provider name, now known to be supported.
|
|
76
|
+
* @throws AuthError NOT_FOUND for any other value.
|
|
77
|
+
*/
|
|
78
|
+
parseProvider(provider) {
|
|
79
|
+
if (!constants_1.SOCIAL_PROVIDERS.includes(provider))
|
|
80
|
+
throw new auth_error_1.AuthError(constants_1.AUTH_ERRORS.notFound);
|
|
81
|
+
return provider;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
exports.SocialController = SocialController;
|
|
85
|
+
__decorate([
|
|
86
|
+
(0, common_1.Post)(constants_1.ROUTES.social.signIn),
|
|
87
|
+
(0, auth_decorators_1.Public)(),
|
|
88
|
+
(0, common_1.HttpCode)(common_1.HttpStatus.OK),
|
|
89
|
+
__param(0, (0, common_1.Param)(constants_1.ROUTE_PARAM.provider)),
|
|
90
|
+
__param(1, (0, common_1.Body)()),
|
|
91
|
+
__param(2, (0, request_context_1.CurrentRequest)()),
|
|
92
|
+
__metadata("design:type", Function),
|
|
93
|
+
__metadata("design:paramtypes", [String, social_dto_1.SocialSignInInput, Object]),
|
|
94
|
+
__metadata("design:returntype", void 0)
|
|
95
|
+
], SocialController.prototype, "signIn", null);
|
|
96
|
+
__decorate([
|
|
97
|
+
(0, common_1.Post)(constants_1.ROUTES.social.link),
|
|
98
|
+
(0, auth_decorators_1.CheckSession)(),
|
|
99
|
+
(0, common_1.HttpCode)(common_1.HttpStatus.OK),
|
|
100
|
+
__param(0, (0, auth_decorators_1.CurrentUserId)()),
|
|
101
|
+
__param(1, (0, common_1.Param)(constants_1.ROUTE_PARAM.provider)),
|
|
102
|
+
__param(2, (0, common_1.Body)()),
|
|
103
|
+
__param(3, (0, request_context_1.CurrentRequest)()),
|
|
104
|
+
__metadata("design:type", Function),
|
|
105
|
+
__metadata("design:paramtypes", [String, String, social_dto_1.SocialSignInInput, Object]),
|
|
106
|
+
__metadata("design:returntype", void 0)
|
|
107
|
+
], SocialController.prototype, "link", null);
|
|
108
|
+
__decorate([
|
|
109
|
+
(0, common_1.Delete)(constants_1.ROUTES.social.unlink),
|
|
110
|
+
(0, auth_decorators_1.CheckSession)(),
|
|
111
|
+
__param(0, (0, auth_decorators_1.CurrentUserId)()),
|
|
112
|
+
__param(1, (0, common_1.Param)(constants_1.ROUTE_PARAM.provider)),
|
|
113
|
+
__param(2, (0, request_context_1.CurrentRequest)()),
|
|
114
|
+
__metadata("design:type", Function),
|
|
115
|
+
__metadata("design:paramtypes", [String, String, Object]),
|
|
116
|
+
__metadata("design:returntype", void 0)
|
|
117
|
+
], SocialController.prototype, "unlink", null);
|
|
118
|
+
exports.SocialController = SocialController = __decorate([
|
|
119
|
+
(0, common_1.Controller)(constants_1.ROUTES.social.prefix),
|
|
120
|
+
(0, refresh_token_cookie_1.LibraryController)(),
|
|
121
|
+
(0, common_1.UsePipes)(strict_validation_pipe_1.strictValidationPipe),
|
|
122
|
+
__metadata("design:paramtypes", [social_auth_service_1.SocialAuthService])
|
|
123
|
+
], SocialController);
|
|
124
|
+
//# sourceMappingURL=social.controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"social.controller.js","sourceRoot":"","sources":["../../../src/features/social/social.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAuG;AACvG,oDAAgD;AAChD,4EAAuE;AACvE,8DAA0E;AAC1E,2CAAiF;AAEjF,8DAA+E;AAC/E,+DAA0D;AAC1D,6CAAiD;AACjD,wEAAkE;AAElE;;;;;;;;GAQG;AAII,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;IACE;IAA7B,YAA6B,UAA6B;QAA7B,eAAU,GAAV,UAAU,CAAmB;IAAG,CAAC;IAE9D;;;;;;;OAOG;IAIH,MAAM,CAA8B,QAAgB,EAAU,IAAuB,EAAoB,OAAuB;QAC9H,OAAO,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACzF,CAAC;IAED;;;;;;;;OAQG;IAIH,IAAI,CACe,MAAc,EACF,QAAgB,EACrC,IAAuB,EACb,OAAuB;QAEzC,OAAO,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3F,CAAC;IAED;;;;;;;OAOG;IAGH,MAAM,CAAkB,MAAc,EAA+B,QAAgB,EAAoB,OAAuB;QAC9H,OAAO,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;IACvF,CAAC;IAED;;;;OAIG;IACK,aAAa,CAAC,QAAgB;QACpC,IAAI,CAAE,4BAAsC,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,MAAM,IAAI,sBAAS,CAAC,uBAAW,CAAC,QAAQ,CAAC,CAAC;QAC3G,OAAO,QAA0B,CAAC;IACpC,CAAC;CACF,CAAA;AA9DY,4CAAgB;AAc3B;IAHC,IAAA,aAAI,EAAC,kBAAM,CAAC,MAAM,CAAC,MAAM,CAAC;IAC1B,IAAA,wBAAM,GAAE;IACR,IAAA,iBAAQ,EAAC,mBAAU,CAAC,EAAE,CAAC;IAChB,WAAA,IAAA,cAAK,EAAC,uBAAW,CAAC,QAAQ,CAAC,CAAA;IAAoB,WAAA,IAAA,aAAI,GAAE,CAAA;IAA2B,WAAA,IAAA,gCAAc,GAAE,CAAA;;6CAApC,8BAAiB;;8CAEpF;AAcD;IAHC,IAAA,aAAI,EAAC,kBAAM,CAAC,MAAM,CAAC,IAAI,CAAC;IACxB,IAAA,8BAAY,GAAE;IACd,IAAA,iBAAQ,EAAC,mBAAU,CAAC,EAAE,CAAC;IAErB,WAAA,IAAA,+BAAa,GAAE,CAAA;IACf,WAAA,IAAA,cAAK,EAAC,uBAAW,CAAC,QAAQ,CAAC,CAAA;IAC3B,WAAA,IAAA,aAAI,GAAE,CAAA;IACN,WAAA,IAAA,gCAAc,GAAE,CAAA;;qDADH,8BAAiB;;4CAIhC;AAYD;IAFC,IAAA,eAAM,EAAC,kBAAM,CAAC,MAAM,CAAC,MAAM,CAAC;IAC5B,IAAA,8BAAY,GAAE;IACP,WAAA,IAAA,+BAAa,GAAE,CAAA;IAAkB,WAAA,IAAA,cAAK,EAAC,uBAAW,CAAC,QAAQ,CAAC,CAAA;IAAoB,WAAA,IAAA,gCAAc,GAAE,CAAA;;;;8CAEvG;2BAnDU,gBAAgB;IAH5B,IAAA,mBAAU,EAAC,kBAAM,CAAC,MAAM,CAAC,MAAM,CAAC;IAChC,IAAA,wCAAiB,GAAE;IACnB,IAAA,iBAAQ,EAAC,6CAAoB,CAAC;qCAEY,uCAAiB;GAD/C,gBAAgB,CA8D5B"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { SignUpDetailsInput } from '../passwordless/passwordless.dto.js';
|
|
2
|
+
/**
|
|
3
|
+
* POST /auth/social/google | apple | facebook
|
|
4
|
+
* (and POST /auth/social/:provider/link for a signed-in user)
|
|
5
|
+
*/
|
|
6
|
+
export declare class SocialSignInInput extends SignUpDetailsInput {
|
|
7
|
+
/** Google / Apple: the ID token. Facebook: the user access token. */
|
|
8
|
+
token: string;
|
|
9
|
+
/** The raw nonce your app used in the provider request, if any. */
|
|
10
|
+
nonce?: string;
|
|
11
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.SocialSignInInput = void 0;
|
|
13
|
+
const class_validator_1 = require("class-validator");
|
|
14
|
+
const constants_1 = require("../../constants.js");
|
|
15
|
+
const passwordless_dto_1 = require("../passwordless/passwordless.dto.js");
|
|
16
|
+
/**
|
|
17
|
+
* POST /auth/social/google | apple | facebook
|
|
18
|
+
* (and POST /auth/social/:provider/link for a signed-in user)
|
|
19
|
+
*/
|
|
20
|
+
class SocialSignInInput extends passwordless_dto_1.SignUpDetailsInput {
|
|
21
|
+
/** Google / Apple: the ID token. Facebook: the user access token. */
|
|
22
|
+
token;
|
|
23
|
+
/** The raw nonce your app used in the provider request, if any. */
|
|
24
|
+
nonce;
|
|
25
|
+
}
|
|
26
|
+
exports.SocialSignInInput = SocialSignInInput;
|
|
27
|
+
__decorate([
|
|
28
|
+
(0, class_validator_1.IsString)(),
|
|
29
|
+
(0, class_validator_1.MaxLength)(constants_1.SOCIAL_TOKEN_INPUT_MAX_LENGTH),
|
|
30
|
+
__metadata("design:type", String)
|
|
31
|
+
], SocialSignInInput.prototype, "token", void 0);
|
|
32
|
+
__decorate([
|
|
33
|
+
(0, class_validator_1.IsOptional)(),
|
|
34
|
+
(0, class_validator_1.IsString)(),
|
|
35
|
+
(0, class_validator_1.MaxLength)(constants_1.NONCE_INPUT_MAX_LENGTH),
|
|
36
|
+
__metadata("design:type", String)
|
|
37
|
+
], SocialSignInInput.prototype, "nonce", void 0);
|
|
38
|
+
//# sourceMappingURL=social.dto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"social.dto.js","sourceRoot":"","sources":["../../../src/features/social/social.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAAkE;AAClE,2CAAoF;AACpF,+EAA8E;AAE9E;;;GAGG;AACH,MAAa,iBAAkB,SAAQ,qCAAkB;IACvD,qEAAqE;IAErE,KAAK,CAAS;IAEd,mEAAmE;IAEnE,KAAK,CAAU;CAChB;AARD,8CAQC;AALC;IADC,IAAA,0BAAQ,GAAE;IAAE,IAAA,2BAAS,EAAC,yCAA6B,CAAC;;gDACvC;AAId;IADC,IAAA,4BAAU,GAAE;IAAE,IAAA,0BAAQ,GAAE;IAAE,IAAA,2BAAS,EAAC,kCAAsB,CAAC;;gDAC7C"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { RequestContext } from '../../common/request-context.js';
|
|
2
|
+
import { AccessTokenClaims } from '../sessions/session.types.js';
|
|
3
|
+
import { UsersService } from '../users/users.service.js';
|
|
4
|
+
import { TwoFactorCodeInput, VerifyTwoFactorChallengeInput } from './two-factor.dto';
|
|
5
|
+
import { TwoFactorService } from './two-factor.service';
|
|
6
|
+
/**
|
|
7
|
+
* Two-factor authentication (authenticator app + backup codes).
|
|
8
|
+
*
|
|
9
|
+
* GET /auth/2fa is it on? how many backup codes are left?
|
|
10
|
+
* POST /auth/2fa/setup start: get the secret and QR-code URL
|
|
11
|
+
* POST /auth/2fa/enable finish: first code -> backup codes
|
|
12
|
+
* POST /auth/2fa/disable turn off (needs a code)
|
|
13
|
+
* POST /auth/2fa/backup-codes new backup codes (needs a code)
|
|
14
|
+
* POST /auth/2fa/verify second step of sign-in
|
|
15
|
+
*/
|
|
16
|
+
export declare class TwoFactorController {
|
|
17
|
+
private readonly twoFactor;
|
|
18
|
+
private readonly users;
|
|
19
|
+
constructor(twoFactor: TwoFactorService, users: UsersService);
|
|
20
|
+
/**
|
|
21
|
+
* GET /auth/2fa — Is 2FA on for the signed-in user, and how many backup codes are left?
|
|
22
|
+
*
|
|
23
|
+
* @param userId - From the access token.
|
|
24
|
+
* @returns `{ isEnabled, remainingBackupCodes }`.
|
|
25
|
+
*/
|
|
26
|
+
getStatus(userId: string): Promise<{
|
|
27
|
+
success: boolean;
|
|
28
|
+
isEnabled: boolean;
|
|
29
|
+
remainingBackupCodes: number;
|
|
30
|
+
}>;
|
|
31
|
+
/**
|
|
32
|
+
* POST /auth/2fa/setup — Starts setup and returns the secret and QR-code URL.
|
|
33
|
+
*
|
|
34
|
+
* @param userId - From the access token.
|
|
35
|
+
* @returns See `TwoFactorService.startSetup`.
|
|
36
|
+
*/
|
|
37
|
+
startSetup(userId: string): Promise<{
|
|
38
|
+
success: true;
|
|
39
|
+
secret: string;
|
|
40
|
+
authenticatorAppUrl: string;
|
|
41
|
+
}>;
|
|
42
|
+
/**
|
|
43
|
+
* POST /auth/2fa/enable — Confirms setup with the first code and returns backup codes.
|
|
44
|
+
*
|
|
45
|
+
* @param user - The access token's claims (user id and session id).
|
|
46
|
+
* @param body - `{ code }`.
|
|
47
|
+
* @param request - Who is asking.
|
|
48
|
+
* @returns See `TwoFactorService.confirmSetup`.
|
|
49
|
+
*/
|
|
50
|
+
enable(user: AccessTokenClaims, body: TwoFactorCodeInput, request: RequestContext): Promise<{
|
|
51
|
+
success: true;
|
|
52
|
+
backupCodes: string[];
|
|
53
|
+
}>;
|
|
54
|
+
/**
|
|
55
|
+
* POST /auth/2fa/disable — Turns 2FA off.
|
|
56
|
+
*
|
|
57
|
+
* @param userId - From the access token.
|
|
58
|
+
* @param body - `{ code }`: an authenticator or backup code.
|
|
59
|
+
* @param request - Who is asking.
|
|
60
|
+
* @returns `{ success: true }`.
|
|
61
|
+
*/
|
|
62
|
+
disable(userId: string, body: TwoFactorCodeInput, request: RequestContext): Promise<{
|
|
63
|
+
success: true;
|
|
64
|
+
}>;
|
|
65
|
+
/**
|
|
66
|
+
* POST /auth/2fa/backup-codes — Replaces all backup codes.
|
|
67
|
+
*
|
|
68
|
+
* @param userId - From the access token.
|
|
69
|
+
* @param body - `{ code }`: an authenticator or backup code.
|
|
70
|
+
* @returns The new backup codes.
|
|
71
|
+
*/
|
|
72
|
+
regenerateBackupCodes(userId: string, body: TwoFactorCodeInput): Promise<{
|
|
73
|
+
success: true;
|
|
74
|
+
backupCodes: string[];
|
|
75
|
+
}>;
|
|
76
|
+
/**
|
|
77
|
+
* POST /auth/2fa/verify — The second step of sign-in. Public: the caller has no tokens yet.
|
|
78
|
+
*
|
|
79
|
+
* @param body - `{ challengeToken, code }`.
|
|
80
|
+
* @param request - Who is asking.
|
|
81
|
+
* @returns Access and refresh tokens.
|
|
82
|
+
*/
|
|
83
|
+
verify(body: VerifyTwoFactorChallengeInput, request: RequestContext): Promise<import("../..").SignedInResult>;
|
|
84
|
+
}
|