@breadstone/archipel-platform-authentication 0.0.1 → 0.0.3
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/package.json +37 -10
- package/src/AuthModule.d.ts +15 -1
- package/src/AuthModule.js +7 -7
- package/src/apple/env.d.ts +3 -0
- package/src/apple/env.js +20 -0
- package/src/apple/index.d.ts +2 -0
- package/src/apple/index.js +8 -0
- package/src/env.d.ts +3 -1
- package/src/env.js +4 -35
- package/src/github/env.d.ts +3 -0
- package/src/github/env.js +18 -0
- package/src/github/index.d.ts +2 -0
- package/src/github/index.js +8 -0
- package/src/google/env.d.ts +3 -0
- package/src/google/env.js +18 -0
- package/src/google/index.d.ts +2 -0
- package/src/google/index.js +8 -0
- package/src/guards/RolesGuard.js +1 -1
- package/src/guards/SocialAuthGuard.d.ts +3 -3
- package/src/guards/SocialAuthGuard.js +8 -6
- package/src/microsoft/env.d.ts +3 -0
- package/src/microsoft/env.js +19 -0
- package/src/microsoft/index.d.ts +2 -0
- package/src/microsoft/index.js +8 -0
- package/src/serializer/SessionSerializer.js +1 -2
- package/src/services/mfa/channels/EmailOtpMfaChannel.js +2 -2
- package/src/services/mfa/channels/PushMfaChannel.js +2 -2
- package/src/services/mfa/channels/SmsMfaChannel.js +2 -2
- package/src/strategies/GithubStrategy.d.ts +0 -1
- package/src/strategies/GithubStrategy.js +5 -12
- package/src/strategies/JwtStrategy.js +1 -1
- package/src/strategies/LocalStrategy.d.ts +4 -1
- package/src/strategies/LocalStrategy.js +9 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@breadstone/archipel-platform-authentication",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "JWT and OAuth authentication, MFA, session management, and email verification for NestJS applications.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -30,30 +30,42 @@
|
|
|
30
30
|
"README.md"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@breadstone/archipel-platform-core": "0.0.
|
|
34
|
-
"@breadstone/archipel-platform-database": "0.0.1",
|
|
35
|
-
"@breadstone/archipel-platform-mailing": "0.0.1",
|
|
36
|
-
"@breadstone/archipel-platform-openapi": "0.0.1",
|
|
33
|
+
"@breadstone/archipel-platform-core": "0.0.3",
|
|
37
34
|
"@nestjs/common": "11.1.18",
|
|
38
35
|
"@nestjs/core": "11.1.18",
|
|
39
36
|
"@nestjs/jwt": "11.0.2",
|
|
40
37
|
"@nestjs/passport": "11.0.5",
|
|
41
38
|
"@nestjs/swagger": "11.2.6",
|
|
42
|
-
"bcrypt": "6.0.0",
|
|
43
39
|
"class-transformer": "0.5.1",
|
|
44
40
|
"class-validator": "0.15.1",
|
|
45
41
|
"express": "5.2.1",
|
|
46
42
|
"passport": "0.7.0",
|
|
47
|
-
"passport-apple": "2.0.2",
|
|
48
43
|
"passport-custom": "1.1.1",
|
|
49
|
-
"passport-github2": "0.1.12",
|
|
50
|
-
"passport-google-oauth20": "2.0.0",
|
|
51
44
|
"passport-jwt": "4.0.1",
|
|
52
45
|
"passport-local": "1.0.0",
|
|
53
|
-
"passport-microsoft": "2.1.0",
|
|
54
46
|
"rxjs": "7.8.2",
|
|
55
47
|
"tslib": "2.8.1"
|
|
56
48
|
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"passport-apple": "^2.0.2",
|
|
51
|
+
"passport-github2": "^0.1.12",
|
|
52
|
+
"passport-google-oauth20": "^2.0.0",
|
|
53
|
+
"passport-microsoft": "^2.1.0"
|
|
54
|
+
},
|
|
55
|
+
"peerDependenciesMeta": {
|
|
56
|
+
"passport-apple": {
|
|
57
|
+
"optional": true
|
|
58
|
+
},
|
|
59
|
+
"passport-github2": {
|
|
60
|
+
"optional": true
|
|
61
|
+
},
|
|
62
|
+
"passport-google-oauth20": {
|
|
63
|
+
"optional": true
|
|
64
|
+
},
|
|
65
|
+
"passport-microsoft": {
|
|
66
|
+
"optional": true
|
|
67
|
+
}
|
|
68
|
+
},
|
|
57
69
|
"devDependencies": {
|
|
58
70
|
"@types/passport-apple": "2.0.3",
|
|
59
71
|
"@types/passport-github2": "1.2.9",
|
|
@@ -63,5 +75,20 @@
|
|
|
63
75
|
"@types/passport-microsoft": "2.1.1",
|
|
64
76
|
"@types/qrcode": "1.5.6",
|
|
65
77
|
"vitest": "4.1.2"
|
|
78
|
+
},
|
|
79
|
+
"exports": {
|
|
80
|
+
"./package.json": "./package.json",
|
|
81
|
+
".": {
|
|
82
|
+
"types": "./src/index.d.ts",
|
|
83
|
+
"default": "./src/index.js"
|
|
84
|
+
},
|
|
85
|
+
"./apple": "./src/apple/index.js",
|
|
86
|
+
"./apple/index": "./src/apple/index.js",
|
|
87
|
+
"./github": "./src/github/index.js",
|
|
88
|
+
"./github/index": "./src/github/index.js",
|
|
89
|
+
"./google": "./src/google/index.js",
|
|
90
|
+
"./google/index": "./src/google/index.js",
|
|
91
|
+
"./microsoft": "./src/microsoft/index.js",
|
|
92
|
+
"./microsoft/index": "./src/microsoft/index.js"
|
|
66
93
|
}
|
|
67
94
|
}
|
package/src/AuthModule.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type IConfigRegistryEntry } from '@breadstone/archipel-platform-core';
|
|
1
2
|
import { DynamicModule, MiddlewareConsumer, Type } from '@nestjs/common';
|
|
2
3
|
import { AuthSubjectPort } from './contracts/AuthSubjectPort';
|
|
3
4
|
import { MfaSubjectPort } from './contracts/MfaSubjectPort';
|
|
@@ -29,9 +30,22 @@ export interface IAuthModuleOptions {
|
|
|
29
30
|
verificationSubject: Type<VerificationSubjectPort>;
|
|
30
31
|
/**
|
|
31
32
|
* Optional implementation of the social auth port (OAuth strategies).
|
|
32
|
-
* When provided
|
|
33
|
+
* When provided together with `socialStrategies`, the social auth flow is enabled.
|
|
33
34
|
*/
|
|
34
35
|
socialAuth?: Type<SocialAuthPort>;
|
|
36
|
+
/**
|
|
37
|
+
* Optional array of social strategy types to register (e.g. `AppleStrategy`, `GithubStrategy`).
|
|
38
|
+
* Import them from the provider-specific sub-paths
|
|
39
|
+
* (e.g. `@breadstone/archipel-platform-authentication/apple`).
|
|
40
|
+
* Requires `socialAuth` to be set.
|
|
41
|
+
*/
|
|
42
|
+
socialStrategies?: Array<Type>;
|
|
43
|
+
/**
|
|
44
|
+
* Optional additional configuration entries to register (e.g. provider-specific OAuth keys).
|
|
45
|
+
* Import them from the provider-specific sub-paths
|
|
46
|
+
* (e.g. `APPLE_AUTH_CONFIG_ENTRIES` from `@breadstone/archipel-platform-authentication/apple`).
|
|
47
|
+
*/
|
|
48
|
+
additionalConfigEntries?: ReadonlyArray<Omit<IConfigRegistryEntry, 'module'>>;
|
|
35
49
|
/**
|
|
36
50
|
* Optional implementation of the token enricher port.
|
|
37
51
|
* When provided, additional claims are added to JWT tokens.
|
package/src/AuthModule.js
CHANGED
|
@@ -35,12 +35,8 @@ const MfaService_1 = require("./services/MfaService");
|
|
|
35
35
|
const SessionService_1 = require("./services/SessionService");
|
|
36
36
|
const VerificationService_1 = require("./services/VerificationService");
|
|
37
37
|
const AnonymousStrategy_1 = require("./strategies/AnonymousStrategy");
|
|
38
|
-
const AppleStrategy_1 = require("./strategies/AppleStrategy");
|
|
39
|
-
const GithubStrategy_1 = require("./strategies/GithubStrategy");
|
|
40
|
-
const GoogleStrategy_1 = require("./strategies/GoogleStrategy");
|
|
41
38
|
const JwtStrategy_1 = require("./strategies/JwtStrategy");
|
|
42
39
|
const LocalStrategy_1 = require("./strategies/LocalStrategy");
|
|
43
|
-
const MicrosoftStrategy_1 = require("./strategies/MicrosoftStrategy");
|
|
44
40
|
/**
|
|
45
41
|
* The `AuthModule` handles JWT-based authentication,
|
|
46
42
|
* including token creation and validation.
|
|
@@ -70,13 +66,17 @@ let AuthModule = AuthModule_1 = class AuthModule {
|
|
|
70
66
|
portProviders.push({ provide: TokenEnricherPort_1.TokenEnricherPort, useClass: options.tokenEnricher });
|
|
71
67
|
}
|
|
72
68
|
const strategies = [JwtStrategy_1.JwtStrategy, LocalStrategy_1.LocalStrategy, AnonymousStrategy_1.AnonymousStrategy];
|
|
73
|
-
if (options.
|
|
74
|
-
strategies.push(
|
|
69
|
+
if (options.socialStrategies) {
|
|
70
|
+
strategies.push(...options.socialStrategies);
|
|
75
71
|
}
|
|
72
|
+
const configEntries = [
|
|
73
|
+
...env_1.PLATFORM_AUTHENTICATION_CONFIG_ENTRIES,
|
|
74
|
+
...(options.additionalConfigEntries ?? []),
|
|
75
|
+
];
|
|
76
76
|
return {
|
|
77
77
|
module: AuthModule_1,
|
|
78
78
|
imports: [
|
|
79
|
-
archipel_platform_core_1.ConfigModule.register('platform-authentication',
|
|
79
|
+
archipel_platform_core_1.ConfigModule.register('platform-authentication', configEntries),
|
|
80
80
|
archipel_platform_core_1.EventModule,
|
|
81
81
|
archipel_platform_core_1.IdentifierModule,
|
|
82
82
|
passport_1.PassportModule.register({
|
package/src/apple/env.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// #region Imports
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.APPLE_AUTH_CONFIG_ENTRIES = void 0;
|
|
5
|
+
const env_1 = require("../env");
|
|
6
|
+
// #endregion
|
|
7
|
+
/** Configuration entries required by Apple Sign-In authentication. */
|
|
8
|
+
exports.APPLE_AUTH_CONFIG_ENTRIES = [
|
|
9
|
+
{ key: env_1.AUTH_APPLE_PRIVATE_KEY, required: true, description: 'Apple Sign-In private key (PEM).' },
|
|
10
|
+
{ key: env_1.AUTH_APPLE_CLIENT_ID, required: true, description: 'Apple Sign-In client ID.' },
|
|
11
|
+
{ key: env_1.AUTH_APPLE_TEAM_ID, required: true, description: 'Apple developer team ID.' },
|
|
12
|
+
{ key: env_1.AUTH_APPLE_KEY_ID, required: true, description: 'Apple Sign-In key ID.' },
|
|
13
|
+
{
|
|
14
|
+
key: env_1.AUTH_APPLE_CALLBACK_URL,
|
|
15
|
+
required: false,
|
|
16
|
+
defaultValue: '/auth/apple/callback',
|
|
17
|
+
description: 'Apple Sign-In callback URL.',
|
|
18
|
+
},
|
|
19
|
+
];
|
|
20
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.APPLE_AUTH_CONFIG_ENTRIES = exports.AppleStrategy = void 0;
|
|
4
|
+
var AppleStrategy_1 = require("../strategies/AppleStrategy");
|
|
5
|
+
Object.defineProperty(exports, "AppleStrategy", { enumerable: true, get: function () { return AppleStrategy_1.AppleStrategy; } });
|
|
6
|
+
var env_1 = require("./env");
|
|
7
|
+
Object.defineProperty(exports, "APPLE_AUTH_CONFIG_ENTRIES", { enumerable: true, get: function () { return env_1.APPLE_AUTH_CONFIG_ENTRIES; } });
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
package/src/env.d.ts
CHANGED
|
@@ -51,7 +51,9 @@ export declare const AUTH_APPLE_CALLBACK_URL: import("@breadstone/archipel-platf
|
|
|
51
51
|
export declare const AUTH_GITHUB_CLIENT_ID: import("@breadstone/archipel-platform-core").IConfigKey<string>;
|
|
52
52
|
/** GitHub OAuth client secret. */
|
|
53
53
|
export declare const AUTH_GITHUB_CLIENT_SECRET: import("@breadstone/archipel-platform-core").IConfigKey<string>;
|
|
54
|
+
/** GitHub OAuth callback URL. */
|
|
55
|
+
export declare const AUTH_GITHUB_CALLBACK_URL: import("@breadstone/archipel-platform-core").IConfigKey<string>;
|
|
54
56
|
/** Username used for the anonymous seed user. */
|
|
55
57
|
export declare const SEED_ANONYMOUS_USERNAME: import("@breadstone/archipel-platform-core").IConfigKey<string>;
|
|
56
|
-
/**
|
|
58
|
+
/** Core configuration entries required by `platform-authentication`. */
|
|
57
59
|
export declare const PLATFORM_AUTHENTICATION_CONFIG_ENTRIES: ReadonlyArray<Omit<IConfigRegistryEntry, 'module'>>;
|
package/src/env.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// #region Imports
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.PLATFORM_AUTHENTICATION_CONFIG_ENTRIES = exports.SEED_ANONYMOUS_USERNAME = exports.AUTH_GITHUB_CLIENT_SECRET = exports.AUTH_GITHUB_CLIENT_ID = exports.AUTH_APPLE_CALLBACK_URL = exports.AUTH_APPLE_KEY_ID = exports.AUTH_APPLE_TEAM_ID = exports.AUTH_APPLE_CLIENT_ID = exports.AUTH_APPLE_PRIVATE_KEY = exports.AUTH_MICROSOFT_TENANT = exports.AUTH_MICROSOFT_CALLBACK_URL = exports.AUTH_MICROSOFT_CLIENT_SECRET = exports.AUTH_MICROSOFT_CLIENT_ID = exports.AUTH_GOOGLE_CALLBACK_URL = exports.AUTH_GOOGLE_CLIENT_SECRET = exports.AUTH_GOOGLE_CLIENT_ID = exports.AUTH_MFA_PUSH_MIN_RESEND = exports.AUTH_MFA_PUSH_CODE_TTL = exports.AUTH_MFA_EMAIL_MIN_RESEND = exports.AUTH_MFA_EMAIL_CODE_TTL = exports.AUTH_MFA_SMS_MIN_RESEND = exports.AUTH_MFA_SMS_CODE_TTL = exports.AUTH_MFA_MAX_ATTEMPTS = exports.AUTH_MFA_CHALLENGE_EXPIRES_IN = exports.AUTH_MFA_ENCRYPTION_KEY = exports.AUTH_VERIFY_JWT_EXPIRES_IN = exports.AUTH_JWT_EXPIRES_IN = exports.AUTH_JWT_SECRET = void 0;
|
|
4
|
+
exports.PLATFORM_AUTHENTICATION_CONFIG_ENTRIES = exports.SEED_ANONYMOUS_USERNAME = exports.AUTH_GITHUB_CALLBACK_URL = exports.AUTH_GITHUB_CLIENT_SECRET = exports.AUTH_GITHUB_CLIENT_ID = exports.AUTH_APPLE_CALLBACK_URL = exports.AUTH_APPLE_KEY_ID = exports.AUTH_APPLE_TEAM_ID = exports.AUTH_APPLE_CLIENT_ID = exports.AUTH_APPLE_PRIVATE_KEY = exports.AUTH_MICROSOFT_TENANT = exports.AUTH_MICROSOFT_CALLBACK_URL = exports.AUTH_MICROSOFT_CLIENT_SECRET = exports.AUTH_MICROSOFT_CLIENT_ID = exports.AUTH_GOOGLE_CALLBACK_URL = exports.AUTH_GOOGLE_CLIENT_SECRET = exports.AUTH_GOOGLE_CLIENT_ID = exports.AUTH_MFA_PUSH_MIN_RESEND = exports.AUTH_MFA_PUSH_CODE_TTL = exports.AUTH_MFA_EMAIL_MIN_RESEND = exports.AUTH_MFA_EMAIL_CODE_TTL = exports.AUTH_MFA_SMS_MIN_RESEND = exports.AUTH_MFA_SMS_CODE_TTL = exports.AUTH_MFA_MAX_ATTEMPTS = exports.AUTH_MFA_CHALLENGE_EXPIRES_IN = exports.AUTH_MFA_ENCRYPTION_KEY = exports.AUTH_VERIFY_JWT_EXPIRES_IN = exports.AUTH_JWT_EXPIRES_IN = exports.AUTH_JWT_SECRET = void 0;
|
|
5
5
|
const archipel_platform_core_1 = require("@breadstone/archipel-platform-core");
|
|
6
6
|
// #endregion
|
|
7
7
|
// ──────────────────────────────────────────────────────────────
|
|
@@ -83,6 +83,8 @@ exports.AUTH_APPLE_CALLBACK_URL = (0, archipel_platform_core_1.createConfigKey)(
|
|
|
83
83
|
exports.AUTH_GITHUB_CLIENT_ID = (0, archipel_platform_core_1.createConfigKey)('AUTH_GITHUB_CLIENT_ID');
|
|
84
84
|
/** GitHub OAuth client secret. */
|
|
85
85
|
exports.AUTH_GITHUB_CLIENT_SECRET = (0, archipel_platform_core_1.createConfigKey)('AUTH_GITHUB_CLIENT_SECRET');
|
|
86
|
+
/** GitHub OAuth callback URL. */
|
|
87
|
+
exports.AUTH_GITHUB_CALLBACK_URL = (0, archipel_platform_core_1.createConfigKey)('AUTH_GITHUB_CALLBACK_URL');
|
|
86
88
|
// ──────────────────────────────────────────────────────────────
|
|
87
89
|
// Seed / Misc
|
|
88
90
|
// ──────────────────────────────────────────────────────────────
|
|
@@ -91,7 +93,7 @@ exports.SEED_ANONYMOUS_USERNAME = (0, archipel_platform_core_1.createConfigKey)(
|
|
|
91
93
|
// ──────────────────────────────────────────────────────────────
|
|
92
94
|
// Registry entries
|
|
93
95
|
// ──────────────────────────────────────────────────────────────
|
|
94
|
-
/**
|
|
96
|
+
/** Core configuration entries required by `platform-authentication`. */
|
|
95
97
|
exports.PLATFORM_AUTHENTICATION_CONFIG_ENTRIES = [
|
|
96
98
|
// JWT & Session
|
|
97
99
|
{ key: exports.AUTH_JWT_SECRET, required: true, description: 'Secret used to sign JWTs.' },
|
|
@@ -140,39 +142,6 @@ exports.PLATFORM_AUTHENTICATION_CONFIG_ENTRIES = [
|
|
|
140
142
|
defaultValue: '30s',
|
|
141
143
|
description: 'Min interval between push resends.',
|
|
142
144
|
},
|
|
143
|
-
// OAuth — Google
|
|
144
|
-
{ key: exports.AUTH_GOOGLE_CLIENT_ID, required: true, description: 'Google OAuth2 client ID.' },
|
|
145
|
-
{ key: exports.AUTH_GOOGLE_CLIENT_SECRET, required: true, description: 'Google OAuth2 client secret.' },
|
|
146
|
-
{
|
|
147
|
-
key: exports.AUTH_GOOGLE_CALLBACK_URL,
|
|
148
|
-
required: false,
|
|
149
|
-
defaultValue: '/auth/google/callback',
|
|
150
|
-
description: 'Google OAuth2 callback URL.',
|
|
151
|
-
},
|
|
152
|
-
// OAuth — Microsoft
|
|
153
|
-
{ key: exports.AUTH_MICROSOFT_CLIENT_ID, required: true, description: 'Microsoft OAuth2 client ID.' },
|
|
154
|
-
{ key: exports.AUTH_MICROSOFT_CLIENT_SECRET, required: true, description: 'Microsoft OAuth2 client secret.' },
|
|
155
|
-
{
|
|
156
|
-
key: exports.AUTH_MICROSOFT_CALLBACK_URL,
|
|
157
|
-
required: false,
|
|
158
|
-
defaultValue: '/auth/microsoft/callback',
|
|
159
|
-
description: 'Microsoft OAuth2 callback URL.',
|
|
160
|
-
},
|
|
161
|
-
{ key: exports.AUTH_MICROSOFT_TENANT, required: false, defaultValue: 'common', description: 'Microsoft tenant ID.' },
|
|
162
|
-
// OAuth — Apple
|
|
163
|
-
{ key: exports.AUTH_APPLE_PRIVATE_KEY, required: true, description: 'Apple Sign-In private key (PEM).' },
|
|
164
|
-
{ key: exports.AUTH_APPLE_CLIENT_ID, required: true, description: 'Apple Sign-In client ID.' },
|
|
165
|
-
{ key: exports.AUTH_APPLE_TEAM_ID, required: true, description: 'Apple developer team ID.' },
|
|
166
|
-
{ key: exports.AUTH_APPLE_KEY_ID, required: true, description: 'Apple Sign-In key ID.' },
|
|
167
|
-
{
|
|
168
|
-
key: exports.AUTH_APPLE_CALLBACK_URL,
|
|
169
|
-
required: false,
|
|
170
|
-
defaultValue: '/auth/apple/callback',
|
|
171
|
-
description: 'Apple Sign-In callback URL.',
|
|
172
|
-
},
|
|
173
|
-
// OAuth — GitHub
|
|
174
|
-
{ key: exports.AUTH_GITHUB_CLIENT_ID, required: true, description: 'GitHub OAuth client ID.' },
|
|
175
|
-
{ key: exports.AUTH_GITHUB_CLIENT_SECRET, required: true, description: 'GitHub OAuth client secret.' },
|
|
176
145
|
// Seed / Misc
|
|
177
146
|
{ key: exports.SEED_ANONYMOUS_USERNAME, required: true, description: 'Username for the anonymous seed user.' },
|
|
178
147
|
];
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// #region Imports
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.GITHUB_AUTH_CONFIG_ENTRIES = void 0;
|
|
5
|
+
const env_1 = require("../env");
|
|
6
|
+
// #endregion
|
|
7
|
+
/** Configuration entries required by GitHub OAuth authentication. */
|
|
8
|
+
exports.GITHUB_AUTH_CONFIG_ENTRIES = [
|
|
9
|
+
{ key: env_1.AUTH_GITHUB_CLIENT_ID, required: true, description: 'GitHub OAuth client ID.' },
|
|
10
|
+
{ key: env_1.AUTH_GITHUB_CLIENT_SECRET, required: true, description: 'GitHub OAuth client secret.' },
|
|
11
|
+
{
|
|
12
|
+
key: env_1.AUTH_GITHUB_CALLBACK_URL,
|
|
13
|
+
required: false,
|
|
14
|
+
defaultValue: '/auth/github/callback',
|
|
15
|
+
description: 'GitHub OAuth callback URL.',
|
|
16
|
+
},
|
|
17
|
+
];
|
|
18
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GITHUB_AUTH_CONFIG_ENTRIES = exports.GithubStrategy = void 0;
|
|
4
|
+
var GithubStrategy_1 = require("../strategies/GithubStrategy");
|
|
5
|
+
Object.defineProperty(exports, "GithubStrategy", { enumerable: true, get: function () { return GithubStrategy_1.GithubStrategy; } });
|
|
6
|
+
var env_1 = require("./env");
|
|
7
|
+
Object.defineProperty(exports, "GITHUB_AUTH_CONFIG_ENTRIES", { enumerable: true, get: function () { return env_1.GITHUB_AUTH_CONFIG_ENTRIES; } });
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// #region Imports
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.GOOGLE_AUTH_CONFIG_ENTRIES = void 0;
|
|
5
|
+
const env_1 = require("../env");
|
|
6
|
+
// #endregion
|
|
7
|
+
/** Configuration entries required by Google OAuth authentication. */
|
|
8
|
+
exports.GOOGLE_AUTH_CONFIG_ENTRIES = [
|
|
9
|
+
{ key: env_1.AUTH_GOOGLE_CLIENT_ID, required: true, description: 'Google OAuth2 client ID.' },
|
|
10
|
+
{ key: env_1.AUTH_GOOGLE_CLIENT_SECRET, required: true, description: 'Google OAuth2 client secret.' },
|
|
11
|
+
{
|
|
12
|
+
key: env_1.AUTH_GOOGLE_CALLBACK_URL,
|
|
13
|
+
required: false,
|
|
14
|
+
defaultValue: '/auth/google/callback',
|
|
15
|
+
description: 'Google OAuth2 callback URL.',
|
|
16
|
+
},
|
|
17
|
+
];
|
|
18
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GOOGLE_AUTH_CONFIG_ENTRIES = exports.GoogleStrategy = void 0;
|
|
4
|
+
var GoogleStrategy_1 = require("../strategies/GoogleStrategy");
|
|
5
|
+
Object.defineProperty(exports, "GoogleStrategy", { enumerable: true, get: function () { return GoogleStrategy_1.GoogleStrategy; } });
|
|
6
|
+
var env_1 = require("./env");
|
|
7
|
+
Object.defineProperty(exports, "GOOGLE_AUTH_CONFIG_ENTRIES", { enumerable: true, get: function () { return env_1.GOOGLE_AUTH_CONFIG_ENTRIES; } });
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
package/src/guards/RolesGuard.js
CHANGED
|
@@ -2,8 +2,8 @@ import { CanActivate, ExecutionContext } from '@nestjs/common';
|
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
3
|
export declare class SocialAuthGuard implements CanActivate {
|
|
4
4
|
private static readonly _availableProviders;
|
|
5
|
-
private readonly
|
|
6
|
-
constructor(
|
|
5
|
+
private readonly _routeParam;
|
|
6
|
+
constructor(routeParam: string);
|
|
7
7
|
canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean>;
|
|
8
8
|
}
|
|
9
|
-
export declare const socialAuthGuardFactory: (
|
|
9
|
+
export declare const socialAuthGuardFactory: (routeParam: string) => SocialAuthGuard;
|
|
@@ -10,16 +10,18 @@ const passport_1 = require("@nestjs/passport");
|
|
|
10
10
|
let SocialAuthGuard = SocialAuthGuard_1 = class SocialAuthGuard {
|
|
11
11
|
// #endregion
|
|
12
12
|
// #region Ctor
|
|
13
|
-
constructor(
|
|
14
|
-
this.
|
|
13
|
+
constructor(routeParam) {
|
|
14
|
+
this._routeParam = routeParam.startsWith(':') ? routeParam.slice(1) : routeParam;
|
|
15
15
|
}
|
|
16
16
|
// #endregion
|
|
17
17
|
// #region Methods
|
|
18
18
|
canActivate(context) {
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
const request = context.switchToHttp().getRequest();
|
|
20
|
+
const provider = request.params[this._routeParam];
|
|
21
|
+
if (!provider || !SocialAuthGuard_1._availableProviders.includes(provider)) {
|
|
22
|
+
throw new common_1.BadRequestException(`Unsupported OAuth provider: ${provider}`);
|
|
21
23
|
}
|
|
22
|
-
const guard = new ((0, passport_1.AuthGuard)(
|
|
24
|
+
const guard = new ((0, passport_1.AuthGuard)(provider))();
|
|
23
25
|
return guard.canActivate(context);
|
|
24
26
|
}
|
|
25
27
|
};
|
|
@@ -30,6 +32,6 @@ exports.SocialAuthGuard = SocialAuthGuard = SocialAuthGuard_1 = tslib_1.__decora
|
|
|
30
32
|
(0, common_1.Injectable)(),
|
|
31
33
|
tslib_1.__metadata("design:paramtypes", [String])
|
|
32
34
|
], SocialAuthGuard);
|
|
33
|
-
const socialAuthGuardFactory = (
|
|
35
|
+
const socialAuthGuardFactory = (routeParam) => new SocialAuthGuard(routeParam);
|
|
34
36
|
exports.socialAuthGuardFactory = socialAuthGuardFactory;
|
|
35
37
|
//# sourceMappingURL=SocialAuthGuard.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// #region Imports
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.MICROSOFT_AUTH_CONFIG_ENTRIES = void 0;
|
|
5
|
+
const env_1 = require("../env");
|
|
6
|
+
// #endregion
|
|
7
|
+
/** Configuration entries required by Microsoft OAuth authentication. */
|
|
8
|
+
exports.MICROSOFT_AUTH_CONFIG_ENTRIES = [
|
|
9
|
+
{ key: env_1.AUTH_MICROSOFT_CLIENT_ID, required: true, description: 'Microsoft OAuth2 client ID.' },
|
|
10
|
+
{ key: env_1.AUTH_MICROSOFT_CLIENT_SECRET, required: true, description: 'Microsoft OAuth2 client secret.' },
|
|
11
|
+
{
|
|
12
|
+
key: env_1.AUTH_MICROSOFT_CALLBACK_URL,
|
|
13
|
+
required: false,
|
|
14
|
+
defaultValue: '/auth/microsoft/callback',
|
|
15
|
+
description: 'Microsoft OAuth2 callback URL.',
|
|
16
|
+
},
|
|
17
|
+
{ key: env_1.AUTH_MICROSOFT_TENANT, required: false, defaultValue: 'common', description: 'Microsoft tenant ID.' },
|
|
18
|
+
];
|
|
19
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MICROSOFT_AUTH_CONFIG_ENTRIES = exports.MicrosoftStrategy = void 0;
|
|
4
|
+
var MicrosoftStrategy_1 = require("../strategies/MicrosoftStrategy");
|
|
5
|
+
Object.defineProperty(exports, "MicrosoftStrategy", { enumerable: true, get: function () { return MicrosoftStrategy_1.MicrosoftStrategy; } });
|
|
6
|
+
var env_1 = require("./env");
|
|
7
|
+
Object.defineProperty(exports, "MICROSOFT_AUTH_CONFIG_ENTRIES", { enumerable: true, get: function () { return env_1.MICROSOFT_AUTH_CONFIG_ENTRIES; } });
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
2
|
+
// #region Imports
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.SessionSerializer = void 0;
|
|
5
5
|
const tslib_1 = require("tslib");
|
|
6
|
-
// #region Imports
|
|
7
6
|
const common_1 = require("@nestjs/common");
|
|
8
7
|
const passport_1 = require("@nestjs/passport");
|
|
9
8
|
// #endregion
|
|
@@ -50,7 +50,7 @@ let EmailOtpMfaChannel = EmailOtpMfaChannel_1 = class EmailOtpMfaChannel {
|
|
|
50
50
|
mfaPreferredMethod: state.preferredMethod,
|
|
51
51
|
mfaUpdatedAt: new Date(),
|
|
52
52
|
});
|
|
53
|
-
this._logger.log(`Sending Email MFA code to ${email} (mock)
|
|
53
|
+
this._logger.log(`Sending Email MFA code to ${email} (mock)`);
|
|
54
54
|
return {
|
|
55
55
|
method: this.method,
|
|
56
56
|
};
|
|
@@ -92,7 +92,7 @@ let EmailOtpMfaChannel = EmailOtpMfaChannel_1 = class EmailOtpMfaChannel {
|
|
|
92
92
|
mfaChannels: state,
|
|
93
93
|
mfaUpdatedAt: new Date(),
|
|
94
94
|
});
|
|
95
|
-
this._logger.log(`Sending Email MFA code to ${email} (login)
|
|
95
|
+
this._logger.log(`Sending Email MFA code to ${email} (login)`);
|
|
96
96
|
}
|
|
97
97
|
async verifyCodeAndMaybeEnable(userId, code, enable) {
|
|
98
98
|
const user = await this._mfaSubject.findById(userId);
|
|
@@ -55,7 +55,7 @@ let PushMfaChannel = PushMfaChannel_1 = class PushMfaChannel {
|
|
|
55
55
|
mfaUpdatedAt: new Date(),
|
|
56
56
|
});
|
|
57
57
|
// Replace with actual push notification send once available.
|
|
58
|
-
this._logger.log(`Simulating push approval code for user ${user.id}
|
|
58
|
+
this._logger.log(`Simulating push approval code for user ${user.id}`);
|
|
59
59
|
return { method: this.method };
|
|
60
60
|
}
|
|
61
61
|
async verifySetup(userId, code) {
|
|
@@ -90,7 +90,7 @@ let PushMfaChannel = PushMfaChannel_1 = class PushMfaChannel {
|
|
|
90
90
|
mfaChannels: state,
|
|
91
91
|
mfaUpdatedAt: new Date(),
|
|
92
92
|
});
|
|
93
|
-
this._logger.log(`Simulating push approval for user ${user.id}
|
|
93
|
+
this._logger.log(`Simulating push approval for user ${user.id}`);
|
|
94
94
|
}
|
|
95
95
|
async verifyCodeAndMaybeEnable(userId, code, enable) {
|
|
96
96
|
const user = await this._mfaSubject.findById(userId);
|
|
@@ -56,7 +56,7 @@ let SmsMfaChannel = SmsMfaChannel_1 = class SmsMfaChannel {
|
|
|
56
56
|
mfaPreferredMethod: state.preferredMethod,
|
|
57
57
|
mfaUpdatedAt: new Date(),
|
|
58
58
|
});
|
|
59
|
-
this._logger.log(`Sending SMS MFA code to ${phone} (mock)
|
|
59
|
+
this._logger.log(`Sending SMS MFA code to ${phone} (mock)`);
|
|
60
60
|
return {
|
|
61
61
|
method: this.method,
|
|
62
62
|
};
|
|
@@ -98,7 +98,7 @@ let SmsMfaChannel = SmsMfaChannel_1 = class SmsMfaChannel {
|
|
|
98
98
|
mfaChannels: state,
|
|
99
99
|
mfaUpdatedAt: new Date(),
|
|
100
100
|
});
|
|
101
|
-
this._logger.log(`Sending SMS MFA code to ${phone} (login)
|
|
101
|
+
this._logger.log(`Sending SMS MFA code to ${phone} (login)`);
|
|
102
102
|
}
|
|
103
103
|
async verifyCodeAndMaybeEnable(userId, code, enable) {
|
|
104
104
|
const user = await this._mfaSubject.findById(userId);
|
|
@@ -7,7 +7,6 @@ declare const GithubStrategy_base: new (...args: [options: import("passport-gith
|
|
|
7
7
|
};
|
|
8
8
|
export declare class GithubStrategy extends GithubStrategy_base {
|
|
9
9
|
private readonly _socialAuth;
|
|
10
|
-
private readonly _configService;
|
|
11
10
|
/**
|
|
12
11
|
* Constructs a new instance of the `GithubStrategy` class.
|
|
13
12
|
*
|
|
@@ -8,11 +8,6 @@ const common_1 = require("@nestjs/common");
|
|
|
8
8
|
const passport_1 = require("@nestjs/passport");
|
|
9
9
|
const passport_github2_1 = require("passport-github2");
|
|
10
10
|
const SocialAuthPort_1 = require("../contracts/SocialAuthPort");
|
|
11
|
-
// import type { authConfig } from '../../../configs/auth.config';
|
|
12
|
-
// import { AuthConfig } from '../../../configs/auth.config';
|
|
13
|
-
// import { UserService } from '../../user/user.service';
|
|
14
|
-
// import { OauthStoreService } from '../oauth/oauth.store';
|
|
15
|
-
// import { pickUserMe } from '../utils';
|
|
16
11
|
// #endregion
|
|
17
12
|
let GithubStrategy = class GithubStrategy extends (0, passport_1.PassportStrategy)(passport_github2_1.Strategy, 'github') {
|
|
18
13
|
// #endregion
|
|
@@ -28,12 +23,9 @@ let GithubStrategy = class GithubStrategy extends (0, passport_1.PassportStrateg
|
|
|
28
23
|
super({
|
|
29
24
|
clientID: configService.get('AUTH_GITHUB_CLIENT_ID'),
|
|
30
25
|
clientSecret: configService.get('AUTH_GITHUB_CLIENT_SECRET'),
|
|
31
|
-
|
|
32
|
-
callbackURL: '/auth/github/callback',
|
|
33
|
-
// store: oauthStoreService
|
|
26
|
+
callbackURL: configService.tryGet('AUTH_GITHUB_CALLBACK_URL', '/auth/github/callback'),
|
|
34
27
|
});
|
|
35
28
|
this._socialAuth = socialAuth;
|
|
36
|
-
this._configService = configService;
|
|
37
29
|
}
|
|
38
30
|
// #endregion
|
|
39
31
|
// #region Methods
|
|
@@ -41,18 +33,19 @@ let GithubStrategy = class GithubStrategy extends (0, passport_1.PassportStrateg
|
|
|
41
33
|
* @public
|
|
42
34
|
*/
|
|
43
35
|
async validate(_accessToken, _refreshToken, profile) {
|
|
44
|
-
const email = profile.emails?.[0]
|
|
36
|
+
const email = profile.emails?.[0]?.value;
|
|
45
37
|
if (!email) {
|
|
46
38
|
throw new common_1.UnauthorizedException('No email provided from GitHub');
|
|
47
39
|
}
|
|
48
|
-
|
|
40
|
+
const displayName = profile.displayName || profile.username;
|
|
41
|
+
if (!displayName) {
|
|
49
42
|
throw new common_1.UnauthorizedException('No display name provided from GitHub');
|
|
50
43
|
}
|
|
51
44
|
const user = await this._socialAuth.findOrCreateByProfile({
|
|
52
45
|
provider: 'github',
|
|
53
46
|
email: email,
|
|
54
47
|
userName: profile.username ?? null,
|
|
55
|
-
displayName:
|
|
48
|
+
displayName: displayName,
|
|
56
49
|
});
|
|
57
50
|
return user;
|
|
58
51
|
}
|
|
@@ -42,7 +42,7 @@ let JwtStrategy = class JwtStrategy extends (0, passport_1.PassportStrategy)(pas
|
|
|
42
42
|
async validate(payload) {
|
|
43
43
|
const user = await this._authSubject.findById(payload.id);
|
|
44
44
|
if (!user) {
|
|
45
|
-
throw new common_1.
|
|
45
|
+
throw new common_1.UnauthorizedException('Invalid token subject');
|
|
46
46
|
}
|
|
47
47
|
return user;
|
|
48
48
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BcryptService } from '@breadstone/archipel-platform-core';
|
|
1
2
|
import { Strategy } from 'passport-local';
|
|
2
3
|
import { AuthSubjectPort } from '../contracts/AuthSubjectPort';
|
|
3
4
|
import type { IAuthSubject } from '../contracts/IAuthSubject';
|
|
@@ -11,13 +12,15 @@ declare const LocalStrategy_base: new (...args: [] | [options: import("passport-
|
|
|
11
12
|
*/
|
|
12
13
|
export declare class LocalStrategy extends LocalStrategy_base {
|
|
13
14
|
private readonly _authSubject;
|
|
15
|
+
private readonly _bcryptService;
|
|
14
16
|
/**
|
|
15
17
|
* Constructs a new instance of the `LocalStrategy` class.
|
|
16
18
|
*
|
|
17
19
|
* @public
|
|
18
20
|
* @param authSubject Auth subject port instance.
|
|
21
|
+
* @param bcryptService Bcrypt service instance.
|
|
19
22
|
*/
|
|
20
|
-
constructor(authSubject: AuthSubjectPort);
|
|
23
|
+
constructor(authSubject: AuthSubjectPort, bcryptService: BcryptService);
|
|
21
24
|
/**
|
|
22
25
|
* Validates the authentication credentials.
|
|
23
26
|
*
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.LocalStrategy = void 0;
|
|
5
5
|
const tslib_1 = require("tslib");
|
|
6
|
+
const archipel_platform_core_1 = require("@breadstone/archipel-platform-core");
|
|
6
7
|
const common_1 = require("@nestjs/common");
|
|
7
8
|
const passport_1 = require("@nestjs/passport");
|
|
8
9
|
const passport_local_1 = require("passport-local");
|
|
@@ -21,10 +22,12 @@ let LocalStrategy = class LocalStrategy extends (0, passport_1.PassportStrategy)
|
|
|
21
22
|
*
|
|
22
23
|
* @public
|
|
23
24
|
* @param authSubject Auth subject port instance.
|
|
25
|
+
* @param bcryptService Bcrypt service instance.
|
|
24
26
|
*/
|
|
25
|
-
constructor(authSubject) {
|
|
27
|
+
constructor(authSubject, bcryptService) {
|
|
26
28
|
super();
|
|
27
29
|
this._authSubject = authSubject;
|
|
30
|
+
this._bcryptService = bcryptService;
|
|
28
31
|
}
|
|
29
32
|
// #endregion
|
|
30
33
|
// #region Methods
|
|
@@ -38,11 +41,11 @@ let LocalStrategy = class LocalStrategy extends (0, passport_1.PassportStrategy)
|
|
|
38
41
|
*/
|
|
39
42
|
async validate(userName, password) {
|
|
40
43
|
const user = await this._authSubject.findByLogin(userName);
|
|
41
|
-
if (!user) {
|
|
42
|
-
throw new common_1.
|
|
44
|
+
if (!user || !user.password) {
|
|
45
|
+
throw new common_1.UnauthorizedException('Invalid credentials');
|
|
43
46
|
}
|
|
44
|
-
|
|
45
|
-
if (
|
|
47
|
+
const isPasswordValid = await this._bcryptService.compare(password, user.password);
|
|
48
|
+
if (!isPasswordValid) {
|
|
46
49
|
throw new common_1.UnauthorizedException('Invalid credentials');
|
|
47
50
|
}
|
|
48
51
|
return user;
|
|
@@ -51,6 +54,6 @@ let LocalStrategy = class LocalStrategy extends (0, passport_1.PassportStrategy)
|
|
|
51
54
|
exports.LocalStrategy = LocalStrategy;
|
|
52
55
|
exports.LocalStrategy = LocalStrategy = tslib_1.__decorate([
|
|
53
56
|
(0, common_1.Injectable)(),
|
|
54
|
-
tslib_1.__metadata("design:paramtypes", [AuthSubjectPort_1.AuthSubjectPort])
|
|
57
|
+
tslib_1.__metadata("design:paramtypes", [AuthSubjectPort_1.AuthSubjectPort, archipel_platform_core_1.BcryptService])
|
|
55
58
|
], LocalStrategy);
|
|
56
59
|
//# sourceMappingURL=LocalStrategy.js.map
|