@lenne.tech/nest-server 11.10.2 → 11.10.4
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/dist/config.env.js +16 -133
- package/dist/config.env.js.map +1 -1
- package/dist/core/common/interfaces/server-options.interface.d.ts +4 -0
- package/dist/core/modules/auth/core-auth.module.js +8 -4
- package/dist/core/modules/auth/core-auth.module.js.map +1 -1
- package/dist/core/modules/auth/guards/roles-guard-registry.d.ts +9 -0
- package/dist/core/modules/auth/guards/roles-guard-registry.js +30 -0
- package/dist/core/modules/auth/guards/roles-guard-registry.js.map +1 -0
- package/dist/core/modules/better-auth/better-auth.config.d.ts +3 -0
- package/dist/core/modules/better-auth/better-auth.config.js +176 -47
- package/dist/core/modules/better-auth/better-auth.config.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.d.ts +5 -1
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.js +101 -8
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-challenge.service.d.ts +20 -0
- package/dist/core/modules/better-auth/core-better-auth-challenge.service.js +142 -0
- package/dist/core/modules/better-auth/core-better-auth-challenge.service.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.js +1 -1
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-web.helper.d.ts +2 -0
- package/dist/core/modules/better-auth/core-better-auth-web.helper.js +29 -1
- package/dist/core/modules/better-auth/core-better-auth-web.helper.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.controller.js +5 -13
- package/dist/core/modules/better-auth/core-better-auth.controller.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.middleware.d.ts +0 -1
- package/dist/core/modules/better-auth/core-better-auth.middleware.js +6 -19
- package/dist/core/modules/better-auth/core-better-auth.middleware.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.module.d.ts +5 -1
- package/dist/core/modules/better-auth/core-better-auth.module.js +74 -27
- package/dist/core/modules/better-auth/core-better-auth.module.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.resolver.js +7 -6
- package/dist/core/modules/better-auth/core-better-auth.resolver.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.service.d.ts +0 -2
- package/dist/core/modules/better-auth/core-better-auth.service.js +23 -37
- package/dist/core/modules/better-auth/core-better-auth.service.js.map +1 -1
- package/dist/core.module.js +10 -1
- package/dist/core.module.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/server/modules/better-auth/better-auth.module.d.ts +4 -1
- package/dist/server/modules/better-auth/better-auth.module.js +4 -1
- package/dist/server/modules/better-auth/better-auth.module.js.map +1 -1
- package/dist/server/server.module.js +1 -4
- package/dist/server/server.module.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/config.env.ts +24 -174
- package/src/core/common/interfaces/server-options.interface.ts +288 -35
- package/src/core/modules/auth/core-auth.module.ts +11 -5
- package/src/core/modules/auth/guards/roles-guard-registry.ts +57 -0
- package/src/core/modules/better-auth/INTEGRATION-CHECKLIST.md +85 -56
- package/src/core/modules/better-auth/README.md +132 -35
- package/src/core/modules/better-auth/better-auth.config.ts +402 -70
- package/src/core/modules/better-auth/core-better-auth-api.middleware.ts +158 -18
- package/src/core/modules/better-auth/core-better-auth-challenge.service.ts +254 -0
- package/src/core/modules/better-auth/core-better-auth-user.mapper.ts +1 -1
- package/src/core/modules/better-auth/core-better-auth-web.helper.ts +64 -1
- package/src/core/modules/better-auth/core-better-auth.controller.ts +6 -14
- package/src/core/modules/better-auth/core-better-auth.middleware.ts +7 -20
- package/src/core/modules/better-auth/core-better-auth.module.ts +173 -38
- package/src/core/modules/better-auth/core-better-auth.resolver.ts +7 -6
- package/src/core/modules/better-auth/core-better-auth.service.ts +27 -48
- package/src/core.module.ts +21 -3
- package/src/index.ts +1 -0
- package/src/server/modules/better-auth/better-auth.module.ts +40 -10
- package/src/server/server.module.ts +2 -4
package/dist/config.env.js
CHANGED
|
@@ -8,55 +8,10 @@ dotenv.config();
|
|
|
8
8
|
const config = {
|
|
9
9
|
development: {
|
|
10
10
|
auth: {
|
|
11
|
-
legacyEndpoints: {
|
|
12
|
-
enabled: true,
|
|
13
|
-
},
|
|
11
|
+
legacyEndpoints: { enabled: true },
|
|
14
12
|
},
|
|
15
13
|
automaticObjectIdFiltering: true,
|
|
16
|
-
|
|
17
|
-
basePath: '/iam',
|
|
18
|
-
baseUrl: 'http://localhost:3000',
|
|
19
|
-
jwt: {
|
|
20
|
-
enabled: true,
|
|
21
|
-
expiresIn: '15m',
|
|
22
|
-
},
|
|
23
|
-
passkey: {
|
|
24
|
-
enabled: false,
|
|
25
|
-
origin: 'http://localhost:3000',
|
|
26
|
-
rpId: 'localhost',
|
|
27
|
-
rpName: 'Nest Server Development',
|
|
28
|
-
},
|
|
29
|
-
rateLimit: {
|
|
30
|
-
enabled: true,
|
|
31
|
-
max: 20,
|
|
32
|
-
message: 'Too many requests, please try again later.',
|
|
33
|
-
skipEndpoints: ['/session', '/callback'],
|
|
34
|
-
strictEndpoints: ['/sign-in', '/sign-up', '/forgot-password', '/reset-password'],
|
|
35
|
-
windowSeconds: 60,
|
|
36
|
-
},
|
|
37
|
-
secret: 'BETTER_AUTH_SECRET_DEV_32_CHARS_MIN',
|
|
38
|
-
socialProviders: {
|
|
39
|
-
apple: {
|
|
40
|
-
clientId: process.env.SOCIAL_APPLE_CLIENT_ID || '',
|
|
41
|
-
clientSecret: process.env.SOCIAL_APPLE_CLIENT_SECRET || '',
|
|
42
|
-
enabled: false,
|
|
43
|
-
},
|
|
44
|
-
github: {
|
|
45
|
-
clientId: process.env.SOCIAL_GITHUB_CLIENT_ID || '',
|
|
46
|
-
clientSecret: process.env.SOCIAL_GITHUB_CLIENT_SECRET || '',
|
|
47
|
-
enabled: false,
|
|
48
|
-
},
|
|
49
|
-
google: {
|
|
50
|
-
clientId: process.env.SOCIAL_GOOGLE_CLIENT_ID || '',
|
|
51
|
-
clientSecret: process.env.SOCIAL_GOOGLE_CLIENT_SECRET || '',
|
|
52
|
-
enabled: false,
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
twoFactor: {
|
|
56
|
-
appName: 'Nest Server Development',
|
|
57
|
-
enabled: false,
|
|
58
|
-
},
|
|
59
|
-
},
|
|
14
|
+
baseUrl: 'http://localhost:3000',
|
|
60
15
|
compression: true,
|
|
61
16
|
cookies: false,
|
|
62
17
|
email: {
|
|
@@ -148,56 +103,21 @@ const config = {
|
|
|
148
103
|
},
|
|
149
104
|
local: {
|
|
150
105
|
auth: {
|
|
151
|
-
legacyEndpoints: {
|
|
152
|
-
enabled: true,
|
|
153
|
-
},
|
|
106
|
+
legacyEndpoints: { enabled: true },
|
|
154
107
|
},
|
|
155
108
|
automaticObjectIdFiltering: true,
|
|
156
109
|
betterAuth: {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
enabled: true,
|
|
160
|
-
jwt: {
|
|
161
|
-
enabled: true,
|
|
162
|
-
expiresIn: '15m',
|
|
163
|
-
},
|
|
164
|
-
passkey: {
|
|
165
|
-
enabled: true,
|
|
166
|
-
origin: 'http://localhost:3000',
|
|
167
|
-
rpId: 'localhost',
|
|
168
|
-
rpName: 'Nest Server Local',
|
|
169
|
-
},
|
|
170
|
-
rateLimit: {
|
|
171
|
-
enabled: true,
|
|
172
|
-
max: 100,
|
|
173
|
-
message: 'Too many requests, please try again later.',
|
|
174
|
-
skipEndpoints: ['/session', '/callback'],
|
|
175
|
-
strictEndpoints: ['/sign-in', '/sign-up', '/forgot-password', '/reset-password'],
|
|
176
|
-
windowSeconds: 60,
|
|
177
|
-
},
|
|
110
|
+
jwt: { enabled: true, expiresIn: '15m' },
|
|
111
|
+
passkey: { enabled: true, origin: 'http://localhost:3001', rpId: 'localhost', rpName: 'Nest Server Local' },
|
|
112
|
+
rateLimit: { enabled: true, max: 100, windowSeconds: 60 },
|
|
178
113
|
secret: 'BETTER_AUTH_SECRET_LOCAL_32_CHARS_M',
|
|
179
114
|
socialProviders: {
|
|
180
|
-
apple: {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
enabled: false,
|
|
184
|
-
},
|
|
185
|
-
github: {
|
|
186
|
-
clientId: process.env.SOCIAL_GITHUB_CLIENT_ID || '',
|
|
187
|
-
clientSecret: process.env.SOCIAL_GITHUB_CLIENT_SECRET || '',
|
|
188
|
-
enabled: false,
|
|
189
|
-
},
|
|
190
|
-
google: {
|
|
191
|
-
clientId: process.env.SOCIAL_GOOGLE_CLIENT_ID || '',
|
|
192
|
-
clientSecret: process.env.SOCIAL_GOOGLE_CLIENT_SECRET || '',
|
|
193
|
-
enabled: false,
|
|
194
|
-
},
|
|
115
|
+
apple: { clientId: '', clientSecret: '', enabled: false },
|
|
116
|
+
github: { clientId: '', clientSecret: '', enabled: false },
|
|
117
|
+
google: { clientId: '', clientSecret: '', enabled: false },
|
|
195
118
|
},
|
|
196
119
|
trustedOrigins: ['http://localhost:3000', 'http://localhost:3001'],
|
|
197
|
-
twoFactor: {
|
|
198
|
-
appName: 'Nest Server Local',
|
|
199
|
-
enabled: true,
|
|
200
|
-
},
|
|
120
|
+
twoFactor: { appName: 'Nest Server Local', enabled: true },
|
|
201
121
|
},
|
|
202
122
|
compression: true,
|
|
203
123
|
cookies: false,
|
|
@@ -304,55 +224,18 @@ const config = {
|
|
|
304
224
|
},
|
|
305
225
|
production: {
|
|
306
226
|
auth: {
|
|
307
|
-
legacyEndpoints: {
|
|
308
|
-
enabled: process.env.LEGACY_AUTH_ENABLED !== 'false',
|
|
309
|
-
},
|
|
227
|
+
legacyEndpoints: { enabled: process.env.LEGACY_AUTH_ENABLED !== 'false' },
|
|
310
228
|
},
|
|
311
229
|
automaticObjectIdFiltering: true,
|
|
230
|
+
baseUrl: process.env.BASE_URL,
|
|
312
231
|
betterAuth: {
|
|
313
|
-
|
|
314
|
-
baseUrl: process.env.BETTER_AUTH_URL || 'https://example.com',
|
|
315
|
-
jwt: {
|
|
316
|
-
enabled: true,
|
|
317
|
-
expiresIn: '15m',
|
|
318
|
-
},
|
|
319
|
-
passkey: {
|
|
320
|
-
enabled: false,
|
|
321
|
-
origin: process.env.BETTER_AUTH_URL || 'https://example.com',
|
|
322
|
-
rpId: process.env.PASSKEY_RP_ID || 'example.com',
|
|
323
|
-
rpName: process.env.PASSKEY_RP_NAME || 'Nest Server Production',
|
|
324
|
-
},
|
|
325
|
-
rateLimit: {
|
|
326
|
-
enabled: process.env.RATE_LIMIT_ENABLED !== 'false',
|
|
327
|
-
max: parseInt(process.env.RATE_LIMIT_MAX || '10', 10),
|
|
328
|
-
message: process.env.RATE_LIMIT_MESSAGE || 'Too many requests, please try again later.',
|
|
329
|
-
skipEndpoints: ['/session', '/callback'],
|
|
330
|
-
strictEndpoints: ['/sign-in', '/sign-up', '/forgot-password', '/reset-password'],
|
|
331
|
-
windowSeconds: parseInt(process.env.RATE_LIMIT_WINDOW_SECONDS || '60', 10),
|
|
332
|
-
},
|
|
232
|
+
rateLimit: { enabled: process.env.RATE_LIMIT_ENABLED !== 'false', max: parseInt(process.env.RATE_LIMIT_MAX || '10', 10) },
|
|
333
233
|
secret: process.env.BETTER_AUTH_SECRET,
|
|
334
234
|
socialProviders: {
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
clientSecret: process.env.SOCIAL_APPLE_CLIENT_SECRET || '',
|
|
338
|
-
enabled: !!process.env.SOCIAL_APPLE_CLIENT_ID,
|
|
339
|
-
},
|
|
340
|
-
github: {
|
|
341
|
-
clientId: process.env.SOCIAL_GITHUB_CLIENT_ID || '',
|
|
342
|
-
clientSecret: process.env.SOCIAL_GITHUB_CLIENT_SECRET || '',
|
|
343
|
-
enabled: !!process.env.SOCIAL_GITHUB_CLIENT_ID,
|
|
344
|
-
},
|
|
345
|
-
google: {
|
|
346
|
-
clientId: process.env.SOCIAL_GOOGLE_CLIENT_ID || '',
|
|
347
|
-
clientSecret: process.env.SOCIAL_GOOGLE_CLIENT_SECRET || '',
|
|
348
|
-
enabled: !!process.env.SOCIAL_GOOGLE_CLIENT_ID,
|
|
349
|
-
},
|
|
350
|
-
},
|
|
351
|
-
trustedOrigins: process.env.TRUSTED_ORIGINS?.split(',') || [],
|
|
352
|
-
twoFactor: {
|
|
353
|
-
appName: process.env.TWO_FACTOR_APP_NAME || 'Nest Server',
|
|
354
|
-
enabled: process.env.TWO_FACTOR_ENABLED === 'true',
|
|
235
|
+
github: { clientId: process.env.SOCIAL_GITHUB_CLIENT_ID || '', clientSecret: process.env.SOCIAL_GITHUB_CLIENT_SECRET || '' },
|
|
236
|
+
google: { clientId: process.env.SOCIAL_GOOGLE_CLIENT_ID || '', clientSecret: process.env.SOCIAL_GOOGLE_CLIENT_SECRET || '' },
|
|
355
237
|
},
|
|
238
|
+
twoFactor: { appName: process.env.TWO_FACTOR_APP_NAME || 'Nest Server' },
|
|
356
239
|
},
|
|
357
240
|
compression: true,
|
|
358
241
|
cookies: false,
|
package/dist/config.env.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.env.js","sourceRoot":"","sources":["../src/config.env.ts"],"names":[],"mappings":";;AAAA,+CAAkD;AAClD,iCAAiC;AACjC,+BAA4B;AAE5B,uEAA2E;
|
|
1
|
+
{"version":3,"file":"config.env.js","sourceRoot":"","sources":["../src/config.env.ts"],"names":[],"mappings":"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"}
|
|
@@ -38,6 +38,8 @@ export interface IBetterAuthJwtConfig {
|
|
|
38
38
|
}
|
|
39
39
|
export interface IBetterAuthPasskeyConfig {
|
|
40
40
|
authenticatorAttachment?: 'cross-platform' | 'platform';
|
|
41
|
+
challengeStorage?: 'cookie' | 'database';
|
|
42
|
+
challengeTtlSeconds?: number;
|
|
41
43
|
enabled?: boolean;
|
|
42
44
|
origin?: string;
|
|
43
45
|
residentKey?: 'discouraged' | 'preferred' | 'required';
|
|
@@ -90,8 +92,10 @@ export interface IJwt {
|
|
|
90
92
|
signInOptions?: JwtSignOptions;
|
|
91
93
|
}
|
|
92
94
|
export interface IServerOptions {
|
|
95
|
+
appUrl?: string;
|
|
93
96
|
auth?: IAuth;
|
|
94
97
|
automaticObjectIdFiltering?: boolean;
|
|
98
|
+
baseUrl?: string;
|
|
95
99
|
betterAuth?: boolean | IBetterAuth;
|
|
96
100
|
brevo?: {
|
|
97
101
|
apiKey: string;
|
|
@@ -15,6 +15,7 @@ const passport_1 = require("@nestjs/passport");
|
|
|
15
15
|
const graphql_subscriptions_1 = require("graphql-subscriptions");
|
|
16
16
|
const auth_guard_strategy_enum_1 = require("./auth-guard-strategy.enum");
|
|
17
17
|
const legacy_auth_rate_limit_guard_1 = require("./guards/legacy-auth-rate-limit.guard");
|
|
18
|
+
const roles_guard_registry_1 = require("./guards/roles-guard-registry");
|
|
18
19
|
const roles_guard_1 = require("./guards/roles.guard");
|
|
19
20
|
const core_auth_user_service_1 = require("./services/core-auth-user.service");
|
|
20
21
|
const core_auth_service_1 = require("./services/core-auth.service");
|
|
@@ -31,11 +32,14 @@ let CoreAuthModule = CoreAuthModule_1 = class CoreAuthModule {
|
|
|
31
32
|
if (Array.isArray(options?.imports)) {
|
|
32
33
|
imports = imports.concat(options.imports);
|
|
33
34
|
}
|
|
35
|
+
const rolesGuardProvider = roles_guard_registry_1.RolesGuardRegistry.isRegistered()
|
|
36
|
+
? []
|
|
37
|
+
: (() => {
|
|
38
|
+
roles_guard_registry_1.RolesGuardRegistry.markRegistered('CoreAuthModule');
|
|
39
|
+
return [{ provide: core_1.APP_GUARD, useClass: roles_guard_1.RolesGuard }];
|
|
40
|
+
})();
|
|
34
41
|
let providers = [
|
|
35
|
-
|
|
36
|
-
provide: core_1.APP_GUARD,
|
|
37
|
-
useClass: roles_guard_1.RolesGuard,
|
|
38
|
-
},
|
|
42
|
+
...rolesGuardProvider,
|
|
39
43
|
{
|
|
40
44
|
provide: core_auth_user_service_1.CoreAuthUserService,
|
|
41
45
|
useClass: UserService,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core-auth.module.js","sourceRoot":"","sources":["../../../../src/core/modules/auth/core-auth.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAyF;AACzF,uCAAyC;AACzC,qCAA0D;AAC1D,+CAAkD;AAClD,iEAA+C;AAE/C,yEAA+D;AAC/D,wFAAiF;AACjF,sDAAkD;AAClD,8EAAwE;AACxE,oEAA+D;AAC/D,kGAAoF;AACpF,4EAAuE;AACvE,4DAAwD;AAMjD,IAAM,cAAc,sBAApB,MAAM,cAAc;IAKzB,MAAM,CAAC,OAAO,CACZ,UAAqB,EACrB,WAAsC,EACtC,OAMC;QAGD,IAAI,OAAO,GAAU;YACnB,UAAU;YACV,yBAAc,CAAC,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC,4CAAiB,CAAC,GAAG,EAAE,4CAAiB,CAAC,WAAW,CAAC,EAAE,CAAC;YACpG,eAAS,CAAC,QAAQ,CAAC,OAAO,CAAC;SAC5B,CAAC;QACF,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC;YACpC,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC5C,CAAC;
|
|
1
|
+
{"version":3,"file":"core-auth.module.js","sourceRoot":"","sources":["../../../../src/core/modules/auth/core-auth.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAyF;AACzF,uCAAyC;AACzC,qCAA0D;AAC1D,+CAAkD;AAClD,iEAA+C;AAE/C,yEAA+D;AAC/D,wFAAiF;AACjF,wEAAmE;AACnE,sDAAkD;AAClD,8EAAwE;AACxE,oEAA+D;AAC/D,kGAAoF;AACpF,4EAAuE;AACvE,4DAAwD;AAMjD,IAAM,cAAc,sBAApB,MAAM,cAAc;IAKzB,MAAM,CAAC,OAAO,CACZ,UAAqB,EACrB,WAAsC,EACtC,OAMC;QAGD,IAAI,OAAO,GAAU;YACnB,UAAU;YACV,yBAAc,CAAC,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC,4CAAiB,CAAC,GAAG,EAAE,4CAAiB,CAAC,WAAW,CAAC,EAAE,CAAC;YACpG,eAAS,CAAC,QAAQ,CAAC,OAAO,CAAC;SAC5B,CAAC;QACF,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC;YACpC,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC5C,CAAC;QAID,MAAM,kBAAkB,GAAG,yCAAkB,CAAC,YAAY,EAAE;YAC1D,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,CAAC,GAAG,EAAE;gBACJ,yCAAkB,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC;gBACpD,OAAO,CAAC,EAAE,OAAO,EAAE,gBAAS,EAAE,QAAQ,EAAE,wBAAU,EAAE,CAAC,CAAC;YACxD,CAAC,CAAC,EAAE,CAAC;QAET,IAAI,SAAS,GAAG;YAEd,GAAG,kBAAkB;YACrB;gBACE,OAAO,EAAE,4CAAmB;gBAC5B,QAAQ,EAAE,WAAW;aACtB;YACD;gBACE,OAAO,EAAE,SAAS;gBAClB,QAAQ,EAAE,IAAI,8BAAM,EAAE;aACvB;YACD;gBACE,OAAO,EAAE,mCAAe;gBACxB,QAAQ,EAAE,OAAO,CAAC,WAAW,IAAI,mCAAe;aACjD;YACD;gBACE,OAAO,EAAE,0BAAW;gBACpB,QAAQ,EAAE,OAAO,CAAC,WAAW,IAAI,0BAAW;aAC7C;YACD;gBACE,OAAO,EAAE,yCAAkB;gBAC3B,QAAQ,EAAE,OAAO,CAAC,kBAAkB,IAAI,yCAAkB;aAC3D;YAED,wDAAqB;YACrB,uDAAwB;SACzB,CAAC;QACF,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC;YACtC,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChD,CAAC;QAGD,OAAO;YACL,OAAO,EAAE;gBACP,mCAAe;gBACf,eAAS;gBACT,0BAAW;gBACX,yCAAkB;gBAClB,wDAAqB;gBACrB,uDAAwB;gBACxB,yBAAc;gBACd,UAAU;aACX;YACD,OAAO;YACP,MAAM,EAAE,gBAAc;YACtB,SAAS;SACV,CAAC;IACJ,CAAC;CACF,CAAA;AAnFY,wCAAc;yBAAd,cAAc;IAD1B,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,cAAc,CAmF1B"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare class RolesGuardRegistry {
|
|
2
|
+
private static readonly logger;
|
|
3
|
+
private static registered;
|
|
4
|
+
private static registeredBy;
|
|
5
|
+
static isRegistered(): boolean;
|
|
6
|
+
static getRegisteredBy(): null | string;
|
|
7
|
+
static markRegistered(moduleName?: string): void;
|
|
8
|
+
static reset(): void;
|
|
9
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RolesGuardRegistry = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
class RolesGuardRegistry {
|
|
6
|
+
static isRegistered() {
|
|
7
|
+
return this.registered;
|
|
8
|
+
}
|
|
9
|
+
static getRegisteredBy() {
|
|
10
|
+
return this.registeredBy;
|
|
11
|
+
}
|
|
12
|
+
static markRegistered(moduleName = 'Unknown') {
|
|
13
|
+
if (this.registered) {
|
|
14
|
+
this.logger.debug(`RolesGuard already registered by ${this.registeredBy}, skipping registration from ${moduleName}`);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
this.registered = true;
|
|
18
|
+
this.registeredBy = moduleName;
|
|
19
|
+
this.logger.debug(`RolesGuard registered globally by ${moduleName}`);
|
|
20
|
+
}
|
|
21
|
+
static reset() {
|
|
22
|
+
this.registered = false;
|
|
23
|
+
this.registeredBy = null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.RolesGuardRegistry = RolesGuardRegistry;
|
|
27
|
+
RolesGuardRegistry.logger = new common_1.Logger('RolesGuardRegistry');
|
|
28
|
+
RolesGuardRegistry.registered = false;
|
|
29
|
+
RolesGuardRegistry.registeredBy = null;
|
|
30
|
+
//# sourceMappingURL=roles-guard-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roles-guard-registry.js","sourceRoot":"","sources":["../../../../../src/core/modules/auth/guards/roles-guard-registry.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AAWxC,MAAa,kBAAkB;IAQ7B,MAAM,CAAC,YAAY;QACjB,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAKD,MAAM,CAAC,eAAe;QACpB,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAQD,MAAM,CAAC,cAAc,CAAC,aAAqB,SAAS;QAClD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,oCAAoC,IAAI,CAAC,YAAY,gCAAgC,UAAU,EAAE,CAClG,CAAC;YACF,OAAO;QACT,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qCAAqC,UAAU,EAAE,CAAC,CAAC;IACvE,CAAC;IAMD,MAAM,CAAC,KAAK;QACV,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;IAC3B,CAAC;;AA5CH,gDA6CC;AA5CyB,yBAAM,GAAG,IAAI,eAAM,CAAC,oBAAoB,CAAC,CAAC;AACnD,6BAAU,GAAG,KAAK,CAAC;AACnB,+BAAY,GAAkB,IAAI,CAAC"}
|
|
@@ -5,5 +5,8 @@ export interface CreateBetterAuthOptions {
|
|
|
5
5
|
config: IBetterAuth;
|
|
6
6
|
db: any;
|
|
7
7
|
fallbackSecrets?: (string | undefined)[];
|
|
8
|
+
serverAppUrl?: string;
|
|
9
|
+
serverBaseUrl?: string;
|
|
10
|
+
serverEnv?: string;
|
|
8
11
|
}
|
|
9
12
|
export declare function createBetterAuthInstance(options: CreateBetterAuthOptions): BetterAuthInstance | null;
|
|
@@ -17,20 +17,28 @@ function createBetterAuthInstance(options) {
|
|
|
17
17
|
if (config?.enabled === false) {
|
|
18
18
|
return null;
|
|
19
19
|
}
|
|
20
|
-
const
|
|
20
|
+
const resolvedUrls = resolveUrls(options);
|
|
21
|
+
for (const warning of resolvedUrls.warnings) {
|
|
22
|
+
logger.log(warning);
|
|
23
|
+
}
|
|
24
|
+
const passkeyNormalization = normalizePasskeyConfig(config, resolvedUrls);
|
|
25
|
+
for (const warning of passkeyNormalization.warnings) {
|
|
26
|
+
logger.warn(warning);
|
|
27
|
+
}
|
|
28
|
+
const validation = validateConfig(config, fallbackSecrets, passkeyNormalization);
|
|
21
29
|
for (const warning of validation.warnings) {
|
|
22
30
|
logger.warn(warning);
|
|
23
31
|
}
|
|
24
32
|
if (!validation.valid) {
|
|
25
33
|
throw new Error(`BetterAuth configuration invalid: ${validation.errors.join('; ')}`);
|
|
26
34
|
}
|
|
27
|
-
const plugins = buildPlugins(config);
|
|
35
|
+
const plugins = buildPlugins(config, passkeyNormalization);
|
|
28
36
|
const socialProviders = buildSocialProviders(config);
|
|
29
|
-
const trustedOrigins = buildTrustedOrigins(config);
|
|
37
|
+
const trustedOrigins = buildTrustedOrigins(config, passkeyNormalization, resolvedUrls);
|
|
30
38
|
const additionalFields = buildUserFields(config);
|
|
31
39
|
const betterAuthConfig = {
|
|
32
40
|
basePath: config.basePath || '/iam',
|
|
33
|
-
baseURL: config.baseUrl || 'http://localhost:3000',
|
|
41
|
+
baseURL: resolvedUrls.baseUrl || config.baseUrl || 'http://localhost:3000',
|
|
34
42
|
database: (0, mongodb_1.mongodbAdapter)(db),
|
|
35
43
|
emailAndPassword: {
|
|
36
44
|
enabled: config.emailAndPassword?.enabled !== false,
|
|
@@ -49,7 +57,7 @@ function createBetterAuthInstance(options) {
|
|
|
49
57
|
const finalConfig = config.options ? { ...betterAuthConfig, ...config.options } : betterAuthConfig;
|
|
50
58
|
return (0, better_auth_1.betterAuth)(finalConfig);
|
|
51
59
|
}
|
|
52
|
-
function buildPlugins(config) {
|
|
60
|
+
function buildPlugins(config, passkeyNormalization) {
|
|
53
61
|
const plugins = [];
|
|
54
62
|
const jwtExplicitlyDisabled = config.jwt === false || (typeof config.jwt === 'object' && config.jwt?.enabled === false);
|
|
55
63
|
if (!jwtExplicitlyDisabled) {
|
|
@@ -60,30 +68,31 @@ function buildPlugins(config) {
|
|
|
60
68
|
},
|
|
61
69
|
}));
|
|
62
70
|
}
|
|
63
|
-
const
|
|
64
|
-
if (
|
|
71
|
+
const twoFactorExplicitlyDisabled = config.twoFactor === false || (typeof config.twoFactor === 'object' && config.twoFactor?.enabled === false);
|
|
72
|
+
if (!twoFactorExplicitlyDisabled) {
|
|
73
|
+
const twoFactorConfig = typeof config.twoFactor === 'object' ? config.twoFactor : {};
|
|
65
74
|
plugins.push((0, plugins_1.twoFactor)({
|
|
66
75
|
issuer: twoFactorConfig.appName || 'Nest Server',
|
|
67
76
|
}));
|
|
68
77
|
}
|
|
69
|
-
|
|
70
|
-
|
|
78
|
+
if (passkeyNormalization.enabled && passkeyNormalization.normalizedConfig) {
|
|
79
|
+
const normalizedPasskey = passkeyNormalization.normalizedConfig;
|
|
71
80
|
const passkeyOptions = {
|
|
72
|
-
origin:
|
|
73
|
-
rpID:
|
|
74
|
-
rpName:
|
|
81
|
+
origin: normalizedPasskey.origin,
|
|
82
|
+
rpID: normalizedPasskey.rpId,
|
|
83
|
+
rpName: normalizedPasskey.rpName,
|
|
75
84
|
};
|
|
76
|
-
if (
|
|
77
|
-
passkeyOptions.authenticatorAttachment =
|
|
85
|
+
if (normalizedPasskey.authenticatorAttachment) {
|
|
86
|
+
passkeyOptions.authenticatorAttachment = normalizedPasskey.authenticatorAttachment;
|
|
78
87
|
}
|
|
79
|
-
if (
|
|
80
|
-
passkeyOptions.residentKey =
|
|
88
|
+
if (normalizedPasskey.residentKey) {
|
|
89
|
+
passkeyOptions.residentKey = normalizedPasskey.residentKey;
|
|
81
90
|
}
|
|
82
|
-
if (
|
|
83
|
-
passkeyOptions.userVerification =
|
|
91
|
+
if (normalizedPasskey.userVerification) {
|
|
92
|
+
passkeyOptions.userVerification = normalizedPasskey.userVerification;
|
|
84
93
|
}
|
|
85
|
-
if (
|
|
86
|
-
passkeyOptions.webAuthnChallengeCookie =
|
|
94
|
+
if (normalizedPasskey.webAuthnChallengeCookie) {
|
|
95
|
+
passkeyOptions.webAuthnChallengeCookie = normalizedPasskey.webAuthnChallengeCookie;
|
|
87
96
|
}
|
|
88
97
|
plugins.push((0, passkey_1.passkey)(passkeyOptions));
|
|
89
98
|
}
|
|
@@ -106,13 +115,15 @@ function buildSocialProviders(config) {
|
|
|
106
115
|
}
|
|
107
116
|
return socialProvidersConfig;
|
|
108
117
|
}
|
|
109
|
-
function buildTrustedOrigins(config) {
|
|
118
|
+
function buildTrustedOrigins(config, passkeyNormalization, resolvedUrls) {
|
|
110
119
|
if (config.trustedOrigins?.length) {
|
|
111
120
|
return config.trustedOrigins;
|
|
112
121
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
122
|
+
if (passkeyNormalization.enabled && passkeyNormalization.trustedOrigins?.length) {
|
|
123
|
+
return passkeyNormalization.trustedOrigins;
|
|
124
|
+
}
|
|
125
|
+
if (resolvedUrls.appUrl) {
|
|
126
|
+
return [resolvedUrls.appUrl];
|
|
116
127
|
}
|
|
117
128
|
return undefined;
|
|
118
129
|
}
|
|
@@ -167,20 +178,6 @@ function getAutoGeneratedSecret() {
|
|
|
167
178
|
}
|
|
168
179
|
return cachedAutoGeneratedSecret;
|
|
169
180
|
}
|
|
170
|
-
function getPluginConfig(config) {
|
|
171
|
-
if (!isPluginEnabled(config))
|
|
172
|
-
return undefined;
|
|
173
|
-
if (typeof config === 'boolean')
|
|
174
|
-
return {};
|
|
175
|
-
return config;
|
|
176
|
-
}
|
|
177
|
-
function isPluginEnabled(config) {
|
|
178
|
-
if (config === undefined)
|
|
179
|
-
return false;
|
|
180
|
-
if (typeof config === 'boolean')
|
|
181
|
-
return config;
|
|
182
|
-
return config.enabled !== false;
|
|
183
|
-
}
|
|
184
181
|
function isValidSecretLength(secret) {
|
|
185
182
|
return secret && secret.length >= 32;
|
|
186
183
|
}
|
|
@@ -193,7 +190,136 @@ function isValidUrl(url) {
|
|
|
193
190
|
return false;
|
|
194
191
|
}
|
|
195
192
|
}
|
|
196
|
-
|
|
193
|
+
const LOCALHOST_DEFAULTS = {
|
|
194
|
+
API_URL: 'http://localhost:3000',
|
|
195
|
+
APP_URL: 'http://localhost:3001',
|
|
196
|
+
};
|
|
197
|
+
const LOCALHOST_ENVS = ['local', 'ci', 'e2e'];
|
|
198
|
+
function deriveAppUrlFromBaseUrl(baseUrl) {
|
|
199
|
+
try {
|
|
200
|
+
const url = new URL(baseUrl);
|
|
201
|
+
const hostname = url.hostname;
|
|
202
|
+
if (hostname.startsWith('api.')) {
|
|
203
|
+
url.hostname = hostname.substring(4);
|
|
204
|
+
return url.origin;
|
|
205
|
+
}
|
|
206
|
+
return url.origin;
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
return baseUrl;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
function extractRpIdFromUrl(url) {
|
|
213
|
+
try {
|
|
214
|
+
const parsedUrl = new URL(url);
|
|
215
|
+
const hostname = parsedUrl.hostname;
|
|
216
|
+
if (hostname === 'localhost' || hostname === '127.0.0.1') {
|
|
217
|
+
return 'localhost';
|
|
218
|
+
}
|
|
219
|
+
const parts = hostname.split('.');
|
|
220
|
+
if (parts.length <= 2) {
|
|
221
|
+
return hostname;
|
|
222
|
+
}
|
|
223
|
+
return parts.slice(-2).join('.');
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
return 'localhost';
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
function normalizePasskeyConfig(config, resolvedUrls) {
|
|
230
|
+
const warnings = [];
|
|
231
|
+
const isExplicitlyDisabled = config.passkey === false || (typeof config.passkey === 'object' && config.passkey?.enabled === false);
|
|
232
|
+
if (isExplicitlyDisabled) {
|
|
233
|
+
return { enabled: false, normalizedConfig: null, trustedOrigins: null, warnings };
|
|
234
|
+
}
|
|
235
|
+
const rawConfig = typeof config.passkey === 'object' ? config.passkey : {};
|
|
236
|
+
const finalRpId = rawConfig.rpId || resolvedUrls.rpId;
|
|
237
|
+
const finalOrigin = rawConfig.origin || resolvedUrls.appUrl;
|
|
238
|
+
const finalTrustedOrigins = config.trustedOrigins?.length ? config.trustedOrigins : resolvedUrls.appUrl ? [resolvedUrls.appUrl] : undefined;
|
|
239
|
+
const hasRequiredConfig = finalRpId && finalOrigin && finalTrustedOrigins?.length;
|
|
240
|
+
if (!hasRequiredConfig) {
|
|
241
|
+
const missingFields = [];
|
|
242
|
+
if (!finalRpId)
|
|
243
|
+
missingFields.push('rpId');
|
|
244
|
+
if (!finalOrigin)
|
|
245
|
+
missingFields.push('origin');
|
|
246
|
+
if (!finalTrustedOrigins?.length)
|
|
247
|
+
missingFields.push('trustedOrigins');
|
|
248
|
+
warnings.push(`⚠️ PASSKEY DISABLED: Cannot auto-detect required values (${missingFields.join(', ')}). ` +
|
|
249
|
+
'To enable Passkey, set baseUrl in your config or configure passkey values explicitly.');
|
|
250
|
+
warnings.push('Fix options:\n' +
|
|
251
|
+
' 1. Set baseUrl: "https://api.example.com" → auto-detects appUrl, rpId, origin\n' +
|
|
252
|
+
' 2. Set env: "local" → uses localhost:3000 (API) and localhost:3001 (App) defaults\n' +
|
|
253
|
+
' 3. Disable Passkey explicitly: passkey: false (no warning)');
|
|
254
|
+
return { enabled: false, normalizedConfig: null, trustedOrigins: null, warnings };
|
|
255
|
+
}
|
|
256
|
+
if (!rawConfig.rpId && resolvedUrls.rpId) {
|
|
257
|
+
warnings.push(`PASSKEY: Using rpId="${finalRpId}" (auto-detected from appUrl)`);
|
|
258
|
+
}
|
|
259
|
+
if (!rawConfig.origin && resolvedUrls.appUrl) {
|
|
260
|
+
warnings.push(`PASSKEY: Using origin="${finalOrigin}" (= appUrl)`);
|
|
261
|
+
}
|
|
262
|
+
if (!config.trustedOrigins?.length && resolvedUrls.appUrl) {
|
|
263
|
+
warnings.push(`PASSKEY: Using trustedOrigins=${JSON.stringify(finalTrustedOrigins)} (= [appUrl])`);
|
|
264
|
+
}
|
|
265
|
+
const normalizedConfig = {
|
|
266
|
+
origin: finalOrigin,
|
|
267
|
+
rpId: finalRpId,
|
|
268
|
+
rpName: rawConfig.rpName || 'Nest Server',
|
|
269
|
+
};
|
|
270
|
+
if (rawConfig.authenticatorAttachment) {
|
|
271
|
+
normalizedConfig.authenticatorAttachment = rawConfig.authenticatorAttachment;
|
|
272
|
+
}
|
|
273
|
+
if (rawConfig.challengeStorage) {
|
|
274
|
+
normalizedConfig.challengeStorage = rawConfig.challengeStorage;
|
|
275
|
+
}
|
|
276
|
+
if (rawConfig.challengeTtlSeconds) {
|
|
277
|
+
normalizedConfig.challengeTtlSeconds = rawConfig.challengeTtlSeconds;
|
|
278
|
+
}
|
|
279
|
+
if (rawConfig.residentKey) {
|
|
280
|
+
normalizedConfig.residentKey = rawConfig.residentKey;
|
|
281
|
+
}
|
|
282
|
+
if (rawConfig.userVerification) {
|
|
283
|
+
normalizedConfig.userVerification = rawConfig.userVerification;
|
|
284
|
+
}
|
|
285
|
+
if (rawConfig.webAuthnChallengeCookie) {
|
|
286
|
+
normalizedConfig.webAuthnChallengeCookie = rawConfig.webAuthnChallengeCookie;
|
|
287
|
+
}
|
|
288
|
+
return {
|
|
289
|
+
enabled: true,
|
|
290
|
+
normalizedConfig,
|
|
291
|
+
trustedOrigins: finalTrustedOrigins,
|
|
292
|
+
warnings,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
function resolveUrls(options) {
|
|
296
|
+
const { config, serverAppUrl, serverBaseUrl, serverEnv } = options;
|
|
297
|
+
const warnings = [];
|
|
298
|
+
const usesLocalhostDefaults = LOCALHOST_ENVS.includes(serverEnv || '');
|
|
299
|
+
let baseUrl = config.baseUrl || serverBaseUrl;
|
|
300
|
+
if (!baseUrl && usesLocalhostDefaults) {
|
|
301
|
+
baseUrl = LOCALHOST_DEFAULTS.API_URL;
|
|
302
|
+
warnings.push(`URL: Using localhost default baseUrl="${baseUrl}" (env: '${serverEnv}')`);
|
|
303
|
+
}
|
|
304
|
+
let appUrl = serverAppUrl;
|
|
305
|
+
const isBaseUrlLocalhost = baseUrl && (baseUrl.includes('localhost') || baseUrl.includes('127.0.0.1'));
|
|
306
|
+
if (!appUrl && usesLocalhostDefaults && isBaseUrlLocalhost) {
|
|
307
|
+
appUrl = LOCALHOST_DEFAULTS.APP_URL;
|
|
308
|
+
warnings.push(`URL: Using localhost default appUrl="${appUrl}" (env: '${serverEnv}')`);
|
|
309
|
+
}
|
|
310
|
+
if (!appUrl && baseUrl) {
|
|
311
|
+
appUrl = deriveAppUrlFromBaseUrl(baseUrl);
|
|
312
|
+
if (appUrl !== baseUrl) {
|
|
313
|
+
warnings.push(`URL: Auto-derived appUrl="${appUrl}" from baseUrl="${baseUrl}"`);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
let rpId;
|
|
317
|
+
if (appUrl) {
|
|
318
|
+
rpId = extractRpIdFromUrl(appUrl);
|
|
319
|
+
}
|
|
320
|
+
return { appUrl, baseUrl, rpId, warnings };
|
|
321
|
+
}
|
|
322
|
+
function validateConfig(config, fallbackSecrets, passkeyNormalization) {
|
|
197
323
|
const errors = [];
|
|
198
324
|
const warnings = [];
|
|
199
325
|
let secretSource = 'explicit';
|
|
@@ -236,15 +362,18 @@ function validateConfig(config, fallbackSecrets) {
|
|
|
236
362
|
}
|
|
237
363
|
}
|
|
238
364
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
365
|
+
if (passkeyNormalization?.trustedOrigins) {
|
|
366
|
+
for (const origin of passkeyNormalization.trustedOrigins) {
|
|
367
|
+
if (!isValidUrl(origin)) {
|
|
368
|
+
errors.push(`Invalid auto-detected trustedOrigin format: ${origin}`);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
244
371
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
372
|
+
if (passkeyNormalization?.enabled && passkeyNormalization.normalizedConfig) {
|
|
373
|
+
const normalizedOrigin = passkeyNormalization.normalizedConfig.origin;
|
|
374
|
+
if (!isValidUrl(normalizedOrigin)) {
|
|
375
|
+
errors.push(`Invalid passkey origin format: ${normalizedOrigin}`);
|
|
376
|
+
}
|
|
248
377
|
}
|
|
249
378
|
if (config.socialProviders) {
|
|
250
379
|
for (const [name, provider] of Object.entries(config.socialProviders)) {
|