@ackplus/nest-auth 2.0.0-beta.2 → 2.0.0-beta.20
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/lib/admin-console/admin-console.module.js +1 -1
- package/dist/lib/admin-console/admin-console.module.js.map +1 -1
- package/dist/lib/admin-console/controllers/admin-auth.controller.d.ts +3 -3
- package/dist/lib/admin-console/controllers/admin-auth.controller.d.ts.map +1 -1
- package/dist/lib/admin-console/controllers/admin-auth.controller.js +11 -11
- package/dist/lib/admin-console/controllers/admin-auth.controller.js.map +1 -1
- package/dist/lib/admin-console/controllers/admin-users.controller.d.ts +13 -17
- package/dist/lib/admin-console/controllers/admin-users.controller.d.ts.map +1 -1
- package/dist/lib/admin-console/controllers/admin-users.controller.js +15 -14
- package/dist/lib/admin-console/controllers/admin-users.controller.js.map +1 -1
- package/dist/lib/admin-console/dto/admin-user.dto.d.ts +4 -2
- package/dist/lib/admin-console/dto/admin-user.dto.d.ts.map +1 -1
- package/dist/lib/admin-console/dto/admin-user.dto.js +16 -8
- package/dist/lib/admin-console/dto/admin-user.dto.js.map +1 -1
- package/dist/lib/admin-console/services/admin-auth.service.d.ts.map +1 -1
- package/dist/lib/admin-console/services/admin-auth.service.js +1 -3
- package/dist/lib/admin-console/services/admin-auth.service.js.map +1 -1
- package/dist/lib/admin-console/services/admin-user-management.service.d.ts +1 -1
- package/dist/lib/admin-console/services/admin-user-management.service.d.ts.map +1 -1
- package/dist/lib/admin-console/services/admin-user-management.service.js +1 -1
- package/dist/lib/admin-console/services/admin-user-management.service.js.map +1 -1
- package/dist/lib/admin-console/static/index.html +224 -224
- package/dist/lib/admin-console/static/nest-auth.json +93 -92
- package/dist/lib/auth/controllers/auth.controller.d.ts +3 -2
- package/dist/lib/auth/controllers/auth.controller.d.ts.map +1 -1
- package/dist/lib/auth/controllers/auth.controller.js +21 -1
- package/dist/lib/auth/controllers/auth.controller.js.map +1 -1
- package/dist/lib/auth/dto/responses/auth.response.dto.d.ts +3 -5
- package/dist/lib/auth/dto/responses/auth.response.dto.d.ts.map +1 -1
- package/dist/lib/auth/dto/responses/auth.response.dto.js +11 -27
- package/dist/lib/auth/dto/responses/auth.response.dto.js.map +1 -1
- package/dist/lib/auth/entities/otp.entity.d.ts +2 -1
- package/dist/lib/auth/entities/otp.entity.d.ts.map +1 -1
- package/dist/lib/auth/entities/otp.entity.js +13 -9
- package/dist/lib/auth/entities/otp.entity.js.map +1 -1
- package/dist/lib/auth/events/user-logged-in.event.d.ts +3 -1
- package/dist/lib/auth/events/user-logged-in.event.d.ts.map +1 -1
- package/dist/lib/auth/events/user-logged-in.event.js.map +1 -1
- package/dist/lib/auth/events/user-registered.event.d.ts +2 -1
- package/dist/lib/auth/events/user-registered.event.d.ts.map +1 -1
- package/dist/lib/auth/events/user-registered.event.js.map +1 -1
- package/dist/lib/auth/services/auth.service.d.ts +11 -5
- package/dist/lib/auth/services/auth.service.d.ts.map +1 -1
- package/dist/lib/auth/services/auth.service.js +202 -140
- package/dist/lib/auth/services/auth.service.js.map +1 -1
- package/dist/lib/auth/services/verification.service.d.ts.map +1 -1
- package/dist/lib/auth/services/verification.service.js +0 -4
- package/dist/lib/auth/services/verification.service.js.map +1 -1
- package/dist/lib/core/entities.d.ts +5 -3
- package/dist/lib/core/entities.d.ts.map +1 -1
- package/dist/lib/core/entities.js +5 -2
- package/dist/lib/core/entities.js.map +1 -1
- package/dist/lib/core/interfaces/auth-module-options.interface.d.ts +18 -3
- package/dist/lib/core/interfaces/auth-module-options.interface.d.ts.map +1 -1
- package/dist/lib/core/interfaces/token-payload.interface.d.ts +3 -1
- package/dist/lib/core/interfaces/token-payload.interface.d.ts.map +1 -1
- package/dist/lib/core/providers/jwt-auth.provider.d.ts +2 -1
- package/dist/lib/core/providers/jwt-auth.provider.d.ts.map +1 -1
- package/dist/lib/core/providers/passwordless-auth.provider.d.ts +2 -1
- package/dist/lib/core/providers/passwordless-auth.provider.d.ts.map +1 -1
- package/dist/lib/core/providers/passwordless-auth.provider.js +1 -0
- package/dist/lib/core/providers/passwordless-auth.provider.js.map +1 -1
- package/dist/lib/core/services/auth-config.service.d.ts.map +1 -1
- package/dist/lib/core/services/auth-config.service.js +6 -0
- package/dist/lib/core/services/auth-config.service.js.map +1 -1
- package/dist/lib/request-context/request-context.d.ts +1 -1
- package/dist/lib/request-context/request-context.d.ts.map +1 -1
- package/dist/lib/request-context/request-context.js +1 -1
- package/dist/lib/request-context/request-context.js.map +1 -1
- package/dist/lib/role/entities/role.entity.d.ts +3 -1
- package/dist/lib/role/entities/role.entity.d.ts.map +1 -1
- package/dist/lib/role/entities/role.entity.js +7 -1
- package/dist/lib/role/entities/role.entity.js.map +1 -1
- package/dist/lib/role/services/role.service.d.ts.map +1 -1
- package/dist/lib/role/services/role.service.js +13 -37
- package/dist/lib/role/services/role.service.js.map +1 -1
- package/dist/lib/role/utils/access-role-resolver.util.d.ts +20 -0
- package/dist/lib/role/utils/access-role-resolver.util.d.ts.map +1 -0
- package/dist/lib/role/utils/access-role-resolver.util.js +63 -0
- package/dist/lib/role/utils/access-role-resolver.util.js.map +1 -0
- package/dist/lib/session/services/session-manager.service.d.ts +5 -1
- package/dist/lib/session/services/session-manager.service.d.ts.map +1 -1
- package/dist/lib/session/services/session-manager.service.js +17 -5
- package/dist/lib/session/services/session-manager.service.js.map +1 -1
- package/dist/lib/tenant/entities/tenant.entity.d.ts +1 -1
- package/dist/lib/tenant/entities/tenant.entity.d.ts.map +1 -1
- package/dist/lib/tenant/entities/tenant.entity.js +1 -1
- package/dist/lib/tenant/entities/tenant.entity.js.map +1 -1
- package/dist/lib/tenant/index.d.ts +1 -1
- package/dist/lib/tenant/index.d.ts.map +1 -1
- package/dist/lib/tenant/index.js +1 -1
- package/dist/lib/tenant/index.js.map +1 -1
- package/dist/lib/tenant/services/tenant.service.d.ts +1 -0
- package/dist/lib/tenant/services/tenant.service.d.ts.map +1 -1
- package/dist/lib/tenant/services/tenant.service.js +5 -0
- package/dist/lib/tenant/services/tenant.service.js.map +1 -1
- package/dist/lib/tenant/tenant-context/services/base-tenant-context.service.d.ts +1 -1
- package/dist/lib/tenant/tenant-context/services/base-tenant-context.service.d.ts.map +1 -1
- package/dist/lib/tenant/tenant-context/services/disabled-tenant-context.service.d.ts +1 -1
- package/dist/lib/tenant/tenant-context/services/disabled-tenant-context.service.d.ts.map +1 -1
- package/dist/lib/tenant/tenant-context/tenant-context.interface.d.ts +1 -1
- package/dist/lib/tenant/tenant-context/tenant-context.interface.d.ts.map +1 -1
- package/dist/lib/user/entities/platform-access.entity.d.ts +16 -0
- package/dist/lib/user/entities/platform-access.entity.d.ts.map +1 -0
- package/dist/lib/user/entities/platform-access.entity.js +89 -0
- package/dist/lib/user/entities/platform-access.entity.js.map +1 -0
- package/dist/lib/{tenant → user}/entities/user-access.entity.d.ts +5 -2
- package/dist/lib/user/entities/user-access.entity.d.ts.map +1 -0
- package/dist/lib/{tenant → user}/entities/user-access.entity.js +29 -4
- package/dist/lib/user/entities/user-access.entity.js.map +1 -0
- package/dist/lib/user/entities/user.entity.d.ts +5 -7
- package/dist/lib/user/entities/user.entity.d.ts.map +1 -1
- package/dist/lib/user/entities/user.entity.js +48 -48
- package/dist/lib/user/entities/user.entity.js.map +1 -1
- package/dist/lib/user/services/user.service.d.ts +1 -2
- package/dist/lib/user/services/user.service.d.ts.map +1 -1
- package/dist/lib/user/services/user.service.js +16 -59
- package/dist/lib/user/services/user.service.js.map +1 -1
- package/dist/lib/user/user.module.d.ts.map +1 -1
- package/dist/lib/user/user.module.js +3 -2
- package/dist/lib/user/user.module.js.map +1 -1
- package/dist/lib/utils/has-token.d.ts +0 -1
- package/dist/lib/utils/has-token.d.ts.map +1 -1
- package/dist/lib/utils/has-token.js +1 -2
- package/dist/lib/utils/has-token.js.map +1 -1
- package/dist/lib/utils/index.d.ts +1 -0
- package/dist/lib/utils/index.d.ts.map +1 -1
- package/dist/lib/utils/index.js +1 -0
- package/dist/lib/utils/index.js.map +1 -1
- package/dist/lib/utils/tenant.d.ts +3 -0
- package/dist/lib/utils/tenant.d.ts.map +1 -0
- package/dist/lib/utils/tenant.js +21 -0
- package/dist/lib/utils/tenant.js.map +1 -0
- package/package.json +2 -2
- package/dist/lib/tenant/entities/user-access.entity.d.ts.map +0 -1
- package/dist/lib/tenant/entities/user-access.entity.js.map +0 -1
|
@@ -18,6 +18,7 @@ const common_2 = require("@nestjs/common");
|
|
|
18
18
|
const typeorm_1 = require("@nestjs/typeorm");
|
|
19
19
|
const typeorm_2 = require("typeorm");
|
|
20
20
|
const user_entity_1 = require("../../user/entities/user.entity");
|
|
21
|
+
const access_role_resolver_util_1 = require("../../role/utils/access-role-resolver.util");
|
|
21
22
|
const auth_constants_1 = require("../../auth.constants");
|
|
22
23
|
const mfa_service_1 = require("./mfa.service");
|
|
23
24
|
const jwt_service_1 = require("../../core/services/jwt.service");
|
|
@@ -43,6 +44,8 @@ const utils_1 = require("../../utils");
|
|
|
43
44
|
const otp_flow_service_1 = require("./otp-flow.service");
|
|
44
45
|
const passwordless_code_requested_event_1 = require("../events/passwordless-code-requested.event");
|
|
45
46
|
const lodash_1 = require("lodash");
|
|
47
|
+
const user_access_entity_1 = require("../../user/entities/user-access.entity");
|
|
48
|
+
const platform_access_entity_1 = require("../../user/entities/platform-access.entity");
|
|
46
49
|
let AuthService = class AuthService {
|
|
47
50
|
userRepository;
|
|
48
51
|
authProviderRegistry;
|
|
@@ -72,7 +75,7 @@ let AuthService = class AuthService {
|
|
|
72
75
|
this.tenantContext = tenantContext;
|
|
73
76
|
this.authConfig = this.authConfigService.getConfig();
|
|
74
77
|
}
|
|
75
|
-
|
|
78
|
+
getUserWithRoles(userId, relations = []) {
|
|
76
79
|
return this.userRepository.findOne({
|
|
77
80
|
where: { id: userId },
|
|
78
81
|
relations: [
|
|
@@ -82,23 +85,32 @@ let AuthService = class AuthService {
|
|
|
82
85
|
],
|
|
83
86
|
});
|
|
84
87
|
}
|
|
85
|
-
async
|
|
86
|
-
const user = await
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (
|
|
93
|
-
|
|
88
|
+
async getUserWithAccess(userId, tenantId, isPlatformAccess = false) {
|
|
89
|
+
const user = await this.userRepository.findOne({
|
|
90
|
+
where: {
|
|
91
|
+
id: userId,
|
|
92
|
+
...(tenantId ? { userAccesses: { tenantId } } : {}),
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
if (isPlatformAccess) {
|
|
96
|
+
const platformAccess = await platform_access_entity_1.NestAuthPlatformAccess.findOne({
|
|
97
|
+
where: { userId, isActive: true },
|
|
98
|
+
relations: ['roles', 'roles.rolePermissions', 'roles.rolePermissions.permission'],
|
|
99
|
+
});
|
|
100
|
+
return { user, platformAccess };
|
|
94
101
|
}
|
|
95
|
-
|
|
102
|
+
const userAccess = await user_access_entity_1.NestAuthUserAccess.findOne({
|
|
103
|
+
where: {
|
|
104
|
+
userId,
|
|
105
|
+
isActive: true,
|
|
106
|
+
tenantId: tenantId ? (0, typeorm_2.Equal)(tenantId) : (0, typeorm_2.IsNull)(),
|
|
107
|
+
},
|
|
108
|
+
relations: ['roles', 'roles.rolePermissions', 'roles.rolePermissions.permission'],
|
|
109
|
+
});
|
|
110
|
+
return { user, userAccess };
|
|
96
111
|
}
|
|
97
112
|
async signup(input) {
|
|
98
113
|
this.debugLogger.logFunctionEntry('signup', 'AuthService', { email: input.email, phone: input.phone, hasPassword: !!input.password });
|
|
99
|
-
const config = this.authConfigService.getConfig();
|
|
100
|
-
const tenantMode = config.tenant?.mode ?? nest_auth_contracts_1.TenantModeEnum.ISOLATED;
|
|
101
|
-
const tenetEnabled = config.tenant?.enabled ?? false;
|
|
102
114
|
try {
|
|
103
115
|
if (this.authConfig.registration?.enabled === false) {
|
|
104
116
|
throw new common_1.ForbiddenException({
|
|
@@ -140,11 +152,9 @@ let AuthService = class AuthService {
|
|
|
140
152
|
code: auth_constants_1.ERROR_CODES.PROVIDER_NOT_FOUND,
|
|
141
153
|
});
|
|
142
154
|
}
|
|
143
|
-
console.log('providersToLink', providersToLink);
|
|
144
155
|
for (const item of providersToLink) {
|
|
145
|
-
|
|
146
|
-
const identity = await item.provider.findIdentity(item.providerId,
|
|
147
|
-
console.log('identity', identity);
|
|
156
|
+
const requiredTenantId = this.tenantService.checkRequiredTenant(tenantId);
|
|
157
|
+
const identity = await item.provider.findIdentity(item.providerId, requiredTenantId ? tenantId : undefined);
|
|
148
158
|
if (identity) {
|
|
149
159
|
this.debugLogger.warn('Identity already exists', 'AuthService', { email: !!email, phone: !!phone, tenantId });
|
|
150
160
|
if (item.type === 'email') {
|
|
@@ -162,10 +172,11 @@ let AuthService = class AuthService {
|
|
|
162
172
|
}
|
|
163
173
|
}
|
|
164
174
|
this.debugLogger.debug('Creating new user via UserService', 'AuthService', { email: !!email, phone: !!phone, tenantId });
|
|
165
|
-
|
|
175
|
+
const user = await this.userService.createUser({
|
|
166
176
|
email,
|
|
167
177
|
phone,
|
|
168
|
-
|
|
178
|
+
emailVerifiedAt: null,
|
|
179
|
+
phoneVerifiedAt: null,
|
|
169
180
|
password
|
|
170
181
|
}, tenantId, input);
|
|
171
182
|
this.debugLogger.info('User created successfully', 'AuthService', { userId: user.id, tenantId });
|
|
@@ -176,32 +187,19 @@ let AuthService = class AuthService {
|
|
|
176
187
|
if (this.authConfig.registrationHooks?.onSignup) {
|
|
177
188
|
this.debugLogger.debug('Applying registrationHooks.onSignup hook', 'AuthService', { userId: user.id });
|
|
178
189
|
const request = request_context_1.RequestContext.currentRequest();
|
|
179
|
-
|
|
180
|
-
if (modifiedUser) {
|
|
181
|
-
user = modifiedUser;
|
|
182
|
-
}
|
|
190
|
+
await this.authConfig.registrationHooks.onSignup(user, input, { request });
|
|
183
191
|
}
|
|
184
|
-
user = await this.
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
const isExistsGuard = userRoles?.some(r => r.guard === input.guard);
|
|
188
|
-
if (!isExistsGuard) {
|
|
189
|
-
await this.userService.deleteUser(user.id);
|
|
190
|
-
throw new common_1.UnauthorizedException({
|
|
191
|
-
message: 'Not allowed to signup with this guard',
|
|
192
|
-
code: auth_constants_1.ERROR_CODES.FORBIDDEN,
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
this.debugLogger.debug('Creating session for new user', 'AuthService', { userId: user.id });
|
|
197
|
-
const session = await this.sessionManager.createSessionFromUser(user, { tenantId });
|
|
192
|
+
const { user: authUser, userAccess } = await this.getUserWithAccess(user.id, tenantId);
|
|
193
|
+
this.debugLogger.debug('Creating session for new user', 'AuthService', { userId: authUser.id });
|
|
194
|
+
const session = await this.sessionManager.createSessionFromUser(authUser, userAccess, { tenantId });
|
|
198
195
|
const tokens = await this.generateTokensFromSession(session);
|
|
199
|
-
const isRequiresMfa = await this.mfaService.isRequiresMfa(
|
|
200
|
-
this.debugLogger.debug('Signup tokens generated', 'AuthService', { userId:
|
|
201
|
-
this.debugLogger.debug('Emitting user registration event', 'AuthService', { userId:
|
|
196
|
+
const isRequiresMfa = await this.mfaService.isRequiresMfa(authUser.id);
|
|
197
|
+
this.debugLogger.debug('Signup tokens generated', 'AuthService', { userId: authUser.id, isRequiresMfa });
|
|
198
|
+
this.debugLogger.debug('Emitting user registration event', 'AuthService', { userId: authUser.id });
|
|
202
199
|
const provider = providersToLink[0]?.provider;
|
|
203
200
|
await this.eventEmitter.emitAsync(auth_constants_1.NestAuthEvents.REGISTERED, new user_registered_event_1.UserRegisteredEvent({
|
|
204
|
-
user,
|
|
201
|
+
user: authUser,
|
|
202
|
+
userAccess,
|
|
205
203
|
tenantId,
|
|
206
204
|
input,
|
|
207
205
|
provider,
|
|
@@ -219,7 +217,7 @@ let AuthService = class AuthService {
|
|
|
219
217
|
isRequiresMfa: false,
|
|
220
218
|
};
|
|
221
219
|
}
|
|
222
|
-
return this.generateAuthResponse(
|
|
220
|
+
return this.generateAuthResponse(authUser, session, tokens, isRequiresMfa, undefined);
|
|
223
221
|
}
|
|
224
222
|
catch (error) {
|
|
225
223
|
this.debugLogger.logError(error, 'signup', { email: input.email, phone: input.phone });
|
|
@@ -229,10 +227,18 @@ let AuthService = class AuthService {
|
|
|
229
227
|
}
|
|
230
228
|
async login(input) {
|
|
231
229
|
let { credentials, providerName, createUserIfNotExists = false, guard, tenantId } = input;
|
|
230
|
+
const isPlatformAccess = await access_role_resolver_util_1.AccessRoleResolver.isPlatformAccess();
|
|
232
231
|
this.debugLogger.logFunctionEntry('login', 'AuthService', { providerName, createUserIfNotExists, guard, tenantId });
|
|
233
232
|
try {
|
|
234
|
-
|
|
235
|
-
|
|
233
|
+
let resolvedTenantId = null;
|
|
234
|
+
if (isPlatformAccess) {
|
|
235
|
+
resolvedTenantId = null;
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
await this.tenantService.resolveTenantId(tenantId);
|
|
239
|
+
resolvedTenantId = tenantId;
|
|
240
|
+
}
|
|
241
|
+
this.debugLogger.logAuthOperation('login', providerName, undefined, { tenantId, resolvedTenantId, createUserIfNotExists, isPlatformAccess });
|
|
236
242
|
const provider = this.authProviderRegistry.getProvider(providerName);
|
|
237
243
|
if (!provider) {
|
|
238
244
|
throw new common_1.UnauthorizedException({
|
|
@@ -247,8 +253,8 @@ let AuthService = class AuthService {
|
|
|
247
253
|
code: auth_constants_1.ERROR_CODES.MISSING_REQUIRED_FIELDS,
|
|
248
254
|
});
|
|
249
255
|
}
|
|
250
|
-
const authProviderUser = await provider.validate(credentials,
|
|
251
|
-
const identity = await provider.findIdentity(authProviderUser.userId,
|
|
256
|
+
const authProviderUser = await provider.validate(credentials, resolvedTenantId);
|
|
257
|
+
const identity = await provider.findIdentity(authProviderUser.userId, resolvedTenantId);
|
|
252
258
|
let user = identity?.user || null;
|
|
253
259
|
if (!user) {
|
|
254
260
|
if (!createUserIfNotExists) {
|
|
@@ -257,7 +263,7 @@ let AuthService = class AuthService {
|
|
|
257
263
|
code: auth_constants_1.ERROR_CODES.INVALID_CREDENTIALS,
|
|
258
264
|
});
|
|
259
265
|
}
|
|
260
|
-
user = await this.handleSocialLogin(provider, authProviderUser,
|
|
266
|
+
user = await this.handleSocialLogin(provider, authProviderUser, resolvedTenantId);
|
|
261
267
|
}
|
|
262
268
|
if (user.isActive === false) {
|
|
263
269
|
throw new common_1.UnauthorizedException({
|
|
@@ -265,22 +271,38 @@ let AuthService = class AuthService {
|
|
|
265
271
|
code: auth_constants_1.ERROR_CODES.ACCOUNT_INACTIVE,
|
|
266
272
|
});
|
|
267
273
|
}
|
|
268
|
-
user = await this.
|
|
274
|
+
const { user: authUser, userAccess, platformAccess } = await this.getUserWithAccess(user.id, resolvedTenantId, isPlatformAccess);
|
|
269
275
|
if (this.authConfig.loginHooks?.onLogin) {
|
|
270
|
-
this.debugLogger.debug('Applying loginHooks.onLogin hook', 'AuthService', { userId:
|
|
276
|
+
this.debugLogger.debug('Applying loginHooks.onLogin hook', 'AuthService', { userId: authUser.id });
|
|
271
277
|
const request = request_context_1.RequestContext.currentRequest();
|
|
272
|
-
await this.authConfig.loginHooks.onLogin(
|
|
278
|
+
await this.authConfig.loginHooks.onLogin(authUser, input, { userAccess, platformAccess, request, provider });
|
|
279
|
+
}
|
|
280
|
+
if (isPlatformAccess) {
|
|
281
|
+
if (authUser && !platformAccess) {
|
|
282
|
+
throw new common_1.ForbiddenException({
|
|
283
|
+
message: 'Only platform admins can login',
|
|
284
|
+
code: auth_constants_1.ERROR_CODES.ACCESS_DENIED,
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
await this.ensureTenantAccess(authUser, resolvedTenantId, createUserIfNotExists);
|
|
273
290
|
}
|
|
274
|
-
await this.ensureTenantAccess(user, tenantId, createUserIfNotExists);
|
|
275
291
|
let isRequiresMfa = false;
|
|
276
292
|
let isTrusted = false;
|
|
277
293
|
if (!provider.skipMfa) {
|
|
278
|
-
isRequiresMfa = await this.mfaService.isRequiresMfa(
|
|
294
|
+
isRequiresMfa = await this.mfaService.isRequiresMfa(authUser.id);
|
|
279
295
|
}
|
|
280
296
|
user.isMfaEnabled = isRequiresMfa;
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
297
|
+
if (guard && (platformAccess || userAccess)) {
|
|
298
|
+
let guardRoles = [];
|
|
299
|
+
if (isPlatformAccess) {
|
|
300
|
+
guardRoles = platformAccess?.roles ?? [];
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
guardRoles = userAccess?.roles ?? [];
|
|
304
|
+
}
|
|
305
|
+
const isExistsGuard = guardRoles.some(r => r.guard === guard);
|
|
284
306
|
if (!isExistsGuard) {
|
|
285
307
|
throw new common_1.UnauthorizedException({
|
|
286
308
|
message: 'Invalid credentials',
|
|
@@ -288,7 +310,11 @@ let AuthService = class AuthService {
|
|
|
288
310
|
});
|
|
289
311
|
}
|
|
290
312
|
}
|
|
291
|
-
let session = await this.sessionManager.createSessionFromUser(
|
|
313
|
+
let session = await this.sessionManager.createSessionFromUser(authUser, userAccess, {
|
|
314
|
+
tenantId: resolvedTenantId,
|
|
315
|
+
platformAccess: platformAccess,
|
|
316
|
+
isPlatformAccess: isPlatformAccess ?? false
|
|
317
|
+
});
|
|
292
318
|
if (isRequiresMfa) {
|
|
293
319
|
isTrusted = await this.checkTrustedDevice(user);
|
|
294
320
|
if (isTrusted) {
|
|
@@ -300,7 +326,9 @@ let AuthService = class AuthService {
|
|
|
300
326
|
}
|
|
301
327
|
const tokens = await this.generateTokensFromSession(session);
|
|
302
328
|
await this.eventEmitter.emitAsync(auth_constants_1.NestAuthEvents.LOGGED_IN, new user_logged_in_event_1.UserLoggedInEvent({
|
|
303
|
-
user,
|
|
329
|
+
user: authUser,
|
|
330
|
+
userAccess,
|
|
331
|
+
platformAccess,
|
|
304
332
|
tenantId,
|
|
305
333
|
input,
|
|
306
334
|
provider,
|
|
@@ -308,7 +336,7 @@ let AuthService = class AuthService {
|
|
|
308
336
|
tokens,
|
|
309
337
|
isRequiresMfa
|
|
310
338
|
}));
|
|
311
|
-
return this.generateAuthResponse(
|
|
339
|
+
return this.generateAuthResponse(authUser, session, tokens, isRequiresMfa);
|
|
312
340
|
}
|
|
313
341
|
catch (error) {
|
|
314
342
|
this.debugLogger.logError(error, 'login', { providerName, createUserIfNotExists });
|
|
@@ -355,7 +383,7 @@ let AuthService = class AuthService {
|
|
|
355
383
|
code: auth_constants_1.ERROR_CODES.REGISTRATION_DISABLED,
|
|
356
384
|
});
|
|
357
385
|
}
|
|
358
|
-
return this.userService.createUser({ email: emailNorm
|
|
386
|
+
return this.userService.createUser({ email: emailNorm }, tenantId ?? undefined, { source: 'passwordless', channel: 'email' });
|
|
359
387
|
}
|
|
360
388
|
else {
|
|
361
389
|
const phoneNorm = (0, utils_1.normalizedPhone)(raw);
|
|
@@ -386,7 +414,7 @@ let AuthService = class AuthService {
|
|
|
386
414
|
code: auth_constants_1.ERROR_CODES.REGISTRATION_DISABLED,
|
|
387
415
|
});
|
|
388
416
|
}
|
|
389
|
-
return this.userService.createUser({ phone: phoneNorm
|
|
417
|
+
return this.userService.createUser({ phone: phoneNorm }, tenantId ?? undefined, { source: 'passwordless', channel: 'sms' });
|
|
390
418
|
}
|
|
391
419
|
}
|
|
392
420
|
async passwordlessSend(input) {
|
|
@@ -427,9 +455,9 @@ let AuthService = class AuthService {
|
|
|
427
455
|
async verify2fa(input) {
|
|
428
456
|
this.debugLogger.logFunctionEntry('verify2fa', 'AuthService', { method: input.method });
|
|
429
457
|
try {
|
|
458
|
+
let user = await request_context_1.RequestContext.currentUser();
|
|
430
459
|
const session = request_context_1.RequestContext.currentSession();
|
|
431
460
|
if (!session) {
|
|
432
|
-
this.debugLogger.error('Session not found for 2FA verification', 'AuthService');
|
|
433
461
|
throw new common_1.UnauthorizedException({
|
|
434
462
|
message: 'Session not found',
|
|
435
463
|
code: auth_constants_1.ERROR_CODES.SESSION_NOT_FOUND,
|
|
@@ -438,13 +466,11 @@ let AuthService = class AuthService {
|
|
|
438
466
|
this.debugLogger.debug('Verifying MFA code', 'AuthService', { userId: session.userId, method: input.method });
|
|
439
467
|
const isValid = await this.mfaService.verifyMfa(session.userId, input.otp, input.method);
|
|
440
468
|
if (!isValid) {
|
|
441
|
-
this.debugLogger.warn('Invalid MFA code provided', 'AuthService', { userId: session.userId, method: input.method });
|
|
442
469
|
throw new common_1.UnauthorizedException({
|
|
443
470
|
message: 'Invalid MFA code',
|
|
444
471
|
code: auth_constants_1.ERROR_CODES.MFA_CODE_INVALID,
|
|
445
472
|
});
|
|
446
473
|
}
|
|
447
|
-
this.debugLogger.debug('Updating session with MFA verification', 'AuthService', { sessionId: session.id });
|
|
448
474
|
const payload = await this.sessionManager.updateSession(session.id, {
|
|
449
475
|
data: {
|
|
450
476
|
...session.data,
|
|
@@ -461,10 +487,12 @@ let AuthService = class AuthService {
|
|
|
461
487
|
trustToken = await this.mfaService.createTrustedDevice(session.userId, userAgent, ip);
|
|
462
488
|
}
|
|
463
489
|
}
|
|
464
|
-
|
|
490
|
+
if (!user) {
|
|
491
|
+
return null;
|
|
492
|
+
}
|
|
465
493
|
this.debugLogger.debug('Emitting 2FA verified event', 'AuthService', { userId: user.id });
|
|
466
494
|
await this.eventEmitter.emitAsync(auth_constants_1.NestAuthEvents.TWO_FACTOR_VERIFIED, new user_2fa_verified_event_1.User2faVerifiedEvent({
|
|
467
|
-
user
|
|
495
|
+
user,
|
|
468
496
|
tenantId: payload.data?.tenantId ?? user?.tenantId,
|
|
469
497
|
input,
|
|
470
498
|
session: payload,
|
|
@@ -488,16 +516,7 @@ let AuthService = class AuthService {
|
|
|
488
516
|
});
|
|
489
517
|
}
|
|
490
518
|
const resolvedTenantId = await this.tenantService.resolveTenantId(tenantId || null);
|
|
491
|
-
const user = await this.
|
|
492
|
-
where: { id: session.userId },
|
|
493
|
-
relations: [
|
|
494
|
-
'userAccesses',
|
|
495
|
-
'userAccesses.tenant',
|
|
496
|
-
'userAccesses.roles',
|
|
497
|
-
'userAccesses.roles.rolePermissions',
|
|
498
|
-
'userAccesses.roles.rolePermissions.permission',
|
|
499
|
-
],
|
|
500
|
-
});
|
|
519
|
+
const { user, userAccess } = await this.getUserWithAccess(session.userId, resolvedTenantId);
|
|
501
520
|
if (!user) {
|
|
502
521
|
throw new common_1.UnauthorizedException({
|
|
503
522
|
message: 'User not found',
|
|
@@ -505,13 +524,12 @@ let AuthService = class AuthService {
|
|
|
505
524
|
});
|
|
506
525
|
}
|
|
507
526
|
await this.ensureTenantAccess(user, resolvedTenantId, false);
|
|
508
|
-
const rolesWithPermissions =
|
|
527
|
+
const rolesWithPermissions = userAccess?.roles ?? [];
|
|
509
528
|
const permissions = (0, lodash_1.chain)(rolesWithPermissions)
|
|
510
529
|
.map((role) => (0, role_mapper_util_1.getRolePermissionNames)(role))
|
|
511
530
|
.flatten()
|
|
512
531
|
.uniq()
|
|
513
532
|
.value();
|
|
514
|
-
;
|
|
515
533
|
const roles = rolesWithPermissions?.map((role) => (0, role_mapper_util_1.mapRoleToSessionSnapshot)(role));
|
|
516
534
|
const updatedSession = await this.sessionManager.updateSession(session.id, {
|
|
517
535
|
data: {
|
|
@@ -525,6 +543,36 @@ let AuthService = class AuthService {
|
|
|
525
543
|
const tokens = await this.generateTokensFromSession(updatedSession);
|
|
526
544
|
return this.generateAuthResponse(user, updatedSession, tokens, false);
|
|
527
545
|
}
|
|
546
|
+
async getSessionUserData() {
|
|
547
|
+
const session = request_context_1.RequestContext.currentSession();
|
|
548
|
+
const tenantId = request_context_1.RequestContext.currentTenantId();
|
|
549
|
+
const isPlatformAccess = await access_role_resolver_util_1.AccessRoleResolver.isPlatformAccess();
|
|
550
|
+
const { user, userAccess, platformAccess } = await this.getUserWithAccess(session.userId, tenantId, isPlatformAccess);
|
|
551
|
+
let rolesWithPermissions = [];
|
|
552
|
+
if (isPlatformAccess) {
|
|
553
|
+
rolesWithPermissions = platformAccess?.roles ?? [];
|
|
554
|
+
}
|
|
555
|
+
else {
|
|
556
|
+
rolesWithPermissions = userAccess?.roles ?? [];
|
|
557
|
+
}
|
|
558
|
+
const permissions = (0, lodash_1.chain)(rolesWithPermissions)
|
|
559
|
+
.map((role) => (0, role_mapper_util_1.getRolePermissionNames)(role))
|
|
560
|
+
.flatten()
|
|
561
|
+
.uniq()
|
|
562
|
+
.value();
|
|
563
|
+
const userRoles = rolesWithPermissions.map((role) => (0, lodash_1.pick)(role, ['id', 'name', 'guard']));
|
|
564
|
+
const config = this.authConfigService.getConfig();
|
|
565
|
+
let serializedUser = {};
|
|
566
|
+
if (config.user?.getSessionUserData) {
|
|
567
|
+
serializedUser = await config.user.getSessionUserData(user);
|
|
568
|
+
}
|
|
569
|
+
return {
|
|
570
|
+
...(0, lodash_1.pick)(user, ['id', 'email', 'phone', 'emailVerifiedAt', 'phoneVerifiedAt', 'isMfaEnabled', 'metadata']),
|
|
571
|
+
...(serializedUser || {}),
|
|
572
|
+
roles: userRoles,
|
|
573
|
+
permissions,
|
|
574
|
+
};
|
|
575
|
+
}
|
|
528
576
|
async send2faCode(userId, method) {
|
|
529
577
|
const user = await this.userRepository.findOne({ where: { id: userId } });
|
|
530
578
|
if (!user) {
|
|
@@ -548,7 +596,7 @@ let AuthService = class AuthService {
|
|
|
548
596
|
try {
|
|
549
597
|
user = await this.userService.createUser({
|
|
550
598
|
[linkUserWith]: linkUserValue,
|
|
551
|
-
|
|
599
|
+
emailVerifiedAt: new Date(),
|
|
552
600
|
metadata: providerUser.metadata || {},
|
|
553
601
|
}, tenantId, {
|
|
554
602
|
[linkUserWith]: linkUserValue,
|
|
@@ -584,11 +632,11 @@ let AuthService = class AuthService {
|
|
|
584
632
|
code: auth_constants_1.ERROR_CODES.REFRESH_TOKEN_INVALID,
|
|
585
633
|
});
|
|
586
634
|
}
|
|
635
|
+
const isPlatformAccess = await access_role_resolver_util_1.AccessRoleResolver.isPlatformAccess();
|
|
587
636
|
this.debugLogger.debug('Verifying refresh token', 'AuthService');
|
|
588
637
|
let payload;
|
|
589
638
|
try {
|
|
590
639
|
payload = await this.jwtService.verifyToken(refreshToken);
|
|
591
|
-
console.log('payload', payload);
|
|
592
640
|
}
|
|
593
641
|
catch (error) {
|
|
594
642
|
this.debugLogger.warn('Invalid or expired refresh token', 'AuthService');
|
|
@@ -610,17 +658,80 @@ let AuthService = class AuthService {
|
|
|
610
658
|
code: auth_constants_1.ERROR_CODES.REFRESH_TOKEN_INVALID,
|
|
611
659
|
});
|
|
612
660
|
}
|
|
613
|
-
const
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
661
|
+
const { user, userAccess, platformAccess } = await this.getUserWithAccess(session.userId, session.data?.tenantId ?? null, isPlatformAccess);
|
|
662
|
+
if (!user) {
|
|
663
|
+
await this.sessionManager.revokeSession(session.id);
|
|
664
|
+
throw new common_1.UnauthorizedException({
|
|
665
|
+
message: 'User not found',
|
|
666
|
+
code: auth_constants_1.ERROR_CODES.USER_NOT_FOUND,
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
if (user.isActive === false) {
|
|
670
|
+
await this.sessionManager.revokeSession(session.id);
|
|
671
|
+
throw new common_1.UnauthorizedException({
|
|
672
|
+
message: 'Your account is suspended, please contact support',
|
|
673
|
+
code: auth_constants_1.ERROR_CODES.ACCOUNT_INACTIVE,
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
const tenantId = session.data?.tenantId ?? null;
|
|
677
|
+
if (!isPlatformAccess && !userAccess) {
|
|
678
|
+
try {
|
|
679
|
+
await this.ensureTenantAccess(user, tenantId, false);
|
|
680
|
+
}
|
|
681
|
+
catch (error) {
|
|
682
|
+
await this.sessionManager.revokeSession(session.id);
|
|
683
|
+
throw error;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
if (isPlatformAccess && !platformAccess) {
|
|
687
|
+
await this.sessionManager.revokeSession(session.id);
|
|
688
|
+
throw new common_1.UnauthorizedException({
|
|
689
|
+
message: 'You are not authorized to platform access',
|
|
690
|
+
code: auth_constants_1.ERROR_CODES.ACCESS_DENIED,
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
const isMfaVerified = !!session.data?.isMfaVerified;
|
|
694
|
+
let roles = [];
|
|
695
|
+
if (isPlatformAccess) {
|
|
696
|
+
roles = platformAccess?.roles ?? [];
|
|
697
|
+
}
|
|
698
|
+
else {
|
|
699
|
+
roles = userAccess?.roles ?? [];
|
|
700
|
+
}
|
|
701
|
+
const permissions = (0, lodash_1.chain)(roles)
|
|
702
|
+
.map((role) => (0, role_mapper_util_1.getRolePermissionNames)(role))
|
|
703
|
+
.flatten()
|
|
704
|
+
.uniq()
|
|
705
|
+
.value();
|
|
706
|
+
let freshSessionData = {
|
|
707
|
+
user,
|
|
708
|
+
isMfaVerified,
|
|
709
|
+
roles: roles.map((role) => (0, role_mapper_util_1.mapRoleToSessionSnapshot)(role)),
|
|
710
|
+
permissions,
|
|
711
|
+
tenantId,
|
|
712
|
+
isPlatformAccess: isPlatformAccess ?? false,
|
|
713
|
+
};
|
|
714
|
+
const customize = auth_config_service_1.AuthConfigService.getOptions().session?.customizeSessionData;
|
|
715
|
+
if (customize) {
|
|
716
|
+
freshSessionData = await customize(freshSessionData, user);
|
|
717
|
+
}
|
|
718
|
+
const refreshedSession = await this.sessionManager.refreshSession(session);
|
|
719
|
+
const updatedSession = await this.sessionManager.updateSession(refreshedSession.id, {
|
|
720
|
+
data: {
|
|
721
|
+
...(refreshedSession.data ?? {}),
|
|
722
|
+
...freshSessionData,
|
|
723
|
+
},
|
|
724
|
+
});
|
|
725
|
+
this.debugLogger.debug('Generating new tokens from refreshed session', 'AuthService', { sessionId: updatedSession.id });
|
|
726
|
+
const tokens = await this.generateTokensFromSession(updatedSession);
|
|
727
|
+
this.debugLogger.debug('Emitting refresh token event', 'AuthService', { sessionId: updatedSession.id });
|
|
617
728
|
await this.eventEmitter.emitAsync(auth_constants_1.NestAuthEvents.REFRESH_TOKEN, new user_refresh_token_event_1.UserRefreshTokenEvent({
|
|
618
729
|
oldRefreshToken: refreshToken,
|
|
619
|
-
session:
|
|
730
|
+
session: updatedSession,
|
|
620
731
|
tokens,
|
|
621
732
|
}));
|
|
622
|
-
this.debugLogger.logFunctionExit('refreshToken', 'AuthService', { sessionId:
|
|
623
|
-
return tokens;
|
|
733
|
+
this.debugLogger.logFunctionExit('refreshToken', 'AuthService', { sessionId: updatedSession.id });
|
|
734
|
+
return this.generateAuthResponse(user, updatedSession, tokens, false);
|
|
624
735
|
}
|
|
625
736
|
catch (error) {
|
|
626
737
|
this.debugLogger.logError(error, 'refreshToken', { hasRefreshToken: !!refreshToken });
|
|
@@ -630,10 +741,10 @@ let AuthService = class AuthService {
|
|
|
630
741
|
}
|
|
631
742
|
async logout(logoutType = 'user', reason) {
|
|
632
743
|
const session = request_context_1.RequestContext.currentSession();
|
|
633
|
-
const user = await
|
|
744
|
+
const user = await request_context_1.RequestContext.currentUser();
|
|
634
745
|
if (session) {
|
|
635
746
|
await this.eventEmitter.emitAsync(auth_constants_1.NestAuthEvents.LOGGED_OUT, new logged_out_event_1.LoggedOutEvent({
|
|
636
|
-
user
|
|
747
|
+
user,
|
|
637
748
|
tenantId: session?.data?.tenantId ?? user?.tenantId,
|
|
638
749
|
session,
|
|
639
750
|
logoutType,
|
|
@@ -658,11 +769,6 @@ let AuthService = class AuthService {
|
|
|
658
769
|
}
|
|
659
770
|
return true;
|
|
660
771
|
}
|
|
661
|
-
getTenantMode() {
|
|
662
|
-
const config = this.authConfigService.getConfig();
|
|
663
|
-
const mode = config.tenant?.mode;
|
|
664
|
-
return mode === nest_auth_contracts_1.TenantModeEnum.SHARED ? nest_auth_contracts_1.TenantModeEnum.SHARED : nest_auth_contracts_1.TenantModeEnum.ISOLATED;
|
|
665
|
-
}
|
|
666
772
|
async ensureTenantAccess(user, tenantId, allowAutoJoin = false) {
|
|
667
773
|
if (!tenantId || !this.tenantContext.isEnabled()) {
|
|
668
774
|
return;
|
|
@@ -686,7 +792,8 @@ let AuthService = class AuthService {
|
|
|
686
792
|
sessionId: session.id,
|
|
687
793
|
email: session.data?.user?.email,
|
|
688
794
|
phone: session.data?.user?.phone,
|
|
689
|
-
|
|
795
|
+
emailVerifiedAt: session.data?.user?.emailVerifiedAt,
|
|
796
|
+
phoneVerifiedAt: session.data?.user?.phoneVerifiedAt,
|
|
690
797
|
roles: session.data?.roles || [],
|
|
691
798
|
tenantId: session.data?.tenantId,
|
|
692
799
|
isMfaEnabled: session.data?.user?.isMfaEnabled,
|
|
@@ -715,10 +822,6 @@ let AuthService = class AuthService {
|
|
|
715
822
|
}
|
|
716
823
|
async generateAuthResponse(user, session, tokens, isRequiresMfa, trustToken) {
|
|
717
824
|
const config = this.authConfigService.getConfig();
|
|
718
|
-
let serializedUser = user;
|
|
719
|
-
if (config.user?.serialize) {
|
|
720
|
-
serializedUser = await config.user.serialize(user);
|
|
721
|
-
}
|
|
722
825
|
const activeTenantId = session?.data?.tenantId;
|
|
723
826
|
let tenants = await this.userService.getUserTenants(user.id);
|
|
724
827
|
if (!tenants.length && activeTenantId) {
|
|
@@ -727,51 +830,10 @@ let AuthService = class AuthService {
|
|
|
727
830
|
tenants = [fallbackTenant];
|
|
728
831
|
}
|
|
729
832
|
}
|
|
730
|
-
let userWithAccesses;
|
|
731
|
-
if (!user?.userAccesses?.length) {
|
|
732
|
-
userWithAccesses = await this.getUserWithRolesAndPermissions(user.id, [
|
|
733
|
-
'userAccesses',
|
|
734
|
-
'userAccesses.tenant',
|
|
735
|
-
]);
|
|
736
|
-
}
|
|
737
|
-
const userAccesses = (userWithAccesses.userAccesses ?? []).map((access) => ({
|
|
738
|
-
id: access.id,
|
|
739
|
-
userId: access.userId,
|
|
740
|
-
tenantId: access.tenantId,
|
|
741
|
-
tenant: access.tenant ? {
|
|
742
|
-
id: access.tenant.id,
|
|
743
|
-
name: access.tenant.name,
|
|
744
|
-
slug: access.tenant.slug,
|
|
745
|
-
description: access.tenant.description,
|
|
746
|
-
metadata: access.tenant.metadata,
|
|
747
|
-
isActive: access.tenant.isActive,
|
|
748
|
-
} : undefined,
|
|
749
|
-
isActive: access.isActive,
|
|
750
|
-
isDefault: access.isDefault,
|
|
751
|
-
status: access.status,
|
|
752
|
-
metadata: access.metadata ?? {},
|
|
753
|
-
createdAt: access.createdAt,
|
|
754
|
-
updatedAt: access.updatedAt,
|
|
755
|
-
}));
|
|
756
|
-
const rolesForResponse = session?.data?.roles || [];
|
|
757
|
-
const roleNames = rolesForResponse?.map(r => r.name) || [];
|
|
758
|
-
const permissions = session?.data?.permissions || [];
|
|
759
833
|
let response = {
|
|
760
834
|
accessToken: tokens.accessToken,
|
|
761
835
|
refreshToken: tokens.refreshToken,
|
|
762
836
|
isRequiresMfa: isRequiresMfa,
|
|
763
|
-
user: {
|
|
764
|
-
id: serializedUser.id,
|
|
765
|
-
email: serializedUser.email,
|
|
766
|
-
phone: serializedUser.phone,
|
|
767
|
-
isVerified: serializedUser.isVerified,
|
|
768
|
-
isMfaEnabled: serializedUser.isMfaEnabled,
|
|
769
|
-
roles: roleNames,
|
|
770
|
-
permissions,
|
|
771
|
-
metadata: serializedUser.metadata,
|
|
772
|
-
tenantId: activeTenantId,
|
|
773
|
-
userAccesses,
|
|
774
|
-
},
|
|
775
837
|
};
|
|
776
838
|
if (isRequiresMfa) {
|
|
777
839
|
const enabledMethods = await this.mfaService.getEnabledMethods(user.id);
|