@dismissible/nestjs-api 1.0.3-alpha.cdc64a4.0 → 2.0.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/README.md +23 -15
- package/bin/dismissible-storage-setup.js +4 -0
- package/config/.env.development.yaml +6 -1
- package/config/.env.yaml +5 -2
- package/package.json +21 -21
- package/src/app.setup.js +9 -40
- package/src/app.setup.js.map +1 -1
- package/src/config/config.module.js +0 -1
- package/src/config/config.module.js.map +1 -1
- package/src/cors/cors.config.js +2 -1
- package/src/cors/cors.config.js.map +1 -1
- package/src/cors/cors.factory.d.ts +2 -0
- package/src/cors/cors.factory.js +29 -0
- package/src/cors/cors.factory.js.map +1 -0
- package/src/cors/index.d.ts +1 -0
- package/src/cors/index.js +1 -0
- package/src/cors/index.js.map +1 -1
- package/src/helmet/helmet.factory.d.ts +2 -0
- package/src/helmet/helmet.factory.js +29 -0
- package/src/helmet/helmet.factory.js.map +1 -0
- package/src/helmet/index.d.ts +1 -0
- package/src/helmet/index.js +1 -0
- package/src/helmet/index.js.map +1 -1
- package/src/storage/storage.config.js +0 -8
- package/src/storage/storage.config.js.map +1 -1
- package/src/swagger/swagger.factory.d.ts +1 -2
- package/src/swagger/swagger.factory.js +10 -1
- package/src/swagger/swagger.factory.js.map +1 -1
- package/src/validation/index.d.ts +1 -0
- package/src/validation/index.js +1 -0
- package/src/validation/index.js.map +1 -1
- package/src/validation/validation.factory.d.ts +2 -0
- package/src/validation/validation.factory.js +19 -0
- package/src/validation/validation.factory.js.map +1 -0
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<a href="https://dismissible.io" target="_blank"><img src="
|
|
2
|
+
<a href="https://dismissible.io" target="_blank"><img src="https://raw.githubusercontent.com/DismissibleIo/dismissible-api/main/docs/images/dismissible_logo.png" width="120" alt="Dismissible" /></a>
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">Never Show The Same Thing Twice!</p>
|
|
@@ -126,7 +126,7 @@ Enable Swagger documentation by setting `DISMISSIBLE_SWAGGER_ENABLED=true` and v
|
|
|
126
126
|
| ------------------------------- | ------------------------------------------------------------------------- | ---------- |
|
|
127
127
|
| `DISMISSIBLE_PORT` | Port the API listens on | `3001` |
|
|
128
128
|
| `DISMISSIBLE_STORAGE_TYPE` | Storage backend type eg. `postgres`, `dynamodb`, `memory` | `postgres` |
|
|
129
|
-
| `
|
|
129
|
+
| `DISMISSIBLE_STORAGE_RUN_SETUP` | Run database migrations on startup. Each storage type will have their own | `false` |
|
|
130
130
|
|
|
131
131
|
### Storage Settings
|
|
132
132
|
|
|
@@ -177,16 +177,20 @@ When enabled, Swagger documentation is published to the path specified by `DISMI
|
|
|
177
177
|
|
|
178
178
|
You can secure your API with any OIDC-compliant provider (Auth0, Okta, Keycloak, etc.). This ensures that no one can fill your dismissible service with junk.
|
|
179
179
|
|
|
180
|
-
| Variable | Description
|
|
181
|
-
| ------------------------------------------ |
|
|
182
|
-
| `DISMISSIBLE_JWT_AUTH_ENABLED` | Enable JWT authentication
|
|
183
|
-
| `DISMISSIBLE_JWT_AUTH_WELL_KNOWN_URL` | OIDC discovery URL
|
|
184
|
-
| `DISMISSIBLE_JWT_AUTH_ISSUER` | Expected JWT issuer
|
|
185
|
-
| `DISMISSIBLE_JWT_AUTH_AUDIENCE` | Expected JWT audience
|
|
186
|
-
| `DISMISSIBLE_JWT_AUTH_ALGORITHMS` | Allowed algorithms (comma-separated)
|
|
187
|
-
| `DISMISSIBLE_JWT_AUTH_JWKS_CACHE_DURATION` | JWKS cache duration (ms)
|
|
188
|
-
| `DISMISSIBLE_JWT_AUTH_REQUEST_TIMEOUT` | Request timeout (ms)
|
|
189
|
-
| `DISMISSIBLE_JWT_AUTH_PRIORITY` | Hook priority (lower runs first)
|
|
180
|
+
| Variable | Description | Default |
|
|
181
|
+
| ------------------------------------------ | ------------------------------------------- | --------------------- |
|
|
182
|
+
| `DISMISSIBLE_JWT_AUTH_ENABLED` | Enable JWT authentication | `false` |
|
|
183
|
+
| `DISMISSIBLE_JWT_AUTH_WELL_KNOWN_URL` | OIDC discovery URL | _required_ if enabled |
|
|
184
|
+
| `DISMISSIBLE_JWT_AUTH_ISSUER` | Expected JWT issuer | _-_ |
|
|
185
|
+
| `DISMISSIBLE_JWT_AUTH_AUDIENCE` | Expected JWT audience | _-_ |
|
|
186
|
+
| `DISMISSIBLE_JWT_AUTH_ALGORITHMS` | Allowed algorithms (comma-separated) | `RS256` |
|
|
187
|
+
| `DISMISSIBLE_JWT_AUTH_JWKS_CACHE_DURATION` | JWKS cache duration (ms) | `600000` |
|
|
188
|
+
| `DISMISSIBLE_JWT_AUTH_REQUEST_TIMEOUT` | Request timeout (ms) | `30000` |
|
|
189
|
+
| `DISMISSIBLE_JWT_AUTH_PRIORITY` | Hook priority (lower runs first) | `-100` |
|
|
190
|
+
| `DISMISSIBLE_JWT_AUTH_MATCH_USER_ID` | Enable user ID matching | `true` |
|
|
191
|
+
| `DISMISSIBLE_JWT_AUTH_USER_ID_CLAIM` | JWT claim key for user ID matching | `sub` |
|
|
192
|
+
| `DISMISSIBLE_JWT_AUTH_USER_ID_MATCH_TYPE` | Match method: `exact`, `substring`, `regex` | `exact` |
|
|
193
|
+
| `DISMISSIBLE_JWT_AUTH_USER_ID_MATCH_REGEX` | Regex pattern (required if type=regex) | _-_ |
|
|
190
194
|
|
|
191
195
|
### CORS Settings
|
|
192
196
|
|
|
@@ -197,8 +201,8 @@ Cross-Origin Resource Sharing (CORS) controls which domains can access your API
|
|
|
197
201
|
|
|
198
202
|
| Variable | Description | Default |
|
|
199
203
|
| ---------------------------------- | ---------------------------------- | ----------------------------------------- |
|
|
200
|
-
| `DISMISSIBLE_CORS_ENABLED` | Enable CORS | `
|
|
201
|
-
| `DISMISSIBLE_CORS_ORIGINS` | Allowed origins (comma-separated) |
|
|
204
|
+
| `DISMISSIBLE_CORS_ENABLED` | Enable CORS | `false` |
|
|
205
|
+
| `DISMISSIBLE_CORS_ORIGINS` | Allowed origins (comma-separated) | `` |
|
|
202
206
|
| `DISMISSIBLE_CORS_METHODS` | Allowed HTTP methods | `GET,POST,DELETE,OPTIONS` |
|
|
203
207
|
| `DISMISSIBLE_CORS_ALLOWED_HEADERS` | Allowed headers | `Content-Type,Authorization,x-request-id` |
|
|
204
208
|
| `DISMISSIBLE_CORS_CREDENTIALS` | Allow credentials | `true` |
|
|
@@ -283,6 +287,10 @@ jwtAuth:
|
|
|
283
287
|
jwksCacheDuration: ${DISMISSIBLE_JWT_AUTH_JWKS_CACHE_DURATION:-600000}
|
|
284
288
|
requestTimeout: ${DISMISSIBLE_JWT_AUTH_REQUEST_TIMEOUT:-30000}
|
|
285
289
|
priority: ${DISMISSIBLE_JWT_AUTH_PRIORITY:--100}
|
|
290
|
+
matchUserId: ${DISMISSIBLE_JWT_AUTH_MATCH_USER_ID:-true}
|
|
291
|
+
userIdClaim: ${DISMISSIBLE_JWT_AUTH_USER_ID_CLAIM:-sub}
|
|
292
|
+
userIdMatchType: ${DISMISSIBLE_JWT_AUTH_USER_ID_MATCH_TYPE:-exact}
|
|
293
|
+
userIdMatchRegex: ${DISMISSIBLE_JWT_AUTH_USER_ID_MATCH_REGEX:-}
|
|
286
294
|
|
|
287
295
|
validation:
|
|
288
296
|
disableErrorMessages: ${DISMISSIBLE_VALIDATION_DISABLE_ERROR_MESSAGES:-true}
|
|
@@ -418,7 +426,7 @@ The fastest way to get started:
|
|
|
418
426
|
# PostgreSQL (default)
|
|
419
427
|
docker run -p 3001:3001 \
|
|
420
428
|
-e DISMISSIBLE_STORAGE_TYPE=postgres \
|
|
421
|
-
-e
|
|
429
|
+
-e DISMISSIBLE_STORAGE_RUN_SETUP=true \
|
|
422
430
|
-e DISMISSIBLE_STORAGE_POSTGRES_CONNECTION_STRING="postgresql://user:password@host:5432/dismissible" \
|
|
423
431
|
dismissibleio/dismissible-api:latest
|
|
424
432
|
|
|
@@ -12,6 +12,10 @@ switch (storageType) {
|
|
|
12
12
|
console.log('Running DynamoDB storage setup...');
|
|
13
13
|
execSync('npm run storage:setup:dynamodb', { stdio: 'inherit' });
|
|
14
14
|
break;
|
|
15
|
+
case 'memory':
|
|
16
|
+
console.log('No setup required for In Memory storage...');
|
|
17
|
+
process.exit(0);
|
|
18
|
+
break;
|
|
15
19
|
default:
|
|
16
20
|
if (storageType) {
|
|
17
21
|
console.log(`Warning: Unknown storage type '${storageType}'. Skipping storage setup.`);
|
|
@@ -9,7 +9,12 @@ helmet:
|
|
|
9
9
|
enabled: false
|
|
10
10
|
|
|
11
11
|
cors:
|
|
12
|
-
enabled:
|
|
12
|
+
enabled: true
|
|
13
|
+
origins: http://localhost:5173
|
|
14
|
+
methods: GET,POST,DELETE,OPTIONS
|
|
15
|
+
allowedHeaders: Content-Type,Authorization,x-request-id
|
|
16
|
+
credentials: true
|
|
17
|
+
maxAge: 86400
|
|
13
18
|
|
|
14
19
|
storage:
|
|
15
20
|
# postgres | dynamodb | memory
|
package/config/.env.yaml
CHANGED
|
@@ -39,11 +39,14 @@ jwtAuth:
|
|
|
39
39
|
wellKnownUrl: ${DISMISSIBLE_JWT_AUTH_WELL_KNOWN_URL:-}
|
|
40
40
|
issuer: ${DISMISSIBLE_JWT_AUTH_ISSUER:-}
|
|
41
41
|
audience: ${DISMISSIBLE_JWT_AUTH_AUDIENCE:-}
|
|
42
|
-
algorithms:
|
|
43
|
-
- ${DISMISSIBLE_JWT_AUTH_ALGORITHMS:-RS256}
|
|
42
|
+
algorithms: ${DISMISSIBLE_JWT_AUTH_ALGORITHMS:-RS256}
|
|
44
43
|
jwksCacheDuration: ${DISMISSIBLE_JWT_AUTH_JWKS_CACHE_DURATION:-600000}
|
|
45
44
|
requestTimeout: ${DISMISSIBLE_JWT_AUTH_REQUEST_TIMEOUT:-30000}
|
|
46
45
|
priority: ${DISMISSIBLE_JWT_AUTH_PRIORITY:--100}
|
|
46
|
+
matchUserId: ${DISMISSIBLE_JWT_AUTH_MATCH_USER_ID:-true}
|
|
47
|
+
userIdMatchType: ${DISMISSIBLE_JWT_AUTH_USER_ID_MATCH_TYPE:-exact}
|
|
48
|
+
userIdMatchRegex: ${DISMISSIBLE_JWT_AUTH_USER_ID_MATCH_REGEX:-}
|
|
49
|
+
userIdClaim: ${DISMISSIBLE_JWT_AUTH_USER_ID_CLAIM:-sub}
|
|
47
50
|
|
|
48
51
|
validation:
|
|
49
52
|
disableErrorMessages: ${DISMISSIBLE_VALIDATION_DISABLE_ERROR_MESSAGES:-true}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dismissible/nestjs-api",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Dismissible API application",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"types": "./src/index.d.ts",
|
|
@@ -30,25 +30,25 @@
|
|
|
30
30
|
"storage:setup:dynamodb": "npx dismissible-dynamodb-setup"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@dismissible/nestjs-core": "
|
|
34
|
-
"@dismissible/nestjs-item": "
|
|
35
|
-
"@dismissible/nestjs-jwt-auth-hook": "
|
|
36
|
-
"@dismissible/nestjs-storage": "
|
|
37
|
-
"@dismissible/nestjs-postgres-storage": "
|
|
38
|
-
"@dismissible/nestjs-dynamodb-storage": "
|
|
39
|
-
"@dismissible/nestjs-logger": "
|
|
40
|
-
"@nestjs/common": "11.1.
|
|
41
|
-
"@nestjs/core": "11.1.
|
|
42
|
-
"@nestjs/platform-fastify": "11.1.
|
|
43
|
-
"fastify": "5.6.2",
|
|
44
|
-
"@fastify/helmet": "13.0.2",
|
|
45
|
-
"@fastify/static": "8.3.0",
|
|
46
|
-
"@nestjs/swagger": "11.2.3",
|
|
47
|
-
"class-transformer": "0.5.1",
|
|
48
|
-
"class-validator": "0.14.3",
|
|
49
|
-
"nest-typed-config": "2.10.1",
|
|
50
|
-
"reflect-metadata": "0.2.2",
|
|
51
|
-
"rxjs": "7.8.2"
|
|
33
|
+
"@dismissible/nestjs-core": "^2.0.1",
|
|
34
|
+
"@dismissible/nestjs-item": "^2.0.1",
|
|
35
|
+
"@dismissible/nestjs-jwt-auth-hook": "^2.0.1",
|
|
36
|
+
"@dismissible/nestjs-storage": "^2.0.1",
|
|
37
|
+
"@dismissible/nestjs-postgres-storage": "^2.0.1",
|
|
38
|
+
"@dismissible/nestjs-dynamodb-storage": "^2.0.1",
|
|
39
|
+
"@dismissible/nestjs-logger": "^2.0.1",
|
|
40
|
+
"@nestjs/common": "^11.1.11",
|
|
41
|
+
"@nestjs/core": "^11.1.11",
|
|
42
|
+
"@nestjs/platform-fastify": "^11.1.11",
|
|
43
|
+
"fastify": "^5.6.2",
|
|
44
|
+
"@fastify/helmet": "^13.0.2",
|
|
45
|
+
"@fastify/static": "^8.3.0",
|
|
46
|
+
"@nestjs/swagger": "^11.2.3",
|
|
47
|
+
"class-transformer": "^0.5.1",
|
|
48
|
+
"class-validator": "^0.14.3",
|
|
49
|
+
"nest-typed-config": "^2.10.1",
|
|
50
|
+
"reflect-metadata": "^0.2.2",
|
|
51
|
+
"rxjs": "^7.8.2"
|
|
52
52
|
},
|
|
53
53
|
"keywords": [
|
|
54
54
|
"nestjs",
|
|
@@ -64,4 +64,4 @@
|
|
|
64
64
|
"access": "public"
|
|
65
65
|
},
|
|
66
66
|
"type": "commonjs"
|
|
67
|
-
}
|
|
67
|
+
}
|
package/src/app.setup.js
CHANGED
|
@@ -1,49 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.configureApp = configureApp;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const common_1 = require("@nestjs/common");
|
|
6
|
-
const helmet_1 = tslib_1.__importDefault(require("@fastify/helmet"));
|
|
7
4
|
const swagger_1 = require("./swagger");
|
|
8
5
|
const cors_1 = require("./cors");
|
|
9
|
-
const
|
|
6
|
+
const helmet_1 = require("./helmet");
|
|
10
7
|
const validation_1 = require("./validation");
|
|
8
|
+
const nestjs_logger_1 = require("@dismissible/nestjs-logger");
|
|
11
9
|
async function configureApp(app) {
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
maxAge: helmetConfig.hstsMaxAge ?? 31536000,
|
|
20
|
-
includeSubDomains: helmetConfig.hstsIncludeSubDomains ?? true,
|
|
21
|
-
preload: helmetConfig.hstsPreload ?? false,
|
|
22
|
-
},
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
const corsConfig = app.get(cors_1.CorsConfig);
|
|
26
|
-
if (corsConfig.enabled) {
|
|
27
|
-
app.enableCors({
|
|
28
|
-
origin: corsConfig.origins ?? ['http://localhost:3001', 'http://localhost:5173'],
|
|
29
|
-
methods: corsConfig.methods ?? ['GET', 'POST', 'DELETE', 'OPTIONS'],
|
|
30
|
-
allowedHeaders: corsConfig.allowedHeaders ?? [
|
|
31
|
-
'Content-Type',
|
|
32
|
-
'Authorization',
|
|
33
|
-
'x-request-id',
|
|
34
|
-
],
|
|
35
|
-
credentials: corsConfig.credentials ?? true,
|
|
36
|
-
maxAge: corsConfig.maxAge ?? 86400,
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
const validationConfig = app.get(validation_1.ValidationConfig);
|
|
40
|
-
app.useGlobalPipes(new common_1.ValidationPipe({
|
|
41
|
-
whitelist: validationConfig.whitelist ?? true,
|
|
42
|
-
forbidNonWhitelisted: validationConfig.forbidNonWhitelisted ?? true,
|
|
43
|
-
transform: validationConfig.transform ?? true,
|
|
44
|
-
disableErrorMessages: validationConfig.disableErrorMessages ?? true,
|
|
45
|
-
}));
|
|
46
|
-
const swaggerConfig = app.get(swagger_1.SwaggerConfig);
|
|
47
|
-
(0, swagger_1.configureAppWithSwagger)(app, swaggerConfig);
|
|
10
|
+
const logger = app.get(nestjs_logger_1.DISMISSIBLE_LOGGER);
|
|
11
|
+
logger.setContext('AppSetup');
|
|
12
|
+
logger.info('Configuring application');
|
|
13
|
+
await (0, helmet_1.configureAppWithHelmet)(app);
|
|
14
|
+
(0, cors_1.configureAppWithCors)(app);
|
|
15
|
+
(0, validation_1.configureAppWithValidation)(app);
|
|
16
|
+
(0, swagger_1.configureAppWithSwagger)(app);
|
|
48
17
|
}
|
|
49
18
|
//# sourceMappingURL=app.setup.js.map
|
package/src/app.setup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.setup.js","sourceRoot":"","sources":["../../../api/src/app.setup.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"app.setup.js","sourceRoot":"","sources":["../../../api/src/app.setup.ts"],"names":[],"mappings":";;AAOA,oCASC;AAfD,uCAAoD;AACpD,iCAA8C;AAC9C,qCAAkD;AAClD,6CAA0D;AAC1D,8DAAoF;AAE7E,KAAK,UAAU,YAAY,CAAC,GAAqB;IACtD,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAqB,kCAAkB,CAAC,CAAC;IAC/D,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IAC9B,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IAEvC,MAAM,IAAA,+BAAsB,EAAC,GAAG,CAAC,CAAC;IAClC,IAAA,2BAAoB,EAAC,GAAG,CAAC,CAAC;IAC1B,IAAA,uCAA0B,EAAC,GAAG,CAAC,CAAC;IAChC,IAAA,iCAAuB,EAAC,GAAG,CAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -22,7 +22,6 @@ let ConfigModule = ConfigModule_1 = class ConfigModule {
|
|
|
22
22
|
schema: options.schema,
|
|
23
23
|
load: [
|
|
24
24
|
(0, nest_typed_config_1.fileLoader)({
|
|
25
|
-
basename: process.env.NODE_ENV ? '.env' : `.env.${process.env.NODE_ENV}`,
|
|
26
25
|
searchFrom: configPath,
|
|
27
26
|
ignoreEnvironmentVariableSubstitution: ignoreEnvSubstitution,
|
|
28
27
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.module.js","sourceRoot":"","sources":["../../../../api/src/config/config.module.ts"],"names":[],"mappings":";;;;;AAAA,2CAA+D;AAC/D,yDAAkE;AAClE,+BAA4B;AAqBrB,IAAM,YAAY,oBAAlB,MAAM,YAAY;IACvB;;;;OAIG;IACH,MAAM,CAAC,OAAO,CAAmB,OAAgC;QAC/D,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,IAAI,IAAA,WAAI,EAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QACnE,MAAM,qBAAqB,GAAG,OAAO,CAAC,qCAAqC,IAAI,KAAK,CAAC;QAErF,OAAO;YACL,MAAM,EAAE,cAAY;YACpB,OAAO,EAAE;gBACP,qCAAiB,CAAC,OAAO,CAAC;oBACxB,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,IAAI,EAAE;wBACJ,IAAA,8BAAU,EAAC;4BACT,
|
|
1
|
+
{"version":3,"file":"config.module.js","sourceRoot":"","sources":["../../../../api/src/config/config.module.ts"],"names":[],"mappings":";;;;;AAAA,2CAA+D;AAC/D,yDAAkE;AAClE,+BAA4B;AAqBrB,IAAM,YAAY,oBAAlB,MAAM,YAAY;IACvB;;;;OAIG;IACH,MAAM,CAAC,OAAO,CAAmB,OAAgC;QAC/D,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,IAAI,IAAA,WAAI,EAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QACnE,MAAM,qBAAqB,GAAG,OAAO,CAAC,qCAAqC,IAAI,KAAK,CAAC;QAErF,OAAO;YACL,MAAM,EAAE,cAAY;YACpB,OAAO,EAAE;gBACP,qCAAiB,CAAC,OAAO,CAAC;oBACxB,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,IAAI,EAAE;wBACJ,IAAA,8BAAU,EAAC;4BACT,UAAU,EAAE,UAAU;4BACtB,qCAAqC,EAAE,qBAAqB;yBAC7D,CAAC;qBACH;iBACF,CAAC;aACH;YACD,OAAO,EAAE,CAAC,qCAAiB,CAAC;SAC7B,CAAC;IACJ,CAAC;CACF,CAAA;AA1BY,oCAAY;uBAAZ,YAAY;IAFxB,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,YAAY,CA0BxB"}
|
package/src/cors/cors.config.js
CHANGED
|
@@ -14,9 +14,10 @@ tslib_1.__decorate([
|
|
|
14
14
|
tslib_1.__metadata("design:type", Boolean)
|
|
15
15
|
], CorsConfig.prototype, "enabled", void 0);
|
|
16
16
|
tslib_1.__decorate([
|
|
17
|
+
(0, class_validator_1.ValidateIf)((o) => o.enabled === true),
|
|
17
18
|
(0, class_validator_1.IsArray)(),
|
|
19
|
+
(0, class_validator_1.ArrayNotEmpty)({ message: 'origins must not be empty when CORS is enabled' }),
|
|
18
20
|
(0, class_validator_1.IsString)({ each: true }),
|
|
19
|
-
(0, class_validator_1.IsOptional)(),
|
|
20
21
|
(0, nestjs_validation_1.TransformCommaSeparated)(),
|
|
21
22
|
tslib_1.__metadata("design:type", Array)
|
|
22
23
|
], CorsConfig.prototype, "origins", void 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cors.config.js","sourceRoot":"","sources":["../../../../api/src/cors/cors.config.ts"],"names":[],"mappings":";;;;AAAA,
|
|
1
|
+
{"version":3,"file":"cors.config.js","sourceRoot":"","sources":["../../../../api/src/cors/cors.config.ts"],"names":[],"mappings":";;;;AAAA,qDAQyB;AACzB,yDAAyC;AACzC,sEAA2F;AAE3F,MAAa,UAAU;CAiCtB;AAjCD,gCAiCC;AA9BiB;IAFf,IAAA,2BAAS,GAAE;IACX,IAAA,oCAAgB,GAAE;;2CACe;AAOlB;IALf,IAAA,4BAAU,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC;IACrC,IAAA,yBAAO,GAAE;IACT,IAAA,+BAAa,EAAC,EAAE,OAAO,EAAE,gDAAgD,EAAE,CAAC;IAC5E,IAAA,0BAAQ,EAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACxB,IAAA,2CAAuB,GAAE;;2CACS;AAMnB;IAJf,IAAA,yBAAO,GAAE;IACT,IAAA,0BAAQ,EAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACxB,IAAA,4BAAU,GAAE;IACZ,IAAA,2CAAuB,GAAE;;2CACS;AAMnB;IAJf,IAAA,yBAAO,GAAE;IACT,IAAA,0BAAQ,EAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACxB,IAAA,4BAAU,GAAE;IACZ,IAAA,2CAAuB,GAAE;;kDACgB;AAK1B;IAHf,IAAA,2BAAS,GAAE;IACX,IAAA,4BAAU,GAAE;IACZ,IAAA,oCAAgB,GAAE;;+CACmB;AAKtB;IAHf,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;IACZ,IAAA,wBAAI,EAAC,GAAG,EAAE,CAAC,MAAM,CAAC;;0CACa"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.configureAppWithCors = configureAppWithCors;
|
|
4
|
+
const cors_config_1 = require("./cors.config");
|
|
5
|
+
const nestjs_logger_1 = require("@dismissible/nestjs-logger");
|
|
6
|
+
function configureAppWithCors(app) {
|
|
7
|
+
const logger = app.get(nestjs_logger_1.DISMISSIBLE_LOGGER);
|
|
8
|
+
logger.setContext('CORS');
|
|
9
|
+
const corsConfig = app.get(cors_config_1.CorsConfig);
|
|
10
|
+
if (corsConfig.enabled) {
|
|
11
|
+
// origins is guaranteed to be non-empty when enabled via @ValidateIf + @ArrayNotEmpty
|
|
12
|
+
app.enableCors({
|
|
13
|
+
origin: corsConfig.origins,
|
|
14
|
+
methods: corsConfig.methods ?? ['GET', 'POST', 'DELETE', 'OPTIONS'],
|
|
15
|
+
allowedHeaders: corsConfig.allowedHeaders ?? [
|
|
16
|
+
'Content-Type',
|
|
17
|
+
'Authorization',
|
|
18
|
+
'x-request-id',
|
|
19
|
+
],
|
|
20
|
+
credentials: corsConfig.credentials ?? true,
|
|
21
|
+
maxAge: corsConfig.maxAge ?? 86400,
|
|
22
|
+
});
|
|
23
|
+
logger.info('CORS is enabled', { corsConfig });
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
logger.info('CORS is disabled');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=cors.factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cors.factory.js","sourceRoot":"","sources":["../../../../api/src/cors/cors.factory.ts"],"names":[],"mappings":";;AAIA,oDAsBC;AAzBD,+CAA2C;AAC3C,8DAAoF;AAEpF,SAAgB,oBAAoB,CAAC,GAAqB;IACxD,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAqB,kCAAkB,CAAC,CAAC;IAC/D,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC1B,MAAM,UAAU,GAAG,GAAG,CAAC,GAAG,CAAC,wBAAU,CAAC,CAAC;IAEvC,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;QACvB,sFAAsF;QACtF,GAAG,CAAC,UAAU,CAAC;YACb,MAAM,EAAE,UAAU,CAAC,OAAQ;YAC3B,OAAO,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC;YACnE,cAAc,EAAE,UAAU,CAAC,cAAc,IAAI;gBAC3C,cAAc;gBACd,eAAe;gBACf,cAAc;aACf;YACD,WAAW,EAAE,UAAU,CAAC,WAAW,IAAI,IAAI;YAC3C,MAAM,EAAE,UAAU,CAAC,MAAM,IAAI,KAAK;SACnC,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;IACjD,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAClC,CAAC;AACH,CAAC"}
|
package/src/cors/index.d.ts
CHANGED
package/src/cors/index.js
CHANGED
package/src/cors/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../api/src/cors/index.ts"],"names":[],"mappings":";;;AAAA,wDAA8B"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../api/src/cors/index.ts"],"names":[],"mappings":";;;AAAA,wDAA8B;AAC9B,yDAA+B"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.configureAppWithHelmet = configureAppWithHelmet;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const helmet_1 = tslib_1.__importDefault(require("@fastify/helmet"));
|
|
6
|
+
const helmet_config_1 = require("./helmet.config");
|
|
7
|
+
const nestjs_logger_1 = require("@dismissible/nestjs-logger");
|
|
8
|
+
async function configureAppWithHelmet(app) {
|
|
9
|
+
const logger = app.get(nestjs_logger_1.DISMISSIBLE_LOGGER);
|
|
10
|
+
logger.setContext('Helmet');
|
|
11
|
+
const helmetConfig = app.get(helmet_config_1.HelmetConfig);
|
|
12
|
+
if (helmetConfig.enabled) {
|
|
13
|
+
const fastifyApp = app;
|
|
14
|
+
await fastifyApp.register(helmet_1.default, {
|
|
15
|
+
contentSecurityPolicy: helmetConfig.contentSecurityPolicy ?? true,
|
|
16
|
+
crossOriginEmbedderPolicy: helmetConfig.crossOriginEmbedderPolicy ?? true,
|
|
17
|
+
hsts: {
|
|
18
|
+
maxAge: helmetConfig.hstsMaxAge ?? 31536000,
|
|
19
|
+
includeSubDomains: helmetConfig.hstsIncludeSubDomains ?? true,
|
|
20
|
+
preload: helmetConfig.hstsPreload ?? false,
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
logger.info('Helmet is enabled', { helmetConfig });
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
logger.info('Helmet is disabled');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=helmet.factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helmet.factory.js","sourceRoot":"","sources":["../../../../api/src/helmet/helmet.factory.ts"],"names":[],"mappings":";;AAMA,wDAoBC;;AAxBD,qEAA4C;AAC5C,mDAA+C;AAC/C,8DAAoF;AAE7E,KAAK,UAAU,sBAAsB,CAAC,GAAqB;IAChE,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAqB,kCAAkB,CAAC,CAAC;IAC/D,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC5B,MAAM,YAAY,GAAG,GAAG,CAAC,GAAG,CAAC,4BAAY,CAAC,CAAC;IAE3C,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,GAA6B,CAAC;QACjD,MAAM,UAAU,CAAC,QAAQ,CAAC,gBAAa,EAAE;YACvC,qBAAqB,EAAE,YAAY,CAAC,qBAAqB,IAAI,IAAI;YACjE,yBAAyB,EAAE,YAAY,CAAC,yBAAyB,IAAI,IAAI;YACzE,IAAI,EAAE;gBACJ,MAAM,EAAE,YAAY,CAAC,UAAU,IAAI,QAAQ;gBAC3C,iBAAiB,EAAE,YAAY,CAAC,qBAAqB,IAAI,IAAI;gBAC7D,OAAO,EAAE,YAAY,CAAC,WAAW,IAAI,KAAK;aAC3C;SACF,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC;IACrD,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACpC,CAAC;AACH,CAAC"}
|
package/src/helmet/index.d.ts
CHANGED
package/src/helmet/index.js
CHANGED
package/src/helmet/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../api/src/helmet/index.ts"],"names":[],"mappings":";;;AAAA,0DAAgC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../api/src/helmet/index.ts"],"names":[],"mappings":";;;AAAA,0DAAgC;AAChC,2DAAiC"}
|
|
@@ -18,14 +18,6 @@ exports.StorageConfig = StorageConfig;
|
|
|
18
18
|
tslib_1.__decorate([
|
|
19
19
|
(0, class_validator_1.IsDefined)(),
|
|
20
20
|
(0, class_validator_1.IsEnum)(StorageType),
|
|
21
|
-
(0, class_transformer_1.Transform)(({ value }) => {
|
|
22
|
-
if (!value)
|
|
23
|
-
return value;
|
|
24
|
-
if (Object.values(StorageType).includes(value)) {
|
|
25
|
-
return value;
|
|
26
|
-
}
|
|
27
|
-
return StorageType[value] || value;
|
|
28
|
-
}),
|
|
29
21
|
tslib_1.__metadata("design:type", String)
|
|
30
22
|
], StorageConfig.prototype, "type", void 0);
|
|
31
23
|
tslib_1.__decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.config.js","sourceRoot":"","sources":["../../../../api/src/storage/storage.config.ts"],"names":[],"mappings":";;;;AAAA,qDAAgF;AAChF,
|
|
1
|
+
{"version":3,"file":"storage.config.js","sourceRoot":"","sources":["../../../../api/src/storage/storage.config.ts"],"names":[],"mappings":";;;;AAAA,qDAAgF;AAChF,yDAAyC;AACzC,kFAA6E;AAC7E,kFAA6E;AAE7E,IAAY,WAIX;AAJD,WAAY,WAAW;IACrB,gCAAiB,CAAA;IACjB,oCAAqB,CAAA;IACrB,oCAAqB,CAAA;AACvB,CAAC,EAJW,WAAW,2BAAX,WAAW,QAItB;AAED,MAAa,aAAa;CAgBzB;AAhBD,sCAgBC;AAbiB;IAFf,IAAA,2BAAS,GAAE;IACX,IAAA,wBAAM,EAAC,WAAW,CAAC;;2CACe;AAMnB;IAJf,IAAA,4BAAU,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,QAAQ,CAAC;IAClD,IAAA,2BAAS,GAAE;IACX,IAAA,gCAAc,GAAE;IAChB,IAAA,wBAAI,EAAC,GAAG,EAAE,CAAC,+CAAqB,CAAC;sCACP,+CAAqB;+CAAC;AAMjC;IAJf,IAAA,4BAAU,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,QAAQ,CAAC;IAClD,IAAA,2BAAS,GAAE;IACX,IAAA,gCAAc,GAAE;IAChB,IAAA,wBAAI,EAAC,GAAG,EAAE,CAAC,+CAAqB,CAAC;sCACP,+CAAqB;+CAAC"}
|
|
@@ -1,3 +1,2 @@
|
|
|
1
1
|
import { INestApplication } from '@nestjs/common';
|
|
2
|
-
|
|
3
|
-
export declare function configureAppWithSwagger(app: INestApplication, swaggerConfig: SwaggerConfig): void;
|
|
2
|
+
export declare function configureAppWithSwagger(app: INestApplication): void;
|
|
@@ -2,11 +2,17 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.configureAppWithSwagger = configureAppWithSwagger;
|
|
4
4
|
const swagger_1 = require("@nestjs/swagger");
|
|
5
|
+
const swagger_config_1 = require("./swagger.config");
|
|
6
|
+
const nestjs_logger_1 = require("@dismissible/nestjs-logger");
|
|
5
7
|
const swaggerDocumentOptions = {
|
|
6
8
|
operationIdFactory: (_controllerKey, methodKey) => methodKey,
|
|
7
9
|
};
|
|
8
|
-
function configureAppWithSwagger(app
|
|
10
|
+
function configureAppWithSwagger(app) {
|
|
11
|
+
const logger = app.get(nestjs_logger_1.DISMISSIBLE_LOGGER);
|
|
12
|
+
logger.setContext('Swagger');
|
|
13
|
+
const swaggerConfig = app.get(swagger_config_1.SwaggerConfig);
|
|
9
14
|
if (swaggerConfig.enabled) {
|
|
15
|
+
logger.info('Swagger is enabled', { swaggerConfig });
|
|
10
16
|
const { path = 'docs' } = swaggerConfig;
|
|
11
17
|
const config = new swagger_1.DocumentBuilder()
|
|
12
18
|
.setTitle('Dismissible')
|
|
@@ -18,5 +24,8 @@ function configureAppWithSwagger(app, swaggerConfig) {
|
|
|
18
24
|
useGlobalPrefix: true,
|
|
19
25
|
});
|
|
20
26
|
}
|
|
27
|
+
else {
|
|
28
|
+
logger.info('Swagger is disabled');
|
|
29
|
+
}
|
|
21
30
|
}
|
|
22
31
|
//# sourceMappingURL=swagger.factory.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"swagger.factory.js","sourceRoot":"","sources":["../../../../api/src/swagger/swagger.factory.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"swagger.factory.js","sourceRoot":"","sources":["../../../../api/src/swagger/swagger.factory.ts"],"names":[],"mappings":";;AASA,0DAsBC;AA9BD,6CAAyF;AACzF,qDAAiD;AACjD,8DAAoF;AAEpF,MAAM,sBAAsB,GAA2B;IACrD,kBAAkB,EAAE,CAAC,cAAsB,EAAE,SAAiB,EAAE,EAAE,CAAC,SAAS;CAC7E,CAAC;AAEF,SAAgB,uBAAuB,CAAC,GAAqB;IAC3D,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAqB,kCAAkB,CAAC,CAAC;IAC/D,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAC7B,MAAM,aAAa,GAAG,GAAG,CAAC,GAAG,CAAC,8BAAa,CAAC,CAAC;IAE7C,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,aAAa,EAAE,CAAC,CAAC;QACrD,MAAM,EAAE,IAAI,GAAG,MAAM,EAAE,GAAG,aAAa,CAAC;QAExC,MAAM,MAAM,GAAG,IAAI,yBAAe,EAAE;aACjC,QAAQ,CAAC,aAAa,CAAC;aACvB,cAAc,CAAC,8CAA8C,CAAC;aAC9D,UAAU,CAAC,KAAK,CAAC;aACjB,KAAK,EAAE,CAAC;QAEX,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,uBAAa,CAAC,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,sBAAsB,CAAC,CAAC;QAChG,uBAAa,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,eAAe,EAAE;YAC9C,eAAe,EAAE,IAAI;SACtB,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACrC,CAAC;AACH,CAAC"}
|
package/src/validation/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../api/src/validation/index.ts"],"names":[],"mappings":";;;AAAA,8DAAoC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../api/src/validation/index.ts"],"names":[],"mappings":";;;AAAA,8DAAoC;AACpC,+DAAqC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.configureAppWithValidation = configureAppWithValidation;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const validation_config_1 = require("./validation.config");
|
|
6
|
+
const nestjs_logger_1 = require("@dismissible/nestjs-logger");
|
|
7
|
+
function configureAppWithValidation(app) {
|
|
8
|
+
const logger = app.get(nestjs_logger_1.DISMISSIBLE_LOGGER);
|
|
9
|
+
logger.setContext('Validation');
|
|
10
|
+
const validationConfig = app.get(validation_config_1.ValidationConfig);
|
|
11
|
+
logger.info('Registering ValidationPipe', { validationConfig });
|
|
12
|
+
app.useGlobalPipes(new common_1.ValidationPipe({
|
|
13
|
+
whitelist: validationConfig.whitelist ?? true,
|
|
14
|
+
forbidNonWhitelisted: validationConfig.forbidNonWhitelisted ?? true,
|
|
15
|
+
transform: validationConfig.transform ?? true,
|
|
16
|
+
disableErrorMessages: validationConfig.disableErrorMessages ?? true,
|
|
17
|
+
}));
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=validation.factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.factory.js","sourceRoot":"","sources":["../../../../api/src/validation/validation.factory.ts"],"names":[],"mappings":";;AAIA,gEAcC;AAlBD,2CAAkE;AAClE,2DAAuD;AACvD,8DAAoF;AAEpF,SAAgB,0BAA0B,CAAC,GAAqB;IAC9D,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAqB,kCAAkB,CAAC,CAAC;IAC/D,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;IAChC,MAAM,gBAAgB,GAAG,GAAG,CAAC,GAAG,CAAC,oCAAgB,CAAC,CAAC;IAEnD,MAAM,CAAC,IAAI,CAAC,4BAA4B,EAAE,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAChE,GAAG,CAAC,cAAc,CAChB,IAAI,uBAAc,CAAC;QACjB,SAAS,EAAE,gBAAgB,CAAC,SAAS,IAAI,IAAI;QAC7C,oBAAoB,EAAE,gBAAgB,CAAC,oBAAoB,IAAI,IAAI;QACnE,SAAS,EAAE,gBAAgB,CAAC,SAAS,IAAI,IAAI;QAC7C,oBAAoB,EAAE,gBAAgB,CAAC,oBAAoB,IAAI,IAAI;KACpE,CAAC,CACH,CAAC;AACJ,CAAC"}
|