@lenne.tech/nest-server 10.0.0 → 10.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/dist/config.env.js +29 -17
- package/dist/config.env.js.map +1 -1
- package/dist/core/common/args/filter.args.js +3 -3
- package/dist/core/common/args/filter.args.js.map +1 -1
- package/dist/core/common/args/pagination.args.js +6 -6
- package/dist/core/common/args/pagination.args.js.map +1 -1
- package/dist/core/common/decorators/restricted.decorator.js +15 -17
- package/dist/core/common/decorators/restricted.decorator.js.map +1 -1
- package/dist/core/common/filters/http-exception-log.filter.js +1 -3
- package/dist/core/common/filters/http-exception-log.filter.js.map +1 -1
- package/dist/core/common/helpers/db.helper.js +14 -14
- package/dist/core/common/helpers/db.helper.js.map +1 -1
- package/dist/core/common/helpers/file.helper.js +2 -2
- package/dist/core/common/helpers/file.helper.js.map +1 -1
- package/dist/core/common/helpers/filter.helper.d.ts +2 -2
- package/dist/core/common/helpers/filter.helper.js +1 -1
- package/dist/core/common/helpers/filter.helper.js.map +1 -1
- package/dist/core/common/helpers/graphql.helper.js +1 -1
- package/dist/core/common/helpers/graphql.helper.js.map +1 -1
- package/dist/core/common/helpers/input.helper.js +31 -38
- package/dist/core/common/helpers/input.helper.js.map +1 -1
- package/dist/core/common/helpers/model.helper.js +7 -7
- package/dist/core/common/helpers/model.helper.js.map +1 -1
- package/dist/core/common/helpers/service.helper.js +2 -2
- package/dist/core/common/helpers/service.helper.js.map +1 -1
- package/dist/core/common/inputs/combined-filter.input.js +3 -3
- package/dist/core/common/inputs/combined-filter.input.js.map +1 -1
- package/dist/core/common/inputs/core-input.input.js +1 -1
- package/dist/core/common/inputs/core-input.input.js.map +1 -1
- package/dist/core/common/inputs/filter.input.js +3 -3
- package/dist/core/common/inputs/filter.input.js.map +1 -1
- package/dist/core/common/inputs/single-filter.input.js +4 -4
- package/dist/core/common/inputs/single-filter.input.js.map +1 -1
- package/dist/core/common/inputs/sort.input.js +1 -1
- package/dist/core/common/inputs/sort.input.js.map +1 -1
- package/dist/core/common/interceptors/check-security.interceptor.d.ts +1 -1
- package/dist/core/common/interceptors/check-security.interceptor.js +2 -2
- package/dist/core/common/interceptors/check-security.interceptor.js.map +1 -1
- package/dist/core/common/interfaces/server-options.interface.d.ts +27 -0
- package/dist/core/common/models/core-model.model.js.map +1 -1
- package/dist/core/common/models/core-persistence.model.js +3 -3
- package/dist/core/common/models/core-persistence.model.js.map +1 -1
- package/dist/core/common/pipes/map-and-validate.pipe.d.ts +1 -1
- package/dist/core/common/pipes/map-and-validate.pipe.js +1 -1
- package/dist/core/common/pipes/map-and-validate.pipe.js.map +1 -1
- package/dist/core/common/scalars/any.scalar.js +2 -2
- package/dist/core/common/scalars/any.scalar.js.map +1 -1
- package/dist/core/common/scalars/date-timestamp.scalar.js +1 -1
- package/dist/core/common/scalars/date-timestamp.scalar.js.map +1 -1
- package/dist/core/common/scalars/date.scalar.js +1 -1
- package/dist/core/common/scalars/date.scalar.js.map +1 -1
- package/dist/core/common/scalars/json.scalar.js +2 -2
- package/dist/core/common/scalars/json.scalar.js.map +1 -1
- package/dist/core/common/services/config.service.js +7 -7
- package/dist/core/common/services/config.service.js.map +1 -1
- package/dist/core/common/services/core-cron-jobs.service.js +5 -5
- package/dist/core/common/services/core-cron-jobs.service.js.map +1 -1
- package/dist/core/common/services/crud.service.js +1 -1
- package/dist/core/common/services/crud.service.js.map +1 -1
- package/dist/core/common/services/mailjet.service.js +5 -5
- package/dist/core/common/services/mailjet.service.js.map +1 -1
- package/dist/core/common/services/module.service.js.map +1 -1
- package/dist/core/common/services/template.service.js +3 -3
- package/dist/core/common/services/template.service.js.map +1 -1
- package/dist/core/common/types/core-model-constructor.type.d.ts +2 -2
- package/dist/core/modules/auth/core-auth.module.js +3 -3
- package/dist/core/modules/auth/core-auth.module.js.map +1 -1
- package/dist/core/modules/auth/core-auth.resolver.js +5 -5
- package/dist/core/modules/auth/core-auth.resolver.js.map +1 -1
- package/dist/core/modules/auth/guards/auth.guard.js +4 -4
- package/dist/core/modules/auth/guards/auth.guard.js.map +1 -1
- package/dist/core/modules/auth/guards/roles.guard.js +1 -1
- package/dist/core/modules/auth/guards/roles.guard.js.map +1 -1
- package/dist/core/modules/auth/services/core-auth.service.js +5 -5
- package/dist/core/modules/auth/services/core-auth.service.js.map +1 -1
- package/dist/core/modules/auth/strategies/jwt.strategy.js.map +1 -1
- package/dist/core/modules/auth/tokens.decorator.js +2 -2
- package/dist/core/modules/auth/tokens.decorator.js.map +1 -1
- package/dist/core/modules/file/core-file-info.model.js +2 -2
- package/dist/core/modules/file/core-file-info.model.js.map +1 -1
- package/dist/core/modules/file/core-file.controller.d.ts +1 -2
- package/dist/core/modules/file/core-file.controller.js +3 -6
- package/dist/core/modules/file/core-file.controller.js.map +1 -1
- package/dist/core/modules/file/core-file.service.js +1 -1
- package/dist/core/modules/file/core-file.service.js.map +1 -1
- package/dist/core/modules/file/interfaces/file-upload.interface.d.ts +1 -1
- package/dist/core/modules/health-check/core-health-check-result.model.d.ts +8 -0
- package/dist/core/modules/health-check/core-health-check-result.model.js +53 -0
- package/dist/core/modules/health-check/core-health-check-result.model.js.map +1 -0
- package/dist/core/modules/health-check/core-health-check.controller.d.ts +6 -0
- package/dist/core/modules/health-check/core-health-check.controller.js +33 -0
- package/dist/core/modules/health-check/core-health-check.controller.js.map +1 -0
- package/dist/core/modules/health-check/core-health-check.module.d.ts +2 -0
- package/dist/core/modules/health-check/core-health-check.module.js +24 -0
- package/dist/core/modules/health-check/core-health-check.module.js.map +1 -0
- package/dist/core/modules/health-check/core-health-check.resolver.d.ts +6 -0
- package/dist/core/modules/health-check/core-health-check.resolver.js +38 -0
- package/dist/core/modules/health-check/core-health-check.resolver.js.map +1 -0
- package/dist/core/modules/health-check/core-health-check.service.d.ts +11 -0
- package/dist/core/modules/health-check/core-health-check.service.js +52 -0
- package/dist/core/modules/health-check/core-health-check.service.js.map +1 -0
- package/dist/core/modules/user/core-user.model.js +4 -4
- package/dist/core/modules/user/core-user.model.js.map +1 -1
- package/dist/core/modules/user/core-user.service.js +2 -2
- package/dist/core/modules/user/core-user.service.js.map +1 -1
- package/dist/core/modules/user/inputs/core-user.input.js +1 -1
- package/dist/core/modules/user/inputs/core-user.input.js.map +1 -1
- package/dist/core.module.js +10 -5
- package/dist/core.module.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/server/modules/auth/auth.service.js +1 -1
- package/dist/server/modules/auth/auth.service.js.map +1 -1
- package/dist/server/modules/file/file.controller.js +1 -1
- package/dist/server/modules/file/file.controller.js.map +1 -1
- package/dist/server/modules/file/file.resolver.js +2 -2
- package/dist/server/modules/file/file.resolver.js.map +1 -1
- package/dist/server/modules/file/file.service.js +1 -1
- package/dist/server/modules/file/file.service.js.map +1 -1
- package/dist/server/modules/file/multer-config.service.js +1 -1
- package/dist/server/modules/file/multer-config.service.js.map +1 -1
- package/dist/server/modules/user/avatar.controller.js +1 -1
- package/dist/server/modules/user/avatar.controller.js.map +1 -1
- package/dist/server/modules/user/user.resolver.js +1 -1
- package/dist/server/modules/user/user.resolver.js.map +1 -1
- package/dist/server/modules/user/user.service.js +3 -3
- package/dist/server/modules/user/user.service.js.map +1 -1
- package/dist/templates/index.ejs +2 -0
- package/dist/templates/password-reset.ejs +3 -0
- package/dist/templates/welcome.ejs +3 -0
- package/dist/test/test.helper.d.ts +1 -1
- package/dist/test/test.helper.js +7 -7
- package/dist/test/test.helper.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +28 -25
- package/src/config.env.ts +32 -20
- package/src/core/common/args/filter.args.ts +4 -4
- package/src/core/common/args/pagination.args.ts +7 -7
- package/src/core/common/decorators/graphql-service-options.decorator.ts +2 -2
- package/src/core/common/decorators/graphql-user.decorator.ts +1 -1
- package/src/core/common/decorators/rest-user.decorator.ts +1 -1
- package/src/core/common/decorators/restricted.decorator.ts +18 -18
- package/src/core/common/filters/http-exception-log.filter.ts +4 -4
- package/src/core/common/helpers/db.helper.ts +35 -40
- package/src/core/common/helpers/decorator.helper.ts +1 -1
- package/src/core/common/helpers/file.helper.ts +2 -2
- package/src/core/common/helpers/filter.helper.ts +7 -8
- package/src/core/common/helpers/graphql.helper.ts +6 -6
- package/src/core/common/helpers/input.helper.ts +54 -61
- package/src/core/common/helpers/model.helper.ts +33 -41
- package/src/core/common/helpers/service.helper.ts +8 -8
- package/src/core/common/inputs/combined-filter.input.ts +4 -4
- package/src/core/common/inputs/core-input.input.ts +2 -2
- package/src/core/common/inputs/filter.input.ts +4 -4
- package/src/core/common/inputs/single-filter.input.ts +4 -4
- package/src/core/common/inputs/sort.input.ts +1 -1
- package/src/core/common/interceptors/check-response.interceptor.ts +1 -1
- package/src/core/common/interceptors/check-security.interceptor.ts +5 -5
- package/src/core/common/interfaces/server-options.interface.ts +31 -0
- package/src/core/common/models/core-model.model.ts +6 -4
- package/src/core/common/models/core-persistence.model.ts +3 -3
- package/src/core/common/pipes/map-and-validate.pipe.ts +2 -2
- package/src/core/common/scalars/any.scalar.ts +2 -2
- package/src/core/common/scalars/date-timestamp.scalar.ts +1 -2
- package/src/core/common/scalars/date.scalar.ts +1 -2
- package/src/core/common/scalars/json.scalar.ts +4 -4
- package/src/core/common/services/config.service.ts +16 -16
- package/src/core/common/services/core-cron-jobs.service.ts +7 -7
- package/src/core/common/services/crud.service.ts +22 -22
- package/src/core/common/services/email.service.ts +1 -1
- package/src/core/common/services/mailjet.service.ts +8 -8
- package/src/core/common/services/module.service.ts +5 -6
- package/src/core/common/services/template.service.ts +4 -4
- package/src/core/common/types/core-model-constructor.type.ts +2 -2
- package/src/core/modules/auth/core-auth.controller.ts +2 -2
- package/src/core/modules/auth/core-auth.module.ts +4 -4
- package/src/core/modules/auth/core-auth.resolver.ts +9 -9
- package/src/core/modules/auth/guards/auth.guard.ts +8 -7
- package/src/core/modules/auth/guards/roles.guard.ts +1 -1
- package/src/core/modules/auth/services/core-auth.service.ts +9 -9
- package/src/core/modules/auth/strategies/jwt-refresh.strategy.ts +1 -1
- package/src/core/modules/auth/strategies/jwt.strategy.ts +1 -1
- package/src/core/modules/auth/tokens.decorator.ts +6 -7
- package/src/core/modules/file/core-file-info.model.ts +2 -2
- package/src/core/modules/file/core-file.controller.ts +2 -4
- package/src/core/modules/file/core-file.service.ts +6 -5
- package/src/core/modules/file/interfaces/file-upload.interface.ts +1 -1
- package/src/core/modules/health-check/core-health-check-result.model.ts +46 -0
- package/src/core/modules/health-check/core-health-check.controller.ts +24 -0
- package/src/core/modules/health-check/core-health-check.module.ts +17 -0
- package/src/core/modules/health-check/core-health-check.resolver.ts +32 -0
- package/src/core/modules/health-check/core-health-check.service.ts +60 -0
- package/src/core/modules/user/core-user.model.ts +5 -5
- package/src/core/modules/user/core-user.service.ts +10 -9
- package/src/core/modules/user/inputs/core-user.input.ts +1 -2
- package/src/core.module.ts +16 -10
- package/src/index.ts +10 -0
- package/src/main.ts +2 -2
- package/src/server/modules/auth/auth.controller.ts +1 -1
- package/src/server/modules/auth/auth.resolver.ts +3 -3
- package/src/server/modules/auth/auth.service.ts +2 -2
- package/src/server/modules/file/file.controller.ts +1 -2
- package/src/server/modules/file/file.module.ts +1 -1
- package/src/server/modules/file/file.resolver.ts +4 -3
- package/src/server/modules/file/file.service.ts +1 -1
- package/src/server/modules/file/multer-config.service.ts +1 -1
- package/src/server/modules/user/avatar.controller.ts +3 -3
- package/src/server/modules/user/user.model.ts +1 -1
- package/src/server/modules/user/user.resolver.ts +4 -4
- package/src/server/modules/user/user.service.ts +4 -4
- package/src/test/test.helper.ts +11 -11
|
@@ -13,7 +13,7 @@ import { ModuleService } from './module.service';
|
|
|
13
13
|
export abstract class CrudService<
|
|
14
14
|
Model extends CoreModel = any,
|
|
15
15
|
CreateInput = any,
|
|
16
|
-
UpdateInput = any
|
|
16
|
+
UpdateInput = any,
|
|
17
17
|
> extends ModuleService<Model> {
|
|
18
18
|
/**
|
|
19
19
|
* Create item
|
|
@@ -25,7 +25,7 @@ export abstract class CrudService<
|
|
|
25
25
|
const currentUserId = serviceOptions?.currentUser?.id;
|
|
26
26
|
return new this.mainDbModel({ ...data.input, createdBy: currentUserId, updatedBy: currentUserId }).save();
|
|
27
27
|
},
|
|
28
|
-
{ input, serviceOptions }
|
|
28
|
+
{ input, serviceOptions },
|
|
29
29
|
);
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -87,7 +87,7 @@ export abstract class CrudService<
|
|
|
87
87
|
*/
|
|
88
88
|
async find(
|
|
89
89
|
filter?: FilterArgs | { filterQuery?: FilterQuery<any>; queryOptions?: QueryOptions; samples?: number },
|
|
90
|
-
serviceOptions?: ServiceOptions
|
|
90
|
+
serviceOptions?: ServiceOptions,
|
|
91
91
|
): Promise<Model[]> {
|
|
92
92
|
// If filter is not instance of FilterArgs a simple form with filterQuery and queryOptions is set
|
|
93
93
|
// and should not be processed as FilterArgs
|
|
@@ -118,7 +118,7 @@ export abstract class CrudService<
|
|
|
118
118
|
}
|
|
119
119
|
return find.exec();
|
|
120
120
|
},
|
|
121
|
-
{ input: filter, serviceOptions }
|
|
121
|
+
{ input: filter, serviceOptions },
|
|
122
122
|
);
|
|
123
123
|
}
|
|
124
124
|
|
|
@@ -128,7 +128,7 @@ export abstract class CrudService<
|
|
|
128
128
|
*/
|
|
129
129
|
async findForce(
|
|
130
130
|
filter?: FilterArgs | { filterQuery?: FilterQuery<any>; queryOptions?: QueryOptions; samples?: number },
|
|
131
|
-
serviceOptions: ServiceOptions = {}
|
|
131
|
+
serviceOptions: ServiceOptions = {},
|
|
132
132
|
): Promise<Model[]> {
|
|
133
133
|
serviceOptions = serviceOptions || {};
|
|
134
134
|
serviceOptions.force = true;
|
|
@@ -141,7 +141,7 @@ export abstract class CrudService<
|
|
|
141
141
|
*/
|
|
142
142
|
async findRaw(
|
|
143
143
|
filter?: FilterArgs | { filterQuery?: FilterQuery<any>; queryOptions?: QueryOptions; samples?: number },
|
|
144
|
-
serviceOptions: ServiceOptions = {}
|
|
144
|
+
serviceOptions: ServiceOptions = {},
|
|
145
145
|
): Promise<Model[]> {
|
|
146
146
|
serviceOptions = serviceOptions || {};
|
|
147
147
|
serviceOptions.prepareInput = null;
|
|
@@ -154,7 +154,7 @@ export abstract class CrudService<
|
|
|
154
154
|
*/
|
|
155
155
|
async findAndCount(
|
|
156
156
|
filter?: FilterArgs | { filterQuery?: FilterQuery<any>; queryOptions?: QueryOptions; samples?: number },
|
|
157
|
-
serviceOptions?: ServiceOptions
|
|
157
|
+
serviceOptions?: ServiceOptions,
|
|
158
158
|
): Promise<{ items: Model[]; totalCount: number }> {
|
|
159
159
|
// If filter is not instance of FilterArgs a simple form with filterQuery and queryOptions is set
|
|
160
160
|
// and should not be processed as FilterArgs
|
|
@@ -217,13 +217,13 @@ export abstract class CrudService<
|
|
|
217
217
|
|
|
218
218
|
// Find and process db items
|
|
219
219
|
const collation = serviceOptions?.collation || ConfigService.get('mongoose.collation');
|
|
220
|
-
const dbResult
|
|
221
|
-
(await this.mainDbModel.aggregate(aggregation, collation ? { collation } : {}).exec())[0] || {};
|
|
220
|
+
const dbResult
|
|
221
|
+
= (await this.mainDbModel.aggregate(aggregation, collation ? { collation } : {}).exec())[0] || {};
|
|
222
222
|
dbResult.totalCount = dbResult.totalCount?.[0]?.total || 0;
|
|
223
|
-
dbResult.items = dbResult.items?.map(
|
|
223
|
+
dbResult.items = dbResult.items?.map(item => this.mainDbModel.hydrate(item)) || [];
|
|
224
224
|
return dbResult;
|
|
225
225
|
},
|
|
226
|
-
{ input: filter, outputPath: 'items', serviceOptions }
|
|
226
|
+
{ input: filter, outputPath: 'items', serviceOptions },
|
|
227
227
|
);
|
|
228
228
|
}
|
|
229
229
|
|
|
@@ -233,7 +233,7 @@ export abstract class CrudService<
|
|
|
233
233
|
*/
|
|
234
234
|
async findAndCountForce(
|
|
235
235
|
filter?: FilterArgs | { filterQuery?: FilterQuery<any>; queryOptions?: QueryOptions; samples?: number },
|
|
236
|
-
serviceOptions: ServiceOptions = {}
|
|
236
|
+
serviceOptions: ServiceOptions = {},
|
|
237
237
|
): Promise<{ items: Model[]; totalCount: number }> {
|
|
238
238
|
serviceOptions = serviceOptions || {};
|
|
239
239
|
serviceOptions.force = true;
|
|
@@ -246,7 +246,7 @@ export abstract class CrudService<
|
|
|
246
246
|
*/
|
|
247
247
|
async findAndCountRaw(
|
|
248
248
|
filter?: FilterArgs | { filterQuery?: FilterQuery<any>; queryOptions?: QueryOptions; samples?: number },
|
|
249
|
-
serviceOptions: ServiceOptions = {}
|
|
249
|
+
serviceOptions: ServiceOptions = {},
|
|
250
250
|
): Promise<{ items: Model[]; totalCount: number }> {
|
|
251
251
|
serviceOptions = serviceOptions || {};
|
|
252
252
|
serviceOptions.prepareInput = null;
|
|
@@ -260,7 +260,7 @@ export abstract class CrudService<
|
|
|
260
260
|
async findAndUpdate(
|
|
261
261
|
filter: FilterArgs | { filterQuery?: FilterQuery<any>; queryOptions?: QueryOptions; samples?: number },
|
|
262
262
|
update: PlainObject<UpdateInput>,
|
|
263
|
-
serviceOptions?: ServiceOptions
|
|
263
|
+
serviceOptions?: ServiceOptions,
|
|
264
264
|
): Promise<Model[]> {
|
|
265
265
|
const dbItems: Model[] = await this.find(filter, serviceOptions);
|
|
266
266
|
if (!dbItems?.length) {
|
|
@@ -276,7 +276,7 @@ export abstract class CrudService<
|
|
|
276
276
|
} catch (e) {
|
|
277
277
|
reject(e);
|
|
278
278
|
}
|
|
279
|
-
})
|
|
279
|
+
}),
|
|
280
280
|
);
|
|
281
281
|
}
|
|
282
282
|
return await Promise.all(promises);
|
|
@@ -289,7 +289,7 @@ export abstract class CrudService<
|
|
|
289
289
|
async findAndUpdateForce(
|
|
290
290
|
filter: FilterArgs | { filterQuery?: FilterQuery<any>; queryOptions?: QueryOptions; samples?: number },
|
|
291
291
|
update: PlainObject<UpdateInput>,
|
|
292
|
-
serviceOptions: ServiceOptions = {}
|
|
292
|
+
serviceOptions: ServiceOptions = {},
|
|
293
293
|
): Promise<Model[]> {
|
|
294
294
|
serviceOptions = serviceOptions || {};
|
|
295
295
|
serviceOptions.force = true;
|
|
@@ -303,7 +303,7 @@ export abstract class CrudService<
|
|
|
303
303
|
async findAndUpdateRaw(
|
|
304
304
|
filter: FilterArgs | { filterQuery?: FilterQuery<any>; queryOptions?: QueryOptions; samples?: number },
|
|
305
305
|
update: PlainObject<UpdateInput>,
|
|
306
|
-
serviceOptions: ServiceOptions = {}
|
|
306
|
+
serviceOptions: ServiceOptions = {},
|
|
307
307
|
): Promise<Model[]> {
|
|
308
308
|
serviceOptions = serviceOptions || {};
|
|
309
309
|
serviceOptions.prepareInput = null;
|
|
@@ -329,7 +329,7 @@ export abstract class CrudService<
|
|
|
329
329
|
*/
|
|
330
330
|
async read(
|
|
331
331
|
input: string | FilterArgs | { filterQuery?: FilterQuery<any>; queryOptions?: QueryOptions },
|
|
332
|
-
serviceOptions?: ServiceOptions
|
|
332
|
+
serviceOptions?: ServiceOptions,
|
|
333
333
|
): Promise<Model | Model[]> {
|
|
334
334
|
if (typeof input === 'string') {
|
|
335
335
|
return this.get(input, serviceOptions);
|
|
@@ -359,7 +359,7 @@ export abstract class CrudService<
|
|
|
359
359
|
*/
|
|
360
360
|
async readForce(
|
|
361
361
|
input: string | FilterArgs | { filterQuery?: FilterQuery<any>; queryOptions?: QueryOptions },
|
|
362
|
-
serviceOptions?: ServiceOptions
|
|
362
|
+
serviceOptions?: ServiceOptions,
|
|
363
363
|
): Promise<Model | Model[]> {
|
|
364
364
|
if (typeof input === 'string') {
|
|
365
365
|
return this.getForce(input, serviceOptions);
|
|
@@ -389,7 +389,7 @@ export abstract class CrudService<
|
|
|
389
389
|
*/
|
|
390
390
|
async readRaw(
|
|
391
391
|
input: string | FilterArgs | { filterQuery?: FilterQuery<any>; queryOptions?: QueryOptions },
|
|
392
|
-
serviceOptions?: ServiceOptions
|
|
392
|
+
serviceOptions?: ServiceOptions,
|
|
393
393
|
): Promise<Model | Model[]> {
|
|
394
394
|
if (typeof input === 'string') {
|
|
395
395
|
return this.getRaw(input, serviceOptions);
|
|
@@ -412,7 +412,7 @@ export abstract class CrudService<
|
|
|
412
412
|
const merged = mergePlain(dbObject, data.input, { updatedBy: currentUserId });
|
|
413
413
|
return await this.mainDbModel.findByIdAndUpdate(id, merged, { returnDocument: 'after' }).exec();
|
|
414
414
|
},
|
|
415
|
-
{ dbObject, input, serviceOptions }
|
|
415
|
+
{ dbObject, input, serviceOptions },
|
|
416
416
|
);
|
|
417
417
|
}
|
|
418
418
|
|
|
@@ -450,7 +450,7 @@ export abstract class CrudService<
|
|
|
450
450
|
await this.mainDbModel.findByIdAndDelete(id).exec();
|
|
451
451
|
return dbObject;
|
|
452
452
|
},
|
|
453
|
-
{ dbObject, serviceOptions }
|
|
453
|
+
{ dbObject, serviceOptions },
|
|
454
454
|
);
|
|
455
455
|
}
|
|
456
456
|
|
|
@@ -30,7 +30,7 @@ export class EmailService {
|
|
|
30
30
|
templateData?: { [key: string]: any };
|
|
31
31
|
text?: string;
|
|
32
32
|
textTemplate?: string;
|
|
33
|
-
}
|
|
33
|
+
},
|
|
34
34
|
): Promise<any> {
|
|
35
35
|
// Process config
|
|
36
36
|
const { attachments, htmlTemplate, senderName, senderEmail, templateData, textTemplate } = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { HttpException, Injectable } from '@nestjs/common';
|
|
2
|
-
import { ConfigService } from './config.service';
|
|
3
2
|
import Mailjet from 'node-mailjet';
|
|
3
|
+
import { ConfigService } from './config.service';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Mailjet service
|
|
@@ -30,7 +30,7 @@ export class MailjetService {
|
|
|
30
30
|
}[];
|
|
31
31
|
templateData?: { [key: string]: any };
|
|
32
32
|
sandbox?: boolean;
|
|
33
|
-
}
|
|
33
|
+
},
|
|
34
34
|
) {
|
|
35
35
|
// Process config
|
|
36
36
|
const { senderName, senderEmail, templateData, attachments, sandbox } = {
|
|
@@ -81,24 +81,24 @@ export class MailjetService {
|
|
|
81
81
|
});
|
|
82
82
|
} catch (e) {
|
|
83
83
|
if (
|
|
84
|
-
this.configService.getFastButReadOnly('email.mailjet.api_key_public')
|
|
85
|
-
this.configService.getFastButReadOnly('email.mailjet.api_key_private')
|
|
84
|
+
this.configService.getFastButReadOnly('email.mailjet.api_key_public')
|
|
85
|
+
&& this.configService.getFastButReadOnly('email.mailjet.api_key_private')
|
|
86
86
|
) {
|
|
87
87
|
throw new HttpException('Cannot connect to mailjet.', 502);
|
|
88
88
|
}
|
|
89
89
|
console.debug(
|
|
90
90
|
JSON.stringify(
|
|
91
91
|
{
|
|
92
|
-
info: 'Mailjet credentials are missing',
|
|
92
|
+
'info': 'Mailjet credentials are missing',
|
|
93
93
|
'email.mailjet.api_key_public':
|
|
94
94
|
this.configService.getFastButReadOnly('email.mailjet.api_key_public') || 'missing',
|
|
95
95
|
'email.mailjet.api_key_private':
|
|
96
96
|
this.configService.getFastButReadOnly('email.mailjet.api_key_private') || 'missing',
|
|
97
|
-
templateData: templateData,
|
|
97
|
+
'templateData': templateData,
|
|
98
98
|
},
|
|
99
99
|
null,
|
|
100
|
-
2
|
|
101
|
-
)
|
|
100
|
+
2,
|
|
101
|
+
),
|
|
102
102
|
);
|
|
103
103
|
return;
|
|
104
104
|
}
|
|
@@ -53,7 +53,7 @@ export abstract class ModuleService<T extends CoreModel = any> {
|
|
|
53
53
|
processType?: ProcessType;
|
|
54
54
|
roles?: string | string[];
|
|
55
55
|
throwError?: boolean;
|
|
56
|
-
}
|
|
56
|
+
},
|
|
57
57
|
): Promise<any> {
|
|
58
58
|
const config = {
|
|
59
59
|
...options,
|
|
@@ -77,7 +77,7 @@ export abstract class ModuleService<T extends CoreModel = any> {
|
|
|
77
77
|
outputPath?: string | string[];
|
|
78
78
|
input?: any;
|
|
79
79
|
serviceOptions?: ServiceOptions;
|
|
80
|
-
}
|
|
80
|
+
},
|
|
81
81
|
) {
|
|
82
82
|
// Configuration with default values
|
|
83
83
|
const config: {
|
|
@@ -151,10 +151,9 @@ export abstract class ModuleService<T extends CoreModel = any> {
|
|
|
151
151
|
opts.metatype = config.inputType;
|
|
152
152
|
}
|
|
153
153
|
config.input = await this.checkRights(config.input, config.currentUser as any, opts);
|
|
154
|
-
}
|
|
155
154
|
|
|
156
|
-
|
|
157
|
-
else if (!config.input && config.checkRights && this.checkRights) {
|
|
155
|
+
// Check roles before processing the service function if they were not already checked during the input check
|
|
156
|
+
} else if (!config.input && config.checkRights && this.checkRights) {
|
|
158
157
|
await this.checkRights(undefined, config.currentUser as any, config);
|
|
159
158
|
}
|
|
160
159
|
|
|
@@ -240,7 +239,7 @@ export abstract class ModuleService<T extends CoreModel = any> {
|
|
|
240
239
|
model?: new (...args: any[]) => T;
|
|
241
240
|
dbModel?: Model<T & Document>;
|
|
242
241
|
ignoreSelections?: boolean;
|
|
243
|
-
} = {}
|
|
242
|
+
} = {},
|
|
244
243
|
) {
|
|
245
244
|
const config = {
|
|
246
245
|
model: this.mainModelConstructor,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import fs = require('fs');
|
|
2
|
+
import { join } from 'path';
|
|
1
3
|
import { Injectable } from '@nestjs/common';
|
|
2
4
|
import ejs = require('ejs');
|
|
3
5
|
import { TemplateFunction } from 'ejs';
|
|
4
|
-
import fs = require('fs');
|
|
5
|
-
import { join } from 'path';
|
|
6
6
|
import { ConfigService } from './config.service';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -44,7 +44,7 @@ export class TemplateService {
|
|
|
44
44
|
|
|
45
45
|
// Get template file
|
|
46
46
|
fs.readFile(
|
|
47
|
-
join(this.configService.getFastButReadOnly('templates.path'), filePath)
|
|
47
|
+
`${join(this.configService.getFastButReadOnly('templates.path'), filePath)}.ejs`,
|
|
48
48
|
{ encoding: 'utf8' },
|
|
49
49
|
(err, data) => {
|
|
50
50
|
if (err) {
|
|
@@ -54,7 +54,7 @@ export class TemplateService {
|
|
|
54
54
|
this.templates[filePath] = ejs.compile(data);
|
|
55
55
|
resolve(this.templates[filePath]);
|
|
56
56
|
}
|
|
57
|
-
}
|
|
57
|
+
},
|
|
58
58
|
);
|
|
59
59
|
});
|
|
60
60
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CoreModel } from '../models/core-model.model';
|
|
2
2
|
|
|
3
|
-
export
|
|
3
|
+
export interface CoreModelConstructor<T extends CoreModel> {
|
|
4
4
|
new (): T;
|
|
5
5
|
init(this: new (...args: any[]) => T, ...args: any[]): T;
|
|
6
6
|
map(
|
|
@@ -27,4 +27,4 @@ export type CoreModelConstructor<T extends CoreModel> = {
|
|
|
27
27
|
mapId?: boolean;
|
|
28
28
|
}
|
|
29
29
|
): T;
|
|
30
|
-
}
|
|
30
|
+
}
|
|
@@ -28,7 +28,7 @@ export class CoreAuthController {
|
|
|
28
28
|
@CurrentUser() currentUser: ICoreAuthUser,
|
|
29
29
|
@Tokens('token') token: string,
|
|
30
30
|
@Res() res: ResponseType,
|
|
31
|
-
@Param('allDevices', ParseBoolPipe) allDevices?: boolean
|
|
31
|
+
@Param('allDevices', ParseBoolPipe) allDevices?: boolean,
|
|
32
32
|
): Promise<boolean> {
|
|
33
33
|
const result = await this.authService.logout(token, { currentUser, allDevices });
|
|
34
34
|
return this.processCookies(res, result);
|
|
@@ -42,7 +42,7 @@ export class CoreAuthController {
|
|
|
42
42
|
async refreshToken(
|
|
43
43
|
@CurrentUser() user: ICoreAuthUser,
|
|
44
44
|
@Tokens('refreshToken') refreshToken: string,
|
|
45
|
-
@Res() res: ResponseType
|
|
45
|
+
@Res() res: ResponseType,
|
|
46
46
|
): Promise<CoreAuthModel> {
|
|
47
47
|
const result = await this.authService.refreshTokens(user, refreshToken);
|
|
48
48
|
return this.processCookies(res, result);
|
|
@@ -2,13 +2,13 @@ import { DynamicModule, ForwardReference, Module, Provider, Type } from '@nestjs
|
|
|
2
2
|
import { APP_GUARD } from '@nestjs/core';
|
|
3
3
|
import { JwtModule, JwtModuleOptions } from '@nestjs/jwt';
|
|
4
4
|
import { PassportModule } from '@nestjs/passport';
|
|
5
|
+
import { PubSub } from 'graphql-subscriptions';
|
|
5
6
|
import { AuthGuardStrategy } from './auth-guard-strategy.enum';
|
|
6
7
|
import { RolesGuard } from './guards/roles.guard';
|
|
7
8
|
import { JwtRefreshStrategy } from './strategies/jwt-refresh.strategy';
|
|
8
9
|
import { JwtStrategy } from './strategies/jwt.strategy';
|
|
9
10
|
import { CoreAuthUserService } from './services/core-auth-user.service';
|
|
10
11
|
import { CoreAuthService } from './services/core-auth.service';
|
|
11
|
-
import { PubSub } from 'graphql-subscriptions';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* CoreAuthModule to handle user authentication and enables Roles
|
|
@@ -28,7 +28,7 @@ export class CoreAuthModule {
|
|
|
28
28
|
jwtRefreshStrategy?: Type<JwtRefreshStrategy>;
|
|
29
29
|
imports?: Array<Type<any> | DynamicModule | Promise<DynamicModule> | ForwardReference>;
|
|
30
30
|
providers?: Provider[];
|
|
31
|
-
}
|
|
31
|
+
},
|
|
32
32
|
): DynamicModule {
|
|
33
33
|
// Process imports
|
|
34
34
|
let imports: any[] = [
|
|
@@ -75,8 +75,8 @@ export class CoreAuthModule {
|
|
|
75
75
|
// Return CoreAuthModule
|
|
76
76
|
return {
|
|
77
77
|
module: CoreAuthModule,
|
|
78
|
-
imports
|
|
79
|
-
providers
|
|
78
|
+
imports,
|
|
79
|
+
providers,
|
|
80
80
|
exports: [CoreAuthService, JwtModule, JwtStrategy, JwtRefreshStrategy, PassportModule, UserModule],
|
|
81
81
|
};
|
|
82
82
|
}
|
|
@@ -17,7 +17,7 @@ import { Tokens } from './tokens.decorator';
|
|
|
17
17
|
/**
|
|
18
18
|
* Authentication resolver for the sign in
|
|
19
19
|
*/
|
|
20
|
-
@Resolver(
|
|
20
|
+
@Resolver(of => CoreAuthModel, { isAbstract: true })
|
|
21
21
|
export class CoreAuthResolver {
|
|
22
22
|
/**
|
|
23
23
|
* Import services
|
|
@@ -32,12 +32,12 @@ export class CoreAuthResolver {
|
|
|
32
32
|
* Logout user (from specific device)
|
|
33
33
|
*/
|
|
34
34
|
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
35
|
-
@Mutation(
|
|
35
|
+
@Mutation(returns => Boolean, { description: 'Logout user (from specific device)' })
|
|
36
36
|
async logout(
|
|
37
37
|
@CurrentUser() currentUser: ICoreAuthUser,
|
|
38
38
|
@Context() ctx: { res: ResponseType },
|
|
39
39
|
@Tokens('token') token: string,
|
|
40
|
-
@Args('allDevices', { nullable: true }) allDevices?: boolean
|
|
40
|
+
@Args('allDevices', { nullable: true }) allDevices?: boolean,
|
|
41
41
|
): Promise<boolean> {
|
|
42
42
|
const result = await this.authService.logout(token, { currentUser, allDevices });
|
|
43
43
|
return this.processCookies(ctx, result);
|
|
@@ -47,11 +47,11 @@ export class CoreAuthResolver {
|
|
|
47
47
|
* Refresh token (for specific device)
|
|
48
48
|
*/
|
|
49
49
|
@UseGuards(AuthGuard(AuthGuardStrategy.JWT_REFRESH))
|
|
50
|
-
@Mutation(
|
|
50
|
+
@Mutation(returns => CoreAuthModel, { description: 'Refresh tokens (for specific device)' })
|
|
51
51
|
async refreshToken(
|
|
52
52
|
@CurrentUser() user: ICoreAuthUser,
|
|
53
53
|
@Tokens('refreshToken') refreshToken: string,
|
|
54
|
-
@Context() ctx: { res: ResponseType }
|
|
54
|
+
@Context() ctx: { res: ResponseType },
|
|
55
55
|
): Promise<CoreAuthModel> {
|
|
56
56
|
const result = await this.authService.refreshTokens(user, refreshToken);
|
|
57
57
|
return this.processCookies(ctx, result);
|
|
@@ -60,13 +60,13 @@ export class CoreAuthResolver {
|
|
|
60
60
|
/**
|
|
61
61
|
* Sign in user via email and password (on specific device)
|
|
62
62
|
*/
|
|
63
|
-
@Mutation(
|
|
63
|
+
@Mutation(returns => CoreAuthModel, {
|
|
64
64
|
description: 'Sign in user via email and password and get JWT tokens (for specific device)',
|
|
65
65
|
})
|
|
66
66
|
async signIn(
|
|
67
67
|
@GraphQLServiceOptions({ gqlPath: 'signIn.user' }) serviceOptions: ServiceOptions,
|
|
68
68
|
@Context() ctx: { res: ResponseType },
|
|
69
|
-
@Args('input') input: CoreAuthSignInInput
|
|
69
|
+
@Args('input') input: CoreAuthSignInInput,
|
|
70
70
|
): Promise<CoreAuthModel> {
|
|
71
71
|
const result = await this.authService.signIn(input, serviceOptions);
|
|
72
72
|
return this.processCookies(ctx, result);
|
|
@@ -75,11 +75,11 @@ export class CoreAuthResolver {
|
|
|
75
75
|
/**
|
|
76
76
|
* Register a new user account (on specific device)
|
|
77
77
|
*/
|
|
78
|
-
@Mutation(
|
|
78
|
+
@Mutation(returns => CoreAuthModel, { description: 'Register a new user account (on specific device)' })
|
|
79
79
|
async signUp(
|
|
80
80
|
@GraphQLServiceOptions({ gqlPath: 'signUp.user' }) serviceOptions: ServiceOptions,
|
|
81
81
|
@Context() ctx: { res: ResponseType },
|
|
82
|
-
@Args('input') input: CoreAuthSignUpInput
|
|
82
|
+
@Args('input') input: CoreAuthSignUpInput,
|
|
83
83
|
): Promise<CoreAuthModel> {
|
|
84
84
|
const result = await this.authService.signUp(input, serviceOptions);
|
|
85
85
|
return this.processCookies(ctx, result);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CanActivate, ExecutionContext, Logger,
|
|
1
|
+
import { CanActivate, ExecutionContext, Logger, Optional, mixin } from '@nestjs/common';
|
|
2
2
|
import { GqlExecutionContext } from '@nestjs/graphql';
|
|
3
3
|
import { AuthModuleOptions, Type } from '@nestjs/passport';
|
|
4
4
|
import { defaultOptions } from '@nestjs/passport/dist/options';
|
|
@@ -12,9 +12,9 @@ import { InvalidTokenException } from '../exceptions/invalid-token.exception';
|
|
|
12
12
|
/**
|
|
13
13
|
* Missing strategy error
|
|
14
14
|
*/
|
|
15
|
-
const NO_STRATEGY_ERROR
|
|
16
|
-
'In order to use "defaultStrategy", please, ensure to import PassportModule in each '
|
|
17
|
-
|
|
15
|
+
const NO_STRATEGY_ERROR
|
|
16
|
+
= 'In order to use "defaultStrategy", please, ensure to import PassportModule in each '
|
|
17
|
+
+ 'place where AuthGuard() is being used. Otherwise, passport won\'t work correctly.';
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Interface for auth guard
|
|
@@ -37,7 +37,7 @@ const createPassportContext = (request, response) => (type, options, callback: (
|
|
|
37
37
|
} catch (err) {
|
|
38
38
|
reject(err);
|
|
39
39
|
}
|
|
40
|
-
})(request, response,
|
|
40
|
+
})(request, response, err => (err ? reject(err) : resolve)),
|
|
41
41
|
);
|
|
42
42
|
|
|
43
43
|
/**
|
|
@@ -73,7 +73,7 @@ function createAuthGuard(type?: string): Type<CanActivate> {
|
|
|
73
73
|
const request = this.getRequest(context);
|
|
74
74
|
const passportFn = createPassportContext(request, response);
|
|
75
75
|
const user = await passportFn(type || this.options.defaultStrategy, options, (err, currentUser, info) =>
|
|
76
|
-
this.handleRequest(err, currentUser, info, context)
|
|
76
|
+
this.handleRequest(err, currentUser, info, context),
|
|
77
77
|
);
|
|
78
78
|
request[options.property || defaultOptions.property] = user;
|
|
79
79
|
return true;
|
|
@@ -100,12 +100,13 @@ function createAuthGuard(type?: string): Type<CanActivate> {
|
|
|
100
100
|
*/
|
|
101
101
|
async logIn<TRequest extends { logIn: (...params) => any } = any>(request: TRequest) {
|
|
102
102
|
const user = request[this.options.property || defaultOptions.property];
|
|
103
|
-
await new Promise<void>((resolve, reject) => request.logIn(user,
|
|
103
|
+
await new Promise<void>((resolve, reject) => request.logIn(user, err => (err ? reject(err) : resolve())));
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
/**
|
|
107
107
|
* Process request
|
|
108
108
|
*/
|
|
109
|
+
// eslint-disable-next-line unused-imports/no-unused-vars
|
|
109
110
|
handleRequest(err, user, info, context): TUser {
|
|
110
111
|
if (err) {
|
|
111
112
|
throw new InvalidTokenException();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { randomUUID } from 'crypto';
|
|
1
2
|
import { BadRequestException, Injectable, UnauthorizedException } from '@nestjs/common';
|
|
2
3
|
import { JwtService } from '@nestjs/jwt';
|
|
3
4
|
import bcrypt = require('bcrypt');
|
|
4
|
-
import { randomUUID } from 'crypto';
|
|
5
5
|
import { sha256 } from 'js-sha256';
|
|
6
6
|
import { getStringIds } from '../../../common/helpers/db.helper';
|
|
7
7
|
import { prepareServiceOptions } from '../../../common/helpers/service.helper';
|
|
@@ -25,7 +25,7 @@ export class CoreAuthService {
|
|
|
25
25
|
constructor(
|
|
26
26
|
protected readonly userService: CoreAuthUserService,
|
|
27
27
|
protected readonly jwtService: JwtService,
|
|
28
|
-
protected readonly configService: ConfigService
|
|
28
|
+
protected readonly configService: ConfigService,
|
|
29
29
|
) {}
|
|
30
30
|
|
|
31
31
|
/**
|
|
@@ -40,7 +40,7 @@ export class CoreAuthService {
|
|
|
40
40
|
*/
|
|
41
41
|
async logout(
|
|
42
42
|
tokenOrRefreshToken: string,
|
|
43
|
-
serviceOptions: ServiceOptions & { allDevices?: boolean }
|
|
43
|
+
serviceOptions: ServiceOptions & { allDevices?: boolean },
|
|
44
44
|
): Promise<boolean> {
|
|
45
45
|
// Check authentication
|
|
46
46
|
const user = serviceOptions.currentUser;
|
|
@@ -162,7 +162,7 @@ export class CoreAuthService {
|
|
|
162
162
|
protected async getResult(
|
|
163
163
|
user: ICoreAuthUser,
|
|
164
164
|
data?: { [key: string]: any; deviceId?: string },
|
|
165
|
-
currentRefreshToken?: string
|
|
165
|
+
currentRefreshToken?: string,
|
|
166
166
|
) {
|
|
167
167
|
// Create new tokens
|
|
168
168
|
const tokens = await this.createTokens(user.id, data);
|
|
@@ -186,10 +186,10 @@ export class CoreAuthService {
|
|
|
186
186
|
path += '.refresh';
|
|
187
187
|
}
|
|
188
188
|
return (
|
|
189
|
-
this.configService.getFastButReadOnly(path
|
|
190
|
-
this.configService.getFastButReadOnly(path
|
|
191
|
-
this.configService.getFastButReadOnly(path
|
|
192
|
-
this.configService.getFastButReadOnly(path
|
|
189
|
+
this.configService.getFastButReadOnly(`${path}.signInOptions.secret`)
|
|
190
|
+
|| this.configService.getFastButReadOnly(`${path}.signInOptions.secretOrPrivateKey`)
|
|
191
|
+
|| this.configService.getFastButReadOnly(`${path}.secret`)
|
|
192
|
+
|| this.configService.getFastButReadOnly(`${path}.secretOrPrivateKey`)
|
|
193
193
|
);
|
|
194
194
|
}
|
|
195
195
|
|
|
@@ -226,7 +226,7 @@ export class CoreAuthService {
|
|
|
226
226
|
user: ICoreAuthUser,
|
|
227
227
|
currentRefreshToken: string,
|
|
228
228
|
newRefreshToken: string,
|
|
229
|
-
data?: Record<string, any
|
|
229
|
+
data?: Record<string, any>,
|
|
230
230
|
): Promise<string> {
|
|
231
231
|
// Check if the update of the update token is allowed
|
|
232
232
|
let deviceId: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
|
2
2
|
import { PassportStrategy } from '@nestjs/passport';
|
|
3
|
-
import { Request as RequestType
|
|
3
|
+
import { Request, Request as RequestType } from 'express';
|
|
4
4
|
import { ExtractJwt, Strategy } from 'passport-jwt';
|
|
5
5
|
import { ConfigService } from '../../../common/services/config.service';
|
|
6
6
|
import { AuthGuardStrategy } from '../auth-guard-strategy.enum';
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
|
2
2
|
import { PassportStrategy } from '@nestjs/passport';
|
|
3
3
|
import { ExtractJwt, Strategy } from 'passport-jwt';
|
|
4
|
+
import { Request as RequestType } from 'express';
|
|
4
5
|
import { ConfigService } from '../../../common/services/config.service';
|
|
5
6
|
import { AuthGuardStrategy } from '../auth-guard-strategy.enum';
|
|
6
7
|
import { JwtPayload } from '../interfaces/jwt-payload.interface';
|
|
7
8
|
import { CoreAuthService } from '../services/core-auth.service';
|
|
8
|
-
import { Request as RequestType } from 'express';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Use JWT strategy for passport
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { GqlExecutionContext } from '@nestjs/graphql';
|
|
1
|
+
import { ExecutionContext, createParamDecorator } from '@nestjs/common';
|
|
3
2
|
import { getContextData } from '../../common/helpers/context.helper';
|
|
4
3
|
|
|
5
4
|
/**
|
|
@@ -8,15 +7,15 @@ import { getContextData } from '../../common/helpers/context.helper';
|
|
|
8
7
|
export const Tokens = createParamDecorator(
|
|
9
8
|
(
|
|
10
9
|
tokenId: 'token' | 'refreshToken' | undefined,
|
|
11
|
-
ctx: ExecutionContext
|
|
10
|
+
ctx: ExecutionContext,
|
|
12
11
|
): string | { token: string; refreshToken: string } => {
|
|
13
12
|
// Get prepared context (REST or GraphQL)
|
|
14
13
|
const context = getContextData(ctx);
|
|
15
14
|
|
|
16
15
|
// Get token from cookie or authorization header
|
|
17
|
-
const token
|
|
18
|
-
context?.request?.cookies?.['token']
|
|
19
|
-
context?.request
|
|
16
|
+
const token
|
|
17
|
+
= context?.request?.cookies?.['token']
|
|
18
|
+
|| context?.request
|
|
20
19
|
?.get('Authorization')
|
|
21
20
|
?.replace(/bearer/i, '')
|
|
22
21
|
.trim();
|
|
@@ -32,5 +31,5 @@ export const Tokens = createParamDecorator(
|
|
|
32
31
|
return tokens[tokenId];
|
|
33
32
|
}
|
|
34
33
|
return tokens;
|
|
35
|
-
}
|
|
34
|
+
},
|
|
36
35
|
);
|
|
@@ -25,8 +25,8 @@ export class CoreFileInfo extends CoreModel {
|
|
|
25
25
|
|
|
26
26
|
@Field(() => Number, {
|
|
27
27
|
description:
|
|
28
|
-
'The size of each chunk in bytes. GridFS divides the document into chunks of size chunkSize, '
|
|
29
|
-
'except for the last, which is only as large as needed. The default size is 255 kilobytes (kB)',
|
|
28
|
+
'The size of each chunk in bytes. GridFS divides the document into chunks of size chunkSize, '
|
|
29
|
+
+ 'except for the last, which is only as large as needed. The default size is 255 kilobytes (kB)',
|
|
30
30
|
nullable: true,
|
|
31
31
|
})
|
|
32
32
|
@Prop({ type: Number, required: false })
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { BadRequestException, Controller, Get, NotFoundException, Param, Res } from '@nestjs/common';
|
|
2
|
-
import { CurrentUser } from '../../common/decorators/current-user.decorator';
|
|
3
|
-
import { CoreUserModel } from '../user/core-user.model';
|
|
4
2
|
import { CoreFileService } from './core-file.service';
|
|
5
3
|
|
|
6
4
|
/**
|
|
@@ -17,7 +15,7 @@ export abstract class CoreFileController {
|
|
|
17
15
|
* Download file
|
|
18
16
|
*/
|
|
19
17
|
@Get(':filename')
|
|
20
|
-
async getFile(@Param('filename') filename: string, @Res() res
|
|
18
|
+
async getFile(@Param('filename') filename: string, @Res() res) {
|
|
21
19
|
if (!filename) {
|
|
22
20
|
throw new BadRequestException('Missing filename for download');
|
|
23
21
|
}
|
|
@@ -28,7 +26,7 @@ export abstract class CoreFileController {
|
|
|
28
26
|
}
|
|
29
27
|
const filestream = await this.fileService.getFileStream(file.id);
|
|
30
28
|
res.header('Content-Type', file.contentType);
|
|
31
|
-
res.header('Content-Disposition',
|
|
29
|
+
res.header('Content-Disposition', `attachment; filename=${file.filename}`);
|
|
32
30
|
return filestream.pipe(res);
|
|
33
31
|
}
|
|
34
32
|
}
|