@flusys/nestjs-auth 3.0.1 → 4.0.0-lts
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/cjs/config/index.js +1 -0
- package/cjs/config/message-keys.js +150 -0
- package/cjs/controllers/authentication.controller.js +9 -4
- package/cjs/controllers/branch.controller.js +1 -0
- package/cjs/controllers/company-selection.controller.js +3 -0
- package/cjs/controllers/company.controller.js +1 -0
- package/cjs/controllers/email-verification.controller.js +7 -2
- package/cjs/controllers/user-permission.controller.js +9 -1
- package/cjs/controllers/user.controller.js +16 -4
- package/cjs/dtos/authentication.dto.js +8 -0
- package/cjs/dtos/user-permission.dto.js +14 -0
- package/cjs/interceptors/set-token.interceptor.js +14 -5
- package/cjs/services/auth-config.service.js +9 -8
- package/cjs/services/auth-datasource.provider.js +7 -4
- package/cjs/services/auth-email.service.js +155 -45
- package/cjs/services/authentication.service.js +274 -60
- package/cjs/services/branch.service.js +1 -1
- package/cjs/services/company-selection-session.service.js +25 -6
- package/cjs/services/company.service.js +1 -1
- package/cjs/services/user-permission.service.js +52 -4
- package/cjs/services/user.service.js +122 -26
- package/cjs/strategies/jwt.strategy.js +18 -4
- package/config/index.d.ts +1 -0
- package/config/message-keys.d.ts +218 -0
- package/controllers/company-selection.controller.d.ts +2 -0
- package/controllers/user-permission.controller.d.ts +4 -0
- package/controllers/user.controller.d.ts +10 -0
- package/dtos/authentication.dto.d.ts +1 -0
- package/dtos/user-permission.dto.d.ts +2 -0
- package/entities/index.d.ts +10 -1
- package/fesm/config/index.js +1 -0
- package/fesm/config/message-keys.js +118 -0
- package/fesm/controllers/authentication.controller.js +9 -3
- package/fesm/controllers/branch.controller.js +1 -0
- package/fesm/controllers/company-selection.controller.js +3 -0
- package/fesm/controllers/company.controller.js +1 -0
- package/fesm/controllers/email-verification.controller.js +7 -2
- package/fesm/controllers/user-permission.controller.js +9 -1
- package/fesm/controllers/user.controller.js +16 -4
- package/fesm/dtos/authentication.dto.js +8 -0
- package/fesm/dtos/user-permission.dto.js +14 -0
- package/fesm/interceptors/set-token.interceptor.js +14 -4
- package/fesm/services/auth-config.service.js +10 -9
- package/fesm/services/auth-datasource.provider.js +7 -4
- package/fesm/services/auth-email.service.js +156 -45
- package/fesm/services/authentication.service.js +276 -61
- package/fesm/services/branch.service.js +1 -1
- package/fesm/services/company-selection-session.service.js +25 -6
- package/fesm/services/company.service.js +1 -1
- package/fesm/services/user-permission.service.js +52 -4
- package/fesm/services/user.service.js +122 -25
- package/fesm/strategies/jwt.strategy.js +18 -4
- package/interfaces/auth-module-options.interface.d.ts +2 -2
- package/interfaces/authentication.interface.d.ts +1 -0
- package/modules/auth.module.d.ts +2 -1
- package/package.json +6 -4
- package/services/auth-config.service.d.ts +0 -2
- package/services/auth-datasource.provider.d.ts +1 -3
- package/services/auth-email.service.d.ts +6 -3
- package/services/authentication.service.d.ts +1 -1
- package/services/branch.service.d.ts +2 -1
- package/services/user.service.d.ts +7 -7
|
@@ -9,16 +9,20 @@ Object.defineProperty(exports, "AuthenticationService", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
const _classes = require("@flusys/nestjs-shared/classes");
|
|
12
|
+
const _constants = require("@flusys/nestjs-shared/constants");
|
|
13
|
+
const _nestjsshared = require("@flusys/nestjs-shared");
|
|
14
|
+
const _config = require("../config");
|
|
12
15
|
const _interfaces = require("@flusys/nestjs-shared/interfaces");
|
|
13
16
|
const _enums = require("@flusys/nestjs-shared/enums");
|
|
14
17
|
const _utils = require("@flusys/nestjs-shared/utils");
|
|
15
18
|
const _common = require("@nestjs/common");
|
|
16
19
|
const _jwt = require("@nestjs/jwt");
|
|
17
20
|
const _bcrypt = /*#__PURE__*/ _interop_require_wildcard(require("bcrypt"));
|
|
18
|
-
const _config = require("../config");
|
|
19
21
|
const _userenricherinterface = require("../interfaces/user-enricher.interface");
|
|
22
|
+
const _authenticationdto = require("../dtos/authentication.dto");
|
|
20
23
|
const _companybranchentity = require("../entities/company-branch.entity");
|
|
21
24
|
const _companyentity = require("../entities/company.entity");
|
|
25
|
+
const _pendingregistrationentity = require("../entities/pending-registration.entity");
|
|
22
26
|
const _usercompanypermissionentity = require("../entities/user-company-permission.entity");
|
|
23
27
|
const _userentity = require("../entities/user.entity");
|
|
24
28
|
const _enums1 = require("../enums");
|
|
@@ -105,7 +109,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
105
109
|
}
|
|
106
110
|
async getUserRepository() {
|
|
107
111
|
if (!this.dataSourceProvider) {
|
|
108
|
-
throw new
|
|
112
|
+
throw new _common.InternalServerErrorException({
|
|
113
|
+
message: 'User repository not available',
|
|
114
|
+
messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE
|
|
115
|
+
});
|
|
109
116
|
}
|
|
110
117
|
return this.dataSourceProvider.getRepository(_userentity.User);
|
|
111
118
|
}
|
|
@@ -126,24 +133,29 @@ let AuthenticationService = class AuthenticationService {
|
|
|
126
133
|
return {
|
|
127
134
|
requiresEmailVerification: true,
|
|
128
135
|
email,
|
|
129
|
-
message: 'Please verify your email address to complete registration.'
|
|
136
|
+
message: 'Please verify your email address to complete registration.',
|
|
137
|
+
messageKey: _config.EMAIL_VERIFICATION_MESSAGES.VERIFICATION_SENT
|
|
130
138
|
};
|
|
131
139
|
}
|
|
132
140
|
const user = await this.validateUser(email, password);
|
|
133
141
|
if (!user.isActive) {
|
|
134
|
-
throw new _common.UnauthorizedException(
|
|
142
|
+
throw new _common.UnauthorizedException({
|
|
143
|
+
message: 'User account is deactivated',
|
|
144
|
+
messageKey: _config.AUTH_MESSAGES.LOGIN_ACCOUNT_DEACTIVATED
|
|
145
|
+
});
|
|
135
146
|
}
|
|
136
147
|
if (this.isEmailVerificationEnabled() && !user.emailVerified) {
|
|
137
148
|
return {
|
|
138
149
|
requiresEmailVerification: true,
|
|
139
150
|
email: user.email,
|
|
140
|
-
message: 'Please verify your email address before logging in.'
|
|
151
|
+
message: 'Please verify your email address before logging in.',
|
|
152
|
+
messageKey: _config.AUTH_MESSAGES.LOGIN_EMAIL_NOT_VERIFIED
|
|
141
153
|
};
|
|
142
154
|
}
|
|
143
155
|
if (!this.isCompanyFeatureEnabled()) {
|
|
144
156
|
return this.generateLoginResponse(user);
|
|
145
157
|
}
|
|
146
|
-
return this.handleCompanyBasedLogin(user);
|
|
158
|
+
return await this.handleCompanyBasedLogin(user);
|
|
147
159
|
}
|
|
148
160
|
async handleCompanyBasedLogin(user) {
|
|
149
161
|
const permissionRepository = await this.getPermissionRepository();
|
|
@@ -195,10 +207,13 @@ let AuthenticationService = class AuthenticationService {
|
|
|
195
207
|
}
|
|
196
208
|
});
|
|
197
209
|
if (existingUser && this.isCompanyFeatureEnabled()) {
|
|
198
|
-
return this.handleExistingUserCompanyRegistration(existingUser, dto);
|
|
210
|
+
return await this.handleExistingUserCompanyRegistration(existingUser, dto);
|
|
199
211
|
}
|
|
200
212
|
if (existingUser) {
|
|
201
|
-
throw new _common.BadRequestException(
|
|
213
|
+
throw new _common.BadRequestException({
|
|
214
|
+
message: 'Registration failed due to email exists. Please try again or contact support.',
|
|
215
|
+
messageKey: _config.AUTH_MESSAGES.REGISTER_EMAIL_EXISTS
|
|
216
|
+
});
|
|
202
217
|
}
|
|
203
218
|
if (this.isEmailVerificationEnabled() && verifyUrlBase) {
|
|
204
219
|
const companyData = this.isCompanyFeatureEnabled() ? {
|
|
@@ -219,19 +234,26 @@ let AuthenticationService = class AuthenticationService {
|
|
|
219
234
|
});
|
|
220
235
|
return {
|
|
221
236
|
requiresEmailVerification: true,
|
|
222
|
-
message: result.message
|
|
237
|
+
message: result.message,
|
|
238
|
+
messageKey: _config.EMAIL_VERIFICATION_MESSAGES.VERIFICATION_SENT
|
|
223
239
|
};
|
|
224
240
|
}
|
|
225
|
-
return this.createUserDirectly(dto);
|
|
241
|
+
return await this.createUserDirectly(dto);
|
|
226
242
|
}
|
|
227
243
|
async handleExistingUserCompanyRegistration(existingUser, dto) {
|
|
228
244
|
if (!dto.companySlug && !dto.newCompanyName) {
|
|
229
|
-
throw new _common.BadRequestException(
|
|
245
|
+
throw new _common.BadRequestException({
|
|
246
|
+
message: 'Email already registered. Please login or provide a company to join/create.',
|
|
247
|
+
messageKey: _config.AUTH_MESSAGES.REGISTER_EMAIL_EXISTS
|
|
248
|
+
});
|
|
230
249
|
}
|
|
231
250
|
const permissionRepository = await this.getPermissionRepository();
|
|
232
251
|
const companyRepository = await this.getCompanyRepository();
|
|
233
252
|
if (!permissionRepository || !companyRepository) {
|
|
234
|
-
throw new _common.BadRequestException(
|
|
253
|
+
throw new _common.BadRequestException({
|
|
254
|
+
message: 'Company feature repositories not available',
|
|
255
|
+
messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE
|
|
256
|
+
});
|
|
235
257
|
}
|
|
236
258
|
if (dto.companySlug) {
|
|
237
259
|
const company = await companyRepository.findOne({
|
|
@@ -249,15 +271,21 @@ let AuthenticationService = class AuthenticationService {
|
|
|
249
271
|
}
|
|
250
272
|
});
|
|
251
273
|
if (existingPermission) {
|
|
252
|
-
throw new _common.BadRequestException(
|
|
274
|
+
throw new _common.BadRequestException({
|
|
275
|
+
message: 'You are already assigned to this company. Please login.',
|
|
276
|
+
messageKey: _config.AUTH_MESSAGES.REGISTER_COMPANY_ALREADY_ASSIGNED
|
|
277
|
+
});
|
|
253
278
|
}
|
|
254
279
|
}
|
|
255
280
|
}
|
|
256
|
-
return this.processCompanyRegistration(existingUser, dto, true);
|
|
281
|
+
return await this.processCompanyRegistration(existingUser, dto, true);
|
|
257
282
|
}
|
|
258
283
|
async createUserDirectly(dto) {
|
|
259
284
|
if (!this.dataSourceProvider) {
|
|
260
|
-
throw new _common.BadRequestException(
|
|
285
|
+
throw new _common.BadRequestException({
|
|
286
|
+
message: 'Data source not available',
|
|
287
|
+
messageKey: _constants.SYSTEM_MESSAGES.DATASOURCE_NOT_AVAILABLE
|
|
288
|
+
});
|
|
261
289
|
}
|
|
262
290
|
const dataSource = await this.dataSourceProvider.getDataSource();
|
|
263
291
|
const queryRunner = dataSource.createQueryRunner();
|
|
@@ -282,21 +310,26 @@ let AuthenticationService = class AuthenticationService {
|
|
|
282
310
|
if (!this.isCompanyFeatureEnabled()) {
|
|
283
311
|
return this.generateRegistrationResponse(user);
|
|
284
312
|
}
|
|
285
|
-
return this.processCompanyRegistration(user, dto);
|
|
313
|
+
return await this.processCompanyRegistration(user, dto);
|
|
286
314
|
} catch (error) {
|
|
287
315
|
await queryRunner.rollbackTransaction();
|
|
288
316
|
if (error instanceof _common.BadRequestException) {
|
|
289
317
|
throw error;
|
|
290
318
|
}
|
|
291
|
-
|
|
292
|
-
|
|
319
|
+
throw new _common.BadRequestException({
|
|
320
|
+
message: 'Registration failed. Please try again.',
|
|
321
|
+
messageKey: _config.AUTH_MESSAGES.REGISTER_FAILED
|
|
322
|
+
});
|
|
293
323
|
} finally{
|
|
294
324
|
await queryRunner.release();
|
|
295
325
|
}
|
|
296
326
|
}
|
|
297
327
|
async createUserFromPendingRegistration(pending) {
|
|
298
328
|
if (!this.dataSourceProvider) {
|
|
299
|
-
throw new _common.BadRequestException(
|
|
329
|
+
throw new _common.BadRequestException({
|
|
330
|
+
message: 'Data source not available',
|
|
331
|
+
messageKey: _constants.SYSTEM_MESSAGES.DATASOURCE_NOT_AVAILABLE
|
|
332
|
+
});
|
|
300
333
|
}
|
|
301
334
|
const dataSource = await this.dataSourceProvider.getDataSource();
|
|
302
335
|
const queryRunner = dataSource.createQueryRunner();
|
|
@@ -309,7 +342,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
309
342
|
}
|
|
310
343
|
});
|
|
311
344
|
if (existingUser) {
|
|
312
|
-
throw new _common.BadRequestException(
|
|
345
|
+
throw new _common.BadRequestException({
|
|
346
|
+
message: 'This email has already been registered.',
|
|
347
|
+
messageKey: _config.AUTH_MESSAGES.REGISTER_EMAIL_EXISTS
|
|
348
|
+
});
|
|
313
349
|
}
|
|
314
350
|
const user = queryRunner.manager.create(_userentity.User, {
|
|
315
351
|
name: pending.name,
|
|
@@ -326,7 +362,7 @@ let AuthenticationService = class AuthenticationService {
|
|
|
326
362
|
}
|
|
327
363
|
await queryRunner.commitTransaction();
|
|
328
364
|
if (this.isCompanyFeatureEnabled() && pending.companyData) {
|
|
329
|
-
return this.processCompanyRegistration(user, pending.companyData);
|
|
365
|
+
return await this.processCompanyRegistration(user, pending.companyData);
|
|
330
366
|
}
|
|
331
367
|
return this.generateRegistrationResponse(user);
|
|
332
368
|
} catch (error) {
|
|
@@ -334,8 +370,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
334
370
|
if (error instanceof _common.BadRequestException) {
|
|
335
371
|
throw error;
|
|
336
372
|
}
|
|
337
|
-
|
|
338
|
-
|
|
373
|
+
throw new _common.BadRequestException({
|
|
374
|
+
message: 'Registration failed. Please try again.',
|
|
375
|
+
messageKey: _config.AUTH_MESSAGES.REGISTER_FAILED
|
|
376
|
+
});
|
|
339
377
|
} finally{
|
|
340
378
|
await queryRunner.release();
|
|
341
379
|
}
|
|
@@ -345,7 +383,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
345
383
|
const branchRepository = await this.getBranchRepository();
|
|
346
384
|
const permissionRepository = await this.getPermissionRepository();
|
|
347
385
|
if (!companyRepository || !branchRepository || !permissionRepository) {
|
|
348
|
-
if (throwOnUnavailable) throw new _common.BadRequestException(
|
|
386
|
+
if (throwOnUnavailable) throw new _common.BadRequestException({
|
|
387
|
+
message: 'Company feature repositories not available',
|
|
388
|
+
messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE
|
|
389
|
+
});
|
|
349
390
|
return this.generateRegistrationResponse(user);
|
|
350
391
|
}
|
|
351
392
|
const { company, branch } = await this.findOrCreateCompanyAndBranch(data, companyRepository, branchRepository);
|
|
@@ -363,7 +404,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
363
404
|
isActive: true
|
|
364
405
|
}
|
|
365
406
|
});
|
|
366
|
-
if (!company) throw new _common.BadRequestException(
|
|
407
|
+
if (!company) throw new _common.BadRequestException({
|
|
408
|
+
message: 'Company not found or inactive',
|
|
409
|
+
messageKey: _config.AUTH_MESSAGES.COMPANY_NOT_FOUND
|
|
410
|
+
});
|
|
367
411
|
const branch = data.branchSlug ? await branchRepo.findOne({
|
|
368
412
|
where: {
|
|
369
413
|
slug: data.branchSlug,
|
|
@@ -380,7 +424,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
380
424
|
createdAt: 'ASC'
|
|
381
425
|
}
|
|
382
426
|
});
|
|
383
|
-
if (data.branchSlug && !branch) throw new _common.BadRequestException(
|
|
427
|
+
if (data.branchSlug && !branch) throw new _common.BadRequestException({
|
|
428
|
+
message: 'Branch not found or inactive',
|
|
429
|
+
messageKey: _config.AUTH_MESSAGES.BRANCH_NOT_FOUND
|
|
430
|
+
});
|
|
384
431
|
return {
|
|
385
432
|
company,
|
|
386
433
|
branch
|
|
@@ -436,17 +483,23 @@ let AuthenticationService = class AuthenticationService {
|
|
|
436
483
|
async select(sessionId, companyId, branchId) {
|
|
437
484
|
this.ensureCompanyFeatureEnabled();
|
|
438
485
|
if (!this.sessionService) {
|
|
439
|
-
throw new _common.BadRequestException(
|
|
486
|
+
throw new _common.BadRequestException({
|
|
487
|
+
message: 'Session service not available',
|
|
488
|
+
messageKey: _config.AUTH_MESSAGES.SESSION_NOT_AVAILABLE
|
|
489
|
+
});
|
|
440
490
|
}
|
|
441
491
|
const session = await this.sessionService.consumeSession(sessionId);
|
|
442
492
|
if (!session) {
|
|
443
|
-
throw new _common.UnauthorizedException(
|
|
493
|
+
throw new _common.UnauthorizedException({
|
|
494
|
+
message: 'Invalid or expired session',
|
|
495
|
+
messageKey: _config.AUTH_MESSAGES.SESSION_INVALID
|
|
496
|
+
});
|
|
444
497
|
}
|
|
445
|
-
return this.validateAndLoginWithCompany(session.userId, companyId, branchId);
|
|
498
|
+
return await this.validateAndLoginWithCompany(session.userId, companyId, branchId);
|
|
446
499
|
}
|
|
447
500
|
async switchCompany(userId, companyId, branchId) {
|
|
448
501
|
this.ensureCompanyFeatureEnabled();
|
|
449
|
-
return this.validateAndLoginWithCompany(userId, companyId, branchId);
|
|
502
|
+
return await this.validateAndLoginWithCompany(userId, companyId, branchId);
|
|
450
503
|
}
|
|
451
504
|
async validateAndLoginWithCompany(userId, companyId, branchId) {
|
|
452
505
|
const userRepository = await this.getUserRepository();
|
|
@@ -456,13 +509,19 @@ let AuthenticationService = class AuthenticationService {
|
|
|
456
509
|
}
|
|
457
510
|
});
|
|
458
511
|
if (!user) {
|
|
459
|
-
throw new _common.NotFoundException(
|
|
512
|
+
throw new _common.NotFoundException({
|
|
513
|
+
message: 'User not found',
|
|
514
|
+
messageKey: _config.USER_MESSAGES.NOT_FOUND
|
|
515
|
+
});
|
|
460
516
|
}
|
|
461
517
|
const permissionRepository = await this.getPermissionRepository();
|
|
462
518
|
const companyRepository = await this.getCompanyRepository();
|
|
463
519
|
const branchRepository = await this.getBranchRepository();
|
|
464
520
|
if (!permissionRepository || !companyRepository || !branchRepository) {
|
|
465
|
-
throw new _common.BadRequestException(
|
|
521
|
+
throw new _common.BadRequestException({
|
|
522
|
+
message: 'Repositories not available',
|
|
523
|
+
messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE
|
|
524
|
+
});
|
|
466
525
|
}
|
|
467
526
|
const hasCompanyAccess = await permissionRepository.findOne({
|
|
468
527
|
where: {
|
|
@@ -472,7 +531,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
472
531
|
}
|
|
473
532
|
});
|
|
474
533
|
if (!hasCompanyAccess) {
|
|
475
|
-
throw new _common.UnauthorizedException(
|
|
534
|
+
throw new _common.UnauthorizedException({
|
|
535
|
+
message: 'No access to this company',
|
|
536
|
+
messageKey: _config.AUTH_MESSAGES.COMPANY_NO_ACCESS
|
|
537
|
+
});
|
|
476
538
|
}
|
|
477
539
|
const company = await companyRepository.findOne({
|
|
478
540
|
where: {
|
|
@@ -481,7 +543,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
481
543
|
}
|
|
482
544
|
});
|
|
483
545
|
if (!company) {
|
|
484
|
-
throw new _common.UnauthorizedException(
|
|
546
|
+
throw new _common.UnauthorizedException({
|
|
547
|
+
message: 'Company not found or inactive',
|
|
548
|
+
messageKey: _config.AUTH_MESSAGES.COMPANY_NOT_FOUND
|
|
549
|
+
});
|
|
485
550
|
}
|
|
486
551
|
const hasBranchAccess = await permissionRepository.findOne({
|
|
487
552
|
where: {
|
|
@@ -491,7 +556,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
491
556
|
}
|
|
492
557
|
});
|
|
493
558
|
if (!hasBranchAccess) {
|
|
494
|
-
throw new _common.UnauthorizedException(
|
|
559
|
+
throw new _common.UnauthorizedException({
|
|
560
|
+
message: 'No access to this branch',
|
|
561
|
+
messageKey: _config.AUTH_MESSAGES.BRANCH_NO_ACCESS
|
|
562
|
+
});
|
|
495
563
|
}
|
|
496
564
|
const branch = await branchRepository.findOne({
|
|
497
565
|
where: {
|
|
@@ -501,7 +569,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
501
569
|
}
|
|
502
570
|
});
|
|
503
571
|
if (!branch) {
|
|
504
|
-
throw new _common.UnauthorizedException(
|
|
572
|
+
throw new _common.UnauthorizedException({
|
|
573
|
+
message: 'Branch not found or inactive',
|
|
574
|
+
messageKey: _config.AUTH_MESSAGES.BRANCH_NOT_FOUND
|
|
575
|
+
});
|
|
505
576
|
}
|
|
506
577
|
return this.generateLoginResponseWithCompany(user, company, branch);
|
|
507
578
|
}
|
|
@@ -511,7 +582,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
511
582
|
secret: this.authConfig.getRefreshTokenSecret()
|
|
512
583
|
});
|
|
513
584
|
if (await this.isTokenRevoked(payload.id, payload.iat)) {
|
|
514
|
-
throw new _common.UnauthorizedException(
|
|
585
|
+
throw new _common.UnauthorizedException({
|
|
586
|
+
message: 'Token has been revoked',
|
|
587
|
+
messageKey: _config.AUTH_MESSAGES.TOKEN_REVOKED
|
|
588
|
+
});
|
|
515
589
|
}
|
|
516
590
|
const userRepository = await this.getUserRepository();
|
|
517
591
|
const user = await userRepository.findOne({
|
|
@@ -520,7 +594,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
520
594
|
}
|
|
521
595
|
});
|
|
522
596
|
if (!user || !user.isActive) {
|
|
523
|
-
throw new _common.UnauthorizedException(
|
|
597
|
+
throw new _common.UnauthorizedException({
|
|
598
|
+
message: 'Invalid refresh token',
|
|
599
|
+
messageKey: _config.AUTH_MESSAGES.TOKEN_INVALID
|
|
600
|
+
});
|
|
524
601
|
}
|
|
525
602
|
return this.generateTokens({
|
|
526
603
|
id: user.id,
|
|
@@ -534,9 +611,11 @@ let AuthenticationService = class AuthenticationService {
|
|
|
534
611
|
branchId: payload.branchId
|
|
535
612
|
}
|
|
536
613
|
});
|
|
537
|
-
} catch
|
|
538
|
-
|
|
539
|
-
|
|
614
|
+
} catch {
|
|
615
|
+
throw new _common.UnauthorizedException({
|
|
616
|
+
message: 'Invalid or expired refresh token',
|
|
617
|
+
messageKey: _config.AUTH_MESSAGES.TOKEN_EXPIRED
|
|
618
|
+
});
|
|
540
619
|
}
|
|
541
620
|
}
|
|
542
621
|
async changePassword(userId, currentPassword, newPassword) {
|
|
@@ -546,24 +625,31 @@ let AuthenticationService = class AuthenticationService {
|
|
|
546
625
|
id: userId
|
|
547
626
|
}
|
|
548
627
|
});
|
|
549
|
-
if (!user) throw new _common.UnauthorizedException(
|
|
628
|
+
if (!user) throw new _common.UnauthorizedException({
|
|
629
|
+
message: 'User not found',
|
|
630
|
+
messageKey: _config.USER_MESSAGES.NOT_FOUND
|
|
631
|
+
});
|
|
550
632
|
if (!await _bcrypt.compare(currentPassword, user.password || '')) {
|
|
551
|
-
throw new _common.UnauthorizedException(
|
|
633
|
+
throw new _common.UnauthorizedException({
|
|
634
|
+
message: 'Current password is incorrect',
|
|
635
|
+
messageKey: _config.AUTH_MESSAGES.PASSWORD_CHANGE_INVALID_CURRENT
|
|
636
|
+
});
|
|
552
637
|
}
|
|
553
638
|
user.password = await _bcrypt.hash(newPassword, _config.BCRYPT_SALT_ROUNDS);
|
|
554
639
|
await userRepository.save(user);
|
|
555
640
|
}
|
|
556
641
|
async logout(userId) {
|
|
557
642
|
if (!this.cacheManager) {
|
|
558
|
-
|
|
559
|
-
|
|
643
|
+
throw new _common.BadRequestException({
|
|
644
|
+
message: 'Logout service temporarily unavailable. Please try again later.',
|
|
645
|
+
messageKey: _config.AUTH_MESSAGES.LOGOUT_SERVICE_UNAVAILABLE
|
|
646
|
+
});
|
|
560
647
|
}
|
|
561
648
|
const revokedAt = Math.floor(Date.now() / 1000);
|
|
562
649
|
const cacheKey = `${_config.TOKEN_REVOKED_PREFIX}:${userId}`;
|
|
563
650
|
const refreshTokenExpiry = this.authConfig.getRefreshTokenExpiration();
|
|
564
651
|
const ttlMs = this.parseExpiryToMs(refreshTokenExpiry);
|
|
565
652
|
await this.cacheManager.set(cacheKey, revokedAt, ttlMs);
|
|
566
|
-
this.logger.log(`User ${userId} logged out - all tokens revoked`);
|
|
567
653
|
}
|
|
568
654
|
async isTokenRevoked(userId, tokenIssuedAt) {
|
|
569
655
|
if (!this.cacheManager || !tokenIssuedAt) {
|
|
@@ -599,7 +685,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
599
685
|
const permissionRepository = await this.getPermissionRepository();
|
|
600
686
|
const companyRepository = await this.getCompanyRepository();
|
|
601
687
|
if (!permissionRepository || !companyRepository) {
|
|
602
|
-
throw new _common.BadRequestException(
|
|
688
|
+
throw new _common.BadRequestException({
|
|
689
|
+
message: 'Repositories not available',
|
|
690
|
+
messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE
|
|
691
|
+
});
|
|
603
692
|
}
|
|
604
693
|
const permissions = await permissionRepository.find({
|
|
605
694
|
where: {
|
|
@@ -620,7 +709,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
620
709
|
const permissionRepository = await this.getPermissionRepository();
|
|
621
710
|
const branchRepository = await this.getBranchRepository();
|
|
622
711
|
if (!permissionRepository || !branchRepository) {
|
|
623
|
-
throw new _common.BadRequestException(
|
|
712
|
+
throw new _common.BadRequestException({
|
|
713
|
+
message: 'Repositories not available',
|
|
714
|
+
messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE
|
|
715
|
+
});
|
|
624
716
|
}
|
|
625
717
|
const companyPermission = await permissionRepository.findOne({
|
|
626
718
|
where: {
|
|
@@ -630,7 +722,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
630
722
|
}
|
|
631
723
|
});
|
|
632
724
|
if (!companyPermission) {
|
|
633
|
-
throw new _common.UnauthorizedException(
|
|
725
|
+
throw new _common.UnauthorizedException({
|
|
726
|
+
message: 'No access to this company',
|
|
727
|
+
messageKey: _config.AUTH_MESSAGES.COMPANY_NO_ACCESS
|
|
728
|
+
});
|
|
634
729
|
}
|
|
635
730
|
const branchPermissions = await permissionRepository.find({
|
|
636
731
|
where: {
|
|
@@ -677,20 +772,32 @@ let AuthenticationService = class AuthenticationService {
|
|
|
677
772
|
id: userId
|
|
678
773
|
}
|
|
679
774
|
});
|
|
680
|
-
if (!user) throw new _common.UnauthorizedException(
|
|
775
|
+
if (!user) throw new _common.UnauthorizedException({
|
|
776
|
+
message: 'User not found',
|
|
777
|
+
messageKey: _config.USER_MESSAGES.NOT_FOUND
|
|
778
|
+
});
|
|
681
779
|
const response = {
|
|
682
780
|
user: this.toUserInfo(user)
|
|
683
781
|
};
|
|
684
782
|
if (this.isCompanyFeatureEnabled()) {
|
|
685
783
|
if (!companyId) {
|
|
686
|
-
throw new _common.UnauthorizedException(
|
|
784
|
+
throw new _common.UnauthorizedException({
|
|
785
|
+
message: 'Company feature is enabled but user has no company assigned.',
|
|
786
|
+
messageKey: _config.AUTH_MESSAGES.COMPANY_REQUIRED
|
|
787
|
+
});
|
|
687
788
|
}
|
|
688
789
|
const company = await this.getCompanyById(companyId);
|
|
689
|
-
if (!company) throw new _common.UnauthorizedException(
|
|
790
|
+
if (!company) throw new _common.UnauthorizedException({
|
|
791
|
+
message: 'Company not found.',
|
|
792
|
+
messageKey: _config.AUTH_MESSAGES.COMPANY_NOT_FOUND
|
|
793
|
+
});
|
|
690
794
|
response.company = this.toCompanyInfo(company);
|
|
691
795
|
if (branchId) {
|
|
692
796
|
const branch = await this.getBranchById(branchId);
|
|
693
|
-
if (!branch) throw new _common.UnauthorizedException(
|
|
797
|
+
if (!branch) throw new _common.UnauthorizedException({
|
|
798
|
+
message: 'Branch not found.',
|
|
799
|
+
messageKey: _config.AUTH_MESSAGES.BRANCH_NOT_FOUND
|
|
800
|
+
});
|
|
694
801
|
response.branch = this.toBranchInfo(branch);
|
|
695
802
|
}
|
|
696
803
|
}
|
|
@@ -698,7 +805,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
698
805
|
}
|
|
699
806
|
ensureCompanyFeatureEnabled() {
|
|
700
807
|
if (!this.isCompanyFeatureEnabled()) {
|
|
701
|
-
throw new _common.BadRequestException(
|
|
808
|
+
throw new _common.BadRequestException({
|
|
809
|
+
message: 'Company feature is not enabled',
|
|
810
|
+
messageKey: _config.AUTH_MESSAGES.COMPANY_FEATURE_NOT_ENABLED
|
|
811
|
+
});
|
|
702
812
|
}
|
|
703
813
|
}
|
|
704
814
|
async validateUser(email, password) {
|
|
@@ -709,7 +819,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
709
819
|
}
|
|
710
820
|
});
|
|
711
821
|
if (!user || !await _bcrypt.compare(password, user.password || '')) {
|
|
712
|
-
throw new _common.UnauthorizedException(
|
|
822
|
+
throw new _common.UnauthorizedException({
|
|
823
|
+
message: 'Invalid credentials',
|
|
824
|
+
messageKey: _config.AUTH_MESSAGES.LOGIN_INVALID_CREDENTIALS
|
|
825
|
+
});
|
|
713
826
|
}
|
|
714
827
|
user.lastLoginAt = new Date();
|
|
715
828
|
await userRepository.save(user);
|
|
@@ -798,13 +911,16 @@ let AuthenticationService = class AuthenticationService {
|
|
|
798
911
|
message: 'You have successfully logged in to your account.',
|
|
799
912
|
type: _enums.NotificationType.INFO,
|
|
800
913
|
companyId
|
|
801
|
-
}).catch((
|
|
802
|
-
|
|
914
|
+
}).catch(()=>{
|
|
915
|
+
// Silent failure - notification is non-critical
|
|
803
916
|
});
|
|
804
917
|
}
|
|
805
918
|
async generateCompanySelectionResponse(user, companies, branches) {
|
|
806
919
|
if (!this.sessionService) {
|
|
807
|
-
throw new _common.BadRequestException(
|
|
920
|
+
throw new _common.BadRequestException({
|
|
921
|
+
message: 'Session service not available',
|
|
922
|
+
messageKey: _config.AUTH_MESSAGES.SESSION_NOT_AVAILABLE
|
|
923
|
+
});
|
|
808
924
|
}
|
|
809
925
|
const sessionId = await this.sessionService.createSession(user.id);
|
|
810
926
|
const companiesWithBranches = companies.map((company)=>({
|
|
@@ -845,7 +961,6 @@ let AuthenticationService = class AuthenticationService {
|
|
|
845
961
|
_define_property(this, "authEmailService", void 0);
|
|
846
962
|
_define_property(this, "userEnricher", void 0);
|
|
847
963
|
_define_property(this, "notificationAdapter", void 0);
|
|
848
|
-
_define_property(this, "logger", void 0);
|
|
849
964
|
this.jwtService = jwtService;
|
|
850
965
|
this.authConfig = authConfig;
|
|
851
966
|
this.cacheManager = cacheManager;
|
|
@@ -854,9 +969,108 @@ let AuthenticationService = class AuthenticationService {
|
|
|
854
969
|
this.authEmailService = authEmailService;
|
|
855
970
|
this.userEnricher = userEnricher;
|
|
856
971
|
this.notificationAdapter = notificationAdapter;
|
|
857
|
-
this.logger = new _common.Logger(AuthenticationService.name);
|
|
858
972
|
}
|
|
859
973
|
};
|
|
974
|
+
_ts_decorate([
|
|
975
|
+
(0, _nestjsshared.LogAction)({
|
|
976
|
+
action: 'auth.login',
|
|
977
|
+
module: 'auth',
|
|
978
|
+
includeParams: false
|
|
979
|
+
}),
|
|
980
|
+
_ts_metadata("design:type", Function),
|
|
981
|
+
_ts_metadata("design:paramtypes", [
|
|
982
|
+
String,
|
|
983
|
+
String
|
|
984
|
+
]),
|
|
985
|
+
_ts_metadata("design:returntype", Promise)
|
|
986
|
+
], AuthenticationService.prototype, "login", null);
|
|
987
|
+
_ts_decorate([
|
|
988
|
+
(0, _nestjsshared.LogAction)({
|
|
989
|
+
action: 'auth.register',
|
|
990
|
+
module: 'auth',
|
|
991
|
+
includeParams: false
|
|
992
|
+
}),
|
|
993
|
+
_ts_metadata("design:type", Function),
|
|
994
|
+
_ts_metadata("design:paramtypes", [
|
|
995
|
+
typeof _authenticationdto.RegistrationDto === "undefined" ? Object : _authenticationdto.RegistrationDto,
|
|
996
|
+
String
|
|
997
|
+
]),
|
|
998
|
+
_ts_metadata("design:returntype", Promise)
|
|
999
|
+
], AuthenticationService.prototype, "register", null);
|
|
1000
|
+
_ts_decorate([
|
|
1001
|
+
(0, _nestjsshared.LogAction)({
|
|
1002
|
+
action: 'auth.createUser',
|
|
1003
|
+
module: 'auth',
|
|
1004
|
+
includeParams: false
|
|
1005
|
+
}),
|
|
1006
|
+
_ts_metadata("design:type", Function),
|
|
1007
|
+
_ts_metadata("design:paramtypes", [
|
|
1008
|
+
typeof _authenticationdto.RegistrationDto === "undefined" ? Object : _authenticationdto.RegistrationDto
|
|
1009
|
+
]),
|
|
1010
|
+
_ts_metadata("design:returntype", Promise)
|
|
1011
|
+
], AuthenticationService.prototype, "createUserDirectly", null);
|
|
1012
|
+
_ts_decorate([
|
|
1013
|
+
(0, _nestjsshared.LogAction)({
|
|
1014
|
+
action: 'auth.createUserFromPending',
|
|
1015
|
+
module: 'auth',
|
|
1016
|
+
includeParams: false
|
|
1017
|
+
}),
|
|
1018
|
+
_ts_metadata("design:type", Function),
|
|
1019
|
+
_ts_metadata("design:paramtypes", [
|
|
1020
|
+
typeof _pendingregistrationentity.PendingRegistration === "undefined" ? Object : _pendingregistrationentity.PendingRegistration
|
|
1021
|
+
]),
|
|
1022
|
+
_ts_metadata("design:returntype", Promise)
|
|
1023
|
+
], AuthenticationService.prototype, "createUserFromPendingRegistration", null);
|
|
1024
|
+
_ts_decorate([
|
|
1025
|
+
(0, _nestjsshared.LogAction)({
|
|
1026
|
+
action: 'auth.companySwitch',
|
|
1027
|
+
module: 'auth'
|
|
1028
|
+
}),
|
|
1029
|
+
_ts_metadata("design:type", Function),
|
|
1030
|
+
_ts_metadata("design:paramtypes", [
|
|
1031
|
+
String,
|
|
1032
|
+
String,
|
|
1033
|
+
String
|
|
1034
|
+
]),
|
|
1035
|
+
_ts_metadata("design:returntype", Promise)
|
|
1036
|
+
], AuthenticationService.prototype, "validateAndLoginWithCompany", null);
|
|
1037
|
+
_ts_decorate([
|
|
1038
|
+
(0, _nestjsshared.LogAction)({
|
|
1039
|
+
action: 'auth.refreshToken',
|
|
1040
|
+
module: 'auth',
|
|
1041
|
+
includeParams: false
|
|
1042
|
+
}),
|
|
1043
|
+
_ts_metadata("design:type", Function),
|
|
1044
|
+
_ts_metadata("design:paramtypes", [
|
|
1045
|
+
String
|
|
1046
|
+
]),
|
|
1047
|
+
_ts_metadata("design:returntype", Promise)
|
|
1048
|
+
], AuthenticationService.prototype, "refreshToken", null);
|
|
1049
|
+
_ts_decorate([
|
|
1050
|
+
(0, _nestjsshared.LogAction)({
|
|
1051
|
+
action: 'auth.changePassword',
|
|
1052
|
+
module: 'auth',
|
|
1053
|
+
includeParams: false
|
|
1054
|
+
}),
|
|
1055
|
+
_ts_metadata("design:type", Function),
|
|
1056
|
+
_ts_metadata("design:paramtypes", [
|
|
1057
|
+
String,
|
|
1058
|
+
String,
|
|
1059
|
+
String
|
|
1060
|
+
]),
|
|
1061
|
+
_ts_metadata("design:returntype", Promise)
|
|
1062
|
+
], AuthenticationService.prototype, "changePassword", null);
|
|
1063
|
+
_ts_decorate([
|
|
1064
|
+
(0, _nestjsshared.LogAction)({
|
|
1065
|
+
action: 'auth.logout',
|
|
1066
|
+
module: 'auth'
|
|
1067
|
+
}),
|
|
1068
|
+
_ts_metadata("design:type", Function),
|
|
1069
|
+
_ts_metadata("design:paramtypes", [
|
|
1070
|
+
String
|
|
1071
|
+
]),
|
|
1072
|
+
_ts_metadata("design:returntype", Promise)
|
|
1073
|
+
], AuthenticationService.prototype, "logout", null);
|
|
860
1074
|
AuthenticationService = _ts_decorate([
|
|
861
1075
|
(0, _common.Injectable)({
|
|
862
1076
|
scope: _common.Scope.REQUEST
|
|
@@ -89,7 +89,7 @@ let BranchService = class BranchService extends _classes.RequestScopedApiService
|
|
|
89
89
|
return result;
|
|
90
90
|
}
|
|
91
91
|
constructor(cacheManager, utilsService, dataSourceProvider, authConfig){
|
|
92
|
-
super('company_branch', null, cacheManager, utilsService, BranchService.name, true), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "dataSourceProvider", void 0), _define_property(this, "authConfig", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.dataSourceProvider = dataSourceProvider, this.authConfig = authConfig;
|
|
92
|
+
super('company_branch', null, cacheManager, utilsService, BranchService.name, true, 'auth'), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "dataSourceProvider", void 0), _define_property(this, "authConfig", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.dataSourceProvider = dataSourceProvider, this.authConfig = authConfig;
|
|
93
93
|
}
|
|
94
94
|
};
|
|
95
95
|
BranchService = _ts_decorate([
|