@flusys/nestjs-auth 3.0.0 → 4.0.0-rc
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 +1 -1
- 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 +306 -71
- 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 +297 -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 +3 -3
- 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 +5 -2
- package/services/branch.service.d.ts +2 -1
- package/services/user.service.d.ts +7 -7
|
@@ -9,17 +9,23 @@ 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");
|
|
15
|
+
const _interfaces = require("@flusys/nestjs-shared/interfaces");
|
|
16
|
+
const _enums = require("@flusys/nestjs-shared/enums");
|
|
12
17
|
const _utils = require("@flusys/nestjs-shared/utils");
|
|
13
18
|
const _common = require("@nestjs/common");
|
|
14
19
|
const _jwt = require("@nestjs/jwt");
|
|
15
20
|
const _bcrypt = /*#__PURE__*/ _interop_require_wildcard(require("bcrypt"));
|
|
16
|
-
const _config = require("../config");
|
|
17
21
|
const _userenricherinterface = require("../interfaces/user-enricher.interface");
|
|
22
|
+
const _authenticationdto = require("../dtos/authentication.dto");
|
|
18
23
|
const _companybranchentity = require("../entities/company-branch.entity");
|
|
19
24
|
const _companyentity = require("../entities/company.entity");
|
|
25
|
+
const _pendingregistrationentity = require("../entities/pending-registration.entity");
|
|
20
26
|
const _usercompanypermissionentity = require("../entities/user-company-permission.entity");
|
|
21
27
|
const _userentity = require("../entities/user.entity");
|
|
22
|
-
const
|
|
28
|
+
const _enums1 = require("../enums");
|
|
23
29
|
const _authconfigservice = require("./auth-config.service");
|
|
24
30
|
const _authdatasourceprovider = require("./auth-datasource.provider");
|
|
25
31
|
const _authemailservice = require("./auth-email.service");
|
|
@@ -103,7 +109,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
103
109
|
}
|
|
104
110
|
async getUserRepository() {
|
|
105
111
|
if (!this.dataSourceProvider) {
|
|
106
|
-
throw new
|
|
112
|
+
throw new _common.InternalServerErrorException({
|
|
113
|
+
message: 'User repository not available',
|
|
114
|
+
messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE
|
|
115
|
+
});
|
|
107
116
|
}
|
|
108
117
|
return this.dataSourceProvider.getRepository(_userentity.User);
|
|
109
118
|
}
|
|
@@ -124,24 +133,29 @@ let AuthenticationService = class AuthenticationService {
|
|
|
124
133
|
return {
|
|
125
134
|
requiresEmailVerification: true,
|
|
126
135
|
email,
|
|
127
|
-
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
|
|
128
138
|
};
|
|
129
139
|
}
|
|
130
140
|
const user = await this.validateUser(email, password);
|
|
131
141
|
if (!user.isActive) {
|
|
132
|
-
throw new _common.UnauthorizedException(
|
|
142
|
+
throw new _common.UnauthorizedException({
|
|
143
|
+
message: 'User account is deactivated',
|
|
144
|
+
messageKey: _config.AUTH_MESSAGES.LOGIN_ACCOUNT_DEACTIVATED
|
|
145
|
+
});
|
|
133
146
|
}
|
|
134
147
|
if (this.isEmailVerificationEnabled() && !user.emailVerified) {
|
|
135
148
|
return {
|
|
136
149
|
requiresEmailVerification: true,
|
|
137
150
|
email: user.email,
|
|
138
|
-
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
|
|
139
153
|
};
|
|
140
154
|
}
|
|
141
155
|
if (!this.isCompanyFeatureEnabled()) {
|
|
142
156
|
return this.generateLoginResponse(user);
|
|
143
157
|
}
|
|
144
|
-
return this.handleCompanyBasedLogin(user);
|
|
158
|
+
return await this.handleCompanyBasedLogin(user);
|
|
145
159
|
}
|
|
146
160
|
async handleCompanyBasedLogin(user) {
|
|
147
161
|
const permissionRepository = await this.getPermissionRepository();
|
|
@@ -152,7 +166,7 @@ let AuthenticationService = class AuthenticationService {
|
|
|
152
166
|
const companyPermissions = await permissionRepository.find({
|
|
153
167
|
where: {
|
|
154
168
|
userId: user.id,
|
|
155
|
-
permissionType:
|
|
169
|
+
permissionType: _enums1.PermissionType.COMPANY
|
|
156
170
|
}
|
|
157
171
|
});
|
|
158
172
|
const companyRepository = await this.getCompanyRepository();
|
|
@@ -171,7 +185,7 @@ let AuthenticationService = class AuthenticationService {
|
|
|
171
185
|
const branchPermissions = await permissionRepository.find({
|
|
172
186
|
where: {
|
|
173
187
|
userId: user.id,
|
|
174
|
-
permissionType:
|
|
188
|
+
permissionType: _enums1.PermissionType.BRANCH
|
|
175
189
|
}
|
|
176
190
|
});
|
|
177
191
|
const branchIds = branchPermissions.map((p)=>p.targetId);
|
|
@@ -193,10 +207,13 @@ let AuthenticationService = class AuthenticationService {
|
|
|
193
207
|
}
|
|
194
208
|
});
|
|
195
209
|
if (existingUser && this.isCompanyFeatureEnabled()) {
|
|
196
|
-
return this.handleExistingUserCompanyRegistration(existingUser, dto);
|
|
210
|
+
return await this.handleExistingUserCompanyRegistration(existingUser, dto);
|
|
197
211
|
}
|
|
198
212
|
if (existingUser) {
|
|
199
|
-
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
|
+
});
|
|
200
217
|
}
|
|
201
218
|
if (this.isEmailVerificationEnabled() && verifyUrlBase) {
|
|
202
219
|
const companyData = this.isCompanyFeatureEnabled() ? {
|
|
@@ -217,19 +234,26 @@ let AuthenticationService = class AuthenticationService {
|
|
|
217
234
|
});
|
|
218
235
|
return {
|
|
219
236
|
requiresEmailVerification: true,
|
|
220
|
-
message: result.message
|
|
237
|
+
message: result.message,
|
|
238
|
+
messageKey: _config.EMAIL_VERIFICATION_MESSAGES.VERIFICATION_SENT
|
|
221
239
|
};
|
|
222
240
|
}
|
|
223
|
-
return this.createUserDirectly(dto);
|
|
241
|
+
return await this.createUserDirectly(dto);
|
|
224
242
|
}
|
|
225
243
|
async handleExistingUserCompanyRegistration(existingUser, dto) {
|
|
226
244
|
if (!dto.companySlug && !dto.newCompanyName) {
|
|
227
|
-
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
|
+
});
|
|
228
249
|
}
|
|
229
250
|
const permissionRepository = await this.getPermissionRepository();
|
|
230
251
|
const companyRepository = await this.getCompanyRepository();
|
|
231
252
|
if (!permissionRepository || !companyRepository) {
|
|
232
|
-
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
|
+
});
|
|
233
257
|
}
|
|
234
258
|
if (dto.companySlug) {
|
|
235
259
|
const company = await companyRepository.findOne({
|
|
@@ -242,20 +266,26 @@ let AuthenticationService = class AuthenticationService {
|
|
|
242
266
|
const existingPermission = await permissionRepository.findOne({
|
|
243
267
|
where: {
|
|
244
268
|
userId: existingUser.id,
|
|
245
|
-
permissionType:
|
|
269
|
+
permissionType: _enums1.PermissionType.COMPANY,
|
|
246
270
|
targetId: company.id
|
|
247
271
|
}
|
|
248
272
|
});
|
|
249
273
|
if (existingPermission) {
|
|
250
|
-
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
|
+
});
|
|
251
278
|
}
|
|
252
279
|
}
|
|
253
280
|
}
|
|
254
|
-
return this.processCompanyRegistration(existingUser, dto, true);
|
|
281
|
+
return await this.processCompanyRegistration(existingUser, dto, true);
|
|
255
282
|
}
|
|
256
283
|
async createUserDirectly(dto) {
|
|
257
284
|
if (!this.dataSourceProvider) {
|
|
258
|
-
throw new _common.BadRequestException(
|
|
285
|
+
throw new _common.BadRequestException({
|
|
286
|
+
message: 'Data source not available',
|
|
287
|
+
messageKey: _constants.SYSTEM_MESSAGES.DATASOURCE_NOT_AVAILABLE
|
|
288
|
+
});
|
|
259
289
|
}
|
|
260
290
|
const dataSource = await this.dataSourceProvider.getDataSource();
|
|
261
291
|
const queryRunner = dataSource.createQueryRunner();
|
|
@@ -280,21 +310,26 @@ let AuthenticationService = class AuthenticationService {
|
|
|
280
310
|
if (!this.isCompanyFeatureEnabled()) {
|
|
281
311
|
return this.generateRegistrationResponse(user);
|
|
282
312
|
}
|
|
283
|
-
return this.processCompanyRegistration(user, dto);
|
|
313
|
+
return await this.processCompanyRegistration(user, dto);
|
|
284
314
|
} catch (error) {
|
|
285
315
|
await queryRunner.rollbackTransaction();
|
|
286
316
|
if (error instanceof _common.BadRequestException) {
|
|
287
317
|
throw error;
|
|
288
318
|
}
|
|
289
|
-
|
|
290
|
-
|
|
319
|
+
throw new _common.BadRequestException({
|
|
320
|
+
message: 'Registration failed. Please try again.',
|
|
321
|
+
messageKey: _config.AUTH_MESSAGES.REGISTER_FAILED
|
|
322
|
+
});
|
|
291
323
|
} finally{
|
|
292
324
|
await queryRunner.release();
|
|
293
325
|
}
|
|
294
326
|
}
|
|
295
327
|
async createUserFromPendingRegistration(pending) {
|
|
296
328
|
if (!this.dataSourceProvider) {
|
|
297
|
-
throw new _common.BadRequestException(
|
|
329
|
+
throw new _common.BadRequestException({
|
|
330
|
+
message: 'Data source not available',
|
|
331
|
+
messageKey: _constants.SYSTEM_MESSAGES.DATASOURCE_NOT_AVAILABLE
|
|
332
|
+
});
|
|
298
333
|
}
|
|
299
334
|
const dataSource = await this.dataSourceProvider.getDataSource();
|
|
300
335
|
const queryRunner = dataSource.createQueryRunner();
|
|
@@ -307,7 +342,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
307
342
|
}
|
|
308
343
|
});
|
|
309
344
|
if (existingUser) {
|
|
310
|
-
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
|
+
});
|
|
311
349
|
}
|
|
312
350
|
const user = queryRunner.manager.create(_userentity.User, {
|
|
313
351
|
name: pending.name,
|
|
@@ -324,7 +362,7 @@ let AuthenticationService = class AuthenticationService {
|
|
|
324
362
|
}
|
|
325
363
|
await queryRunner.commitTransaction();
|
|
326
364
|
if (this.isCompanyFeatureEnabled() && pending.companyData) {
|
|
327
|
-
return this.processCompanyRegistration(user, pending.companyData);
|
|
365
|
+
return await this.processCompanyRegistration(user, pending.companyData);
|
|
328
366
|
}
|
|
329
367
|
return this.generateRegistrationResponse(user);
|
|
330
368
|
} catch (error) {
|
|
@@ -332,8 +370,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
332
370
|
if (error instanceof _common.BadRequestException) {
|
|
333
371
|
throw error;
|
|
334
372
|
}
|
|
335
|
-
|
|
336
|
-
|
|
373
|
+
throw new _common.BadRequestException({
|
|
374
|
+
message: 'Registration failed. Please try again.',
|
|
375
|
+
messageKey: _config.AUTH_MESSAGES.REGISTER_FAILED
|
|
376
|
+
});
|
|
337
377
|
} finally{
|
|
338
378
|
await queryRunner.release();
|
|
339
379
|
}
|
|
@@ -343,7 +383,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
343
383
|
const branchRepository = await this.getBranchRepository();
|
|
344
384
|
const permissionRepository = await this.getPermissionRepository();
|
|
345
385
|
if (!companyRepository || !branchRepository || !permissionRepository) {
|
|
346
|
-
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
|
+
});
|
|
347
390
|
return this.generateRegistrationResponse(user);
|
|
348
391
|
}
|
|
349
392
|
const { company, branch } = await this.findOrCreateCompanyAndBranch(data, companyRepository, branchRepository);
|
|
@@ -361,7 +404,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
361
404
|
isActive: true
|
|
362
405
|
}
|
|
363
406
|
});
|
|
364
|
-
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
|
+
});
|
|
365
411
|
const branch = data.branchSlug ? await branchRepo.findOne({
|
|
366
412
|
where: {
|
|
367
413
|
slug: data.branchSlug,
|
|
@@ -378,7 +424,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
378
424
|
createdAt: 'ASC'
|
|
379
425
|
}
|
|
380
426
|
});
|
|
381
|
-
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
|
+
});
|
|
382
431
|
return {
|
|
383
432
|
company,
|
|
384
433
|
branch
|
|
@@ -420,13 +469,13 @@ let AuthenticationService = class AuthenticationService {
|
|
|
420
469
|
async assignUserPermissions(userId, companyId, branchId, permissionRepo) {
|
|
421
470
|
await permissionRepo.save(permissionRepo.create({
|
|
422
471
|
userId,
|
|
423
|
-
permissionType:
|
|
472
|
+
permissionType: _enums1.PermissionType.COMPANY,
|
|
424
473
|
targetId: companyId
|
|
425
474
|
}));
|
|
426
475
|
if (branchId) {
|
|
427
476
|
await permissionRepo.save(permissionRepo.create({
|
|
428
477
|
userId,
|
|
429
|
-
permissionType:
|
|
478
|
+
permissionType: _enums1.PermissionType.BRANCH,
|
|
430
479
|
targetId: branchId
|
|
431
480
|
}));
|
|
432
481
|
}
|
|
@@ -434,17 +483,23 @@ let AuthenticationService = class AuthenticationService {
|
|
|
434
483
|
async select(sessionId, companyId, branchId) {
|
|
435
484
|
this.ensureCompanyFeatureEnabled();
|
|
436
485
|
if (!this.sessionService) {
|
|
437
|
-
throw new _common.BadRequestException(
|
|
486
|
+
throw new _common.BadRequestException({
|
|
487
|
+
message: 'Session service not available',
|
|
488
|
+
messageKey: _config.AUTH_MESSAGES.SESSION_NOT_AVAILABLE
|
|
489
|
+
});
|
|
438
490
|
}
|
|
439
491
|
const session = await this.sessionService.consumeSession(sessionId);
|
|
440
492
|
if (!session) {
|
|
441
|
-
throw new _common.UnauthorizedException(
|
|
493
|
+
throw new _common.UnauthorizedException({
|
|
494
|
+
message: 'Invalid or expired session',
|
|
495
|
+
messageKey: _config.AUTH_MESSAGES.SESSION_INVALID
|
|
496
|
+
});
|
|
442
497
|
}
|
|
443
|
-
return this.validateAndLoginWithCompany(session.userId, companyId, branchId);
|
|
498
|
+
return await this.validateAndLoginWithCompany(session.userId, companyId, branchId);
|
|
444
499
|
}
|
|
445
500
|
async switchCompany(userId, companyId, branchId) {
|
|
446
501
|
this.ensureCompanyFeatureEnabled();
|
|
447
|
-
return this.validateAndLoginWithCompany(userId, companyId, branchId);
|
|
502
|
+
return await this.validateAndLoginWithCompany(userId, companyId, branchId);
|
|
448
503
|
}
|
|
449
504
|
async validateAndLoginWithCompany(userId, companyId, branchId) {
|
|
450
505
|
const userRepository = await this.getUserRepository();
|
|
@@ -454,23 +509,32 @@ let AuthenticationService = class AuthenticationService {
|
|
|
454
509
|
}
|
|
455
510
|
});
|
|
456
511
|
if (!user) {
|
|
457
|
-
throw new _common.NotFoundException(
|
|
512
|
+
throw new _common.NotFoundException({
|
|
513
|
+
message: 'User not found',
|
|
514
|
+
messageKey: _config.USER_MESSAGES.NOT_FOUND
|
|
515
|
+
});
|
|
458
516
|
}
|
|
459
517
|
const permissionRepository = await this.getPermissionRepository();
|
|
460
518
|
const companyRepository = await this.getCompanyRepository();
|
|
461
519
|
const branchRepository = await this.getBranchRepository();
|
|
462
520
|
if (!permissionRepository || !companyRepository || !branchRepository) {
|
|
463
|
-
throw new _common.BadRequestException(
|
|
521
|
+
throw new _common.BadRequestException({
|
|
522
|
+
message: 'Repositories not available',
|
|
523
|
+
messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE
|
|
524
|
+
});
|
|
464
525
|
}
|
|
465
526
|
const hasCompanyAccess = await permissionRepository.findOne({
|
|
466
527
|
where: {
|
|
467
528
|
userId,
|
|
468
|
-
permissionType:
|
|
529
|
+
permissionType: _enums1.PermissionType.COMPANY,
|
|
469
530
|
targetId: companyId
|
|
470
531
|
}
|
|
471
532
|
});
|
|
472
533
|
if (!hasCompanyAccess) {
|
|
473
|
-
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
|
+
});
|
|
474
538
|
}
|
|
475
539
|
const company = await companyRepository.findOne({
|
|
476
540
|
where: {
|
|
@@ -479,17 +543,23 @@ let AuthenticationService = class AuthenticationService {
|
|
|
479
543
|
}
|
|
480
544
|
});
|
|
481
545
|
if (!company) {
|
|
482
|
-
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
|
+
});
|
|
483
550
|
}
|
|
484
551
|
const hasBranchAccess = await permissionRepository.findOne({
|
|
485
552
|
where: {
|
|
486
553
|
userId,
|
|
487
|
-
permissionType:
|
|
554
|
+
permissionType: _enums1.PermissionType.BRANCH,
|
|
488
555
|
targetId: branchId
|
|
489
556
|
}
|
|
490
557
|
});
|
|
491
558
|
if (!hasBranchAccess) {
|
|
492
|
-
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
|
+
});
|
|
493
563
|
}
|
|
494
564
|
const branch = await branchRepository.findOne({
|
|
495
565
|
where: {
|
|
@@ -499,7 +569,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
499
569
|
}
|
|
500
570
|
});
|
|
501
571
|
if (!branch) {
|
|
502
|
-
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
|
+
});
|
|
503
576
|
}
|
|
504
577
|
return this.generateLoginResponseWithCompany(user, company, branch);
|
|
505
578
|
}
|
|
@@ -509,7 +582,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
509
582
|
secret: this.authConfig.getRefreshTokenSecret()
|
|
510
583
|
});
|
|
511
584
|
if (await this.isTokenRevoked(payload.id, payload.iat)) {
|
|
512
|
-
throw new _common.UnauthorizedException(
|
|
585
|
+
throw new _common.UnauthorizedException({
|
|
586
|
+
message: 'Token has been revoked',
|
|
587
|
+
messageKey: _config.AUTH_MESSAGES.TOKEN_REVOKED
|
|
588
|
+
});
|
|
513
589
|
}
|
|
514
590
|
const userRepository = await this.getUserRepository();
|
|
515
591
|
const user = await userRepository.findOne({
|
|
@@ -518,7 +594,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
518
594
|
}
|
|
519
595
|
});
|
|
520
596
|
if (!user || !user.isActive) {
|
|
521
|
-
throw new _common.UnauthorizedException(
|
|
597
|
+
throw new _common.UnauthorizedException({
|
|
598
|
+
message: 'Invalid refresh token',
|
|
599
|
+
messageKey: _config.AUTH_MESSAGES.TOKEN_INVALID
|
|
600
|
+
});
|
|
522
601
|
}
|
|
523
602
|
return this.generateTokens({
|
|
524
603
|
id: user.id,
|
|
@@ -532,9 +611,11 @@ let AuthenticationService = class AuthenticationService {
|
|
|
532
611
|
branchId: payload.branchId
|
|
533
612
|
}
|
|
534
613
|
});
|
|
535
|
-
} catch
|
|
536
|
-
|
|
537
|
-
|
|
614
|
+
} catch {
|
|
615
|
+
throw new _common.UnauthorizedException({
|
|
616
|
+
message: 'Invalid or expired refresh token',
|
|
617
|
+
messageKey: _config.AUTH_MESSAGES.TOKEN_EXPIRED
|
|
618
|
+
});
|
|
538
619
|
}
|
|
539
620
|
}
|
|
540
621
|
async changePassword(userId, currentPassword, newPassword) {
|
|
@@ -544,24 +625,31 @@ let AuthenticationService = class AuthenticationService {
|
|
|
544
625
|
id: userId
|
|
545
626
|
}
|
|
546
627
|
});
|
|
547
|
-
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
|
+
});
|
|
548
632
|
if (!await _bcrypt.compare(currentPassword, user.password || '')) {
|
|
549
|
-
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
|
+
});
|
|
550
637
|
}
|
|
551
638
|
user.password = await _bcrypt.hash(newPassword, _config.BCRYPT_SALT_ROUNDS);
|
|
552
639
|
await userRepository.save(user);
|
|
553
640
|
}
|
|
554
641
|
async logout(userId) {
|
|
555
642
|
if (!this.cacheManager) {
|
|
556
|
-
|
|
557
|
-
|
|
643
|
+
throw new _common.BadRequestException({
|
|
644
|
+
message: 'Logout service temporarily unavailable. Please try again later.',
|
|
645
|
+
messageKey: _config.AUTH_MESSAGES.LOGOUT_SERVICE_UNAVAILABLE
|
|
646
|
+
});
|
|
558
647
|
}
|
|
559
648
|
const revokedAt = Math.floor(Date.now() / 1000);
|
|
560
649
|
const cacheKey = `${_config.TOKEN_REVOKED_PREFIX}:${userId}`;
|
|
561
650
|
const refreshTokenExpiry = this.authConfig.getRefreshTokenExpiration();
|
|
562
651
|
const ttlMs = this.parseExpiryToMs(refreshTokenExpiry);
|
|
563
652
|
await this.cacheManager.set(cacheKey, revokedAt, ttlMs);
|
|
564
|
-
this.logger.log(`User ${userId} logged out - all tokens revoked`);
|
|
565
653
|
}
|
|
566
654
|
async isTokenRevoked(userId, tokenIssuedAt) {
|
|
567
655
|
if (!this.cacheManager || !tokenIssuedAt) {
|
|
@@ -597,12 +685,15 @@ let AuthenticationService = class AuthenticationService {
|
|
|
597
685
|
const permissionRepository = await this.getPermissionRepository();
|
|
598
686
|
const companyRepository = await this.getCompanyRepository();
|
|
599
687
|
if (!permissionRepository || !companyRepository) {
|
|
600
|
-
throw new _common.BadRequestException(
|
|
688
|
+
throw new _common.BadRequestException({
|
|
689
|
+
message: 'Repositories not available',
|
|
690
|
+
messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE
|
|
691
|
+
});
|
|
601
692
|
}
|
|
602
693
|
const permissions = await permissionRepository.find({
|
|
603
694
|
where: {
|
|
604
695
|
userId,
|
|
605
|
-
permissionType:
|
|
696
|
+
permissionType: _enums1.PermissionType.COMPANY
|
|
606
697
|
}
|
|
607
698
|
});
|
|
608
699
|
const companyIds = permissions.map((p)=>p.targetId);
|
|
@@ -618,22 +709,28 @@ let AuthenticationService = class AuthenticationService {
|
|
|
618
709
|
const permissionRepository = await this.getPermissionRepository();
|
|
619
710
|
const branchRepository = await this.getBranchRepository();
|
|
620
711
|
if (!permissionRepository || !branchRepository) {
|
|
621
|
-
throw new _common.BadRequestException(
|
|
712
|
+
throw new _common.BadRequestException({
|
|
713
|
+
message: 'Repositories not available',
|
|
714
|
+
messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE
|
|
715
|
+
});
|
|
622
716
|
}
|
|
623
717
|
const companyPermission = await permissionRepository.findOne({
|
|
624
718
|
where: {
|
|
625
719
|
userId,
|
|
626
|
-
permissionType:
|
|
720
|
+
permissionType: _enums1.PermissionType.COMPANY,
|
|
627
721
|
targetId: companyId
|
|
628
722
|
}
|
|
629
723
|
});
|
|
630
724
|
if (!companyPermission) {
|
|
631
|
-
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
|
+
});
|
|
632
729
|
}
|
|
633
730
|
const branchPermissions = await permissionRepository.find({
|
|
634
731
|
where: {
|
|
635
732
|
userId,
|
|
636
|
-
permissionType:
|
|
733
|
+
permissionType: _enums1.PermissionType.BRANCH
|
|
637
734
|
}
|
|
638
735
|
});
|
|
639
736
|
const branchIds = branchPermissions.map((p)=>p.targetId);
|
|
@@ -675,20 +772,32 @@ let AuthenticationService = class AuthenticationService {
|
|
|
675
772
|
id: userId
|
|
676
773
|
}
|
|
677
774
|
});
|
|
678
|
-
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
|
+
});
|
|
679
779
|
const response = {
|
|
680
780
|
user: this.toUserInfo(user)
|
|
681
781
|
};
|
|
682
782
|
if (this.isCompanyFeatureEnabled()) {
|
|
683
783
|
if (!companyId) {
|
|
684
|
-
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
|
+
});
|
|
685
788
|
}
|
|
686
789
|
const company = await this.getCompanyById(companyId);
|
|
687
|
-
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
|
+
});
|
|
688
794
|
response.company = this.toCompanyInfo(company);
|
|
689
795
|
if (branchId) {
|
|
690
796
|
const branch = await this.getBranchById(branchId);
|
|
691
|
-
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
|
+
});
|
|
692
801
|
response.branch = this.toBranchInfo(branch);
|
|
693
802
|
}
|
|
694
803
|
}
|
|
@@ -696,7 +805,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
696
805
|
}
|
|
697
806
|
ensureCompanyFeatureEnabled() {
|
|
698
807
|
if (!this.isCompanyFeatureEnabled()) {
|
|
699
|
-
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
|
+
});
|
|
700
812
|
}
|
|
701
813
|
}
|
|
702
814
|
async validateUser(email, password) {
|
|
@@ -707,7 +819,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
707
819
|
}
|
|
708
820
|
});
|
|
709
821
|
if (!user || !await _bcrypt.compare(password, user.password || '')) {
|
|
710
|
-
throw new _common.UnauthorizedException(
|
|
822
|
+
throw new _common.UnauthorizedException({
|
|
823
|
+
message: 'Invalid credentials',
|
|
824
|
+
messageKey: _config.AUTH_MESSAGES.LOGIN_INVALID_CREDENTIALS
|
|
825
|
+
});
|
|
711
826
|
}
|
|
712
827
|
user.lastLoginAt = new Date();
|
|
713
828
|
await userRepository.save(user);
|
|
@@ -764,6 +879,7 @@ let AuthenticationService = class AuthenticationService {
|
|
|
764
879
|
email: user.email,
|
|
765
880
|
type: 'access'
|
|
766
881
|
});
|
|
882
|
+
this.sendLoginNotification(user.id);
|
|
767
883
|
return {
|
|
768
884
|
accessToken,
|
|
769
885
|
refreshToken,
|
|
@@ -778,6 +894,7 @@ let AuthenticationService = class AuthenticationService {
|
|
|
778
894
|
companyId: company.id,
|
|
779
895
|
branchId: branch?.id
|
|
780
896
|
});
|
|
897
|
+
this.sendLoginNotification(user.id, company.id);
|
|
781
898
|
return {
|
|
782
899
|
accessToken,
|
|
783
900
|
refreshToken,
|
|
@@ -786,9 +903,24 @@ let AuthenticationService = class AuthenticationService {
|
|
|
786
903
|
branch: branch ? this.toBranchInfo(branch) : undefined
|
|
787
904
|
};
|
|
788
905
|
}
|
|
906
|
+
sendLoginNotification(userId, companyId) {
|
|
907
|
+
if (!this.notificationAdapter) return;
|
|
908
|
+
this.notificationAdapter.send({
|
|
909
|
+
userId,
|
|
910
|
+
title: 'Login successful',
|
|
911
|
+
message: 'You have successfully logged in to your account.',
|
|
912
|
+
type: _enums.NotificationType.INFO,
|
|
913
|
+
companyId
|
|
914
|
+
}).catch(()=>{
|
|
915
|
+
// Silent failure - notification is non-critical
|
|
916
|
+
});
|
|
917
|
+
}
|
|
789
918
|
async generateCompanySelectionResponse(user, companies, branches) {
|
|
790
919
|
if (!this.sessionService) {
|
|
791
|
-
throw new _common.BadRequestException(
|
|
920
|
+
throw new _common.BadRequestException({
|
|
921
|
+
message: 'Session service not available',
|
|
922
|
+
messageKey: _config.AUTH_MESSAGES.SESSION_NOT_AVAILABLE
|
|
923
|
+
});
|
|
792
924
|
}
|
|
793
925
|
const sessionId = await this.sessionService.createSession(user.id);
|
|
794
926
|
const companiesWithBranches = companies.map((company)=>({
|
|
@@ -820,7 +952,7 @@ let AuthenticationService = class AuthenticationService {
|
|
|
820
952
|
};
|
|
821
953
|
}
|
|
822
954
|
// NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
|
|
823
|
-
constructor(jwtService, authConfig, cacheManager, dataSourceProvider, sessionService, authEmailService, userEnricher){
|
|
955
|
+
constructor(jwtService, authConfig, cacheManager, dataSourceProvider, sessionService, authEmailService, userEnricher, notificationAdapter){
|
|
824
956
|
_define_property(this, "jwtService", void 0);
|
|
825
957
|
_define_property(this, "authConfig", void 0);
|
|
826
958
|
_define_property(this, "cacheManager", void 0);
|
|
@@ -828,7 +960,7 @@ let AuthenticationService = class AuthenticationService {
|
|
|
828
960
|
_define_property(this, "sessionService", void 0);
|
|
829
961
|
_define_property(this, "authEmailService", void 0);
|
|
830
962
|
_define_property(this, "userEnricher", void 0);
|
|
831
|
-
_define_property(this, "
|
|
963
|
+
_define_property(this, "notificationAdapter", void 0);
|
|
832
964
|
this.jwtService = jwtService;
|
|
833
965
|
this.authConfig = authConfig;
|
|
834
966
|
this.cacheManager = cacheManager;
|
|
@@ -836,9 +968,109 @@ let AuthenticationService = class AuthenticationService {
|
|
|
836
968
|
this.sessionService = sessionService;
|
|
837
969
|
this.authEmailService = authEmailService;
|
|
838
970
|
this.userEnricher = userEnricher;
|
|
839
|
-
this.
|
|
971
|
+
this.notificationAdapter = notificationAdapter;
|
|
840
972
|
}
|
|
841
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);
|
|
842
1074
|
AuthenticationService = _ts_decorate([
|
|
843
1075
|
(0, _common.Injectable)({
|
|
844
1076
|
scope: _common.Scope.REQUEST
|
|
@@ -855,6 +1087,8 @@ AuthenticationService = _ts_decorate([
|
|
|
855
1087
|
_ts_param(5, (0, _common.Inject)(_authemailservice.AuthEmailService)),
|
|
856
1088
|
_ts_param(6, (0, _common.Optional)()),
|
|
857
1089
|
_ts_param(6, (0, _common.Inject)(_config.USER_ENRICHER)),
|
|
1090
|
+
_ts_param(7, (0, _common.Optional)()),
|
|
1091
|
+
_ts_param(7, (0, _common.Inject)(_interfaces.NOTIFICATION_ADAPTER)),
|
|
858
1092
|
_ts_metadata("design:type", Function),
|
|
859
1093
|
_ts_metadata("design:paramtypes", [
|
|
860
1094
|
typeof _jwt.JwtService === "undefined" ? Object : _jwt.JwtService,
|
|
@@ -863,6 +1097,7 @@ AuthenticationService = _ts_decorate([
|
|
|
863
1097
|
typeof _authdatasourceprovider.AuthDataSourceProvider === "undefined" ? Object : _authdatasourceprovider.AuthDataSourceProvider,
|
|
864
1098
|
typeof _companyselectionsessionservice.CompanySelectionSessionService === "undefined" ? Object : _companyselectionsessionservice.CompanySelectionSessionService,
|
|
865
1099
|
typeof _authemailservice.AuthEmailService === "undefined" ? Object : _authemailservice.AuthEmailService,
|
|
866
|
-
typeof _userenricherinterface.IUserEnricher === "undefined" ? Object : _userenricherinterface.IUserEnricher
|
|
1100
|
+
typeof _userenricherinterface.IUserEnricher === "undefined" ? Object : _userenricherinterface.IUserEnricher,
|
|
1101
|
+
typeof _interfaces.INotificationAdapter === "undefined" ? Object : _interfaces.INotificationAdapter
|
|
867
1102
|
])
|
|
868
1103
|
], AuthenticationService);
|