@lenne.tech/nest-server 10.0.11 → 10.1.1
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 +1 -0
- package/dist/config.env.js.map +1 -1
- package/dist/core/common/helpers/filter.helper.d.ts +9 -0
- package/dist/core/common/helpers/filter.helper.js +18 -1
- package/dist/core/common/helpers/filter.helper.js.map +1 -1
- package/dist/core/common/interceptors/check-security.interceptor.js +19 -2
- package/dist/core/common/interceptors/check-security.interceptor.js.map +1 -1
- package/dist/core/common/interfaces/server-options.interface.d.ts +1 -0
- package/dist/core/common/services/module.service.js +9 -1
- package/dist/core/common/services/module.service.js.map +1 -1
- package/dist/main.js +2 -1
- package/dist/main.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/config.env.ts +1 -0
- package/src/core/common/helpers/filter.helper.ts +34 -5
- package/src/core/common/interceptors/check-security.interceptor.ts +19 -2
- package/src/core/common/interfaces/server-options.interface.ts +6 -0
- package/src/core/common/services/module.service.ts +9 -1
- package/src/main.ts +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lenne.tech/nest-server",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.1.1",
|
|
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",
|
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
"start:prod": "./node_modules/.bin/grunt production",
|
|
34
34
|
"start:nodemon": "ts-node -r tsconfig-paths/register src/main.ts",
|
|
35
35
|
"start:debug": "nodemon --config nodemon-debug.json",
|
|
36
|
-
"start:dev": "
|
|
37
|
-
"start:dev:
|
|
38
|
-
"start:local": "NODE_ENV=local
|
|
39
|
-
"start:local:
|
|
36
|
+
"start:dev": "nodemon",
|
|
37
|
+
"start:dev:swc": "nest start -b swc -w --type-check",
|
|
38
|
+
"start:local": "NODE_ENV=local nodemon",
|
|
39
|
+
"start:local:swc": "NODE_ENV=local nest start -b swc -w --type-check",
|
|
40
40
|
"test": "NODE_ENV=local jest",
|
|
41
41
|
"test:cov": "NODE_ENV=local jest --coverage",
|
|
42
42
|
"test:debug": "NODE_ENV=local node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
|
package/src/config.env.ts
CHANGED
|
@@ -206,11 +206,11 @@ export function generateFilterQuery<T = any>(
|
|
|
206
206
|
case ComparisonOperatorEnum.REGEX:
|
|
207
207
|
result[field] = not
|
|
208
208
|
? {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
209
|
+
$not: {
|
|
210
|
+
$regex: new RegExp(value),
|
|
211
|
+
$options: options || '',
|
|
212
|
+
},
|
|
213
|
+
}
|
|
214
214
|
: { $regex: new RegExp(value), $options: options || '' };
|
|
215
215
|
break;
|
|
216
216
|
}
|
|
@@ -265,3 +265,32 @@ export function generateFindOptions(
|
|
|
265
265
|
|
|
266
266
|
return queryOptions;
|
|
267
267
|
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Merge FilterArgs and FilterQueries
|
|
271
|
+
*/
|
|
272
|
+
export function filterMerge<T = unknown>(
|
|
273
|
+
filterArgs: Partial<FilterArgs>,
|
|
274
|
+
filterQuery: Partial<FilterQuery<T>>,
|
|
275
|
+
options?: {
|
|
276
|
+
operator?: '$and' | '$or' | '$nor';
|
|
277
|
+
queryOptions?: Partial<QueryOptions>;
|
|
278
|
+
samples?: number;
|
|
279
|
+
},
|
|
280
|
+
): { filterQuery: FilterQuery<T>; queryOptions?: QueryOptions; samples?: number } {
|
|
281
|
+
const config = {
|
|
282
|
+
operator: '$and',
|
|
283
|
+
...options,
|
|
284
|
+
};
|
|
285
|
+
const converted = convertFilterArgsToQuery(filterArgs);
|
|
286
|
+
return {
|
|
287
|
+
filterQuery: (converted[0]
|
|
288
|
+
? { [config.operator]: [converted[0], filterQuery || {}] }
|
|
289
|
+
: filterQuery
|
|
290
|
+
) as FilterQuery<T>,
|
|
291
|
+
queryOptions: converted[1] || config.queryOptions
|
|
292
|
+
? { ...converted[1], ...config.queryOptions }
|
|
293
|
+
: undefined,
|
|
294
|
+
samples: config.samples,
|
|
295
|
+
};
|
|
296
|
+
}
|
|
@@ -2,6 +2,7 @@ import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nes
|
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
3
|
import { map } from 'rxjs/operators';
|
|
4
4
|
import { getContextData } from '../helpers/context.helper';
|
|
5
|
+
import { getStringIds } from '../helpers/db.helper';
|
|
5
6
|
import { processDeep } from '../helpers/input.helper';
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -28,7 +29,15 @@ export class CheckSecurityInterceptor implements NestInterceptor {
|
|
|
28
29
|
map((data) => {
|
|
29
30
|
// Check data
|
|
30
31
|
if (data && typeof data === 'object' && typeof data.securityCheck === 'function') {
|
|
31
|
-
|
|
32
|
+
const dataJson = JSON.stringify(data);
|
|
33
|
+
const response = data.securityCheck(user, force);
|
|
34
|
+
new Promise(() => {
|
|
35
|
+
if (dataJson !== JSON.stringify(response)) {
|
|
36
|
+
const id = getStringIds(data);
|
|
37
|
+
console.debug('CheckSecurityInterceptor: securityCheck changed data of type', data.constructor.name, id && !Array.isArray(id) ? `with ID: ${id}` : '');
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
return response;
|
|
32
41
|
}
|
|
33
42
|
|
|
34
43
|
// Check if data is writeable (e.g. objects from direct access to json files via http are not writable)
|
|
@@ -49,7 +58,15 @@ export class CheckSecurityInterceptor implements NestInterceptor {
|
|
|
49
58
|
}
|
|
50
59
|
return item;
|
|
51
60
|
}
|
|
52
|
-
|
|
61
|
+
const itemJson = JSON.stringify(item);
|
|
62
|
+
const response = item.securityCheck(user, force);
|
|
63
|
+
new Promise(() => {
|
|
64
|
+
if (itemJson !== JSON.stringify(response)) {
|
|
65
|
+
const id = getStringIds(item);
|
|
66
|
+
console.debug('CheckSecurityInterceptor: securityCheck changed item of type', item.constructor.name, id && !Array.isArray(id) ? `with ID: ${id}` : '');
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
return response;
|
|
53
70
|
},
|
|
54
71
|
{ specialFunctions: ['securityCheck'] },
|
|
55
72
|
);
|
|
@@ -277,6 +277,12 @@ export interface IServerOptions {
|
|
|
277
277
|
};
|
|
278
278
|
};
|
|
279
279
|
|
|
280
|
+
/**
|
|
281
|
+
* Hostname of the server
|
|
282
|
+
* default: localhost
|
|
283
|
+
*/
|
|
284
|
+
hostname?: string;
|
|
285
|
+
|
|
280
286
|
/**
|
|
281
287
|
* Ignore selections in fieldSelection
|
|
282
288
|
* [ConfigService must be integrated in ModuleService]
|
|
@@ -131,7 +131,15 @@ export abstract class ModuleService<T extends CoreModel = any> {
|
|
|
131
131
|
if (!opts.targetModel && config.inputType) {
|
|
132
132
|
opts.targetModel = config.inputType;
|
|
133
133
|
}
|
|
134
|
-
|
|
134
|
+
const originalInput = config.input;
|
|
135
|
+
const inputJSON = JSON.stringify(originalInput);
|
|
136
|
+
const preparedInput = await this.prepareInput(config.input, config);
|
|
137
|
+
new Promise(() => {
|
|
138
|
+
if (inputJSON?.replace(/"password":\s*"[^"]*"/, '') !== JSON.stringify(preparedInput)?.replace(/"password":\s*"[^"]*"/, '')) {
|
|
139
|
+
console.debug('CheckSecurityInterceptor: securityCheck changed input of type', originalInput.constructor.name, 'to type', preparedInput.constructor.name);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
config.input = preparedInput;
|
|
135
143
|
}
|
|
136
144
|
|
|
137
145
|
// Get DB object
|
package/src/main.ts
CHANGED
|
@@ -54,7 +54,8 @@ async function bootstrap() {
|
|
|
54
54
|
server.enableCors();
|
|
55
55
|
|
|
56
56
|
// Start server on configured port
|
|
57
|
-
await server.listen(envConfig.port);
|
|
57
|
+
await server.listen(envConfig.port, envConfig.hostname);
|
|
58
|
+
console.debug(`Server startet at ${await server.getUrl()}`);
|
|
58
59
|
|
|
59
60
|
// Run command after server init
|
|
60
61
|
if (envConfig.execAfterInit) {
|