@flusys/nestjs-auth 6.0.1 → 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.
@@ -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", Object)
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, {
@@ -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
- /** Revoke permission from user */ async revokePermission(userId, targetId, type) {
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);
@@ -14,6 +14,6 @@ export declare class CompanyBranch extends Identity {
14
14
  parentId: string | null;
15
15
  parent: CompanyBranch | null;
16
16
  children: CompanyBranch[];
17
- companyId: string | null;
17
+ companyId: string;
18
18
  company: Company;
19
19
  }
@@ -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", Object)
134
+ _ts_metadata("design:type", String)
136
135
  ], CompanyBranch.prototype, "companyId", void 0);
137
136
  _ts_decorate([
138
137
  ManyToOne(()=>Company, (company)=>company.branches, {
@@ -25,14 +25,38 @@ function _ts_param(paramIndex, decorator) {
25
25
  decorator(target, key, paramIndex);
26
26
  };
27
27
  }
28
- import { HybridCache, ApiService } from '@flusys/nestjs-shared/classes';
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 { HybridCache, ApiService } from '@flusys/nestjs-shared/classes';
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 { ConflictException, Inject, Injectable, NotFoundException, Scope } from '@nestjs/common';
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
- /** Revoke permission from user */ async revokePermission(userId, targetId, type) {
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.1",
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.1",
97
- "@flusys/nestjs-shared": "6.0.1"
96
+ "@flusys/nestjs-core": "6.0.2",
97
+ "@flusys/nestjs-shared": "6.0.2"
98
98
  }
99
99
  }
@@ -1,8 +1,8 @@
1
- import { HybridCache, ApiService } from '@flusys/nestjs-shared/classes';
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
- constructor(cacheManager: HybridCache, utilsService: UtilsService, dataSourceProvider: AuthDataSourceProvider, authConfig: AuthConfigService);
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 { HybridCache, ApiService } from '@flusys/nestjs-shared/classes';
2
- import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
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
- constructor(cacheManager: HybridCache, utilsService: UtilsService, dataSourceProvider: AuthDataSourceProvider);
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
  }