@flusys/nestjs-auth 6.4.0 → 7.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/config/event-actions.js +45 -0
- package/cjs/config/index.js +1 -0
- package/cjs/config/message-keys.js +12 -0
- package/cjs/modules/auth.module.js +2 -1
- package/cjs/services/auth-email.service.js +21 -0
- package/cjs/services/auth-email.service.spec.js +52 -0
- package/cjs/services/authentication.service.js +62 -4
- package/cjs/services/authentication.service.spec.js +58 -0
- package/cjs/services/branch.service.js +20 -0
- package/cjs/services/branch.service.spec.js +15 -0
- package/cjs/services/company.service.js +20 -0
- package/cjs/services/company.service.spec.js +14 -0
- package/cjs/services/user-permission.service.js +20 -0
- package/cjs/services/user-permission.service.spec.js +52 -0
- package/cjs/services/user.service.js +36 -18
- package/cjs/services/user.service.spec.js +15 -1
- package/config/event-actions.d.ts +21 -0
- package/config/index.d.ts +1 -0
- package/config/message-keys.d.ts +6 -0
- package/fesm/config/event-actions.js +24 -0
- package/fesm/config/index.js +1 -0
- package/fesm/config/message-keys.js +6 -0
- package/fesm/modules/auth.module.js +3 -2
- package/fesm/services/auth-email.service.js +22 -1
- package/fesm/services/auth-email.service.spec.js +52 -0
- package/fesm/services/authentication.service.js +64 -6
- package/fesm/services/authentication.service.spec.js +58 -0
- package/fesm/services/branch.service.js +22 -2
- package/fesm/services/branch.service.spec.js +15 -0
- package/fesm/services/company.service.js +22 -2
- package/fesm/services/company.service.spec.js +14 -0
- package/fesm/services/user-permission.service.js +21 -1
- package/fesm/services/user-permission.service.spec.js +52 -0
- package/fesm/services/user.service.js +36 -18
- package/fesm/services/user.service.spec.js +15 -1
- package/interfaces/auth-module-options.interface.d.ts +2 -0
- package/package.json +3 -3
- package/services/auth-email.service.d.ts +1 -0
- package/services/authentication.service.d.ts +3 -0
- package/services/user-permission.service.d.ts +1 -0
|
@@ -10,6 +10,7 @@ describe('BranchService', ()=>{
|
|
|
10
10
|
let mockQueryRunner;
|
|
11
11
|
beforeEach(()=>{
|
|
12
12
|
mockRepo = createMockRepository();
|
|
13
|
+
mockRepo.find.mockResolvedValue([]);
|
|
13
14
|
Object.assign(mockRepo.createQueryBuilder(), {
|
|
14
15
|
leftJoinAndSelect: jest.fn().mockReturnThis(),
|
|
15
16
|
addOrderBy: jest.fn().mockReturnThis()
|
|
@@ -78,6 +79,20 @@ describe('BranchService', ()=>{
|
|
|
78
79
|
}, null, mockQueryRunner);
|
|
79
80
|
expect(mockPermissionSyncAdapter.onBranchDeleted).toHaveBeenCalledWith('branch-1', 'company-1');
|
|
80
81
|
});
|
|
82
|
+
it('rejects deleting a readonly branch', async ()=>{
|
|
83
|
+
mockRepo.find.mockResolvedValue([
|
|
84
|
+
{
|
|
85
|
+
id: 'branch-1',
|
|
86
|
+
name: 'Default Branch',
|
|
87
|
+
readOnly: true
|
|
88
|
+
}
|
|
89
|
+
]);
|
|
90
|
+
const permissionRepo = mockQueryRunner.manager.getRepository(UserCompanyPermission);
|
|
91
|
+
await expect(service.beforeDeleteOperation({
|
|
92
|
+
id: 'branch-1'
|
|
93
|
+
}, null, mockQueryRunner)).rejects.toThrow('Cannot delete readonly branch');
|
|
94
|
+
expect(permissionRepo.delete).not.toHaveBeenCalled();
|
|
95
|
+
});
|
|
81
96
|
});
|
|
82
97
|
describe('getSelectQuery', ()=>{
|
|
83
98
|
it('applies the default selected fields when none are provided', async ()=>{
|
|
@@ -28,8 +28,9 @@ function _ts_param(paramIndex, decorator) {
|
|
|
28
28
|
import { ApiService, HybridCache } from '@flusys/nestjs-shared/classes';
|
|
29
29
|
import { IPermissionSyncAdapter, PERMISSION_SYNC_ADAPTER } from '@flusys/nestjs-shared/interfaces';
|
|
30
30
|
import { UtilsService } from '@flusys/nestjs-shared/modules';
|
|
31
|
-
import { Inject, Injectable, Optional, Scope } from '@nestjs/common';
|
|
32
|
-
import { In } from 'typeorm';
|
|
31
|
+
import { ForbiddenException, Inject, Injectable, Optional, Scope } from '@nestjs/common';
|
|
32
|
+
import { In, IsNull } from 'typeorm';
|
|
33
|
+
import { COMPANY_MESSAGES } from '../config';
|
|
33
34
|
import { CompanyBranch } from '../entities/company-branch.entity';
|
|
34
35
|
import { Company } from '../entities/company.entity';
|
|
35
36
|
import { UserCompanyPermission } from '../entities/user-company-permission.entity';
|
|
@@ -39,6 +40,24 @@ export class CompanyService extends ApiService {
|
|
|
39
40
|
const companyIds = Array.isArray(dto.id) ? dto.id : [
|
|
40
41
|
dto.id
|
|
41
42
|
];
|
|
43
|
+
await this.ensureDataSourceRepository();
|
|
44
|
+
const readonlyCompanies = await this.repository.find({
|
|
45
|
+
where: {
|
|
46
|
+
id: In(companyIds),
|
|
47
|
+
readOnly: true,
|
|
48
|
+
deletedAt: IsNull()
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
if (readonlyCompanies.length > 0) {
|
|
52
|
+
const names = readonlyCompanies.map((c)=>c.name).join(', ');
|
|
53
|
+
throw new ForbiddenException({
|
|
54
|
+
message: `Cannot delete readonly company(ies): ${names}`,
|
|
55
|
+
messageKey: COMPANY_MESSAGES.READONLY_DELETE_FORBIDDEN,
|
|
56
|
+
messageVariables: {
|
|
57
|
+
names
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
42
61
|
const branchRows = await queryRunner.manager.getRepository(CompanyBranch).find({
|
|
43
62
|
where: {
|
|
44
63
|
companyId: In(companyIds)
|
|
@@ -69,6 +88,7 @@ export class CompanyService extends ApiService {
|
|
|
69
88
|
'email',
|
|
70
89
|
'phone',
|
|
71
90
|
'isActive',
|
|
91
|
+
'readOnly',
|
|
72
92
|
'createdAt'
|
|
73
93
|
];
|
|
74
94
|
}
|
|
@@ -11,6 +11,7 @@ describe('CompanyService', ()=>{
|
|
|
11
11
|
let permissionRepo;
|
|
12
12
|
beforeEach(()=>{
|
|
13
13
|
mockRepo = createMockRepository();
|
|
14
|
+
mockRepo.find.mockResolvedValue([]);
|
|
14
15
|
const mockDataSourceProvider = createMockDataSourceProvider(mockRepo);
|
|
15
16
|
mockPermissionSyncAdapter = {
|
|
16
17
|
onCompanyDeleted: jest.fn()
|
|
@@ -75,6 +76,19 @@ describe('CompanyService', ()=>{
|
|
|
75
76
|
expect(mockPermissionSyncAdapter.onCompanyDeleted).toHaveBeenCalledWith('company-1');
|
|
76
77
|
expect(mockPermissionSyncAdapter.onCompanyDeleted).toHaveBeenCalledWith('company-2');
|
|
77
78
|
});
|
|
79
|
+
it('rejects deleting a readonly company', async ()=>{
|
|
80
|
+
mockRepo.find.mockResolvedValue([
|
|
81
|
+
{
|
|
82
|
+
id: 'company-1',
|
|
83
|
+
name: 'Default Company',
|
|
84
|
+
readOnly: true
|
|
85
|
+
}
|
|
86
|
+
]);
|
|
87
|
+
await expect(service.beforeDeleteOperation({
|
|
88
|
+
id: 'company-1'
|
|
89
|
+
}, null, mockQueryRunner)).rejects.toThrow('Cannot delete readonly company');
|
|
90
|
+
expect(branchRepo.find).not.toHaveBeenCalled();
|
|
91
|
+
});
|
|
78
92
|
});
|
|
79
93
|
describe('getSelectQuery', ()=>{
|
|
80
94
|
it('applies the default selected fields when none are provided', async ()=>{
|
|
@@ -26,9 +26,10 @@ function _ts_param(paramIndex, decorator) {
|
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
import { LogAction } from '@flusys/nestjs-shared';
|
|
29
|
+
import { publishDomainEvent } from '@flusys/nestjs-shared/classes';
|
|
29
30
|
import { IPermissionSyncAdapter, PERMISSION_SYNC_ADAPTER } from '@flusys/nestjs-shared/interfaces';
|
|
30
31
|
import { ConflictException, Inject, Injectable, NotFoundException, Optional, Scope } from '@nestjs/common';
|
|
31
|
-
import { USER_PERMISSION_MESSAGES } from '../config';
|
|
32
|
+
import { AUTH_EVENT_ACTIONS, AUTH_EVENT_ENTITIES, AUTH_EVENT_MODULE, USER_PERMISSION_MESSAGES } from '../config';
|
|
32
33
|
import { PermissionType, UserCompanyPermission } from '../entities/user-company-permission.entity';
|
|
33
34
|
import { AuthDataSourceProvider } from './auth-datasource.provider';
|
|
34
35
|
export class UserPermissionService {
|
|
@@ -92,6 +93,7 @@ export class UserPermissionService {
|
|
|
92
93
|
}
|
|
93
94
|
throw error;
|
|
94
95
|
}
|
|
96
|
+
await this.publishPermissionEvent(AUTH_EVENT_ACTIONS.PERMISSION_GRANTED, userId, targetId, type);
|
|
95
97
|
}
|
|
96
98
|
async revokePermission(userId, targetId, type) {
|
|
97
99
|
const repository = await this.getRepository();
|
|
@@ -124,6 +126,24 @@ export class UserPermissionService {
|
|
|
124
126
|
} else {
|
|
125
127
|
if (companyId) await this.permissionSyncAdapter?.onUserBranchAccessRevoked?.(userId, targetId, companyId);
|
|
126
128
|
}
|
|
129
|
+
await this.publishPermissionEvent(AUTH_EVENT_ACTIONS.PERMISSION_REVOKED, userId, targetId, type, companyId);
|
|
130
|
+
}
|
|
131
|
+
async publishPermissionEvent(action, userId, targetId, type, companyId) {
|
|
132
|
+
await publishDomainEvent({
|
|
133
|
+
module: AUTH_EVENT_MODULE,
|
|
134
|
+
entity: AUTH_EVENT_ENTITIES.USER_PERMISSION,
|
|
135
|
+
action,
|
|
136
|
+
ids: [
|
|
137
|
+
targetId
|
|
138
|
+
],
|
|
139
|
+
metadata: {
|
|
140
|
+
targetUserId: userId,
|
|
141
|
+
permissionType: type,
|
|
142
|
+
...companyId ? {
|
|
143
|
+
companyId
|
|
144
|
+
} : {}
|
|
145
|
+
}
|
|
146
|
+
});
|
|
127
147
|
}
|
|
128
148
|
async revokeBranchPermissionsForCompany(repository, userId, companyId) {
|
|
129
149
|
const branchPermissions = await repository.createQueryBuilder('permission').innerJoin('permission.branch', 'branch').where('permission.userId = :userId', {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ConflictException, NotFoundException } from '@nestjs/common';
|
|
2
|
+
import { EventBusRegistry } from '@flusys/nestjs-shared/classes';
|
|
2
3
|
import { createMockDataSourceProvider, createMockRepository } from '@test-utils/mocks/repository.mock';
|
|
3
4
|
import { UserPermissionService } from './user-permission.service';
|
|
4
5
|
import { PermissionType } from '../entities/user-company-permission.entity';
|
|
@@ -195,4 +196,55 @@ describe('UserPermissionService', ()=>{
|
|
|
195
196
|
});
|
|
196
197
|
});
|
|
197
198
|
});
|
|
199
|
+
describe('domain events', ()=>{
|
|
200
|
+
let publish;
|
|
201
|
+
beforeEach(()=>{
|
|
202
|
+
publish = jest.fn().mockResolvedValue(undefined);
|
|
203
|
+
EventBusRegistry.reset();
|
|
204
|
+
EventBusRegistry.setBus({
|
|
205
|
+
publish,
|
|
206
|
+
subscribe: jest.fn(),
|
|
207
|
+
close: jest.fn()
|
|
208
|
+
});
|
|
209
|
+
EventBusRegistry.configureModule('auth', {
|
|
210
|
+
enabled: true
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
afterEach(()=>{
|
|
214
|
+
EventBusRegistry.reset();
|
|
215
|
+
});
|
|
216
|
+
it('publishes permission-granted after a new assignment', async ()=>{
|
|
217
|
+
mockRepo.findOne.mockResolvedValue(null);
|
|
218
|
+
mockRepo.create.mockReturnValue(buildPermission());
|
|
219
|
+
mockRepo.save.mockResolvedValue(buildPermission());
|
|
220
|
+
await service.assignPermission('user-1', 'company-1', PermissionType.COMPANY);
|
|
221
|
+
expect(publish).toHaveBeenCalledWith(expect.objectContaining({
|
|
222
|
+
name: 'auth.user_company_permission.permission-granted',
|
|
223
|
+
payload: expect.objectContaining({
|
|
224
|
+
ids: [
|
|
225
|
+
'company-1'
|
|
226
|
+
],
|
|
227
|
+
metadata: expect.objectContaining({
|
|
228
|
+
targetUserId: 'user-1',
|
|
229
|
+
permissionType: PermissionType.COMPANY
|
|
230
|
+
})
|
|
231
|
+
})
|
|
232
|
+
}));
|
|
233
|
+
});
|
|
234
|
+
it('does not publish when the assignment is rejected as a duplicate', async ()=>{
|
|
235
|
+
mockRepo.findOne.mockResolvedValue(buildPermission());
|
|
236
|
+
await expect(service.assignPermission('user-1', 'company-1', PermissionType.COMPANY)).rejects.toThrow(ConflictException);
|
|
237
|
+
expect(publish).not.toHaveBeenCalled();
|
|
238
|
+
});
|
|
239
|
+
it('does not publish when the auth module has events disabled', async ()=>{
|
|
240
|
+
EventBusRegistry.configureModule('auth', {
|
|
241
|
+
enabled: false
|
|
242
|
+
});
|
|
243
|
+
mockRepo.findOne.mockResolvedValue(null);
|
|
244
|
+
mockRepo.create.mockReturnValue(buildPermission());
|
|
245
|
+
mockRepo.save.mockResolvedValue(buildPermission());
|
|
246
|
+
await service.assignPermission('user-1', 'company-1', PermissionType.COMPANY);
|
|
247
|
+
expect(publish).not.toHaveBeenCalled();
|
|
248
|
+
});
|
|
249
|
+
});
|
|
198
250
|
});
|
|
@@ -79,10 +79,13 @@ export class UserService extends ApiService {
|
|
|
79
79
|
await this.repository.update(id, {
|
|
80
80
|
emailVerified: true
|
|
81
81
|
});
|
|
82
|
-
await
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
await Promise.all([
|
|
83
|
+
this.clearCacheForAll(),
|
|
84
|
+
this.clearCacheForId([
|
|
85
|
+
{
|
|
86
|
+
id
|
|
87
|
+
}
|
|
88
|
+
])
|
|
86
89
|
]);
|
|
87
90
|
}
|
|
88
91
|
async verifyPhone(id) {
|
|
@@ -90,10 +93,13 @@ export class UserService extends ApiService {
|
|
|
90
93
|
await this.repository.update(id, {
|
|
91
94
|
phoneVerified: true
|
|
92
95
|
});
|
|
93
|
-
await
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
96
|
+
await Promise.all([
|
|
97
|
+
this.clearCacheForAll(),
|
|
98
|
+
this.clearCacheForId([
|
|
99
|
+
{
|
|
100
|
+
id
|
|
101
|
+
}
|
|
102
|
+
])
|
|
97
103
|
]);
|
|
98
104
|
}
|
|
99
105
|
async updateStatus(id, isActive, user) {
|
|
@@ -123,10 +129,13 @@ export class UserService extends ApiService {
|
|
|
123
129
|
isActive
|
|
124
130
|
});
|
|
125
131
|
}
|
|
126
|
-
await
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
132
|
+
await Promise.all([
|
|
133
|
+
this.clearCacheForAll(),
|
|
134
|
+
this.clearCacheForId([
|
|
135
|
+
{
|
|
136
|
+
id
|
|
137
|
+
}
|
|
138
|
+
])
|
|
130
139
|
]);
|
|
131
140
|
}
|
|
132
141
|
async convertSingleDtoToEntity(dto, user) {
|
|
@@ -350,8 +359,11 @@ export class UserService extends ApiService {
|
|
|
350
359
|
}
|
|
351
360
|
}
|
|
352
361
|
await queryRunner.commitTransaction();
|
|
353
|
-
await
|
|
354
|
-
|
|
362
|
+
await Promise.all([
|
|
363
|
+
this.clearCacheForAll(),
|
|
364
|
+
this.clearCacheForId([
|
|
365
|
+
savedUser
|
|
366
|
+
])
|
|
355
367
|
]);
|
|
356
368
|
return this.convertEntityToResponseDto(savedUser, false);
|
|
357
369
|
} catch (error) {
|
|
@@ -420,8 +432,11 @@ export class UserService extends ApiService {
|
|
|
420
432
|
try {
|
|
421
433
|
await this.userEnricher.updateProfileSection(userId, sectionId, data, queryRunner);
|
|
422
434
|
await queryRunner.commitTransaction();
|
|
423
|
-
await
|
|
424
|
-
|
|
435
|
+
await Promise.all([
|
|
436
|
+
this.clearCacheForAll(),
|
|
437
|
+
this.clearCacheForId([
|
|
438
|
+
userEntity
|
|
439
|
+
])
|
|
425
440
|
]);
|
|
426
441
|
} catch (error) {
|
|
427
442
|
await queryRunner.rollbackTransaction();
|
|
@@ -490,8 +505,11 @@ export class UserService extends ApiService {
|
|
|
490
505
|
await this.userEnricher.updateProfileExtras(userId, extras, queryRunner);
|
|
491
506
|
}
|
|
492
507
|
await queryRunner.commitTransaction();
|
|
493
|
-
await
|
|
494
|
-
|
|
508
|
+
await Promise.all([
|
|
509
|
+
this.clearCacheForAll(),
|
|
510
|
+
this.clearCacheForId([
|
|
511
|
+
findUser
|
|
512
|
+
])
|
|
495
513
|
]);
|
|
496
514
|
return findUser.id;
|
|
497
515
|
} catch (error) {
|
|
@@ -79,6 +79,13 @@ describe('UserService', ()=>{
|
|
|
79
79
|
};
|
|
80
80
|
service = new UserService({}, mockUtilsService, mockDataSourceProvider, mockAuthConfig, mockUserEnricher);
|
|
81
81
|
});
|
|
82
|
+
/**
|
|
83
|
+
* Every write path has to drop both the list cache and the row's own cache, or a
|
|
84
|
+
* stale user keeps being served from `get-all`.
|
|
85
|
+
*/ function expectCacheCleared(id) {
|
|
86
|
+
expect(mockUtilsService.clearCache).toHaveBeenCalledWith('appuser', expect.anything());
|
|
87
|
+
expect(mockUtilsService.clearCache).toHaveBeenCalledWith('appuser', expect.anything(), id);
|
|
88
|
+
}
|
|
82
89
|
describe('ensureDataSourceRepository', ()=>{
|
|
83
90
|
it('does not load the permission repository when the company feature is disabled', async ()=>{
|
|
84
91
|
await service.ensureDataSourceRepository();
|
|
@@ -97,13 +104,14 @@ describe('UserService', ()=>{
|
|
|
97
104
|
expect(userRepo.update).toHaveBeenCalledWith('user-1', {
|
|
98
105
|
emailVerified: true
|
|
99
106
|
});
|
|
100
|
-
|
|
107
|
+
expectCacheCleared('user-1');
|
|
101
108
|
});
|
|
102
109
|
it('marks the phone as verified and clears the cache', async ()=>{
|
|
103
110
|
await service.verifyPhone('user-1');
|
|
104
111
|
expect(userRepo.update).toHaveBeenCalledWith('user-1', {
|
|
105
112
|
phoneVerified: true
|
|
106
113
|
});
|
|
114
|
+
expectCacheCleared('user-1');
|
|
107
115
|
});
|
|
108
116
|
});
|
|
109
117
|
describe('updateStatus', ()=>{
|
|
@@ -112,6 +120,7 @@ describe('UserService', ()=>{
|
|
|
112
120
|
expect(userRepo.update).toHaveBeenCalledWith('user-1', {
|
|
113
121
|
isActive: false
|
|
114
122
|
});
|
|
123
|
+
expectCacheCleared('user-1');
|
|
115
124
|
});
|
|
116
125
|
it('throws NotFoundException when the company permission is missing', async ()=>{
|
|
117
126
|
companyFeatureEnabled = true;
|
|
@@ -134,6 +143,7 @@ describe('UserService', ()=>{
|
|
|
134
143
|
isActive: false
|
|
135
144
|
}));
|
|
136
145
|
expect(userRepo.update).not.toHaveBeenCalled();
|
|
146
|
+
expectCacheCleared('user-1');
|
|
137
147
|
});
|
|
138
148
|
});
|
|
139
149
|
describe('convertSingleDtoToEntity', ()=>{
|
|
@@ -344,6 +354,7 @@ describe('UserService', ()=>{
|
|
|
344
354
|
expect(result).toEqual(expect.objectContaining({
|
|
345
355
|
id: 'user-1'
|
|
346
356
|
}));
|
|
357
|
+
expectCacheCleared(savedUser.id);
|
|
347
358
|
});
|
|
348
359
|
it('rolls back the transaction if permission assignment fails', async ()=>{
|
|
349
360
|
companyFeatureEnabled = true;
|
|
@@ -532,6 +543,7 @@ describe('UserService', ()=>{
|
|
|
532
543
|
foo: 'bar'
|
|
533
544
|
}, queryRunner);
|
|
534
545
|
expect(queryRunner.commitTransaction).toHaveBeenCalled();
|
|
546
|
+
expectCacheCleared('user-1');
|
|
535
547
|
});
|
|
536
548
|
it('rolls back the transaction when the enricher throws', async ()=>{
|
|
537
549
|
userRepo.findOne.mockResolvedValue(buildAppUser());
|
|
@@ -625,6 +637,7 @@ describe('UserService', ()=>{
|
|
|
625
637
|
expect(queryRunner.manager.save).toHaveBeenCalled();
|
|
626
638
|
expect(queryRunner.commitTransaction).toHaveBeenCalled();
|
|
627
639
|
expect(result).toBe('user-1');
|
|
640
|
+
expectCacheCleared('user-1');
|
|
628
641
|
});
|
|
629
642
|
it('does not require the current password when an admin updates another user profile', async ()=>{
|
|
630
643
|
service.dataSource = mockDataSource;
|
|
@@ -641,6 +654,7 @@ describe('UserService', ()=>{
|
|
|
641
654
|
}));
|
|
642
655
|
expect(queryRunner.manager.save).toHaveBeenCalled();
|
|
643
656
|
expect(queryRunner.commitTransaction).toHaveBeenCalled();
|
|
657
|
+
expectCacheCleared('other-user');
|
|
644
658
|
});
|
|
645
659
|
it('rolls back the transaction when save fails', async ()=>{
|
|
646
660
|
service.dataSource = mockDataSource;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IBootstrapAppConfig, IDataSourceServiceOptions, IDynamicModuleConfig, IModuleOptionsFactory } from '@flusys/nestjs-core';
|
|
2
|
+
import { IModuleEventsConfig } from '@flusys/nestjs-shared/interfaces';
|
|
2
3
|
import { ModuleMetadata, Provider, Type } from '@nestjs/common';
|
|
3
4
|
export interface IAuthModuleConfig extends IDataSourceServiceOptions {
|
|
4
5
|
jwtSecret?: string;
|
|
@@ -6,6 +7,7 @@ export interface IAuthModuleConfig extends IDataSourceServiceOptions {
|
|
|
6
7
|
refreshTokenSecret?: string;
|
|
7
8
|
refreshTokenExpiration?: string;
|
|
8
9
|
refreshTokenCookieName?: string;
|
|
10
|
+
events?: IModuleEventsConfig;
|
|
9
11
|
}
|
|
10
12
|
export interface AuthModuleOptions extends IDynamicModuleConfig {
|
|
11
13
|
bootstrapAppConfig?: IBootstrapAppConfig;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flusys/nestjs-auth",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0-beta.1",
|
|
4
4
|
"description": "Authentication and authorization infrastructure for NestJS applications",
|
|
5
5
|
"main": "cjs/index.js",
|
|
6
6
|
"module": "fesm/index.js",
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"rxjs": "^7.8.0"
|
|
99
99
|
},
|
|
100
100
|
"dependencies": {
|
|
101
|
-
"@flusys/nestjs-core": "
|
|
102
|
-
"@flusys/nestjs-shared": "
|
|
101
|
+
"@flusys/nestjs-core": "7.0.0-beta.1",
|
|
102
|
+
"@flusys/nestjs-shared": "7.0.0-beta.1"
|
|
103
103
|
}
|
|
104
104
|
}
|
|
@@ -61,4 +61,7 @@ export declare class AuthenticationService {
|
|
|
61
61
|
private generateCompanySelectionResponse;
|
|
62
62
|
private generateRegistrationResponse;
|
|
63
63
|
private generateRegistrationResponseWithCompany;
|
|
64
|
+
private publishSessionEvent;
|
|
65
|
+
private publishUserEvent;
|
|
66
|
+
private publishAuthEvent;
|
|
64
67
|
}
|
|
@@ -10,6 +10,7 @@ export declare class UserPermissionService {
|
|
|
10
10
|
findUserPermissions(userId: string, type: PermissionType): Promise<UserCompanyPermission[]>;
|
|
11
11
|
assignPermission(userId: string, targetId: string, type: PermissionType): Promise<void>;
|
|
12
12
|
revokePermission(userId: string, targetId: string, type: PermissionType): Promise<void>;
|
|
13
|
+
private publishPermissionEvent;
|
|
13
14
|
private revokeBranchPermissionsForCompany;
|
|
14
15
|
findUserCompanies: (userId: string) => Promise<UserCompanyPermission[]>;
|
|
15
16
|
findUserBranches(userId: string, companyId?: string): Promise<UserCompanyPermission[]>;
|