@flusys/nestjs-auth 6.0.0 → 6.0.2
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/entities/company-branch.entity.js +2 -3
- package/cjs/services/authentication.service.js +8 -3
- package/cjs/services/branch.service.js +30 -3
- package/cjs/services/company.service.js +34 -3
- package/cjs/services/user-permission.service.js +35 -4
- package/entities/company-branch.entity.d.ts +1 -1
- package/fesm/entities/company-branch.entity.js +2 -3
- package/fesm/services/authentication.service.js +8 -3
- package/fesm/services/branch.service.js +32 -5
- package/fesm/services/company.service.js +36 -5
- package/fesm/services/user-permission.service.js +36 -5
- package/package.json +3 -3
- package/services/branch.service.d.ts +7 -5
- package/services/company.service.d.ts +7 -4
- package/services/user-permission.service.d.ts +4 -1
|
@@ -139,10 +139,9 @@ _ts_decorate([
|
|
|
139
139
|
_ts_decorate([
|
|
140
140
|
(0, _typeorm.Column)({
|
|
141
141
|
name: 'company_id',
|
|
142
|
-
type: 'uuid'
|
|
143
|
-
nullable: true
|
|
142
|
+
type: 'uuid'
|
|
144
143
|
}),
|
|
145
|
-
_ts_metadata("design:type",
|
|
144
|
+
_ts_metadata("design:type", String)
|
|
146
145
|
], CompanyBranch.prototype, "companyId", void 0);
|
|
147
146
|
_ts_decorate([
|
|
148
147
|
(0, _typeorm.ManyToOne)(()=>_companyentity.Company, (company)=>company.branches, {
|
|
@@ -591,7 +591,10 @@ let AuthenticationService = class AuthenticationService {
|
|
|
591
591
|
async refreshToken(refreshToken) {
|
|
592
592
|
try {
|
|
593
593
|
const payload = this.jwtService.verify(refreshToken, {
|
|
594
|
-
secret: this.authConfig.getRefreshTokenSecret()
|
|
594
|
+
secret: this.authConfig.getRefreshTokenSecret(),
|
|
595
|
+
algorithms: [
|
|
596
|
+
'HS256'
|
|
597
|
+
]
|
|
595
598
|
});
|
|
596
599
|
if (await this.isTokenRevoked(payload.id, payload.iat)) {
|
|
597
600
|
throw new _common.UnauthorizedException({
|
|
@@ -943,14 +946,16 @@ let AuthenticationService = class AuthenticationService {
|
|
|
943
946
|
type: 'access'
|
|
944
947
|
}, {
|
|
945
948
|
secret: this.authConfig.getJwtSecret(),
|
|
946
|
-
expiresIn: this.authConfig.getJwtExpiration()
|
|
949
|
+
expiresIn: this.authConfig.getJwtExpiration(),
|
|
950
|
+
algorithm: 'HS256'
|
|
947
951
|
});
|
|
948
952
|
const refreshToken = this.jwtService.sign({
|
|
949
953
|
...payload,
|
|
950
954
|
type: 'refresh'
|
|
951
955
|
}, {
|
|
952
956
|
secret: this.authConfig.getRefreshTokenSecret(),
|
|
953
|
-
expiresIn: this.authConfig.getRefreshTokenExpiration()
|
|
957
|
+
expiresIn: this.authConfig.getRefreshTokenExpiration(),
|
|
958
|
+
algorithm: 'HS256'
|
|
954
959
|
});
|
|
955
960
|
return {
|
|
956
961
|
accessToken,
|
|
@@ -9,10 +9,13 @@ Object.defineProperty(exports, "BranchService", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
const _classes = require("@flusys/nestjs-shared/classes");
|
|
12
|
+
const _interfaces = require("@flusys/nestjs-shared/interfaces");
|
|
12
13
|
const _modules = require("@flusys/nestjs-shared/modules");
|
|
13
14
|
const _utils = require("@flusys/nestjs-shared/utils");
|
|
14
15
|
const _common = require("@nestjs/common");
|
|
16
|
+
const _typeorm = require("typeorm");
|
|
15
17
|
const _companybranchentity = require("../entities/company-branch.entity");
|
|
18
|
+
const _usercompanypermissionentity = require("../entities/user-company-permission.entity");
|
|
16
19
|
const _authconfigservice = require("./auth-config.service");
|
|
17
20
|
const _authdatasourceprovider = require("./auth-datasource.provider");
|
|
18
21
|
function _define_property(obj, key, value) {
|
|
@@ -43,6 +46,27 @@ function _ts_param(paramIndex, decorator) {
|
|
|
43
46
|
};
|
|
44
47
|
}
|
|
45
48
|
let BranchService = class BranchService extends _classes.ApiService {
|
|
49
|
+
async beforeDeleteOperation(dto, user, queryRunner) {
|
|
50
|
+
const branchIds = Array.isArray(dto.id) ? dto.id : [
|
|
51
|
+
dto.id
|
|
52
|
+
];
|
|
53
|
+
await queryRunner.manager.getRepository(_usercompanypermissionentity.UserCompanyPermission).delete({
|
|
54
|
+
targetId: (0, _typeorm.In)(branchIds)
|
|
55
|
+
});
|
|
56
|
+
if (!this.permissionSyncAdapter?.onBranchDeleted) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const rows = await queryRunner.manager.getRepository(_companybranchentity.CompanyBranch).find({
|
|
60
|
+
where: {
|
|
61
|
+
id: (0, _typeorm.In)(branchIds)
|
|
62
|
+
},
|
|
63
|
+
select: [
|
|
64
|
+
'id',
|
|
65
|
+
'companyId'
|
|
66
|
+
]
|
|
67
|
+
});
|
|
68
|
+
await Promise.all(rows.map((row)=>this.permissionSyncAdapter.onBranchDeleted(row.id, row.companyId)));
|
|
69
|
+
}
|
|
46
70
|
// Query Customization
|
|
47
71
|
async getSelectQuery(query, _user, select) {
|
|
48
72
|
if (!select?.length) {
|
|
@@ -84,8 +108,8 @@ let BranchService = class BranchService extends _classes.ApiService {
|
|
|
84
108
|
}
|
|
85
109
|
return result;
|
|
86
110
|
}
|
|
87
|
-
constructor(cacheManager, utilsService, dataSourceProvider, authConfig){
|
|
88
|
-
super('company_branch', cacheManager, utilsService, BranchService.name, true, 'auth', _companybranchentity.CompanyBranch, dataSourceProvider), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "authConfig", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.authConfig = authConfig;
|
|
111
|
+
constructor(cacheManager, utilsService, dataSourceProvider, authConfig, permissionSyncAdapter){
|
|
112
|
+
super('company_branch', cacheManager, utilsService, BranchService.name, true, 'auth', _companybranchentity.CompanyBranch, dataSourceProvider), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "authConfig", void 0), _define_property(this, "permissionSyncAdapter", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.authConfig = authConfig, this.permissionSyncAdapter = permissionSyncAdapter;
|
|
89
113
|
}
|
|
90
114
|
};
|
|
91
115
|
BranchService = _ts_decorate([
|
|
@@ -96,11 +120,14 @@ BranchService = _ts_decorate([
|
|
|
96
120
|
_ts_param(1, (0, _common.Inject)(_modules.UtilsService)),
|
|
97
121
|
_ts_param(2, (0, _common.Inject)(_authdatasourceprovider.AuthDataSourceProvider)),
|
|
98
122
|
_ts_param(3, (0, _common.Inject)(_authconfigservice.AuthConfigService)),
|
|
123
|
+
_ts_param(4, (0, _common.Optional)()),
|
|
124
|
+
_ts_param(4, (0, _common.Inject)(_interfaces.PERMISSION_SYNC_ADAPTER)),
|
|
99
125
|
_ts_metadata("design:type", Function),
|
|
100
126
|
_ts_metadata("design:paramtypes", [
|
|
101
127
|
typeof _classes.HybridCache === "undefined" ? Object : _classes.HybridCache,
|
|
102
128
|
typeof _modules.UtilsService === "undefined" ? Object : _modules.UtilsService,
|
|
103
129
|
typeof _authdatasourceprovider.AuthDataSourceProvider === "undefined" ? Object : _authdatasourceprovider.AuthDataSourceProvider,
|
|
104
|
-
typeof _authconfigservice.AuthConfigService === "undefined" ? Object : _authconfigservice.AuthConfigService
|
|
130
|
+
typeof _authconfigservice.AuthConfigService === "undefined" ? Object : _authconfigservice.AuthConfigService,
|
|
131
|
+
typeof _interfaces.IPermissionSyncAdapter === "undefined" ? Object : _interfaces.IPermissionSyncAdapter
|
|
105
132
|
])
|
|
106
133
|
], BranchService);
|
|
@@ -9,9 +9,13 @@ Object.defineProperty(exports, "CompanyService", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
const _classes = require("@flusys/nestjs-shared/classes");
|
|
12
|
+
const _interfaces = require("@flusys/nestjs-shared/interfaces");
|
|
12
13
|
const _modules = require("@flusys/nestjs-shared/modules");
|
|
13
14
|
const _common = require("@nestjs/common");
|
|
15
|
+
const _typeorm = require("typeorm");
|
|
16
|
+
const _companybranchentity = require("../entities/company-branch.entity");
|
|
14
17
|
const _companyentity = require("../entities/company.entity");
|
|
18
|
+
const _usercompanypermissionentity = require("../entities/user-company-permission.entity");
|
|
15
19
|
const _authdatasourceprovider = require("./auth-datasource.provider");
|
|
16
20
|
function _define_property(obj, key, value) {
|
|
17
21
|
if (key in obj) {
|
|
@@ -41,6 +45,30 @@ function _ts_param(paramIndex, decorator) {
|
|
|
41
45
|
};
|
|
42
46
|
}
|
|
43
47
|
let CompanyService = class CompanyService extends _classes.ApiService {
|
|
48
|
+
async beforeDeleteOperation(dto, user, queryRunner) {
|
|
49
|
+
const companyIds = Array.isArray(dto.id) ? dto.id : [
|
|
50
|
+
dto.id
|
|
51
|
+
];
|
|
52
|
+
const branchRows = await queryRunner.manager.getRepository(_companybranchentity.CompanyBranch).find({
|
|
53
|
+
where: {
|
|
54
|
+
companyId: (0, _typeorm.In)(companyIds)
|
|
55
|
+
},
|
|
56
|
+
select: [
|
|
57
|
+
'id'
|
|
58
|
+
]
|
|
59
|
+
});
|
|
60
|
+
const targetIds = [
|
|
61
|
+
...companyIds,
|
|
62
|
+
...branchRows.map((row)=>row.id)
|
|
63
|
+
];
|
|
64
|
+
await queryRunner.manager.getRepository(_usercompanypermissionentity.UserCompanyPermission).delete({
|
|
65
|
+
targetId: (0, _typeorm.In)(targetIds)
|
|
66
|
+
});
|
|
67
|
+
if (!this.permissionSyncAdapter?.onCompanyDeleted) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
await Promise.all(companyIds.map((companyId)=>this.permissionSyncAdapter.onCompanyDeleted(companyId)));
|
|
71
|
+
}
|
|
44
72
|
// Query Customization
|
|
45
73
|
async getSelectQuery(query, _user, select) {
|
|
46
74
|
if (!select?.length) {
|
|
@@ -69,8 +97,8 @@ let CompanyService = class CompanyService extends _classes.ApiService {
|
|
|
69
97
|
isRaw: false
|
|
70
98
|
};
|
|
71
99
|
}
|
|
72
|
-
constructor(cacheManager, utilsService, dataSourceProvider){
|
|
73
|
-
super('company', cacheManager, utilsService, CompanyService.name, true, 'auth', _companyentity.Company, dataSourceProvider), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService;
|
|
100
|
+
constructor(cacheManager, utilsService, dataSourceProvider, permissionSyncAdapter){
|
|
101
|
+
super('company', cacheManager, utilsService, CompanyService.name, true, 'auth', _companyentity.Company, dataSourceProvider), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "permissionSyncAdapter", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.permissionSyncAdapter = permissionSyncAdapter;
|
|
74
102
|
}
|
|
75
103
|
};
|
|
76
104
|
CompanyService = _ts_decorate([
|
|
@@ -80,10 +108,13 @@ CompanyService = _ts_decorate([
|
|
|
80
108
|
_ts_param(0, (0, _common.Inject)('CACHE_INSTANCE')),
|
|
81
109
|
_ts_param(1, (0, _common.Inject)(_modules.UtilsService)),
|
|
82
110
|
_ts_param(2, (0, _common.Inject)(_authdatasourceprovider.AuthDataSourceProvider)),
|
|
111
|
+
_ts_param(3, (0, _common.Optional)()),
|
|
112
|
+
_ts_param(3, (0, _common.Inject)(_interfaces.PERMISSION_SYNC_ADAPTER)),
|
|
83
113
|
_ts_metadata("design:type", Function),
|
|
84
114
|
_ts_metadata("design:paramtypes", [
|
|
85
115
|
typeof _classes.HybridCache === "undefined" ? Object : _classes.HybridCache,
|
|
86
116
|
typeof _modules.UtilsService === "undefined" ? Object : _modules.UtilsService,
|
|
87
|
-
typeof _authdatasourceprovider.AuthDataSourceProvider === "undefined" ? Object : _authdatasourceprovider.AuthDataSourceProvider
|
|
117
|
+
typeof _authdatasourceprovider.AuthDataSourceProvider === "undefined" ? Object : _authdatasourceprovider.AuthDataSourceProvider,
|
|
118
|
+
typeof _interfaces.IPermissionSyncAdapter === "undefined" ? Object : _interfaces.IPermissionSyncAdapter
|
|
88
119
|
])
|
|
89
120
|
], CompanyService);
|
|
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "UserPermissionService", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
const _nestjsshared = require("@flusys/nestjs-shared");
|
|
12
|
+
const _interfaces = require("@flusys/nestjs-shared/interfaces");
|
|
12
13
|
const _common = require("@nestjs/common");
|
|
13
14
|
const _config = require("../config");
|
|
14
15
|
const _usercompanypermissionentity = require("../entities/user-company-permission.entity");
|
|
@@ -102,7 +103,7 @@ let UserPermissionService = class UserPermissionService {
|
|
|
102
103
|
throw error;
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
|
-
|
|
106
|
+
async revokePermission(userId, targetId, type) {
|
|
106
107
|
const repository = await this.getRepository();
|
|
107
108
|
const typeName = type === _usercompanypermissionentity.PermissionType.COMPANY ? 'company' : 'branch';
|
|
108
109
|
const permission = await repository.findOne({
|
|
@@ -110,7 +111,10 @@ let UserPermissionService = class UserPermissionService {
|
|
|
110
111
|
userId,
|
|
111
112
|
targetId,
|
|
112
113
|
permissionType: type
|
|
113
|
-
}
|
|
114
|
+
},
|
|
115
|
+
relations: [
|
|
116
|
+
type === _usercompanypermissionentity.PermissionType.BRANCH ? 'branch' : 'company'
|
|
117
|
+
]
|
|
114
118
|
});
|
|
115
119
|
if (!permission) {
|
|
116
120
|
throw new _common.NotFoundException({
|
|
@@ -121,7 +125,29 @@ let UserPermissionService = class UserPermissionService {
|
|
|
121
125
|
}
|
|
122
126
|
});
|
|
123
127
|
}
|
|
128
|
+
const companyId = type === _usercompanypermissionentity.PermissionType.COMPANY ? targetId : permission.branch?.companyId;
|
|
124
129
|
await repository.remove(permission);
|
|
130
|
+
if (type === _usercompanypermissionentity.PermissionType.COMPANY) {
|
|
131
|
+
const revokedBranchIds = await this.revokeBranchPermissionsForCompany(repository, userId, targetId);
|
|
132
|
+
await this.permissionSyncAdapter?.onUserCompanyAccessRevoked?.(userId, targetId);
|
|
133
|
+
await Promise.all(revokedBranchIds.map((branchId)=>this.permissionSyncAdapter?.onUserBranchAccessRevoked?.(userId, branchId, targetId)));
|
|
134
|
+
} else {
|
|
135
|
+
if (companyId) await this.permissionSyncAdapter?.onUserBranchAccessRevoked?.(userId, targetId, companyId);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async revokeBranchPermissionsForCompany(repository, userId, companyId) {
|
|
139
|
+
const branchPermissions = await repository.createQueryBuilder('permission').innerJoin('permission.branch', 'branch').where('permission.userId = :userId', {
|
|
140
|
+
userId
|
|
141
|
+
}).andWhere('permission.permissionType = :type', {
|
|
142
|
+
type: _usercompanypermissionentity.PermissionType.BRANCH
|
|
143
|
+
}).andWhere('branch.companyId = :companyId', {
|
|
144
|
+
companyId
|
|
145
|
+
}).getMany();
|
|
146
|
+
if (branchPermissions.length === 0) {
|
|
147
|
+
return [];
|
|
148
|
+
}
|
|
149
|
+
await repository.remove(branchPermissions);
|
|
150
|
+
return branchPermissions.map((permission)=>permission.targetId);
|
|
125
151
|
}
|
|
126
152
|
/** Find user branch permissions with optional company filter */ async findUserBranches(userId, companyId) {
|
|
127
153
|
const repository = await this.getRepository();
|
|
@@ -137,12 +163,14 @@ let UserPermissionService = class UserPermissionService {
|
|
|
137
163
|
}
|
|
138
164
|
return queryBuilder.getMany();
|
|
139
165
|
}
|
|
140
|
-
constructor(dataSourceProvider){
|
|
166
|
+
constructor(dataSourceProvider, permissionSyncAdapter){
|
|
141
167
|
_define_property(this, "dataSourceProvider", void 0);
|
|
168
|
+
_define_property(this, "permissionSyncAdapter", void 0);
|
|
142
169
|
_define_property(this, "_repository", void 0);
|
|
143
170
|
// Convenience Methods
|
|
144
171
|
_define_property(this, "findUserCompanies", void 0);
|
|
145
172
|
this.dataSourceProvider = dataSourceProvider;
|
|
173
|
+
this.permissionSyncAdapter = permissionSyncAdapter;
|
|
146
174
|
this._repository = null;
|
|
147
175
|
this.findUserCompanies = (userId)=>this.findUserPermissions(userId, _usercompanypermissionentity.PermissionType.COMPANY);
|
|
148
176
|
}
|
|
@@ -178,8 +206,11 @@ UserPermissionService = _ts_decorate([
|
|
|
178
206
|
scope: _common.Scope.REQUEST
|
|
179
207
|
}),
|
|
180
208
|
_ts_param(0, (0, _common.Inject)(_authdatasourceprovider.AuthDataSourceProvider)),
|
|
209
|
+
_ts_param(1, (0, _common.Optional)()),
|
|
210
|
+
_ts_param(1, (0, _common.Inject)(_interfaces.PERMISSION_SYNC_ADAPTER)),
|
|
181
211
|
_ts_metadata("design:type", Function),
|
|
182
212
|
_ts_metadata("design:paramtypes", [
|
|
183
|
-
typeof _authdatasourceprovider.AuthDataSourceProvider === "undefined" ? Object : _authdatasourceprovider.AuthDataSourceProvider
|
|
213
|
+
typeof _authdatasourceprovider.AuthDataSourceProvider === "undefined" ? Object : _authdatasourceprovider.AuthDataSourceProvider,
|
|
214
|
+
typeof _interfaces.IPermissionSyncAdapter === "undefined" ? Object : _interfaces.IPermissionSyncAdapter
|
|
184
215
|
])
|
|
185
216
|
], UserPermissionService);
|
|
@@ -129,10 +129,9 @@ _ts_decorate([
|
|
|
129
129
|
_ts_decorate([
|
|
130
130
|
Column({
|
|
131
131
|
name: 'company_id',
|
|
132
|
-
type: 'uuid'
|
|
133
|
-
nullable: true
|
|
132
|
+
type: 'uuid'
|
|
134
133
|
}),
|
|
135
|
-
_ts_metadata("design:type",
|
|
134
|
+
_ts_metadata("design:type", String)
|
|
136
135
|
], CompanyBranch.prototype, "companyId", void 0);
|
|
137
136
|
_ts_decorate([
|
|
138
137
|
ManyToOne(()=>Company, (company)=>company.branches, {
|
|
@@ -540,7 +540,10 @@ export class AuthenticationService {
|
|
|
540
540
|
async refreshToken(refreshToken) {
|
|
541
541
|
try {
|
|
542
542
|
const payload = this.jwtService.verify(refreshToken, {
|
|
543
|
-
secret: this.authConfig.getRefreshTokenSecret()
|
|
543
|
+
secret: this.authConfig.getRefreshTokenSecret(),
|
|
544
|
+
algorithms: [
|
|
545
|
+
'HS256'
|
|
546
|
+
]
|
|
544
547
|
});
|
|
545
548
|
if (await this.isTokenRevoked(payload.id, payload.iat)) {
|
|
546
549
|
throw new UnauthorizedException({
|
|
@@ -892,14 +895,16 @@ export class AuthenticationService {
|
|
|
892
895
|
type: 'access'
|
|
893
896
|
}, {
|
|
894
897
|
secret: this.authConfig.getJwtSecret(),
|
|
895
|
-
expiresIn: this.authConfig.getJwtExpiration()
|
|
898
|
+
expiresIn: this.authConfig.getJwtExpiration(),
|
|
899
|
+
algorithm: 'HS256'
|
|
896
900
|
});
|
|
897
901
|
const refreshToken = this.jwtService.sign({
|
|
898
902
|
...payload,
|
|
899
903
|
type: 'refresh'
|
|
900
904
|
}, {
|
|
901
905
|
secret: this.authConfig.getRefreshTokenSecret(),
|
|
902
|
-
expiresIn: this.authConfig.getRefreshTokenExpiration()
|
|
906
|
+
expiresIn: this.authConfig.getRefreshTokenExpiration(),
|
|
907
|
+
algorithm: 'HS256'
|
|
903
908
|
});
|
|
904
909
|
return {
|
|
905
910
|
accessToken,
|
|
@@ -25,14 +25,38 @@ function _ts_param(paramIndex, decorator) {
|
|
|
25
25
|
decorator(target, key, paramIndex);
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
-
import {
|
|
28
|
+
import { ApiService, HybridCache } from '@flusys/nestjs-shared/classes';
|
|
29
|
+
import { IPermissionSyncAdapter, PERMISSION_SYNC_ADAPTER } from '@flusys/nestjs-shared/interfaces';
|
|
29
30
|
import { UtilsService } from '@flusys/nestjs-shared/modules';
|
|
30
31
|
import { applyCompanyFilter } from '@flusys/nestjs-shared/utils';
|
|
31
|
-
import { Inject, Injectable, Scope } from '@nestjs/common';
|
|
32
|
+
import { Inject, Injectable, Optional, Scope } from '@nestjs/common';
|
|
33
|
+
import { In } from 'typeorm';
|
|
32
34
|
import { CompanyBranch } from '../entities/company-branch.entity';
|
|
35
|
+
import { UserCompanyPermission } from '../entities/user-company-permission.entity';
|
|
33
36
|
import { AuthConfigService } from './auth-config.service';
|
|
34
37
|
import { AuthDataSourceProvider } from './auth-datasource.provider';
|
|
35
38
|
export class BranchService extends ApiService {
|
|
39
|
+
async beforeDeleteOperation(dto, user, queryRunner) {
|
|
40
|
+
const branchIds = Array.isArray(dto.id) ? dto.id : [
|
|
41
|
+
dto.id
|
|
42
|
+
];
|
|
43
|
+
await queryRunner.manager.getRepository(UserCompanyPermission).delete({
|
|
44
|
+
targetId: In(branchIds)
|
|
45
|
+
});
|
|
46
|
+
if (!this.permissionSyncAdapter?.onBranchDeleted) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const rows = await queryRunner.manager.getRepository(CompanyBranch).find({
|
|
50
|
+
where: {
|
|
51
|
+
id: In(branchIds)
|
|
52
|
+
},
|
|
53
|
+
select: [
|
|
54
|
+
'id',
|
|
55
|
+
'companyId'
|
|
56
|
+
]
|
|
57
|
+
});
|
|
58
|
+
await Promise.all(rows.map((row)=>this.permissionSyncAdapter.onBranchDeleted(row.id, row.companyId)));
|
|
59
|
+
}
|
|
36
60
|
// Query Customization
|
|
37
61
|
async getSelectQuery(query, _user, select) {
|
|
38
62
|
if (!select?.length) {
|
|
@@ -74,8 +98,8 @@ export class BranchService extends ApiService {
|
|
|
74
98
|
}
|
|
75
99
|
return result;
|
|
76
100
|
}
|
|
77
|
-
constructor(cacheManager, utilsService, dataSourceProvider, authConfig){
|
|
78
|
-
super('company_branch', cacheManager, utilsService, BranchService.name, true, 'auth', CompanyBranch, dataSourceProvider), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "authConfig", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.authConfig = authConfig;
|
|
101
|
+
constructor(cacheManager, utilsService, dataSourceProvider, authConfig, permissionSyncAdapter){
|
|
102
|
+
super('company_branch', cacheManager, utilsService, BranchService.name, true, 'auth', CompanyBranch, dataSourceProvider), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "authConfig", void 0), _define_property(this, "permissionSyncAdapter", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.authConfig = authConfig, this.permissionSyncAdapter = permissionSyncAdapter;
|
|
79
103
|
}
|
|
80
104
|
}
|
|
81
105
|
BranchService = _ts_decorate([
|
|
@@ -86,11 +110,14 @@ BranchService = _ts_decorate([
|
|
|
86
110
|
_ts_param(1, Inject(UtilsService)),
|
|
87
111
|
_ts_param(2, Inject(AuthDataSourceProvider)),
|
|
88
112
|
_ts_param(3, Inject(AuthConfigService)),
|
|
113
|
+
_ts_param(4, Optional()),
|
|
114
|
+
_ts_param(4, Inject(PERMISSION_SYNC_ADAPTER)),
|
|
89
115
|
_ts_metadata("design:type", Function),
|
|
90
116
|
_ts_metadata("design:paramtypes", [
|
|
91
117
|
typeof HybridCache === "undefined" ? Object : HybridCache,
|
|
92
118
|
typeof UtilsService === "undefined" ? Object : UtilsService,
|
|
93
119
|
typeof AuthDataSourceProvider === "undefined" ? Object : AuthDataSourceProvider,
|
|
94
|
-
typeof AuthConfigService === "undefined" ? Object : AuthConfigService
|
|
120
|
+
typeof AuthConfigService === "undefined" ? Object : AuthConfigService,
|
|
121
|
+
typeof IPermissionSyncAdapter === "undefined" ? Object : IPermissionSyncAdapter
|
|
95
122
|
])
|
|
96
123
|
], BranchService);
|
|
@@ -25,12 +25,40 @@ function _ts_param(paramIndex, decorator) {
|
|
|
25
25
|
decorator(target, key, paramIndex);
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
-
import {
|
|
28
|
+
import { ApiService, HybridCache } from '@flusys/nestjs-shared/classes';
|
|
29
|
+
import { IPermissionSyncAdapter, PERMISSION_SYNC_ADAPTER } from '@flusys/nestjs-shared/interfaces';
|
|
29
30
|
import { UtilsService } from '@flusys/nestjs-shared/modules';
|
|
30
|
-
import { Inject, Injectable, Scope } from '@nestjs/common';
|
|
31
|
+
import { Inject, Injectable, Optional, Scope } from '@nestjs/common';
|
|
32
|
+
import { In } from 'typeorm';
|
|
33
|
+
import { CompanyBranch } from '../entities/company-branch.entity';
|
|
31
34
|
import { Company } from '../entities/company.entity';
|
|
35
|
+
import { UserCompanyPermission } from '../entities/user-company-permission.entity';
|
|
32
36
|
import { AuthDataSourceProvider } from './auth-datasource.provider';
|
|
33
37
|
export class CompanyService extends ApiService {
|
|
38
|
+
async beforeDeleteOperation(dto, user, queryRunner) {
|
|
39
|
+
const companyIds = Array.isArray(dto.id) ? dto.id : [
|
|
40
|
+
dto.id
|
|
41
|
+
];
|
|
42
|
+
const branchRows = await queryRunner.manager.getRepository(CompanyBranch).find({
|
|
43
|
+
where: {
|
|
44
|
+
companyId: In(companyIds)
|
|
45
|
+
},
|
|
46
|
+
select: [
|
|
47
|
+
'id'
|
|
48
|
+
]
|
|
49
|
+
});
|
|
50
|
+
const targetIds = [
|
|
51
|
+
...companyIds,
|
|
52
|
+
...branchRows.map((row)=>row.id)
|
|
53
|
+
];
|
|
54
|
+
await queryRunner.manager.getRepository(UserCompanyPermission).delete({
|
|
55
|
+
targetId: In(targetIds)
|
|
56
|
+
});
|
|
57
|
+
if (!this.permissionSyncAdapter?.onCompanyDeleted) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
await Promise.all(companyIds.map((companyId)=>this.permissionSyncAdapter.onCompanyDeleted(companyId)));
|
|
61
|
+
}
|
|
34
62
|
// Query Customization
|
|
35
63
|
async getSelectQuery(query, _user, select) {
|
|
36
64
|
if (!select?.length) {
|
|
@@ -59,8 +87,8 @@ export class CompanyService extends ApiService {
|
|
|
59
87
|
isRaw: false
|
|
60
88
|
};
|
|
61
89
|
}
|
|
62
|
-
constructor(cacheManager, utilsService, dataSourceProvider){
|
|
63
|
-
super('company', cacheManager, utilsService, CompanyService.name, true, 'auth', Company, dataSourceProvider), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService;
|
|
90
|
+
constructor(cacheManager, utilsService, dataSourceProvider, permissionSyncAdapter){
|
|
91
|
+
super('company', cacheManager, utilsService, CompanyService.name, true, 'auth', Company, dataSourceProvider), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "permissionSyncAdapter", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.permissionSyncAdapter = permissionSyncAdapter;
|
|
64
92
|
}
|
|
65
93
|
}
|
|
66
94
|
CompanyService = _ts_decorate([
|
|
@@ -70,10 +98,13 @@ CompanyService = _ts_decorate([
|
|
|
70
98
|
_ts_param(0, Inject('CACHE_INSTANCE')),
|
|
71
99
|
_ts_param(1, Inject(UtilsService)),
|
|
72
100
|
_ts_param(2, Inject(AuthDataSourceProvider)),
|
|
101
|
+
_ts_param(3, Optional()),
|
|
102
|
+
_ts_param(3, Inject(PERMISSION_SYNC_ADAPTER)),
|
|
73
103
|
_ts_metadata("design:type", Function),
|
|
74
104
|
_ts_metadata("design:paramtypes", [
|
|
75
105
|
typeof HybridCache === "undefined" ? Object : HybridCache,
|
|
76
106
|
typeof UtilsService === "undefined" ? Object : UtilsService,
|
|
77
|
-
typeof AuthDataSourceProvider === "undefined" ? Object : AuthDataSourceProvider
|
|
107
|
+
typeof AuthDataSourceProvider === "undefined" ? Object : AuthDataSourceProvider,
|
|
108
|
+
typeof IPermissionSyncAdapter === "undefined" ? Object : IPermissionSyncAdapter
|
|
78
109
|
])
|
|
79
110
|
], CompanyService);
|
|
@@ -26,7 +26,8 @@ function _ts_param(paramIndex, decorator) {
|
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
import { LogAction } from '@flusys/nestjs-shared';
|
|
29
|
-
import {
|
|
29
|
+
import { IPermissionSyncAdapter, PERMISSION_SYNC_ADAPTER } from '@flusys/nestjs-shared/interfaces';
|
|
30
|
+
import { ConflictException, Inject, Injectable, NotFoundException, Optional, Scope } from '@nestjs/common';
|
|
30
31
|
import { USER_PERMISSION_MESSAGES } from '../config';
|
|
31
32
|
import { PermissionType, UserCompanyPermission } from '../entities/user-company-permission.entity';
|
|
32
33
|
import { AuthDataSourceProvider } from './auth-datasource.provider';
|
|
@@ -92,7 +93,7 @@ export class UserPermissionService {
|
|
|
92
93
|
throw error;
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
|
-
|
|
96
|
+
async revokePermission(userId, targetId, type) {
|
|
96
97
|
const repository = await this.getRepository();
|
|
97
98
|
const typeName = type === PermissionType.COMPANY ? 'company' : 'branch';
|
|
98
99
|
const permission = await repository.findOne({
|
|
@@ -100,7 +101,10 @@ export class UserPermissionService {
|
|
|
100
101
|
userId,
|
|
101
102
|
targetId,
|
|
102
103
|
permissionType: type
|
|
103
|
-
}
|
|
104
|
+
},
|
|
105
|
+
relations: [
|
|
106
|
+
type === PermissionType.BRANCH ? 'branch' : 'company'
|
|
107
|
+
]
|
|
104
108
|
});
|
|
105
109
|
if (!permission) {
|
|
106
110
|
throw new NotFoundException({
|
|
@@ -111,7 +115,29 @@ export class UserPermissionService {
|
|
|
111
115
|
}
|
|
112
116
|
});
|
|
113
117
|
}
|
|
118
|
+
const companyId = type === PermissionType.COMPANY ? targetId : permission.branch?.companyId;
|
|
114
119
|
await repository.remove(permission);
|
|
120
|
+
if (type === PermissionType.COMPANY) {
|
|
121
|
+
const revokedBranchIds = await this.revokeBranchPermissionsForCompany(repository, userId, targetId);
|
|
122
|
+
await this.permissionSyncAdapter?.onUserCompanyAccessRevoked?.(userId, targetId);
|
|
123
|
+
await Promise.all(revokedBranchIds.map((branchId)=>this.permissionSyncAdapter?.onUserBranchAccessRevoked?.(userId, branchId, targetId)));
|
|
124
|
+
} else {
|
|
125
|
+
if (companyId) await this.permissionSyncAdapter?.onUserBranchAccessRevoked?.(userId, targetId, companyId);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
async revokeBranchPermissionsForCompany(repository, userId, companyId) {
|
|
129
|
+
const branchPermissions = await repository.createQueryBuilder('permission').innerJoin('permission.branch', 'branch').where('permission.userId = :userId', {
|
|
130
|
+
userId
|
|
131
|
+
}).andWhere('permission.permissionType = :type', {
|
|
132
|
+
type: PermissionType.BRANCH
|
|
133
|
+
}).andWhere('branch.companyId = :companyId', {
|
|
134
|
+
companyId
|
|
135
|
+
}).getMany();
|
|
136
|
+
if (branchPermissions.length === 0) {
|
|
137
|
+
return [];
|
|
138
|
+
}
|
|
139
|
+
await repository.remove(branchPermissions);
|
|
140
|
+
return branchPermissions.map((permission)=>permission.targetId);
|
|
115
141
|
}
|
|
116
142
|
/** Find user branch permissions with optional company filter */ async findUserBranches(userId, companyId) {
|
|
117
143
|
const repository = await this.getRepository();
|
|
@@ -127,12 +153,14 @@ export class UserPermissionService {
|
|
|
127
153
|
}
|
|
128
154
|
return queryBuilder.getMany();
|
|
129
155
|
}
|
|
130
|
-
constructor(dataSourceProvider){
|
|
156
|
+
constructor(dataSourceProvider, permissionSyncAdapter){
|
|
131
157
|
_define_property(this, "dataSourceProvider", void 0);
|
|
158
|
+
_define_property(this, "permissionSyncAdapter", void 0);
|
|
132
159
|
_define_property(this, "_repository", void 0);
|
|
133
160
|
// Convenience Methods
|
|
134
161
|
_define_property(this, "findUserCompanies", void 0);
|
|
135
162
|
this.dataSourceProvider = dataSourceProvider;
|
|
163
|
+
this.permissionSyncAdapter = permissionSyncAdapter;
|
|
136
164
|
this._repository = null;
|
|
137
165
|
this.findUserCompanies = (userId)=>this.findUserPermissions(userId, PermissionType.COMPANY);
|
|
138
166
|
}
|
|
@@ -168,8 +196,11 @@ UserPermissionService = _ts_decorate([
|
|
|
168
196
|
scope: Scope.REQUEST
|
|
169
197
|
}),
|
|
170
198
|
_ts_param(0, Inject(AuthDataSourceProvider)),
|
|
199
|
+
_ts_param(1, Optional()),
|
|
200
|
+
_ts_param(1, Inject(PERMISSION_SYNC_ADAPTER)),
|
|
171
201
|
_ts_metadata("design:type", Function),
|
|
172
202
|
_ts_metadata("design:paramtypes", [
|
|
173
|
-
typeof AuthDataSourceProvider === "undefined" ? Object : AuthDataSourceProvider
|
|
203
|
+
typeof AuthDataSourceProvider === "undefined" ? Object : AuthDataSourceProvider,
|
|
204
|
+
typeof IPermissionSyncAdapter === "undefined" ? Object : IPermissionSyncAdapter
|
|
174
205
|
])
|
|
175
206
|
], UserPermissionService);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flusys/nestjs-auth",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.2",
|
|
4
4
|
"description": "Authentication and authorization infrastructure for NestJS applications",
|
|
5
5
|
"main": "cjs/index.js",
|
|
6
6
|
"module": "fesm/index.js",
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
"rxjs": "^7.8.0"
|
|
94
94
|
},
|
|
95
95
|
"dependencies": {
|
|
96
|
-
"@flusys/nestjs-core": "6.0.
|
|
97
|
-
"@flusys/nestjs-shared": "6.0.
|
|
96
|
+
"@flusys/nestjs-core": "6.0.2",
|
|
97
|
+
"@flusys/nestjs-shared": "6.0.2"
|
|
98
98
|
}
|
|
99
99
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { FilterAndPaginationDto } from '@flusys/nestjs-shared/dtos';
|
|
3
|
-
import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
|
|
1
|
+
import { ApiService, HybridCache } from '@flusys/nestjs-shared/classes';
|
|
2
|
+
import { DeleteDto, FilterAndPaginationDto } from '@flusys/nestjs-shared/dtos';
|
|
3
|
+
import { ILoggedUserInfo, IPermissionSyncAdapter } from '@flusys/nestjs-shared/interfaces';
|
|
4
4
|
import { UtilsService } from '@flusys/nestjs-shared/modules';
|
|
5
|
-
import { SelectQueryBuilder } from 'typeorm';
|
|
5
|
+
import { QueryRunner, SelectQueryBuilder } from 'typeorm';
|
|
6
6
|
import { CreateCompanyBranchDto, UpdateCompanyBranchDto } from '../dtos/company-branch.dto';
|
|
7
7
|
import { CompanyBranch } from '../entities/company-branch.entity';
|
|
8
8
|
import { ICompanyBranch } from '../interfaces/company-branch.interface';
|
|
@@ -12,7 +12,9 @@ export declare class BranchService extends ApiService<CreateCompanyBranchDto, Up
|
|
|
12
12
|
protected cacheManager: HybridCache;
|
|
13
13
|
protected utilsService: UtilsService;
|
|
14
14
|
private readonly authConfig;
|
|
15
|
-
|
|
15
|
+
private readonly permissionSyncAdapter?;
|
|
16
|
+
constructor(cacheManager: HybridCache, utilsService: UtilsService, dataSourceProvider: AuthDataSourceProvider, authConfig: AuthConfigService, permissionSyncAdapter?: IPermissionSyncAdapter | undefined);
|
|
17
|
+
protected beforeDeleteOperation(dto: DeleteDto, user: ILoggedUserInfo | null, queryRunner: QueryRunner): Promise<void>;
|
|
16
18
|
getSelectQuery(query: SelectQueryBuilder<CompanyBranch>, _user: ILoggedUserInfo | null, select?: string[]): Promise<{
|
|
17
19
|
query: SelectQueryBuilder<CompanyBranch>;
|
|
18
20
|
isRaw: boolean;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { ApiService, HybridCache } from '@flusys/nestjs-shared/classes';
|
|
2
|
+
import { DeleteDto } from '@flusys/nestjs-shared/dtos';
|
|
3
|
+
import { ILoggedUserInfo, IPermissionSyncAdapter } from '@flusys/nestjs-shared/interfaces';
|
|
3
4
|
import { UtilsService } from '@flusys/nestjs-shared/modules';
|
|
4
|
-
import { SelectQueryBuilder } from 'typeorm';
|
|
5
|
+
import { QueryRunner, SelectQueryBuilder } from 'typeorm';
|
|
5
6
|
import { CreateCompanyDto, UpdateCompanyDto } from '../dtos/company.dto';
|
|
6
7
|
import { Company } from '../entities/company.entity';
|
|
7
8
|
import { ICompany } from '../interfaces/company.interface';
|
|
@@ -9,7 +10,9 @@ import { AuthDataSourceProvider } from './auth-datasource.provider';
|
|
|
9
10
|
export declare class CompanyService extends ApiService<CreateCompanyDto, UpdateCompanyDto, ICompany, Company> {
|
|
10
11
|
protected cacheManager: HybridCache;
|
|
11
12
|
protected utilsService: UtilsService;
|
|
12
|
-
|
|
13
|
+
private readonly permissionSyncAdapter?;
|
|
14
|
+
constructor(cacheManager: HybridCache, utilsService: UtilsService, dataSourceProvider: AuthDataSourceProvider, permissionSyncAdapter?: IPermissionSyncAdapter | undefined);
|
|
15
|
+
protected beforeDeleteOperation(dto: DeleteDto, user: ILoggedUserInfo | null, queryRunner: QueryRunner): Promise<void>;
|
|
13
16
|
getSelectQuery(query: SelectQueryBuilder<Company>, _user: ILoggedUserInfo | null, select?: string[]): Promise<{
|
|
14
17
|
query: SelectQueryBuilder<Company>;
|
|
15
18
|
isRaw: boolean;
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
+
import { IPermissionSyncAdapter } from '@flusys/nestjs-shared/interfaces';
|
|
1
2
|
import { PermissionType, UserCompanyPermission } from '../entities/user-company-permission.entity';
|
|
2
3
|
import { AuthDataSourceProvider } from './auth-datasource.provider';
|
|
3
4
|
export declare class UserPermissionService {
|
|
4
5
|
private readonly dataSourceProvider;
|
|
6
|
+
private readonly permissionSyncAdapter?;
|
|
5
7
|
private _repository;
|
|
6
|
-
constructor(dataSourceProvider: AuthDataSourceProvider);
|
|
8
|
+
constructor(dataSourceProvider: AuthDataSourceProvider, permissionSyncAdapter?: IPermissionSyncAdapter | undefined);
|
|
7
9
|
private getRepository;
|
|
8
10
|
findUserPermissions(userId: string, type: PermissionType): Promise<UserCompanyPermission[]>;
|
|
9
11
|
assignPermission(userId: string, targetId: string, type: PermissionType): Promise<void>;
|
|
10
12
|
revokePermission(userId: string, targetId: string, type: PermissionType): Promise<void>;
|
|
13
|
+
private revokeBranchPermissionsForCompany;
|
|
11
14
|
findUserCompanies: (userId: string) => Promise<UserCompanyPermission[]>;
|
|
12
15
|
findUserBranches(userId: string, companyId?: string): Promise<UserCompanyPermission[]>;
|
|
13
16
|
}
|