@flusys/nestjs-auth 1.0.0-rc → 1.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 +530 -396
- package/cjs/controllers/authentication.controller.js +160 -28
- package/cjs/controllers/user-permission.controller.js +49 -136
- package/cjs/docs/auth-swagger.config.js +14 -7
- package/cjs/dtos/authentication.dto.js +0 -30
- package/cjs/dtos/index.js +0 -1
- package/cjs/entities/user-company-permission.entity.js +3 -3
- package/cjs/interceptors/clear-token.interceptor.js +8 -18
- package/cjs/interceptors/set-token.interceptor.js +8 -55
- package/cjs/interfaces/auth-email-provider.interface.js +1 -1
- package/cjs/modules/auth.module.js +63 -129
- package/cjs/services/auth-config.service.js +6 -29
- package/cjs/services/auth-datasource.provider.js +8 -20
- package/cjs/services/auth-email.service.js +72 -87
- package/cjs/services/authentication.service.js +211 -355
- package/cjs/services/branch.service.js +9 -5
- package/cjs/services/user-permission.service.js +43 -71
- package/cjs/services/user.service.js +18 -47
- package/cjs/strategies/jwt.strategy.js +44 -44
- package/controllers/authentication.controller.d.ts +5 -3
- package/controllers/user-permission.controller.d.ts +5 -4
- package/dtos/authentication.dto.d.ts +0 -4
- package/dtos/index.d.ts +0 -1
- package/entities/index.d.ts +3 -3
- package/entities/user-company-permission.entity.d.ts +1 -1
- package/fesm/controllers/authentication.controller.js +162 -30
- package/fesm/controllers/user-permission.controller.js +50 -137
- package/fesm/docs/auth-swagger.config.js +14 -7
- package/fesm/dtos/authentication.dto.js +0 -30
- package/fesm/dtos/index.js +0 -1
- package/fesm/entities/user-company-permission.entity.js +3 -3
- package/fesm/interceptors/clear-token.interceptor.js +8 -18
- package/fesm/interceptors/set-token.interceptor.js +8 -55
- package/fesm/interfaces/auth-email-provider.interface.js +1 -1
- package/fesm/modules/auth.module.js +63 -129
- package/fesm/services/auth-config.service.js +6 -29
- package/fesm/services/auth-datasource.provider.js +8 -20
- package/fesm/services/auth-email.service.js +72 -87
- package/fesm/services/authentication.service.js +211 -355
- package/fesm/services/branch.service.js +9 -5
- package/fesm/services/user-permission.service.js +44 -72
- package/fesm/services/user.service.js +18 -47
- package/fesm/strategies/jwt.strategy.js +44 -44
- package/interceptors/clear-token.interceptor.d.ts +0 -1
- package/interceptors/set-token.interceptor.d.ts +1 -2
- package/interfaces/authentication.interface.d.ts +0 -4
- package/modules/auth.module.d.ts +6 -2
- package/package.json +3 -3
- package/services/auth-config.service.d.ts +2 -7
- package/services/auth-datasource.provider.d.ts +2 -4
- package/services/auth-email.service.d.ts +7 -4
- package/services/authentication.service.d.ts +14 -8
- package/services/user-permission.service.d.ts +6 -8
- package/services/user.service.d.ts +1 -1
- package/strategies/jwt.strategy.d.ts +4 -1
- package/cjs/dtos/user-company-permission.dto.js +0 -110
- package/cjs/guards/auth-throttler.guard.js +0 -53
- package/dtos/user-company-permission.dto.d.ts +0 -10
- package/fesm/dtos/user-company-permission.dto.js +0 -98
- package/fesm/guards/auth-throttler.guard.js +0 -43
- package/guards/auth-throttler.guard.d.ts +0 -7
|
@@ -80,11 +80,11 @@ _ts_decorate([
|
|
|
80
80
|
], UserCompanyPermission.prototype, "user", void 0);
|
|
81
81
|
_ts_decorate([
|
|
82
82
|
(0, _typeorm.Column)({
|
|
83
|
-
type: '
|
|
84
|
-
|
|
83
|
+
type: 'varchar',
|
|
84
|
+
length: 50,
|
|
85
85
|
name: 'permission_type'
|
|
86
86
|
}),
|
|
87
|
-
_ts_metadata("design:type",
|
|
87
|
+
_ts_metadata("design:type", String)
|
|
88
88
|
], UserCompanyPermission.prototype, "permissionType", void 0);
|
|
89
89
|
_ts_decorate([
|
|
90
90
|
(0, _typeorm.Column)({
|
|
@@ -8,6 +8,7 @@ Object.defineProperty(exports, "ClearToken", {
|
|
|
8
8
|
return ClearToken;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
+
const _utils = require("@flusys/nestjs-shared/utils");
|
|
11
12
|
const _common = require("@nestjs/common");
|
|
12
13
|
const _rxjs = require("rxjs");
|
|
13
14
|
const _config = require("../config");
|
|
@@ -47,27 +48,16 @@ let ClearToken = class ClearToken {
|
|
|
47
48
|
const req = context.switchToHttp().getRequest();
|
|
48
49
|
const res = context.switchToHttp().getResponse();
|
|
49
50
|
return next.handle().pipe((0, _rxjs.map)((value)=>{
|
|
50
|
-
|
|
51
|
+
if ((0, _utils.isBrowserRequest)(req)) {
|
|
52
|
+
res.clearCookie(this.cookieName, {
|
|
53
|
+
httpOnly: true,
|
|
54
|
+
path: '/',
|
|
55
|
+
...(0, _utils.buildCookieOptions)(req)
|
|
56
|
+
});
|
|
57
|
+
}
|
|
51
58
|
return value;
|
|
52
59
|
}));
|
|
53
60
|
}
|
|
54
|
-
clearRefreshTokenCookie(req, res) {
|
|
55
|
-
const origin = req.headers.origin || '';
|
|
56
|
-
const hostname = req.hostname || '';
|
|
57
|
-
const isHttps = origin.startsWith('https://') || req.secure;
|
|
58
|
-
let cookieDomain = hostname;
|
|
59
|
-
const domainParts = hostname.split('.');
|
|
60
|
-
if (domainParts.length > 2) {
|
|
61
|
-
cookieDomain = '.' + domainParts.slice(-2).join('.');
|
|
62
|
-
}
|
|
63
|
-
res.clearCookie(this.cookieName, {
|
|
64
|
-
httpOnly: true,
|
|
65
|
-
secure: isHttps,
|
|
66
|
-
sameSite: isHttps ? 'strict' : 'lax',
|
|
67
|
-
domain: cookieDomain,
|
|
68
|
-
path: '/'
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
61
|
constructor(authConfig){
|
|
72
62
|
_define_property(this, "authConfig", void 0);
|
|
73
63
|
this.authConfig = authConfig;
|
|
@@ -8,6 +8,7 @@ Object.defineProperty(exports, "SetToken", {
|
|
|
8
8
|
return SetToken;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
+
const _utils = require("@flusys/nestjs-shared/utils");
|
|
11
12
|
const _common = require("@nestjs/common");
|
|
12
13
|
const _buffer = require("buffer");
|
|
13
14
|
const _rxjs = require("rxjs");
|
|
@@ -44,67 +45,23 @@ let SetToken = class SetToken {
|
|
|
44
45
|
get cookieName() {
|
|
45
46
|
return this.authConfig?.getRefreshTokenCookieName() ?? _config.DEFAULT_COOKIE_NAME;
|
|
46
47
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const match = expiry.match(/^(\d+)(s|m|h|d|w)$/);
|
|
50
|
-
if (!match) {
|
|
51
|
-
return 7 * 24 * 60 * 60 * 1000; // Default 7 days
|
|
52
|
-
}
|
|
53
|
-
const value = parseInt(match[1], 10);
|
|
54
|
-
const unit = match[2];
|
|
55
|
-
const multipliers = {
|
|
56
|
-
s: 1000,
|
|
57
|
-
m: 60 * 1000,
|
|
58
|
-
h: 60 * 60 * 1000,
|
|
59
|
-
d: 24 * 60 * 60 * 1000,
|
|
60
|
-
w: 7 * 24 * 60 * 60 * 1000
|
|
61
|
-
};
|
|
62
|
-
return value * (multipliers[unit] || multipliers['d']);
|
|
48
|
+
get maxAgeMs() {
|
|
49
|
+
return (0, _utils.parseDurationToMs)(this.authConfig?.getRefreshTokenExpiration() ?? '7d');
|
|
63
50
|
}
|
|
64
51
|
intercept(context, next) {
|
|
65
52
|
const req = context.switchToHttp().getRequest();
|
|
66
53
|
const res = context.switchToHttp().getResponse();
|
|
67
54
|
return next.handle().pipe((0, _rxjs.map)((value)=>{
|
|
68
|
-
if (!value
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const isBrowser = this.isBrowserRequest(req);
|
|
72
|
-
const tokenValue = value.refreshToken;
|
|
73
|
-
if (isBrowser) {
|
|
74
|
-
this.setRefreshTokenCookie(req, res, tokenValue);
|
|
55
|
+
if (!value?.refreshToken) return value;
|
|
56
|
+
if ((0, _utils.isBrowserRequest)(req)) {
|
|
57
|
+
this.setRefreshTokenCookie(req, res, value.refreshToken);
|
|
75
58
|
const { refreshToken, ...responseWithoutToken } = value;
|
|
76
59
|
return responseWithoutToken;
|
|
77
60
|
}
|
|
78
61
|
return value;
|
|
79
62
|
}), (0, _rxjs.catchError)((err)=>(0, _rxjs.throwError)(()=>err)));
|
|
80
63
|
}
|
|
81
|
-
isBrowserRequest(req) {
|
|
82
|
-
const clientType = req.headers['x-client-type'];
|
|
83
|
-
if (clientType) {
|
|
84
|
-
return clientType.toLowerCase() === 'browser' || clientType.toLowerCase() === 'web';
|
|
85
|
-
}
|
|
86
|
-
const accept = req.headers['accept'] || '';
|
|
87
|
-
if (accept.includes('text/html')) {
|
|
88
|
-
return true;
|
|
89
|
-
}
|
|
90
|
-
const userAgent = req.headers['user-agent'] || '';
|
|
91
|
-
const browserPatterns = /mozilla|chrome|safari|firefox|edge|opera|msie/i;
|
|
92
|
-
return browserPatterns.test(userAgent) && !userAgent.includes('Postman');
|
|
93
|
-
}
|
|
94
64
|
setRefreshTokenCookie(req, res, tokenValue) {
|
|
95
|
-
const hostname = req.hostname || '';
|
|
96
|
-
// Determine if we're in production - always use secure cookies in production
|
|
97
|
-
// This handles TLS-terminating proxies correctly (they set x-forwarded-proto)
|
|
98
|
-
const isProduction = process.env.NODE_ENV === 'production';
|
|
99
|
-
const forwardedProto = req.headers['x-forwarded-proto'];
|
|
100
|
-
const isHttps = isProduction || forwardedProto === 'https' || req.secure;
|
|
101
|
-
// Set cookie domain - only for subdomains with 3+ parts
|
|
102
|
-
// For security, limit to same domain unless explicitly configured
|
|
103
|
-
let cookieDomain;
|
|
104
|
-
const domainParts = hostname.split('.');
|
|
105
|
-
if (domainParts.length > 2 && !hostname.includes('localhost')) {
|
|
106
|
-
cookieDomain = '.' + domainParts.slice(-2).join('.');
|
|
107
|
-
}
|
|
108
65
|
const rawCookieString = `${this.cookieName}=${tokenValue}; HttpOnly`;
|
|
109
66
|
const estimatedBytes = _buffer.Buffer.byteLength(rawCookieString, 'utf8');
|
|
110
67
|
if (estimatedBytes > _config.MAX_COOKIE_BYTES) {
|
|
@@ -112,13 +69,9 @@ let SetToken = class SetToken {
|
|
|
112
69
|
}
|
|
113
70
|
res.cookie(this.cookieName, tokenValue, {
|
|
114
71
|
httpOnly: true,
|
|
115
|
-
secure: isHttps,
|
|
116
|
-
sameSite: isHttps ? 'strict' : 'lax',
|
|
117
|
-
...cookieDomain && {
|
|
118
|
-
domain: cookieDomain
|
|
119
|
-
},
|
|
120
72
|
path: '/',
|
|
121
|
-
maxAge: this.
|
|
73
|
+
maxAge: this.maxAgeMs,
|
|
74
|
+
...(0, _utils.buildCookieOptions)(req)
|
|
122
75
|
});
|
|
123
76
|
}
|
|
124
77
|
constructor(authConfig){
|
|
@@ -12,15 +12,15 @@ const _modules = require("@flusys/nestjs-shared/modules");
|
|
|
12
12
|
const _common = require("@nestjs/common");
|
|
13
13
|
const _jwt = require("@nestjs/jwt");
|
|
14
14
|
const _passport = require("@nestjs/passport");
|
|
15
|
-
const
|
|
16
|
-
const _authdatasourceprovider = require("../services/auth-datasource.provider");
|
|
15
|
+
const _guards = require("@flusys/nestjs-shared/guards");
|
|
17
16
|
const _authconstants = require("../config/auth.constants");
|
|
18
17
|
const _controllers = require("../controllers");
|
|
19
18
|
const _entities = require("../entities");
|
|
20
|
-
const _guards = require("@flusys/nestjs-shared/guards");
|
|
21
19
|
const _cleartokeninterceptor = require("../interceptors/clear-token.interceptor");
|
|
22
20
|
const _settokeninterceptor = require("../interceptors/set-token.interceptor");
|
|
23
21
|
const _services = require("../services");
|
|
22
|
+
const _authconfigservice = require("../services/auth-config.service");
|
|
23
|
+
const _authdatasourceprovider = require("../services/auth-datasource.provider");
|
|
24
24
|
const _jwtstrategy = require("../strategies/jwt.strategy");
|
|
25
25
|
function _ts_decorate(decorators, target, key, desc) {
|
|
26
26
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -30,82 +30,42 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
30
30
|
}
|
|
31
31
|
let AuthModule = class AuthModule {
|
|
32
32
|
static forRoot(options) {
|
|
33
|
-
|
|
33
|
+
const optionsProvider = {
|
|
34
|
+
provide: _authconstants.AUTH_MODULE_OPTIONS,
|
|
35
|
+
useValue: options
|
|
36
|
+
};
|
|
37
|
+
return this.buildModule(options, [
|
|
38
|
+
optionsProvider,
|
|
39
|
+
...options.providers ?? []
|
|
40
|
+
]);
|
|
34
41
|
}
|
|
35
|
-
static forRootAsync(
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
// Build imports
|
|
39
|
-
const imports = [
|
|
40
|
-
...externalImports,
|
|
41
|
-
_passport.PassportModule.register({
|
|
42
|
-
defaultStrategy: 'jwt'
|
|
43
|
-
}),
|
|
44
|
-
_jwt.JwtModule.register({}),
|
|
45
|
-
_modules.CacheModule,
|
|
46
|
-
_modules.UtilsModule
|
|
47
|
-
];
|
|
48
|
-
// Build controllers based on configuration
|
|
49
|
-
const controllers = [];
|
|
50
|
-
if (includeController) {
|
|
51
|
-
// Core authentication controller (always included)
|
|
52
|
-
controllers.push(_controllers.AuthenticationController);
|
|
53
|
-
// User controller (always included)
|
|
54
|
-
controllers.push(_controllers.UserController);
|
|
55
|
-
// Company feature controllers (conditional)
|
|
56
|
-
if (enableCompanyFeature) {
|
|
57
|
-
controllers.push(_controllers.CompanySelectionController, _controllers.CompanyController, _controllers.BranchController, _controllers.UserPermissionController);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
// Build providers
|
|
61
|
-
const providers = [
|
|
42
|
+
static forRootAsync(options) {
|
|
43
|
+
const asyncProviders = this.createAsyncProviders(options);
|
|
44
|
+
return this.buildModule(options, [
|
|
62
45
|
...asyncProviders,
|
|
63
|
-
...
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
_guards.JwtAuthGuard,
|
|
70
|
-
_services.AuthenticationService,
|
|
71
|
-
_services.AuthEmailService,
|
|
72
|
-
// Interceptors
|
|
73
|
-
_settokeninterceptor.SetToken,
|
|
74
|
-
_cleartokeninterceptor.ClearToken,
|
|
75
|
-
// Core services (always included)
|
|
76
|
-
_services.UserService
|
|
77
|
-
];
|
|
78
|
-
// Company feature services (conditional)
|
|
79
|
-
if (enableCompanyFeature) {
|
|
80
|
-
providers.push(_services.CompanySelectionSessionService, _services.CompanyService, _services.BranchService, _services.UserPermissionService);
|
|
81
|
-
}
|
|
82
|
-
// Build exports
|
|
83
|
-
const exports1 = [
|
|
84
|
-
_passport.PassportModule,
|
|
85
|
-
_authconstants.AUTH_MODULE_OPTIONS,
|
|
86
|
-
_authconfigservice.AuthConfigService,
|
|
87
|
-
_authdatasourceprovider.AuthDataSourceProvider,
|
|
88
|
-
_jwtstrategy.JwtStrategy,
|
|
89
|
-
_guards.JwtAuthGuard,
|
|
90
|
-
_services.AuthenticationService,
|
|
91
|
-
_services.AuthEmailService,
|
|
92
|
-
_services.UserService
|
|
93
|
-
];
|
|
94
|
-
if (enableCompanyFeature) {
|
|
95
|
-
exports1.push(_services.CompanySelectionSessionService, _services.CompanyService, _services.BranchService, _services.UserPermissionService);
|
|
96
|
-
}
|
|
46
|
+
...options.providers ?? []
|
|
47
|
+
], options.imports);
|
|
48
|
+
}
|
|
49
|
+
/** Build the dynamic module with shared logic */ static buildModule(options, providers, externalImports = []) {
|
|
50
|
+
const { global = false, includeController = true, bootstrapAppConfig } = options;
|
|
51
|
+
const enableCompanyFeature = bootstrapAppConfig?.enableCompanyFeature ?? false;
|
|
97
52
|
return {
|
|
98
53
|
module: AuthModule,
|
|
99
54
|
global,
|
|
100
|
-
imports
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
55
|
+
imports: [
|
|
56
|
+
...externalImports,
|
|
57
|
+
...this.buildImports()
|
|
58
|
+
],
|
|
59
|
+
controllers: this.buildControllers(includeController, enableCompanyFeature),
|
|
60
|
+
providers: [
|
|
61
|
+
...providers,
|
|
62
|
+
...this.buildProviders(enableCompanyFeature)
|
|
63
|
+
],
|
|
64
|
+
exports: this.buildExports(enableCompanyFeature)
|
|
104
65
|
};
|
|
105
66
|
}
|
|
106
|
-
static
|
|
107
|
-
|
|
108
|
-
const imports = [
|
|
67
|
+
/** Common module imports */ static buildImports() {
|
|
68
|
+
return [
|
|
109
69
|
_passport.PassportModule.register({
|
|
110
70
|
defaultStrategy: 'jwt'
|
|
111
71
|
}),
|
|
@@ -113,42 +73,36 @@ let AuthModule = class AuthModule {
|
|
|
113
73
|
_modules.CacheModule,
|
|
114
74
|
_modules.UtilsModule
|
|
115
75
|
];
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if (includeController)
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
controllers.push(_controllers.CompanySelectionController, _controllers.CompanyController, _controllers.BranchController, _controllers.UserPermissionController);
|
|
126
|
-
}
|
|
76
|
+
}
|
|
77
|
+
/** Build controllers based on feature flags */ static buildControllers(includeController, enableCompanyFeature) {
|
|
78
|
+
if (!includeController) return [];
|
|
79
|
+
const controllers = [
|
|
80
|
+
_controllers.AuthenticationController,
|
|
81
|
+
_controllers.UserController
|
|
82
|
+
];
|
|
83
|
+
if (enableCompanyFeature) {
|
|
84
|
+
controllers.push(_controllers.CompanySelectionController, _controllers.CompanyController, _controllers.BranchController, _controllers.UserPermissionController);
|
|
127
85
|
}
|
|
86
|
+
return controllers;
|
|
87
|
+
}
|
|
88
|
+
/** Core providers (without AUTH_MODULE_OPTIONS - that's added separately) */ static buildProviders(enableCompanyFeature) {
|
|
128
89
|
const providers = [
|
|
129
|
-
{
|
|
130
|
-
provide: _authconstants.AUTH_MODULE_OPTIONS,
|
|
131
|
-
useValue: options
|
|
132
|
-
},
|
|
133
|
-
...additionalProviders,
|
|
134
|
-
// Config & Infrastructure
|
|
135
90
|
_authconfigservice.AuthConfigService,
|
|
136
91
|
_authdatasourceprovider.AuthDataSourceProvider,
|
|
137
|
-
// Auth core
|
|
138
92
|
_jwtstrategy.JwtStrategy,
|
|
139
93
|
_guards.JwtAuthGuard,
|
|
140
94
|
_services.AuthenticationService,
|
|
141
95
|
_services.AuthEmailService,
|
|
142
|
-
// Interceptors
|
|
143
96
|
_settokeninterceptor.SetToken,
|
|
144
97
|
_cleartokeninterceptor.ClearToken,
|
|
145
|
-
// Core services (always included)
|
|
146
98
|
_services.UserService
|
|
147
99
|
];
|
|
148
|
-
// Company feature services (conditional)
|
|
149
100
|
if (enableCompanyFeature) {
|
|
150
101
|
providers.push(_services.CompanySelectionSessionService, _services.CompanyService, _services.BranchService, _services.UserPermissionService);
|
|
151
102
|
}
|
|
103
|
+
return providers;
|
|
104
|
+
}
|
|
105
|
+
/** Build module exports */ static buildExports(enableCompanyFeature) {
|
|
152
106
|
const exports1 = [
|
|
153
107
|
_passport.PassportModule,
|
|
154
108
|
_authconstants.AUTH_MODULE_OPTIONS,
|
|
@@ -163,16 +117,9 @@ let AuthModule = class AuthModule {
|
|
|
163
117
|
if (enableCompanyFeature) {
|
|
164
118
|
exports1.push(_services.CompanySelectionSessionService, _services.CompanyService, _services.BranchService, _services.UserPermissionService);
|
|
165
119
|
}
|
|
166
|
-
return
|
|
167
|
-
module: AuthModule,
|
|
168
|
-
global,
|
|
169
|
-
imports,
|
|
170
|
-
controllers,
|
|
171
|
-
providers,
|
|
172
|
-
exports: exports1
|
|
173
|
-
};
|
|
120
|
+
return exports1;
|
|
174
121
|
}
|
|
175
|
-
static createAsyncProviders(options) {
|
|
122
|
+
/** Create async providers for forRootAsync */ static createAsyncProviders(options) {
|
|
176
123
|
const staticOptions = {
|
|
177
124
|
global: options.global,
|
|
178
125
|
includeController: options.includeController,
|
|
@@ -182,13 +129,10 @@ let AuthModule = class AuthModule {
|
|
|
182
129
|
return [
|
|
183
130
|
{
|
|
184
131
|
provide: _authconstants.AUTH_MODULE_OPTIONS,
|
|
185
|
-
useFactory: async (...args)=>{
|
|
186
|
-
const config = await options.useFactory(...args);
|
|
187
|
-
return {
|
|
132
|
+
useFactory: async (...args)=>({
|
|
188
133
|
...staticOptions,
|
|
189
|
-
config
|
|
190
|
-
}
|
|
191
|
-
},
|
|
134
|
+
config: await options.useFactory(...args)
|
|
135
|
+
}),
|
|
192
136
|
inject: options.inject || []
|
|
193
137
|
}
|
|
194
138
|
];
|
|
@@ -201,13 +145,10 @@ let AuthModule = class AuthModule {
|
|
|
201
145
|
},
|
|
202
146
|
{
|
|
203
147
|
provide: _authconstants.AUTH_MODULE_OPTIONS,
|
|
204
|
-
useFactory: async (factory)=>{
|
|
205
|
-
const config = await factory.createAuthOptions();
|
|
206
|
-
return {
|
|
148
|
+
useFactory: async (factory)=>({
|
|
207
149
|
...staticOptions,
|
|
208
|
-
config
|
|
209
|
-
}
|
|
210
|
-
},
|
|
150
|
+
config: await factory.createAuthOptions()
|
|
151
|
+
}),
|
|
211
152
|
inject: [
|
|
212
153
|
options.useClass
|
|
213
154
|
]
|
|
@@ -218,13 +159,10 @@ let AuthModule = class AuthModule {
|
|
|
218
159
|
return [
|
|
219
160
|
{
|
|
220
161
|
provide: _authconstants.AUTH_MODULE_OPTIONS,
|
|
221
|
-
useFactory: async (factory)=>{
|
|
222
|
-
const config = await factory.createAuthOptions();
|
|
223
|
-
return {
|
|
162
|
+
useFactory: async (factory)=>({
|
|
224
163
|
...staticOptions,
|
|
225
|
-
config
|
|
226
|
-
}
|
|
227
|
-
},
|
|
164
|
+
config: await factory.createAuthOptions()
|
|
165
|
+
}),
|
|
228
166
|
inject: [
|
|
229
167
|
options.useExisting
|
|
230
168
|
]
|
|
@@ -238,18 +176,14 @@ let AuthModule = class AuthModule {
|
|
|
238
176
|
}
|
|
239
177
|
];
|
|
240
178
|
}
|
|
241
|
-
static getEntities(enableCompanyFeature = false) {
|
|
242
|
-
|
|
243
|
-
_entities.User
|
|
244
|
-
];
|
|
245
|
-
const companyEntities = enableCompanyFeature ? [
|
|
179
|
+
/** Get auth entities based on feature flags */ static getEntities(enableCompanyFeature = false) {
|
|
180
|
+
return enableCompanyFeature ? [
|
|
181
|
+
_entities.User,
|
|
246
182
|
_entities.Company,
|
|
247
183
|
_entities.CompanyBranch,
|
|
248
184
|
_entities.UserCompanyPermission
|
|
249
|
-
] : [
|
|
250
|
-
|
|
251
|
-
...coreEntities,
|
|
252
|
-
...companyEntities
|
|
185
|
+
] : [
|
|
186
|
+
_entities.User
|
|
253
187
|
];
|
|
254
188
|
}
|
|
255
189
|
};
|
|
@@ -9,8 +9,8 @@ Object.defineProperty(exports, "AuthConfigService", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
const _common = require("@nestjs/common");
|
|
12
|
-
const _authmoduleoptionsinterface = require("../interfaces/auth-module-options.interface");
|
|
13
12
|
const _authconstants = require("../config/auth.constants");
|
|
13
|
+
const _authmoduleoptionsinterface = require("../interfaces/auth-module-options.interface");
|
|
14
14
|
function _define_property(obj, key, value) {
|
|
15
15
|
if (key in obj) {
|
|
16
16
|
Object.defineProperty(obj, key, {
|
|
@@ -39,15 +39,15 @@ function _ts_param(paramIndex, decorator) {
|
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
41
|
let AuthConfigService = class AuthConfigService {
|
|
42
|
-
// Database Mode
|
|
43
|
-
|
|
42
|
+
// Database Mode (required by IModuleConfigService)
|
|
43
|
+
getDatabaseMode() {
|
|
44
44
|
return this.options.bootstrapAppConfig?.databaseMode ?? 'single';
|
|
45
45
|
}
|
|
46
|
-
|
|
46
|
+
isMultiTenant() {
|
|
47
47
|
return this.getDatabaseMode() === 'multi-tenant';
|
|
48
48
|
}
|
|
49
49
|
// Feature Flags
|
|
50
|
-
|
|
50
|
+
isCompanyFeatureEnabled() {
|
|
51
51
|
return this.options.bootstrapAppConfig?.enableCompanyFeature ?? false;
|
|
52
52
|
}
|
|
53
53
|
// JWT Configuration
|
|
@@ -64,16 +64,14 @@ let AuthConfigService = class AuthConfigService {
|
|
|
64
64
|
if (this.config.refreshTokenSecret) {
|
|
65
65
|
return this.config.refreshTokenSecret;
|
|
66
66
|
}
|
|
67
|
-
// Production: require separate refresh token secret for security
|
|
68
67
|
if (process.env.NODE_ENV === 'production') {
|
|
69
68
|
throw new _common.InternalServerErrorException('[AuthModule] REFRESH_TOKEN_SECRET is required in production - ' + 'using the same secret for access and refresh tokens is a security risk');
|
|
70
69
|
}
|
|
71
|
-
// Development: warn once about fallback to JWT secret
|
|
72
70
|
if (!this.refreshTokenSecretWarned) {
|
|
73
71
|
this.refreshTokenSecretWarned = true;
|
|
74
72
|
this.logger.warn('REFRESH_TOKEN_SECRET not configured - using JWT_SECRET as fallback. ' + 'For better security, configure a separate refresh token secret.');
|
|
75
73
|
}
|
|
76
|
-
return this.
|
|
74
|
+
return this.getJwtSecret();
|
|
77
75
|
}
|
|
78
76
|
/** Get refresh token expiration time */ getRefreshTokenExpiration() {
|
|
79
77
|
return this.config.refreshTokenExpiration ?? '7d';
|
|
@@ -85,27 +83,6 @@ let AuthConfigService = class AuthConfigService {
|
|
|
85
83
|
/** Get frontend URL for email links */ getFrontendUrl() {
|
|
86
84
|
return this.config.frontendUrl;
|
|
87
85
|
}
|
|
88
|
-
// Database Configuration
|
|
89
|
-
/** Get default database config */ getDefaultDatabaseConfig() {
|
|
90
|
-
return this.config.defaultDatabaseConfig ?? this.config.tenantDefaultDatabaseConfig;
|
|
91
|
-
}
|
|
92
|
-
/** Get tenant default database config (for multi-tenant) */ getTenantDefaultDatabaseConfig() {
|
|
93
|
-
return this.config.tenantDefaultDatabaseConfig;
|
|
94
|
-
}
|
|
95
|
-
/** Get registered tenants */ getTenants() {
|
|
96
|
-
return this.config.tenants ?? [];
|
|
97
|
-
}
|
|
98
|
-
// Raw Options
|
|
99
|
-
/** Get full module options */ getOptions() {
|
|
100
|
-
return {
|
|
101
|
-
...this.options
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
/** Get runtime config */ getConfig() {
|
|
105
|
-
return {
|
|
106
|
-
...this.config
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
86
|
constructor(injectedOptions){
|
|
110
87
|
_define_property(this, "logger", new _common.Logger(AuthConfigService.name));
|
|
111
88
|
_define_property(this, "options", void 0);
|
|
@@ -141,40 +141,28 @@ let AuthDataSourceProvider = class AuthDataSourceProvider extends _modules.Multi
|
|
|
141
141
|
};
|
|
142
142
|
}
|
|
143
143
|
// Feature Flags
|
|
144
|
-
/**
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
/** Get enable company feature for specific tenant. Falls back to global setting. */ getEnableCompanyFeatureForTenant(tenant) {
|
|
148
|
-
return tenant?.enableCompanyFeature ?? this.getEnableCompanyFeature();
|
|
149
|
-
}
|
|
150
|
-
/** Get enable company feature for current request context */ getEnableCompanyFeatureForCurrentTenant() {
|
|
151
|
-
return this.getEnableCompanyFeatureForTenant(this.getCurrentTenant() ?? undefined);
|
|
144
|
+
/** Check if company feature is enabled (tenant-specific or global fallback) */ isCompanyFeatureEnabled(tenant) {
|
|
145
|
+
const effectiveTenant = tenant ?? this.getCurrentTenant();
|
|
146
|
+
return effectiveTenant?.enableCompanyFeature ?? this.authOptions.bootstrapAppConfig?.enableCompanyFeature ?? false;
|
|
152
147
|
}
|
|
153
148
|
// Entity Management
|
|
154
|
-
/** Get auth entities based on company feature flag */ async getAuthEntities(
|
|
155
|
-
const enable = enableCompanyFeature ?? this.getEnableCompanyFeature();
|
|
149
|
+
/** Get auth entities based on company feature flag */ async getAuthEntities() {
|
|
156
150
|
const { Company, CompanyBranch, User, UserCompanyPermission, UserToken, PendingRegistration } = await Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../entities")));
|
|
157
151
|
const coreEntities = [
|
|
158
152
|
User,
|
|
159
153
|
UserToken,
|
|
160
154
|
PendingRegistration
|
|
161
155
|
];
|
|
162
|
-
|
|
156
|
+
return this.isCompanyFeatureEnabled() ? [
|
|
157
|
+
...coreEntities,
|
|
163
158
|
Company,
|
|
164
159
|
CompanyBranch,
|
|
165
160
|
UserCompanyPermission
|
|
166
|
-
] :
|
|
167
|
-
return [
|
|
168
|
-
...coreEntities,
|
|
169
|
-
...companyEntities
|
|
170
|
-
];
|
|
161
|
+
] : coreEntities;
|
|
171
162
|
}
|
|
172
163
|
// Overrides
|
|
173
164
|
/** Override to dynamically set entities based on tenant config */ async createDataSourceFromConfig(config) {
|
|
174
|
-
|
|
175
|
-
const enableCompanyFeature = this.getEnableCompanyFeatureForTenant(currentTenant ?? undefined);
|
|
176
|
-
const entities = await this.getAuthEntities(enableCompanyFeature);
|
|
177
|
-
return super.createDataSourceFromConfig(config, entities);
|
|
165
|
+
return super.createDataSourceFromConfig(config, await this.getAuthEntities());
|
|
178
166
|
}
|
|
179
167
|
constructor(authOptions, request){
|
|
180
168
|
super(AuthDataSourceProvider.buildParentOptions(authOptions), request), _define_property(this, "authOptions", void 0), _define_property(this, "logger", void 0), this.authOptions = authOptions, this.logger = new _common.Logger(AuthDataSourceProvider.name);
|