@omnitronix/game-engine-sdk 1.0.2 → 1.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/bootstrap/index.d.ts +2 -0
- package/dist/bootstrap/index.d.ts.map +1 -1
- package/dist/bootstrap/index.js +4 -2
- package/dist/common/api-docs/setup-documentation.d.ts.map +1 -1
- package/dist/common/api-docs/setup-documentation.js +4 -0
- package/dist/common/error-handling/all-exceptions.filter.js +1 -1
- package/dist/common/logger/logging.middleware.d.ts.map +1 -1
- package/dist/common/logger/logging.middleware.js +25 -7
- package/dist/esm/bootstrap/index.js +4 -2
- package/dist/esm/common/api-docs/setup-documentation.js +4 -0
- package/dist/esm/common/error-handling/all-exceptions.filter.js +1 -1
- package/dist/esm/common/logger/logging.middleware.js +25 -7
- package/package.json +1 -1
|
@@ -5,6 +5,8 @@ export interface GameEngineAppOptions {
|
|
|
5
5
|
bootstrapOptions?: {
|
|
6
6
|
driver: 'database' | 'in-memory';
|
|
7
7
|
};
|
|
8
|
+
/** Allowed CORS origins. Defaults to false (CORS disabled). */
|
|
9
|
+
corsOrigins?: string[] | boolean;
|
|
8
10
|
}
|
|
9
11
|
/**
|
|
10
12
|
* Creates and bootstraps a game engine NestJS application with
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bootstrap/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAsD,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAK1F,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IACrB,gBAAgB,CAAC,EAAE;QAAE,MAAM,EAAE,UAAU,GAAG,WAAW,CAAA;KAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bootstrap/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAsD,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAK1F,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IACrB,gBAAgB,CAAC,EAAE;QAAE,MAAM,EAAE,UAAU,GAAG,WAAW,CAAA;KAAE,CAAC;IACxD,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;CAClC;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,2DA0HtE"}
|
package/dist/bootstrap/index.js
CHANGED
|
@@ -51,7 +51,7 @@ const http2 = __importStar(require("http2"));
|
|
|
51
51
|
* Swagger docs, Connect RPC gRPC server, and graceful shutdown.
|
|
52
52
|
*/
|
|
53
53
|
async function createGameEngineApp(options) {
|
|
54
|
-
const { serviceName, appModule, bootstrapOptions } = options;
|
|
54
|
+
const { serviceName, appModule, bootstrapOptions, corsOrigins = false } = options;
|
|
55
55
|
const logger = new logger_1.Logger(serviceName);
|
|
56
56
|
const moduleArg = bootstrapOptions
|
|
57
57
|
? appModule.register
|
|
@@ -61,7 +61,9 @@ async function createGameEngineApp(options) {
|
|
|
61
61
|
const app = await core_1.NestFactory.create(moduleArg, {
|
|
62
62
|
logger: logger,
|
|
63
63
|
});
|
|
64
|
-
|
|
64
|
+
if (corsOrigins) {
|
|
65
|
+
app.enableCors({ origin: corsOrigins });
|
|
66
|
+
}
|
|
65
67
|
const configService = app.get(config_1.ConfigService);
|
|
66
68
|
const shutdownService = app.get(shutdown_out_port_1.SHUTDOWN_OUT_PORT);
|
|
67
69
|
let isShuttingDown = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup-documentation.d.ts","sourceRoot":"","sources":["../../../src/common/api-docs/setup-documentation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAMlD,eAAO,MAAM,kBAAkB,GAC7B,KAAK,gBAAgB,CAAC,GAAG,CAAC,EAC1B,MAAM,MAAM,EACZ,cAAc,MAAM,
|
|
1
|
+
{"version":3,"file":"setup-documentation.d.ts","sourceRoot":"","sources":["../../../src/common/api-docs/setup-documentation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAMlD,eAAO,MAAM,kBAAkB,GAC7B,KAAK,gBAAgB,CAAC,GAAG,CAAC,EAC1B,MAAM,MAAM,EACZ,cAAc,MAAM,kBA0BrB,CAAC"}
|
|
@@ -5,6 +5,10 @@ const swagger_1 = require("@nestjs/swagger");
|
|
|
5
5
|
const logger_1 = require("../logger/logger");
|
|
6
6
|
const logger = new logger_1.Logger('ApiDocs');
|
|
7
7
|
const setupDocumentation = async (app, port, serviceName) => {
|
|
8
|
+
if (process.env.NODE_ENV === 'production' && process.env.ENABLE_SWAGGER !== 'true') {
|
|
9
|
+
logger.log('Swagger docs disabled in production (set ENABLE_SWAGGER=true to override)');
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
8
12
|
const config = new swagger_1.DocumentBuilder()
|
|
9
13
|
.setTitle(serviceName ? `${serviceName} API` : 'Game Engine API')
|
|
10
14
|
.setDescription('API documentation')
|
|
@@ -100,7 +100,7 @@ let ExceptionsFilter = ExceptionsFilter_1 = class ExceptionsFilter {
|
|
|
100
100
|
return this.buildResponsePayload({
|
|
101
101
|
status: common_1.HttpStatus.INTERNAL_SERVER_ERROR,
|
|
102
102
|
internalCode: internal_error_code_1.InternalErrorCode.INTERNAL_SERVER_ERROR,
|
|
103
|
-
message:
|
|
103
|
+
message: 'Internal server error',
|
|
104
104
|
path: request.url,
|
|
105
105
|
});
|
|
106
106
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logging.middleware.d.ts","sourceRoot":"","sources":["../../../src/common/logger/logging.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"logging.middleware.d.ts","sourceRoot":"","sources":["../../../src/common/logger/logging.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AA4B1D,qBACa,iBAAkB,YAAW,cAAc;IACtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;;IAMhC,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY;CAkBpD"}
|
|
@@ -14,19 +14,37 @@ exports.LoggingMiddleware = void 0;
|
|
|
14
14
|
const common_1 = require("@nestjs/common");
|
|
15
15
|
const logger_1 = require("./logger");
|
|
16
16
|
const BLOCKED_ENDPOINTS = ['/api/races/active'];
|
|
17
|
+
const SENSITIVE_FIELDS = new Set([
|
|
18
|
+
'password', 'token', 'secret', 'authorization',
|
|
19
|
+
'apikey', 'api_key', 'accesstoken', 'refreshtoken',
|
|
20
|
+
'creditcard', 'ssn', 'private_key', 'privatekey',
|
|
21
|
+
]);
|
|
22
|
+
function sanitize(obj) {
|
|
23
|
+
if (obj === null || obj === undefined || typeof obj !== 'object')
|
|
24
|
+
return obj;
|
|
25
|
+
if (Array.isArray(obj))
|
|
26
|
+
return obj.map(sanitize);
|
|
27
|
+
const result = {};
|
|
28
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
29
|
+
if (SENSITIVE_FIELDS.has(key.toLowerCase())) {
|
|
30
|
+
result[key] = '***';
|
|
31
|
+
}
|
|
32
|
+
else if (typeof value === 'object' && value !== null) {
|
|
33
|
+
result[key] = sanitize(value);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
result[key] = value;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
17
41
|
let LoggingMiddleware = LoggingMiddleware_1 = class LoggingMiddleware {
|
|
18
42
|
constructor() {
|
|
19
43
|
this.logger = new logger_1.Logger(LoggingMiddleware_1.name);
|
|
20
44
|
}
|
|
21
45
|
use(req, res, next) {
|
|
22
46
|
const { method, originalUrl, body } = req;
|
|
23
|
-
const sanitizedBody =
|
|
24
|
-
if (sanitizedBody.password) {
|
|
25
|
-
sanitizedBody.password = '***';
|
|
26
|
-
}
|
|
27
|
-
if (sanitizedBody.token) {
|
|
28
|
-
sanitizedBody.token = '***';
|
|
29
|
-
}
|
|
47
|
+
const sanitizedBody = sanitize(body);
|
|
30
48
|
res.on('finish', () => {
|
|
31
49
|
const isBlockedEndpoint = BLOCKED_ENDPOINTS.some(endpoint => originalUrl.includes(endpoint));
|
|
32
50
|
const isSuccessfulRequest = res.statusCode < 400;
|
|
@@ -15,7 +15,7 @@ import * as http2 from 'http2';
|
|
|
15
15
|
* Swagger docs, Connect RPC gRPC server, and graceful shutdown.
|
|
16
16
|
*/
|
|
17
17
|
export async function createGameEngineApp(options) {
|
|
18
|
-
const { serviceName, appModule, bootstrapOptions } = options;
|
|
18
|
+
const { serviceName, appModule, bootstrapOptions, corsOrigins = false } = options;
|
|
19
19
|
const logger = new Logger(serviceName);
|
|
20
20
|
const moduleArg = bootstrapOptions
|
|
21
21
|
? appModule.register
|
|
@@ -25,7 +25,9 @@ export async function createGameEngineApp(options) {
|
|
|
25
25
|
const app = await NestFactory.create(moduleArg, {
|
|
26
26
|
logger: logger,
|
|
27
27
|
});
|
|
28
|
-
|
|
28
|
+
if (corsOrigins) {
|
|
29
|
+
app.enableCors({ origin: corsOrigins });
|
|
30
|
+
}
|
|
29
31
|
const configService = app.get(ConfigService);
|
|
30
32
|
const shutdownService = app.get(SHUTDOWN_OUT_PORT);
|
|
31
33
|
let isShuttingDown = false;
|
|
@@ -2,6 +2,10 @@ import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
|
|
2
2
|
import { Logger } from '../logger/logger';
|
|
3
3
|
const logger = new Logger('ApiDocs');
|
|
4
4
|
export const setupDocumentation = async (app, port, serviceName) => {
|
|
5
|
+
if (process.env.NODE_ENV === 'production' && process.env.ENABLE_SWAGGER !== 'true') {
|
|
6
|
+
logger.log('Swagger docs disabled in production (set ENABLE_SWAGGER=true to override)');
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
5
9
|
const config = new DocumentBuilder()
|
|
6
10
|
.setTitle(serviceName ? `${serviceName} API` : 'Game Engine API')
|
|
7
11
|
.setDescription('API documentation')
|
|
@@ -97,7 +97,7 @@ let ExceptionsFilter = ExceptionsFilter_1 = class ExceptionsFilter {
|
|
|
97
97
|
return this.buildResponsePayload({
|
|
98
98
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
99
99
|
internalCode: InternalErrorCode.INTERNAL_SERVER_ERROR,
|
|
100
|
-
message:
|
|
100
|
+
message: 'Internal server error',
|
|
101
101
|
path: request.url,
|
|
102
102
|
});
|
|
103
103
|
}
|
|
@@ -11,19 +11,37 @@ var LoggingMiddleware_1;
|
|
|
11
11
|
import { Injectable } from '@nestjs/common';
|
|
12
12
|
import { Logger } from './logger';
|
|
13
13
|
const BLOCKED_ENDPOINTS = ['/api/races/active'];
|
|
14
|
+
const SENSITIVE_FIELDS = new Set([
|
|
15
|
+
'password', 'token', 'secret', 'authorization',
|
|
16
|
+
'apikey', 'api_key', 'accesstoken', 'refreshtoken',
|
|
17
|
+
'creditcard', 'ssn', 'private_key', 'privatekey',
|
|
18
|
+
]);
|
|
19
|
+
function sanitize(obj) {
|
|
20
|
+
if (obj === null || obj === undefined || typeof obj !== 'object')
|
|
21
|
+
return obj;
|
|
22
|
+
if (Array.isArray(obj))
|
|
23
|
+
return obj.map(sanitize);
|
|
24
|
+
const result = {};
|
|
25
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
26
|
+
if (SENSITIVE_FIELDS.has(key.toLowerCase())) {
|
|
27
|
+
result[key] = '***';
|
|
28
|
+
}
|
|
29
|
+
else if (typeof value === 'object' && value !== null) {
|
|
30
|
+
result[key] = sanitize(value);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
result[key] = value;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
14
38
|
let LoggingMiddleware = LoggingMiddleware_1 = class LoggingMiddleware {
|
|
15
39
|
constructor() {
|
|
16
40
|
this.logger = new Logger(LoggingMiddleware_1.name);
|
|
17
41
|
}
|
|
18
42
|
use(req, res, next) {
|
|
19
43
|
const { method, originalUrl, body } = req;
|
|
20
|
-
const sanitizedBody =
|
|
21
|
-
if (sanitizedBody.password) {
|
|
22
|
-
sanitizedBody.password = '***';
|
|
23
|
-
}
|
|
24
|
-
if (sanitizedBody.token) {
|
|
25
|
-
sanitizedBody.token = '***';
|
|
26
|
-
}
|
|
44
|
+
const sanitizedBody = sanitize(body);
|
|
27
45
|
res.on('finish', () => {
|
|
28
46
|
const isBlockedEndpoint = BLOCKED_ENDPOINTS.some(endpoint => originalUrl.includes(endpoint));
|
|
29
47
|
const isSuccessfulRequest = res.statusCode < 400;
|