@lenne.tech/nest-server 10.2.9 → 10.2.10
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 +6 -3
- package/dist/config.env.js.map +1 -1
- package/dist/core/common/decorators/restricted.decorator.js.map +1 -1
- package/dist/core/common/helpers/db.helper.js.map +1 -1
- package/dist/core/common/helpers/filter.helper.js +1 -3
- package/dist/core/common/helpers/filter.helper.js.map +1 -1
- package/dist/core/common/interceptors/check-security.interceptor.js.map +1 -1
- package/dist/core/common/plugins/complexity.plugin.js +2 -1
- package/dist/core/common/plugins/complexity.plugin.js.map +1 -1
- package/dist/core/common/services/core-cron-jobs.service.js.map +1 -1
- package/dist/core/common/services/crud.service.js.map +1 -1
- package/dist/core/common/services/email.service.js +2 -1
- package/dist/core/common/services/email.service.js.map +1 -1
- package/dist/core/common/services/model-doc.service.js +6 -2
- package/dist/core/common/services/model-doc.service.js.map +1 -1
- package/dist/core/common/services/module.service.js +2 -1
- package/dist/core/common/services/module.service.js.map +1 -1
- package/dist/core/modules/auth/core-auth.controller.js +2 -1
- package/dist/core/modules/auth/core-auth.controller.js.map +1 -1
- package/dist/core/modules/auth/core-auth.resolver.js +2 -1
- package/dist/core/modules/auth/core-auth.resolver.js.map +1 -1
- package/dist/core/modules/auth/services/core-auth.service.js.map +1 -1
- package/dist/core/modules/auth/strategies/jwt-refresh.strategy.js +2 -1
- package/dist/core/modules/auth/strategies/jwt-refresh.strategy.js.map +1 -1
- package/dist/core/modules/auth/strategies/jwt.strategy.js +2 -1
- package/dist/core/modules/auth/strategies/jwt.strategy.js.map +1 -1
- package/dist/core/modules/file/core-file.service.js.map +1 -1
- package/dist/core/modules/health-check/core-health-check.module.js.map +1 -1
- package/dist/core/modules/health-check/core-health-check.resolver.js.map +1 -1
- package/dist/core/modules/health-check/core-health-check.service.js.map +1 -1
- package/dist/core/modules/user/core-user.service.js.map +1 -1
- package/dist/core.module.js +1 -2
- package/dist/core.module.js.map +1 -1
- package/dist/server/common/services/cron-jobs.service.js +2 -1
- package/dist/server/common/services/cron-jobs.service.js.map +1 -1
- package/dist/server/modules/user/user.resolver.js +2 -1
- package/dist/server/modules/user/user.resolver.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/config.env.ts +21 -15
- package/src/core/common/decorators/restricted.decorator.ts +1 -3
- package/src/core/common/helpers/db.helper.ts +2 -2
- package/src/core/common/helpers/filter.helper.ts +8 -14
- package/src/core/common/interceptors/check-security.interceptor.ts +10 -2
- package/src/core/common/interfaces/core-persistence-model.interface.ts +1 -1
- package/src/core/common/interfaces/cron-job-config-with-time-zone.interface.ts +2 -1
- package/src/core/common/interfaces/cron-job-config-with-utc-offset.interface.ts +2 -2
- package/src/core/common/interfaces/server-options.interface.ts +5 -9
- package/src/core/common/plugins/complexity.plugin.ts +4 -1
- package/src/core/common/services/core-cron-jobs.service.ts +7 -3
- package/src/core/common/services/crud.service.ts +23 -14
- package/src/core/common/services/email.service.ts +4 -1
- package/src/core/common/services/model-doc.service.ts +11 -12
- package/src/core/common/services/module.service.ts +10 -2
- package/src/core/common/types/core-model-constructor.type.ts +2 -2
- package/src/core/modules/auth/core-auth.controller.ts +4 -1
- package/src/core/modules/auth/core-auth.resolver.ts +4 -1
- package/src/core/modules/auth/services/core-auth.service.ts +8 -5
- package/src/core/modules/auth/strategies/jwt-refresh.strategy.ts +4 -1
- package/src/core/modules/auth/strategies/jwt.strategy.ts +4 -1
- package/src/core/modules/file/core-file.service.ts +4 -1
- package/src/core/modules/health-check/core-health-check.module.ts +1 -2
- package/src/core/modules/health-check/core-health-check.resolver.ts +1 -3
- package/src/core/modules/health-check/core-health-check.service.ts +28 -22
- package/src/core/modules/user/core-user.service.ts +2 -2
- package/src/core.module.ts +1 -2
- package/src/server/common/services/cron-jobs.service.ts +4 -1
- package/src/server/modules/user/user.resolver.ts +4 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lenne.tech/nest-server",
|
|
3
|
-
"version": "10.2.
|
|
3
|
+
"version": "10.2.10",
|
|
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",
|
package/src/config.env.ts
CHANGED
|
@@ -305,26 +305,32 @@ console.info(`Configured for: ${envConfig.env}${env !== envConfig.env ? ` (reque
|
|
|
305
305
|
if (envConfig.loadLocalConfig) {
|
|
306
306
|
let localConfig;
|
|
307
307
|
if (typeof envConfig.loadLocalConfig === 'string') {
|
|
308
|
-
import(envConfig.loadLocalConfig)
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
308
|
+
import(envConfig.loadLocalConfig)
|
|
309
|
+
.then((loadedConfig) => {
|
|
310
|
+
localConfig = loadedConfig.default || loadedConfig;
|
|
311
|
+
merge(envConfig, localConfig);
|
|
312
|
+
})
|
|
313
|
+
.catch(() => {
|
|
314
|
+
console.info(`Configuration ${envConfig.loadLocalConfig} not found!`);
|
|
315
|
+
});
|
|
314
316
|
} else {
|
|
315
317
|
// get config from src directory
|
|
316
|
-
import(join(__dirname, 'config.json'))
|
|
317
|
-
|
|
318
|
-
merge(envConfig, localConfig);
|
|
319
|
-
}).catch(() => {
|
|
320
|
-
// if not found try to find in project directory
|
|
321
|
-
import(join(__dirname, '..', 'config.json')).then((loadedConfig) => {
|
|
318
|
+
import(join(__dirname, 'config.json'))
|
|
319
|
+
.then((loadedConfig) => {
|
|
322
320
|
localConfig = loadedConfig.default || loadedConfig;
|
|
323
321
|
merge(envConfig, localConfig);
|
|
324
|
-
})
|
|
325
|
-
|
|
322
|
+
})
|
|
323
|
+
.catch(() => {
|
|
324
|
+
// if not found try to find in project directory
|
|
325
|
+
import(join(__dirname, '..', 'config.json'))
|
|
326
|
+
.then((loadedConfig) => {
|
|
327
|
+
localConfig = loadedConfig.default || loadedConfig;
|
|
328
|
+
merge(envConfig, localConfig);
|
|
329
|
+
})
|
|
330
|
+
.catch(() => {
|
|
331
|
+
console.info('No local config.json found!');
|
|
332
|
+
});
|
|
326
333
|
});
|
|
327
|
-
});
|
|
328
334
|
}
|
|
329
335
|
}
|
|
330
336
|
|
|
@@ -227,9 +227,7 @@ export const checkRestricted = (
|
|
|
227
227
|
// Throw error
|
|
228
228
|
if (config.throwError) {
|
|
229
229
|
throw new UnauthorizedException(
|
|
230
|
-
`The current user has no access rights for ${
|
|
231
|
-
propertyKey
|
|
232
|
-
}${data.constructor?.name ? ` of ${data.constructor.name}` : ''}`,
|
|
230
|
+
`The current user has no access rights for ${propertyKey}${data.constructor?.name ? ` of ${data.constructor.name}` : ''}`,
|
|
233
231
|
);
|
|
234
232
|
}
|
|
235
233
|
|
|
@@ -63,7 +63,8 @@ export function addIds(
|
|
|
63
63
|
) {
|
|
64
64
|
const converted = result[0] instanceof Types.ObjectId ? getObjectIds(ids) : getStringIds(ids);
|
|
65
65
|
result.push(...(converted as any));
|
|
66
|
-
} else {
|
|
66
|
+
} else {
|
|
67
|
+
// Add ID
|
|
67
68
|
result.push(...ids);
|
|
68
69
|
}
|
|
69
70
|
}
|
|
@@ -637,7 +638,6 @@ export async function setPopulates<T = Document | Query<any, any>>(
|
|
|
637
638
|
* Get ID of element as string
|
|
638
639
|
*/
|
|
639
640
|
function getStringId(element: any): string {
|
|
640
|
-
|
|
641
641
|
// Check element
|
|
642
642
|
if (!element) {
|
|
643
643
|
return element;
|
|
@@ -207,11 +207,11 @@ export function generateFilterQuery<T = any>(
|
|
|
207
207
|
case ComparisonOperatorEnum.REGEX:
|
|
208
208
|
result[field] = not
|
|
209
209
|
? {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
210
|
+
$not: {
|
|
211
|
+
$options: options || '',
|
|
212
|
+
$regex: new RegExp(value),
|
|
213
|
+
},
|
|
214
|
+
}
|
|
215
215
|
: { $options: options || '', $regex: new RegExp(value) };
|
|
216
216
|
break;
|
|
217
217
|
}
|
|
@@ -224,10 +224,7 @@ export function generateFilterQuery<T = any>(
|
|
|
224
224
|
/**
|
|
225
225
|
* Generate find options
|
|
226
226
|
*/
|
|
227
|
-
export function generateFindOptions(
|
|
228
|
-
filterArgs: Partial<FilterArgs>,
|
|
229
|
-
options?: { maxLimit?: number },
|
|
230
|
-
): QueryOptions {
|
|
227
|
+
export function generateFindOptions(filterArgs: Partial<FilterArgs>, options?: { maxLimit?: number }): QueryOptions {
|
|
231
228
|
// Check filterArgs
|
|
232
229
|
if (!filterArgs) {
|
|
233
230
|
return {};
|
|
@@ -287,11 +284,8 @@ export function filterMerge<T = unknown>(
|
|
|
287
284
|
return {
|
|
288
285
|
filterQuery: (converted[0]
|
|
289
286
|
? { [config.operator]: [converted[0], filterQuery || {}] }
|
|
290
|
-
: filterQuery
|
|
291
|
-
|
|
292
|
-
queryOptions: converted[1] || config.queryOptions
|
|
293
|
-
? { ...converted[1], ...config.queryOptions }
|
|
294
|
-
: undefined,
|
|
287
|
+
: filterQuery) as FilterQuery<T>,
|
|
288
|
+
queryOptions: converted[1] || config.queryOptions ? { ...converted[1], ...config.queryOptions } : undefined,
|
|
295
289
|
samples: config.samples,
|
|
296
290
|
};
|
|
297
291
|
}
|
|
@@ -35,7 +35,11 @@ export class CheckSecurityInterceptor implements NestInterceptor {
|
|
|
35
35
|
new Promise(() => {
|
|
36
36
|
if (dataJson !== JSON.stringify(response)) {
|
|
37
37
|
const id = getStringIds(data);
|
|
38
|
-
console.debug(
|
|
38
|
+
console.debug(
|
|
39
|
+
'CheckSecurityInterceptor: securityCheck changed data of type',
|
|
40
|
+
data.constructor.name,
|
|
41
|
+
id && !Array.isArray(id) ? `with ID: ${id}` : '',
|
|
42
|
+
);
|
|
39
43
|
}
|
|
40
44
|
});
|
|
41
45
|
return response;
|
|
@@ -64,7 +68,11 @@ export class CheckSecurityInterceptor implements NestInterceptor {
|
|
|
64
68
|
new Promise(() => {
|
|
65
69
|
if (itemJson !== JSON.stringify(response)) {
|
|
66
70
|
const id = getStringIds(item);
|
|
67
|
-
console.debug(
|
|
71
|
+
console.debug(
|
|
72
|
+
'CheckSecurityInterceptor: securityCheck changed item of type',
|
|
73
|
+
item.constructor.name,
|
|
74
|
+
id && !Array.isArray(id) ? `with ID: ${id}` : '',
|
|
75
|
+
);
|
|
68
76
|
}
|
|
69
77
|
});
|
|
70
78
|
return response;
|
|
@@ -8,7 +8,8 @@ import { CronJobConfig } from './cron-job-config.interface';
|
|
|
8
8
|
* This config can define timezone but not utcOffset,
|
|
9
9
|
* if you want to use utcOffset, you have to use the CronJobConfigWithUtcOffset
|
|
10
10
|
*/
|
|
11
|
-
export interface CronJobConfigWithTimeZone<OC extends CronOnCompleteCommand | null = null, C = null>
|
|
11
|
+
export interface CronJobConfigWithTimeZone<OC extends CronOnCompleteCommand | null = null, C = null>
|
|
12
|
+
extends CronJobConfig {
|
|
12
13
|
/**
|
|
13
14
|
* Specify the timezone for the execution. This will modify the actual time relative to your timezone.
|
|
14
15
|
* If the timezone is invalid, an error is thrown. Can be any string accepted by luxon's `DateTime.setZone()`
|
|
@@ -8,8 +8,8 @@ import { CronJobConfig } from './cron-job-config.interface';
|
|
|
8
8
|
* This config can define utcOffset but not timezone,
|
|
9
9
|
* if you want to use timezone, you have to use the CronJobConfigWithTimezone
|
|
10
10
|
*/
|
|
11
|
-
export interface CronJobConfigWithUtcOffset<OC extends CronOnCompleteCommand | null = null, C = null>
|
|
12
|
-
|
|
11
|
+
export interface CronJobConfigWithUtcOffset<OC extends CronOnCompleteCommand | null = null, C = null>
|
|
12
|
+
extends CronJobConfig {
|
|
13
13
|
/**
|
|
14
14
|
* Specify the timezone for the execution. This will modify the actual time relative to your timezone.
|
|
15
15
|
* If the timezone is invalid, an error is thrown. Can be any string accepted by luxon's `DateTime.setZone()`
|
|
@@ -44,7 +44,7 @@ export interface IJwt {
|
|
|
44
44
|
secretOrKeyProvider?: (
|
|
45
45
|
request: Record<string, any>,
|
|
46
46
|
rawJwtToken: string,
|
|
47
|
-
done: (err: any, secret: string) => any
|
|
47
|
+
done: (err: any, secret: string) => any,
|
|
48
48
|
) => any;
|
|
49
49
|
|
|
50
50
|
/**
|
|
@@ -112,7 +112,10 @@ export interface IServerOptions {
|
|
|
112
112
|
* Cron jobs configuration object with the name of the cron job function as key
|
|
113
113
|
* and the cron expression or config as value
|
|
114
114
|
*/
|
|
115
|
-
cronJobs?: Record<
|
|
115
|
+
cronJobs?: Record<
|
|
116
|
+
string,
|
|
117
|
+
CronExpression | CronJobConfigWithTimeZone | CronJobConfigWithUtcOffset | Date | Falsy | string
|
|
118
|
+
>;
|
|
116
119
|
|
|
117
120
|
/**
|
|
118
121
|
* SMTP and template configuration for sending emails
|
|
@@ -207,17 +210,14 @@ export interface IServerOptions {
|
|
|
207
210
|
* Whether to activate health check endpoints
|
|
208
211
|
*/
|
|
209
212
|
healthCheck?: {
|
|
210
|
-
|
|
211
213
|
/**
|
|
212
214
|
* Configuration of single health checks
|
|
213
215
|
*/
|
|
214
216
|
configs?: {
|
|
215
|
-
|
|
216
217
|
/**
|
|
217
218
|
* Configuration for database health check
|
|
218
219
|
*/
|
|
219
220
|
database?: {
|
|
220
|
-
|
|
221
221
|
/**
|
|
222
222
|
* Whether to enable the database health check
|
|
223
223
|
*/
|
|
@@ -238,7 +238,6 @@ export interface IServerOptions {
|
|
|
238
238
|
* Configuration for memory heap health check
|
|
239
239
|
*/
|
|
240
240
|
memoryHeap?: {
|
|
241
|
-
|
|
242
241
|
/**
|
|
243
242
|
* Whether to enable the memory heap health check
|
|
244
243
|
*/
|
|
@@ -259,7 +258,6 @@ export interface IServerOptions {
|
|
|
259
258
|
* Configuration for memory resident set size health check
|
|
260
259
|
*/
|
|
261
260
|
memoryRss?: {
|
|
262
|
-
|
|
263
261
|
/**
|
|
264
262
|
* Whether to enable the memory resident set size health check
|
|
265
263
|
*/
|
|
@@ -280,7 +278,6 @@ export interface IServerOptions {
|
|
|
280
278
|
* Configuration for disk space health check
|
|
281
279
|
*/
|
|
282
280
|
storage?: {
|
|
283
|
-
|
|
284
281
|
/**
|
|
285
282
|
* Whether to enable the disk space health check
|
|
286
283
|
*/
|
|
@@ -368,7 +365,6 @@ export interface IServerOptions {
|
|
|
368
365
|
* Configuration for Mongoose
|
|
369
366
|
*/
|
|
370
367
|
mongoose?: {
|
|
371
|
-
|
|
372
368
|
/**
|
|
373
369
|
* Collation allows users to specify language-specific rules for string comparison,
|
|
374
370
|
* such as rules for letter-case and accent marks.
|
|
@@ -8,7 +8,10 @@ import { ConfigService } from '../services/config.service';
|
|
|
8
8
|
|
|
9
9
|
@Plugin()
|
|
10
10
|
export class ComplexityPlugin implements ApolloServerPlugin {
|
|
11
|
-
constructor(
|
|
11
|
+
constructor(
|
|
12
|
+
private gqlSchemaHost: GraphQLSchemaHost,
|
|
13
|
+
private configService: ConfigService,
|
|
14
|
+
) {}
|
|
12
15
|
|
|
13
16
|
async requestDidStart(): Promise<GraphQLRequestListener> {
|
|
14
17
|
const maxComplexity: number = this.configService.getFastButReadOnly('graphQl.maxComplexity');
|
|
@@ -32,7 +32,10 @@ export abstract class CoreCronJobs implements OnApplicationBootstrap {
|
|
|
32
32
|
*/
|
|
33
33
|
protected constructor(
|
|
34
34
|
protected schedulerRegistry: SchedulerRegistry,
|
|
35
|
-
protected cronJobs: Record<
|
|
35
|
+
protected cronJobs: Record<
|
|
36
|
+
string,
|
|
37
|
+
CronExpression | CronJobConfigWithTimeZone | CronJobConfigWithUtcOffset | Date | Falsy | string
|
|
38
|
+
>,
|
|
36
39
|
options?: { log?: boolean },
|
|
37
40
|
) {
|
|
38
41
|
this.config = {
|
|
@@ -72,8 +75,9 @@ export abstract class CoreCronJobs implements OnApplicationBootstrap {
|
|
|
72
75
|
}
|
|
73
76
|
|
|
74
77
|
// Prepare config
|
|
75
|
-
let conf: CronJobConfigWithTimeZone | CronJobConfigWithUtcOffset
|
|
76
|
-
|
|
78
|
+
let conf: CronJobConfigWithTimeZone | CronJobConfigWithUtcOffset = CronExpressionOrConfig as
|
|
79
|
+
| CronJobConfigWithTimeZone
|
|
80
|
+
| CronJobConfigWithUtcOffset;
|
|
77
81
|
if (typeof CronExpressionOrConfig === 'string' || CronExpressionOrConfig instanceof Date) {
|
|
78
82
|
conf = {
|
|
79
83
|
cronTime: CronExpressionOrConfig as Date | string,
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { NotFoundException } from '@nestjs/common';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
AggregateOptions,
|
|
4
|
+
Document,
|
|
5
|
+
FilterQuery,
|
|
6
|
+
Model as MongooseModel,
|
|
7
|
+
PipelineStage,
|
|
8
|
+
Query,
|
|
9
|
+
QueryOptions,
|
|
10
|
+
} from 'mongoose';
|
|
3
11
|
|
|
4
12
|
import { FilterArgs } from '../args/filter.args';
|
|
5
13
|
import { getStringIds } from '../helpers/db.helper';
|
|
@@ -16,7 +24,6 @@ export abstract class CrudService<
|
|
|
16
24
|
CreateInput = any,
|
|
17
25
|
UpdateInput = any,
|
|
18
26
|
> extends ModuleService<Model> {
|
|
19
|
-
|
|
20
27
|
/**
|
|
21
28
|
* Aggregate
|
|
22
29
|
* @param serviceOptions.aggregateOptions Aggregate options, see https://www.mongodb.com/docs/manual/core/aggregation-pipeline/
|
|
@@ -379,7 +386,6 @@ export abstract class CrudService<
|
|
|
379
386
|
|
|
380
387
|
return this.process(
|
|
381
388
|
async (data) => {
|
|
382
|
-
|
|
383
389
|
// Prepare filter query
|
|
384
390
|
const filterQuery = { filterQuery: data?.input?.filterQuery, queryOptions: data?.input?.queryOptions };
|
|
385
391
|
if (data?.input instanceof FilterArgs) {
|
|
@@ -447,7 +453,7 @@ export abstract class CrudService<
|
|
|
447
453
|
*/
|
|
448
454
|
async read(
|
|
449
455
|
filter: { filterQuery?: FilterQuery<any>; queryOptions?: QueryOptions } | FilterArgs,
|
|
450
|
-
serviceOptions?: ServiceOptions
|
|
456
|
+
serviceOptions?: ServiceOptions,
|
|
451
457
|
): Promise<Model[]>;
|
|
452
458
|
|
|
453
459
|
/**
|
|
@@ -476,7 +482,7 @@ export abstract class CrudService<
|
|
|
476
482
|
*/
|
|
477
483
|
async readForce(
|
|
478
484
|
filter: { filterQuery?: FilterQuery<any>; queryOptions?: QueryOptions } | FilterArgs,
|
|
479
|
-
serviceOptions?: ServiceOptions
|
|
485
|
+
serviceOptions?: ServiceOptions,
|
|
480
486
|
): Promise<Model[]>;
|
|
481
487
|
|
|
482
488
|
/**
|
|
@@ -506,7 +512,7 @@ export abstract class CrudService<
|
|
|
506
512
|
*/
|
|
507
513
|
async readRaw(
|
|
508
514
|
filter: { filterQuery?: FilterQuery<any>; queryOptions?: QueryOptions } | FilterArgs,
|
|
509
|
-
serviceOptions?: ServiceOptions
|
|
515
|
+
serviceOptions?: ServiceOptions,
|
|
510
516
|
): Promise<Model[]>;
|
|
511
517
|
|
|
512
518
|
/**
|
|
@@ -618,14 +624,17 @@ export abstract class CrudService<
|
|
|
618
624
|
queryOrDocument: Document | Document[] | Query<unknown, unknown>,
|
|
619
625
|
serviceOptions?: ServiceOptions,
|
|
620
626
|
): Promise<T> {
|
|
621
|
-
return this.process(
|
|
622
|
-
|
|
623
|
-
if (
|
|
624
|
-
queryOrDocument.select
|
|
627
|
+
return this.process(
|
|
628
|
+
() => {
|
|
629
|
+
if (queryOrDocument instanceof Query) {
|
|
630
|
+
if (serviceOptions?.select && queryOrDocument.select && typeof queryOrDocument.select === 'function') {
|
|
631
|
+
queryOrDocument.select(serviceOptions.select);
|
|
632
|
+
}
|
|
633
|
+
return queryOrDocument.exec();
|
|
625
634
|
}
|
|
626
|
-
return queryOrDocument
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
|
|
635
|
+
return queryOrDocument;
|
|
636
|
+
},
|
|
637
|
+
{ serviceOptions },
|
|
638
|
+
);
|
|
630
639
|
}
|
|
631
640
|
}
|
|
@@ -15,7 +15,10 @@ export class EmailService {
|
|
|
15
15
|
/**
|
|
16
16
|
* Inject services
|
|
17
17
|
*/
|
|
18
|
-
constructor(
|
|
18
|
+
constructor(
|
|
19
|
+
protected configService: ConfigService,
|
|
20
|
+
protected templateService: TemplateService,
|
|
21
|
+
) {}
|
|
19
22
|
|
|
20
23
|
/**
|
|
21
24
|
* Send a mail
|
|
@@ -20,11 +20,7 @@ export interface ModelDocSchemaConfig {
|
|
|
20
20
|
*/
|
|
21
21
|
@Injectable()
|
|
22
22
|
export class ModelDocService implements OnApplicationBootstrap {
|
|
23
|
-
|
|
24
|
-
constructor(
|
|
25
|
-
@InjectConnection() private readonly connection: Connection,
|
|
26
|
-
) {
|
|
27
|
-
}
|
|
23
|
+
constructor(@InjectConnection() private readonly connection: Connection) {}
|
|
28
24
|
|
|
29
25
|
/**
|
|
30
26
|
* Lifecycle hook that is called right after the application has started.
|
|
@@ -40,7 +36,6 @@ export class ModelDocService implements OnApplicationBootstrap {
|
|
|
40
36
|
* @protected
|
|
41
37
|
*/
|
|
42
38
|
protected getSchemaJson(): Record<string, Record<string, ModelDocSchemaConfig>> {
|
|
43
|
-
|
|
44
39
|
// Prepare results
|
|
45
40
|
const results: Record<string, Record<string, ModelDocSchemaConfig>> = {};
|
|
46
41
|
|
|
@@ -59,11 +54,16 @@ export class ModelDocService implements OnApplicationBootstrap {
|
|
|
59
54
|
isArray: path.instance === 'Array',
|
|
60
55
|
name: path.path,
|
|
61
56
|
ref: Array.isArray(obj) ? undefined : obj.ref,
|
|
62
|
-
type:
|
|
63
|
-
|
|
64
|
-
?
|
|
65
|
-
|
|
66
|
-
|
|
57
|
+
type:
|
|
58
|
+
path.instance === 'Array'
|
|
59
|
+
? Array.isArray(obj)
|
|
60
|
+
? obj[0]() === ''
|
|
61
|
+
? 'String'
|
|
62
|
+
: obj[0]()
|
|
63
|
+
: typeof obj.type === 'function'
|
|
64
|
+
? obj.type.name
|
|
65
|
+
: obj.type
|
|
66
|
+
: path.instance,
|
|
67
67
|
};
|
|
68
68
|
if (results[modelName][key].type === 'Mixed') {
|
|
69
69
|
results[modelName][key].type = 'JSON';
|
|
@@ -118,7 +118,6 @@ export class ModelDocService implements OnApplicationBootstrap {
|
|
|
118
118
|
* @protected
|
|
119
119
|
*/
|
|
120
120
|
protected yUmlToSvg(yUmlText: string) {
|
|
121
|
-
|
|
122
121
|
// Create diagrams
|
|
123
122
|
// see https://github.com/jaime-olivares/yuml-diagram
|
|
124
123
|
// and https://yuml.me/diagram/scruffy/class/samples
|
|
@@ -143,8 +143,16 @@ export abstract class ModuleService<T extends CoreModel = any> {
|
|
|
143
143
|
const inputJSON = JSON.stringify(originalInput);
|
|
144
144
|
const preparedInput = await this.prepareInput(config.input, config);
|
|
145
145
|
new Promise(() => {
|
|
146
|
-
if (
|
|
147
|
-
|
|
146
|
+
if (
|
|
147
|
+
inputJSON?.replace(/"password":\s*"[^"]*"/, '')
|
|
148
|
+
!== JSON.stringify(preparedInput)?.replace(/"password":\s*"[^"]*"/, '')
|
|
149
|
+
) {
|
|
150
|
+
console.debug(
|
|
151
|
+
'CheckSecurityInterceptor: securityCheck changed input of type',
|
|
152
|
+
originalInput.constructor.name,
|
|
153
|
+
'to type',
|
|
154
|
+
preparedInput.constructor.name,
|
|
155
|
+
);
|
|
148
156
|
}
|
|
149
157
|
});
|
|
150
158
|
config.input = preparedInput;
|
|
@@ -12,7 +12,7 @@ export interface CoreModelConstructor<T extends CoreModel> {
|
|
|
12
12
|
init?: any;
|
|
13
13
|
item?: T;
|
|
14
14
|
mapId?: boolean;
|
|
15
|
-
}
|
|
15
|
+
},
|
|
16
16
|
): T;
|
|
17
17
|
mapDeep(
|
|
18
18
|
this: new (...args: any[]) => T,
|
|
@@ -24,7 +24,7 @@ export interface CoreModelConstructor<T extends CoreModel> {
|
|
|
24
24
|
init?: any;
|
|
25
25
|
item?: T;
|
|
26
26
|
mapId?: boolean;
|
|
27
|
-
}
|
|
27
|
+
},
|
|
28
28
|
): T;
|
|
29
29
|
new (): T;
|
|
30
30
|
}
|
|
@@ -18,7 +18,10 @@ export class CoreAuthController {
|
|
|
18
18
|
/**
|
|
19
19
|
* Import services
|
|
20
20
|
*/
|
|
21
|
-
constructor(
|
|
21
|
+
constructor(
|
|
22
|
+
protected readonly authService: CoreAuthService,
|
|
23
|
+
protected readonly configService: ConfigService,
|
|
24
|
+
) {}
|
|
22
25
|
|
|
23
26
|
/**
|
|
24
27
|
* Logout user (from specific device)
|
|
@@ -23,7 +23,10 @@ export class CoreAuthResolver {
|
|
|
23
23
|
/**
|
|
24
24
|
* Import services
|
|
25
25
|
*/
|
|
26
|
-
constructor(
|
|
26
|
+
constructor(
|
|
27
|
+
protected readonly authService: CoreAuthService,
|
|
28
|
+
protected readonly configService: ConfigService,
|
|
29
|
+
) {}
|
|
27
30
|
|
|
28
31
|
// ===========================================================================
|
|
29
32
|
// Mutations
|
|
@@ -206,7 +206,6 @@ export class CoreAuthService {
|
|
|
206
206
|
* Get JWT and refresh token
|
|
207
207
|
*/
|
|
208
208
|
protected async createTokens(userId: string, data?: { [key: string]: any; deviceId?: string }) {
|
|
209
|
-
|
|
210
209
|
// Initializations
|
|
211
210
|
const sameTokenIdPeriod: number = this.configService.getFastButReadOnly('jwt.sameTokenIdPeriod', 0);
|
|
212
211
|
const deviceId = data?.deviceId || randomUUID();
|
|
@@ -288,10 +287,14 @@ export class CoreAuthService {
|
|
|
288
287
|
}
|
|
289
288
|
user.refreshTokens[deviceId] = { ...data, deviceId, tokenId: payload.tokenId };
|
|
290
289
|
user.tempTokens[deviceId] = { createdAt: new Date().getTime(), deviceId, tokenId: payload.tokenId };
|
|
291
|
-
await this.userService.update(
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
290
|
+
await this.userService.update(
|
|
291
|
+
getStringIds(user),
|
|
292
|
+
{
|
|
293
|
+
refreshTokens: user.refreshTokens,
|
|
294
|
+
tempTokens: user.tempTokens,
|
|
295
|
+
},
|
|
296
|
+
{ force: true },
|
|
297
|
+
);
|
|
295
298
|
|
|
296
299
|
// Return new token
|
|
297
300
|
return newRefreshToken;
|
|
@@ -9,7 +9,10 @@ import { CoreAuthService } from '../services/core-auth.service';
|
|
|
9
9
|
|
|
10
10
|
@Injectable()
|
|
11
11
|
export class JwtRefreshStrategy extends PassportStrategy(Strategy, AuthGuardStrategy.JWT_REFRESH) {
|
|
12
|
-
constructor(
|
|
12
|
+
constructor(
|
|
13
|
+
protected readonly authService: CoreAuthService,
|
|
14
|
+
protected readonly configService: ConfigService,
|
|
15
|
+
) {
|
|
13
16
|
super({
|
|
14
17
|
jwtFromRequest: ExtractJwt.fromExtractors([
|
|
15
18
|
JwtRefreshStrategy.extractJWTFromCookie,
|
|
@@ -16,7 +16,10 @@ export class JwtStrategy extends PassportStrategy(Strategy, AuthGuardStrategy.JW
|
|
|
16
16
|
/**
|
|
17
17
|
* Init JWT strategy
|
|
18
18
|
*/
|
|
19
|
-
constructor(
|
|
19
|
+
constructor(
|
|
20
|
+
protected readonly authService: CoreAuthService,
|
|
21
|
+
protected readonly configService: ConfigService,
|
|
22
|
+
) {
|
|
20
23
|
super({
|
|
21
24
|
jwtFromRequest: ExtractJwt.fromExtractors([
|
|
22
25
|
JwtStrategy.extractJWTFromCookie,
|
|
@@ -27,7 +27,10 @@ export abstract class CoreFileService {
|
|
|
27
27
|
/**
|
|
28
28
|
* Include MongoDB connection and create File bucket
|
|
29
29
|
*/
|
|
30
|
-
protected constructor(
|
|
30
|
+
protected constructor(
|
|
31
|
+
protected readonly connection: Connection,
|
|
32
|
+
bucketName = 'fs',
|
|
33
|
+
) {
|
|
31
34
|
this.files = createBucket({ bucketName, connection });
|
|
32
35
|
}
|
|
33
36
|
|
|
@@ -5,7 +5,6 @@ import { RoleEnum } from '../../common/enums/role.enum';
|
|
|
5
5
|
import { CoreHealthCheckService } from './core-health-check.service';
|
|
6
6
|
import { CoreHealthCheckResult } from './core-health-check-result.model';
|
|
7
7
|
|
|
8
|
-
|
|
9
8
|
/**
|
|
10
9
|
* Resolver to process with user data
|
|
11
10
|
*/
|
|
@@ -15,8 +14,7 @@ export class CoreHealthCheckResolver {
|
|
|
15
14
|
/**
|
|
16
15
|
* Import services
|
|
17
16
|
*/
|
|
18
|
-
constructor(protected readonly healthCheckService: CoreHealthCheckService) {
|
|
19
|
-
}
|
|
17
|
+
constructor(protected readonly healthCheckService: CoreHealthCheckService) {}
|
|
20
18
|
|
|
21
19
|
// ===========================================================================
|
|
22
20
|
// Queries
|