@lenne.tech/nest-server 11.9.0 → 11.10.0
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 +2 -0
- package/dist/config.env.js.map +1 -1
- package/dist/core/common/helpers/logging.helper.d.ts +6 -0
- package/dist/core/common/helpers/logging.helper.js +55 -0
- package/dist/core/common/helpers/logging.helper.js.map +1 -0
- package/dist/core/common/interfaces/server-options.interface.d.ts +37 -19
- package/dist/core/modules/auth/guards/roles.guard.js +33 -2
- package/dist/core/modules/auth/guards/roles.guard.js.map +1 -1
- package/dist/core/modules/auth/services/core-auth.service.d.ts +5 -5
- package/dist/core/modules/auth/services/core-auth.service.js +4 -4
- package/dist/core/modules/auth/services/core-auth.service.js.map +1 -1
- package/dist/core/modules/auth/tokens.decorator.d.ts +1 -1
- package/dist/core/modules/better-auth/better-auth.config.js +32 -10
- package/dist/core/modules/better-auth/better-auth.config.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.resolver.d.ts +16 -16
- package/dist/core/modules/better-auth/better-auth.resolver.js +34 -34
- package/dist/core/modules/better-auth/better-auth.resolver.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.types.d.ts +2 -1
- package/dist/core/modules/better-auth/better-auth.types.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.d.ts +10 -0
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.js +91 -0
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth-auth.model.d.ts +9 -0
- package/dist/core/modules/better-auth/{better-auth-auth.model.js → core-better-auth-auth.model.js} +17 -17
- package/dist/core/modules/better-auth/core-better-auth-auth.model.js.map +1 -0
- package/dist/core/modules/better-auth/{better-auth-migration-status.model.d.ts → core-better-auth-migration-status.model.d.ts} +1 -1
- package/dist/core/modules/better-auth/{better-auth-migration-status.model.js → core-better-auth-migration-status.model.js} +14 -14
- package/dist/core/modules/better-auth/core-better-auth-migration-status.model.js.map +1 -0
- package/dist/core/modules/better-auth/{better-auth-models.d.ts → core-better-auth-models.d.ts} +8 -8
- package/dist/core/modules/better-auth/{better-auth-models.js → core-better-auth-models.js} +61 -61
- package/dist/core/modules/better-auth/core-better-auth-models.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth-rate-limit.middleware.d.ts +12 -0
- package/dist/core/modules/better-auth/{better-auth-rate-limit.middleware.js → core-better-auth-rate-limit.middleware.js} +10 -10
- package/dist/core/modules/better-auth/core-better-auth-rate-limit.middleware.js.map +1 -0
- package/dist/core/modules/better-auth/{better-auth-rate-limiter.service.d.ts → core-better-auth-rate-limiter.service.d.ts} +1 -1
- package/dist/core/modules/better-auth/{better-auth-rate-limiter.service.js → core-better-auth-rate-limiter.service.js} +8 -8
- package/dist/core/modules/better-auth/core-better-auth-rate-limiter.service.js.map +1 -0
- package/dist/core/modules/better-auth/{better-auth-user.mapper.d.ts → core-better-auth-user.mapper.d.ts} +1 -1
- package/dist/core/modules/better-auth/{better-auth-user.mapper.js → core-better-auth-user.mapper.js} +10 -9
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth-web.helper.d.ts +19 -0
- package/dist/core/modules/better-auth/core-better-auth-web.helper.js +152 -0
- package/dist/core/modules/better-auth/core-better-auth-web.helper.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth.controller.d.ts +23 -32
- package/dist/core/modules/better-auth/core-better-auth.controller.js +184 -201
- package/dist/core/modules/better-auth/core-better-auth.controller.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.middleware.d.ts +22 -0
- package/dist/core/modules/better-auth/{better-auth.middleware.js → core-better-auth.middleware.js} +45 -18
- package/dist/core/modules/better-auth/core-better-auth.middleware.js.map +1 -0
- package/dist/core/modules/better-auth/{better-auth.module.d.ts → core-better-auth.module.d.ts} +6 -6
- package/dist/core/modules/better-auth/{better-auth.module.js → core-better-auth.module.js} +65 -60
- package/dist/core/modules/better-auth/core-better-auth.module.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth.resolver.d.ts +19 -19
- package/dist/core/modules/better-auth/core-better-auth.resolver.js +18 -18
- package/dist/core/modules/better-auth/core-better-auth.resolver.js.map +1 -1
- package/dist/core/modules/better-auth/{better-auth.service.d.ts → core-better-auth.service.d.ts} +3 -2
- package/dist/core/modules/better-auth/{better-auth.service.js → core-better-auth.service.js} +75 -35
- package/dist/core/modules/better-auth/core-better-auth.service.js.map +1 -0
- package/dist/core/modules/better-auth/index.d.ts +11 -9
- package/dist/core/modules/better-auth/index.js +11 -9
- package/dist/core/modules/better-auth/index.js.map +1 -1
- package/dist/core/modules/error-code/core-error-code.controller.js.map +1 -1
- package/dist/core/modules/user/interfaces/core-user-service-options.interface.d.ts +2 -2
- package/dist/core.module.js +6 -6
- package/dist/core.module.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/server/modules/better-auth/better-auth.controller.d.ts +5 -5
- package/dist/server/modules/better-auth/better-auth.controller.js +4 -4
- package/dist/server/modules/better-auth/better-auth.controller.js.map +1 -1
- package/dist/server/modules/better-auth/better-auth.module.js +3 -3
- package/dist/server/modules/better-auth/better-auth.module.js.map +1 -1
- package/dist/server/modules/better-auth/better-auth.resolver.d.ts +17 -17
- package/dist/server/modules/better-auth/better-auth.resolver.js +18 -18
- package/dist/server/modules/better-auth/better-auth.resolver.js.map +1 -1
- package/dist/server/modules/user/user.service.d.ts +2 -2
- package/dist/server/modules/user/user.service.js +2 -2
- package/dist/server/modules/user/user.service.js.map +1 -1
- package/dist/test/test.helper.d.ts +1 -0
- package/dist/test/test.helper.js +5 -1
- package/dist/test/test.helper.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +5 -3
- package/src/config.env.ts +15 -0
- package/src/core/common/helpers/logging.helper.ts +134 -0
- package/src/core/common/interfaces/server-options.interface.ts +419 -234
- package/src/core/modules/auth/guards/roles.guard.ts +44 -3
- package/src/core/modules/auth/services/core-auth.service.ts +4 -4
- package/src/core/modules/better-auth/ARCHITECTURE.md +102 -0
- package/src/core/modules/better-auth/INTEGRATION-CHECKLIST.md +277 -8
- package/src/core/modules/better-auth/README.md +97 -53
- package/src/core/modules/better-auth/better-auth.config.ts +66 -18
- package/src/core/modules/better-auth/better-auth.resolver.ts +32 -32
- package/src/core/modules/better-auth/better-auth.types.ts +3 -2
- package/src/core/modules/better-auth/core-better-auth-api.middleware.ts +134 -0
- package/src/core/modules/better-auth/{better-auth-auth.model.ts → core-better-auth-auth.model.ts} +6 -6
- package/src/core/modules/better-auth/{better-auth-migration-status.model.ts → core-better-auth-migration-status.model.ts} +1 -1
- package/src/core/modules/better-auth/{better-auth-models.ts → core-better-auth-models.ts} +9 -9
- package/src/core/modules/better-auth/{better-auth-rate-limit.middleware.ts → core-better-auth-rate-limit.middleware.ts} +5 -5
- package/src/core/modules/better-auth/{better-auth-rate-limiter.service.ts → core-better-auth-rate-limiter.service.ts} +2 -2
- package/src/core/modules/better-auth/{better-auth-user.mapper.ts → core-better-auth-user.mapper.ts} +4 -3
- package/src/core/modules/better-auth/core-better-auth-web.helper.ts +272 -0
- package/src/core/modules/better-auth/core-better-auth.controller.ts +386 -230
- package/src/core/modules/better-auth/{better-auth.middleware.ts → core-better-auth.middleware.ts} +57 -17
- package/src/core/modules/better-auth/{better-auth.module.ts → core-better-auth.module.ts} +77 -66
- package/src/core/modules/better-auth/core-better-auth.resolver.ts +42 -42
- package/src/core/modules/better-auth/{better-auth.service.ts → core-better-auth.service.ts} +86 -40
- package/src/core/modules/better-auth/index.ts +18 -11
- package/src/core/modules/error-code/INTEGRATION-CHECKLIST.md +4 -1
- package/src/core/modules/error-code/core-error-code.controller.ts +3 -2
- package/src/core/modules/user/interfaces/core-user-service-options.interface.ts +3 -3
- package/src/core.module.ts +12 -12
- package/src/index.ts +1 -0
- package/src/server/modules/better-auth/better-auth.controller.ts +4 -4
- package/src/server/modules/better-auth/better-auth.module.ts +1 -1
- package/src/server/modules/better-auth/better-auth.resolver.ts +31 -31
- package/src/server/modules/user/user.service.ts +2 -2
- package/src/test/test.helper.ts +13 -1
- package/dist/core/modules/better-auth/better-auth-auth.model.d.ts +0 -9
- package/dist/core/modules/better-auth/better-auth-auth.model.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth-migration-status.model.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth-models.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth-rate-limit.middleware.d.ts +0 -12
- package/dist/core/modules/better-auth/better-auth-rate-limit.middleware.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth-rate-limiter.service.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth-user.mapper.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth.middleware.d.ts +0 -21
- package/dist/core/modules/better-auth/better-auth.middleware.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth.module.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth.service.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lenne.tech/nest-server",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.10.0",
|
|
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",
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
"vitest:watch": "NODE_ENV=local vitest --config vitest-e2e.config.ts",
|
|
63
63
|
"vitest:unit": "vitest run --config vitest.config.ts",
|
|
64
64
|
"test:unit:watch": "vitest --config vitest.config.ts",
|
|
65
|
+
"test:types": "tsc --noEmit --skipLibCheck -p tests/types/tsconfig.json",
|
|
65
66
|
"watch": "npm-watch",
|
|
66
67
|
"link:eslint": "yalc add @lenne.tech/eslint-config-ts && yalc link @lenne.tech/eslint-config-ts && npm install",
|
|
67
68
|
"unlink:eslint": "yalc remove @lenne.tech/eslint-config-ts && npm install"
|
|
@@ -79,7 +80,7 @@
|
|
|
79
80
|
"dependencies": {
|
|
80
81
|
"@apollo/server": "5.2.0",
|
|
81
82
|
"@as-integrations/express5": "1.1.2",
|
|
82
|
-
"@better-auth/passkey": "1.4.
|
|
83
|
+
"@better-auth/passkey": "^1.4.16",
|
|
83
84
|
"@getbrevo/brevo": "3.0.1",
|
|
84
85
|
"@nestjs/apollo": "13.2.3",
|
|
85
86
|
"@nestjs/common": "11.1.9",
|
|
@@ -97,7 +98,7 @@
|
|
|
97
98
|
"@tus/server": "2.3.0",
|
|
98
99
|
"apollo-server-core": "3.13.0",
|
|
99
100
|
"bcrypt": "6.0.0",
|
|
100
|
-
"better-auth": "1.4.
|
|
101
|
+
"better-auth": "^1.4.16",
|
|
101
102
|
"class-transformer": "0.5.1",
|
|
102
103
|
"class-validator": "0.14.3",
|
|
103
104
|
"compression": "1.8.1",
|
|
@@ -146,6 +147,7 @@
|
|
|
146
147
|
"@typescript-eslint/parser": "8.50.0",
|
|
147
148
|
"@vitest/coverage-v8": "4.0.16",
|
|
148
149
|
"@vitest/ui": "4.0.16",
|
|
150
|
+
"otpauth": "9.4.1",
|
|
149
151
|
"ansi-colors": "4.1.3",
|
|
150
152
|
"eslint": "9.39.2",
|
|
151
153
|
"eslint-config-prettier": "10.1.8",
|
package/src/config.env.ts
CHANGED
|
@@ -69,6 +69,12 @@ const config: { [env: string]: IServerOptions } = {
|
|
|
69
69
|
appName: 'Nest Server Development',
|
|
70
70
|
enabled: false,
|
|
71
71
|
},
|
|
72
|
+
// CORS trustedOrigins configuration:
|
|
73
|
+
// - Not set + Passkey disabled: All origins allowed (default)
|
|
74
|
+
// - Not set + Passkey enabled: Server startup FAILS (trustedOrigins required)
|
|
75
|
+
// - Set explicitly: Only configured origins allowed
|
|
76
|
+
// Uncomment and configure when enabling Passkey:
|
|
77
|
+
// trustedOrigins: ['http://localhost:3000', 'http://localhost:3001'],
|
|
72
78
|
},
|
|
73
79
|
compression: true,
|
|
74
80
|
cookies: false,
|
|
@@ -223,6 +229,10 @@ const config: { [env: string]: IServerOptions } = {
|
|
|
223
229
|
enabled: false,
|
|
224
230
|
},
|
|
225
231
|
},
|
|
232
|
+
// REQUIRED when Passkey is enabled!
|
|
233
|
+
// Passkey uses credentials: 'include' which requires explicit CORS origins.
|
|
234
|
+
// Server startup will fail if Passkey is enabled without trustedOrigins.
|
|
235
|
+
trustedOrigins: ['http://localhost:3000', 'http://localhost:3001'],
|
|
226
236
|
twoFactor: {
|
|
227
237
|
appName: 'Nest Server Local',
|
|
228
238
|
enabled: true,
|
|
@@ -399,10 +409,15 @@ const config: { [env: string]: IServerOptions } = {
|
|
|
399
409
|
enabled: !!process.env.SOCIAL_GOOGLE_CLIENT_ID,
|
|
400
410
|
},
|
|
401
411
|
},
|
|
412
|
+
// REQUIRED for Passkey in production!
|
|
413
|
+
// Passkey uses credentials: 'include' which requires explicit origins (no wildcard '*')
|
|
414
|
+
// Configure all frontend URLs that need Passkey authentication:
|
|
415
|
+
trustedOrigins: process.env.TRUSTED_ORIGINS?.split(',') || [],
|
|
402
416
|
twoFactor: {
|
|
403
417
|
appName: process.env.TWO_FACTOR_APP_NAME || 'Nest Server',
|
|
404
418
|
enabled: process.env.TWO_FACTOR_ENABLED === 'true',
|
|
405
419
|
},
|
|
420
|
+
// Example: TRUSTED_ORIGINS=https://app.example.com,https://admin.example.com
|
|
406
421
|
},
|
|
407
422
|
compression: true,
|
|
408
423
|
cookies: false,
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logging helper functions for safe logging of sensitive data.
|
|
3
|
+
*
|
|
4
|
+
* These functions help mask sensitive information in logs to comply with
|
|
5
|
+
* security best practices and GDPR requirements.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { maskToken, maskEmail, maskSensitive } from './logging.helper';
|
|
10
|
+
*
|
|
11
|
+
* // Instead of: logger.debug(`Token: ${token}`)
|
|
12
|
+
* logger.debug(`Token: ${maskToken(token)}`);
|
|
13
|
+
*
|
|
14
|
+
* // Instead of: logger.debug(`User: ${user.email}`)
|
|
15
|
+
* logger.debug(`User: ${maskEmail(user.email)}`);
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Checks if the current environment is production.
|
|
21
|
+
* Use this to conditionally skip verbose debug logging in production.
|
|
22
|
+
*
|
|
23
|
+
* @returns true if NODE_ENV is 'production'
|
|
24
|
+
*/
|
|
25
|
+
export function isProduction(): boolean {
|
|
26
|
+
return process.env.NODE_ENV === 'production';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Masks a cookie header for safe logging.
|
|
31
|
+
* Removes all cookie values, keeping only cookie names.
|
|
32
|
+
*
|
|
33
|
+
* @param cookieHeader - The cookie header string
|
|
34
|
+
* @returns Masked cookie header showing only cookie names
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* maskCookieHeader('session=abc123; token=xyz789') // 'session=***; token=***'
|
|
38
|
+
*/
|
|
39
|
+
export function maskCookieHeader(cookieHeader: null | string | undefined): string {
|
|
40
|
+
if (!cookieHeader) {
|
|
41
|
+
return 'none';
|
|
42
|
+
}
|
|
43
|
+
// Replace cookie values with ***
|
|
44
|
+
return cookieHeader.replace(/=([^;]*)/g, '=***');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Masks an email address for safe logging.
|
|
49
|
+
* Shows only the first 2 characters of the local part and the domain.
|
|
50
|
+
*
|
|
51
|
+
* @param email - The email to mask
|
|
52
|
+
* @returns Masked email or 'none' if not provided
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* maskEmail('john.doe@example.com') // 'jo***@example.com'
|
|
56
|
+
* maskEmail(null) // 'none'
|
|
57
|
+
*/
|
|
58
|
+
export function maskEmail(email: null | string | undefined): string {
|
|
59
|
+
if (!email) {
|
|
60
|
+
return 'none';
|
|
61
|
+
}
|
|
62
|
+
const atIndex = email.indexOf('@');
|
|
63
|
+
if (atIndex <= 0) {
|
|
64
|
+
return '***';
|
|
65
|
+
}
|
|
66
|
+
const localPart = email.substring(0, atIndex);
|
|
67
|
+
const domain = email.substring(atIndex);
|
|
68
|
+
const visibleChars = Math.min(2, localPart.length);
|
|
69
|
+
return `${localPart.substring(0, visibleChars)}***${domain}`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Masks an ObjectId or ID string for safe logging.
|
|
74
|
+
*
|
|
75
|
+
* @param id - The ID to mask
|
|
76
|
+
* @returns Masked ID or 'none' if not provided
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* maskId('507f1f77bcf86cd799439011') // '507f***9011'
|
|
80
|
+
*/
|
|
81
|
+
export function maskId(id: null | string | undefined): string {
|
|
82
|
+
return maskSensitive(id, 4, 4);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Masks sensitive string data for safe logging.
|
|
87
|
+
* Generic function for any sensitive string.
|
|
88
|
+
*
|
|
89
|
+
* @param value - The value to mask
|
|
90
|
+
* @param visibleStart - Number of characters to show at start (default: 4)
|
|
91
|
+
* @param visibleEnd - Number of characters to show at end (default: 0)
|
|
92
|
+
* @returns Masked value or 'none' if not provided
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* maskSensitive('secretpassword123') // 'secr***'
|
|
96
|
+
* maskSensitive('secretpassword123', 2, 2) // 'se***23'
|
|
97
|
+
*/
|
|
98
|
+
export function maskSensitive(
|
|
99
|
+
value: null | string | undefined,
|
|
100
|
+
visibleStart: number = 4,
|
|
101
|
+
visibleEnd: number = 0,
|
|
102
|
+
): string {
|
|
103
|
+
if (!value) {
|
|
104
|
+
return 'none';
|
|
105
|
+
}
|
|
106
|
+
const minLength = visibleStart + visibleEnd + 3; // At least 3 chars for '***'
|
|
107
|
+
if (value.length <= minLength) {
|
|
108
|
+
return '***';
|
|
109
|
+
}
|
|
110
|
+
const start = value.substring(0, visibleStart);
|
|
111
|
+
const end = visibleEnd > 0 ? value.substring(value.length - visibleEnd) : '';
|
|
112
|
+
return `${start}***${end}`;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Masks a token for safe logging.
|
|
117
|
+
* Shows only the first 4 and last 4 characters.
|
|
118
|
+
*
|
|
119
|
+
* @param token - The token to mask
|
|
120
|
+
* @returns Masked token or 'none' if not provided
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* maskToken('abc123xyz789') // 'abc1...9'
|
|
124
|
+
* maskToken(null) // 'none'
|
|
125
|
+
*/
|
|
126
|
+
export function maskToken(token: null | string | undefined): string {
|
|
127
|
+
if (!token) {
|
|
128
|
+
return 'none';
|
|
129
|
+
}
|
|
130
|
+
if (token.length <= 8) {
|
|
131
|
+
return '***';
|
|
132
|
+
}
|
|
133
|
+
return `${token.substring(0, 4)}...${token.substring(token.length - 4)}`;
|
|
134
|
+
}
|