@lenne.tech/nest-server 11.14.0 → 11.15.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/dist/core/common/interfaces/server-options.interface.d.ts +1 -1
- package/dist/core/modules/better-auth/core-better-auth-email-verification.service.js +3 -0
- package/dist/core/modules/better-auth/core-better-auth-email-verification.service.js.map +1 -1
- package/dist/core.module.d.ts +1 -0
- package/dist/core.module.js +41 -25
- package/dist/core.module.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -1
- package/src/core/common/interfaces/server-options.interface.ts +22 -18
- package/src/core/modules/better-auth/core-better-auth-email-verification.service.ts +5 -1
- package/src/core.module.ts +52 -29
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lenne.tech/nest-server",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.15.0",
|
|
4
4
|
"description": "Modern, fast, powerful Node.js web framework in TypeScript based on Nest with a GraphQL API and a connection to MongoDB (or other databases).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"node",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"vitest:unit": "vitest run --config vitest.config.ts",
|
|
54
54
|
"test:unit:watch": "vitest --config vitest.config.ts",
|
|
55
55
|
"test:types": "tsc --noEmit --skipLibCheck -p tests/types/tsconfig.json",
|
|
56
|
+
"test:cleanup": "find tests -type f \\( -name '*.txt' -o -name '*.bin' \\) -not -name '.gitkeep' -delete && echo 'Test artifacts cleaned up'",
|
|
56
57
|
"watch": "npm-watch"
|
|
57
58
|
},
|
|
58
59
|
"repository": {
|
|
@@ -1099,28 +1099,32 @@ export interface IServerOptions {
|
|
|
1099
1099
|
* Configuration of the GraphQL module
|
|
1100
1100
|
* see https://docs.nestjs.com/graphql/quick-start
|
|
1101
1101
|
* and https://www.apollographql.com/docs/apollo-server/api/apollo-server/
|
|
1102
|
+
*
|
|
1103
|
+
* Set to `false` to completely disable GraphQL (no GraphQLModule, no /graphql endpoint).
|
|
1102
1104
|
*/
|
|
1103
|
-
graphQl?:
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1105
|
+
graphQl?:
|
|
1106
|
+
| false
|
|
1107
|
+
| {
|
|
1108
|
+
/**
|
|
1109
|
+
* Driver configuration for Apollo
|
|
1110
|
+
*/
|
|
1111
|
+
driver?: ApolloDriverConfig;
|
|
1108
1112
|
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
+
/**
|
|
1114
|
+
* Subscription authentication
|
|
1115
|
+
*/
|
|
1116
|
+
enableSubscriptionAuth?: boolean;
|
|
1113
1117
|
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
+
/**
|
|
1119
|
+
* Maximum complexity of GraphQL requests
|
|
1120
|
+
*/
|
|
1121
|
+
maxComplexity?: number;
|
|
1118
1122
|
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1123
|
+
/**
|
|
1124
|
+
* Module options (forRootAsync)
|
|
1125
|
+
*/
|
|
1126
|
+
options?: GqlModuleAsyncOptions;
|
|
1127
|
+
};
|
|
1124
1128
|
|
|
1125
1129
|
/**
|
|
1126
1130
|
* Whether to activate health check endpoints
|
|
@@ -168,9 +168,13 @@ export class CoreBetterAuthEmailVerificationService {
|
|
|
168
168
|
url = this.buildFrontendVerificationUrl(token);
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
//
|
|
171
|
+
// Log verification URL in non-production environments for debugging and test capture
|
|
172
172
|
// Uses console.log directly to ensure reliable capture in test environments (Vitest)
|
|
173
173
|
// NestJS Logger may buffer output which makes interception unreliable in tests
|
|
174
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
175
|
+
// oxlint-disable-next-line no-console
|
|
176
|
+
console.log(`[EMAIL VERIFICATION] User: ${user.email}, URL: ${url}`);
|
|
177
|
+
}
|
|
174
178
|
|
|
175
179
|
// Brevo template path: send via Brevo transactional API if configured
|
|
176
180
|
if (this.config.brevoTemplateId && this.brevoService) {
|
package/src/core.module.ts
CHANGED
|
@@ -42,11 +42,15 @@ import { CoreSystemSetupModule } from './core/modules/system-setup/core-system-s
|
|
|
42
42
|
@Global()
|
|
43
43
|
@Module({})
|
|
44
44
|
export class CoreModule implements NestModule {
|
|
45
|
+
private static graphQlEnabled = true;
|
|
46
|
+
|
|
45
47
|
/**
|
|
46
48
|
* Integrate middleware, e.g. GraphQL upload handing for express
|
|
47
49
|
*/
|
|
48
50
|
configure(consumer: MiddlewareConsumer) {
|
|
49
|
-
|
|
51
|
+
if (CoreModule.graphQlEnabled) {
|
|
52
|
+
consumer.apply(graphqlUploadExpress()).forRoutes('graphql');
|
|
53
|
+
}
|
|
50
54
|
}
|
|
51
55
|
|
|
52
56
|
/**
|
|
@@ -138,24 +142,35 @@ export class CoreModule implements NestModule {
|
|
|
138
142
|
};
|
|
139
143
|
}
|
|
140
144
|
|
|
145
|
+
// Determine if GraphQL is enabled (false means explicitly disabled)
|
|
146
|
+
const isGraphQlEnabled = options.graphQl !== false;
|
|
147
|
+
CoreModule.graphQlEnabled = isGraphQlEnabled;
|
|
148
|
+
|
|
141
149
|
// Check if autoRegister: false for IAM-only mode (project imports its own BetterAuth module)
|
|
142
150
|
const rawBetterAuth = options?.betterAuth;
|
|
143
151
|
const isAutoRegisterDisabledEarly = typeof rawBetterAuth === 'object' && rawBetterAuth?.autoRegister === false;
|
|
144
152
|
|
|
145
|
-
// Build GraphQL driver configuration based on auth mode
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
153
|
+
// Build GraphQL driver configuration based on auth mode (only if GraphQL is enabled)
|
|
154
|
+
let graphQlDriverConfig = {};
|
|
155
|
+
if (isGraphQlEnabled) {
|
|
156
|
+
graphQlDriverConfig = isIamOnlyMode
|
|
157
|
+
? isAutoRegisterDisabledEarly
|
|
158
|
+
? this.buildLazyIamGraphQlDriver(cors, options)
|
|
159
|
+
: this.buildIamOnlyGraphQlDriver(cors, options)
|
|
160
|
+
: this.buildLegacyGraphQlDriver(AuthService, AuthModule, cors, options);
|
|
161
|
+
}
|
|
151
162
|
|
|
152
163
|
const config: IServerOptions = merge(
|
|
153
164
|
{
|
|
154
165
|
env: 'develop',
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
166
|
+
...(isGraphQlEnabled
|
|
167
|
+
? {
|
|
168
|
+
graphQl: {
|
|
169
|
+
driver: graphQlDriverConfig,
|
|
170
|
+
enableSubscriptionAuth: true,
|
|
171
|
+
},
|
|
172
|
+
}
|
|
173
|
+
: {}),
|
|
159
174
|
mongoose: {
|
|
160
175
|
options: {
|
|
161
176
|
connectionFactory: (connection) => {
|
|
@@ -190,8 +205,8 @@ export class CoreModule implements NestModule {
|
|
|
190
205
|
MailjetService,
|
|
191
206
|
];
|
|
192
207
|
|
|
193
|
-
// Add ComplexityPlugin only if not in Vitest (Vitest has dual GraphQL loading issue)
|
|
194
|
-
if (!process.env.VITEST) {
|
|
208
|
+
// Add ComplexityPlugin only if not in Vitest (Vitest has dual GraphQL loading issue) and GraphQL is enabled
|
|
209
|
+
if (!process.env.VITEST && isGraphQlEnabled) {
|
|
195
210
|
providers.push(ComplexityPlugin);
|
|
196
211
|
}
|
|
197
212
|
|
|
@@ -228,12 +243,15 @@ export class CoreModule implements NestModule {
|
|
|
228
243
|
// and: https://mongoosejs.com/docs/guide.html#strictQuery
|
|
229
244
|
mongoose.set('strictQuery', config.mongoose.strictQuery || false);
|
|
230
245
|
|
|
231
|
-
const imports: any[] = [
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
246
|
+
const imports: any[] = [MongooseModule.forRoot(config.mongoose.uri, config.mongoose.options)];
|
|
247
|
+
|
|
248
|
+
if (isGraphQlEnabled && config.graphQl) {
|
|
249
|
+
imports.push(
|
|
250
|
+
GraphQLModule.forRootAsync<ApolloDriverConfig>(
|
|
251
|
+
Object.assign({ driver: ApolloDriver }, config.graphQl.driver, config.graphQl.options),
|
|
252
|
+
),
|
|
253
|
+
);
|
|
254
|
+
}
|
|
237
255
|
|
|
238
256
|
// Add ErrorCodeModule based on configuration
|
|
239
257
|
// autoRegister defaults to true (backward compatible)
|
|
@@ -311,7 +329,7 @@ export class CoreModule implements NestModule {
|
|
|
311
329
|
|
|
312
330
|
// Set exports
|
|
313
331
|
const exports: any[] = [ConfigService, EmailService, TemplateService, MailjetService];
|
|
314
|
-
if (!process.env.VITEST) {
|
|
332
|
+
if (!process.env.VITEST && isGraphQlEnabled) {
|
|
315
333
|
exports.push(ComplexityPlugin);
|
|
316
334
|
}
|
|
317
335
|
|
|
@@ -335,6 +353,8 @@ export class CoreModule implements NestModule {
|
|
|
335
353
|
* This is the recommended mode for new projects.
|
|
336
354
|
*/
|
|
337
355
|
private static buildIamOnlyGraphQlDriver(cors: object, options: Partial<IServerOptions>) {
|
|
356
|
+
// This method is only called when graphQl !== false, extract config with type narrowing
|
|
357
|
+
const graphQlOpts = typeof options?.graphQl === 'object' ? options.graphQl : undefined;
|
|
338
358
|
return {
|
|
339
359
|
imports: [CoreBetterAuthModule],
|
|
340
360
|
inject: [CoreBetterAuthService, CoreBetterAuthUserMapper],
|
|
@@ -350,7 +370,7 @@ export class CoreModule implements NestModule {
|
|
|
350
370
|
context: ({ extra }) => extra,
|
|
351
371
|
onConnect: async (context: Context<any>) => {
|
|
352
372
|
const { connectionParams, extra } = context;
|
|
353
|
-
const enableAuth =
|
|
373
|
+
const enableAuth = graphQlOpts?.enableSubscriptionAuth ?? true;
|
|
354
374
|
|
|
355
375
|
if (enableAuth) {
|
|
356
376
|
// Get headers from raw headers or connection params
|
|
@@ -385,7 +405,7 @@ export class CoreModule implements NestModule {
|
|
|
385
405
|
},
|
|
386
406
|
'subscriptions-transport-ws': {
|
|
387
407
|
onConnect: async (connectionParams) => {
|
|
388
|
-
const enableAuth =
|
|
408
|
+
const enableAuth = graphQlOpts?.enableSubscriptionAuth ?? true;
|
|
389
409
|
|
|
390
410
|
if (enableAuth) {
|
|
391
411
|
const authToken: string = connectionParams?.Authorization?.split(' ')[1];
|
|
@@ -415,7 +435,7 @@ export class CoreModule implements NestModule {
|
|
|
415
435
|
},
|
|
416
436
|
},
|
|
417
437
|
},
|
|
418
|
-
|
|
438
|
+
graphQlOpts?.driver,
|
|
419
439
|
),
|
|
420
440
|
};
|
|
421
441
|
}
|
|
@@ -430,6 +450,8 @@ export class CoreModule implements NestModule {
|
|
|
430
450
|
* which happens after all modules are initialized.
|
|
431
451
|
*/
|
|
432
452
|
private static buildLazyIamGraphQlDriver(cors: object, options: Partial<IServerOptions>) {
|
|
453
|
+
// This method is only called when graphQl !== false, extract config with type narrowing
|
|
454
|
+
const graphQlOpts = typeof options?.graphQl === 'object' ? options.graphQl : undefined;
|
|
433
455
|
return {
|
|
434
456
|
useFactory: async () =>
|
|
435
457
|
Object.assign(
|
|
@@ -443,7 +465,7 @@ export class CoreModule implements NestModule {
|
|
|
443
465
|
context: ({ extra }) => extra,
|
|
444
466
|
onConnect: async (context: Context<any>) => {
|
|
445
467
|
const { connectionParams, extra } = context;
|
|
446
|
-
const enableAuth =
|
|
468
|
+
const enableAuth = graphQlOpts?.enableSubscriptionAuth ?? true;
|
|
447
469
|
|
|
448
470
|
if (enableAuth) {
|
|
449
471
|
const betterAuthService = CoreBetterAuthModule.getServiceInstance();
|
|
@@ -482,7 +504,7 @@ export class CoreModule implements NestModule {
|
|
|
482
504
|
},
|
|
483
505
|
'subscriptions-transport-ws': {
|
|
484
506
|
onConnect: async (connectionParams) => {
|
|
485
|
-
const enableAuth =
|
|
507
|
+
const enableAuth = graphQlOpts?.enableSubscriptionAuth ?? true;
|
|
486
508
|
|
|
487
509
|
if (enableAuth) {
|
|
488
510
|
const betterAuthService = CoreBetterAuthModule.getServiceInstance();
|
|
@@ -517,7 +539,7 @@ export class CoreModule implements NestModule {
|
|
|
517
539
|
},
|
|
518
540
|
},
|
|
519
541
|
},
|
|
520
|
-
|
|
542
|
+
graphQlOpts?.driver,
|
|
521
543
|
),
|
|
522
544
|
};
|
|
523
545
|
}
|
|
@@ -536,8 +558,9 @@ export class CoreModule implements NestModule {
|
|
|
536
558
|
cors: object,
|
|
537
559
|
options: Partial<IServerOptions>,
|
|
538
560
|
) {
|
|
539
|
-
//
|
|
540
|
-
const
|
|
561
|
+
// This method is only called when graphQl !== false, extract config with type narrowing
|
|
562
|
+
const graphQlOpts = typeof options?.graphQl === 'object' ? options.graphQl : undefined;
|
|
563
|
+
const enableSubscriptionAuth = graphQlOpts?.enableSubscriptionAuth ?? true;
|
|
541
564
|
|
|
542
565
|
return {
|
|
543
566
|
imports: [AuthModule],
|
|
@@ -599,7 +622,7 @@ export class CoreModule implements NestModule {
|
|
|
599
622
|
},
|
|
600
623
|
},
|
|
601
624
|
},
|
|
602
|
-
|
|
625
|
+
graphQlOpts?.driver,
|
|
603
626
|
),
|
|
604
627
|
};
|
|
605
628
|
}
|