@flusys/nestjs-auth 6.3.0 → 6.4.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.
@@ -130,10 +130,13 @@ let UserService = class UserService extends _classes.ApiService {
130
130
  await this.repository.update(id, {
131
131
  emailVerified: true
132
132
  });
133
- await this.clearCacheForId([
134
- {
135
- id
136
- }
133
+ await Promise.all([
134
+ this.clearCacheForAll(),
135
+ this.clearCacheForId([
136
+ {
137
+ id
138
+ }
139
+ ])
137
140
  ]);
138
141
  }
139
142
  async verifyPhone(id) {
@@ -141,10 +144,13 @@ let UserService = class UserService extends _classes.ApiService {
141
144
  await this.repository.update(id, {
142
145
  phoneVerified: true
143
146
  });
144
- await this.clearCacheForId([
145
- {
146
- id
147
- }
147
+ await Promise.all([
148
+ this.clearCacheForAll(),
149
+ this.clearCacheForId([
150
+ {
151
+ id
152
+ }
153
+ ])
148
154
  ]);
149
155
  }
150
156
  async updateStatus(id, isActive, user) {
@@ -174,10 +180,13 @@ let UserService = class UserService extends _classes.ApiService {
174
180
  isActive
175
181
  });
176
182
  }
177
- await this.clearCacheForId([
178
- {
179
- id
180
- }
183
+ await Promise.all([
184
+ this.clearCacheForAll(),
185
+ this.clearCacheForId([
186
+ {
187
+ id
188
+ }
189
+ ])
181
190
  ]);
182
191
  }
183
192
  async convertSingleDtoToEntity(dto, user) {
@@ -401,8 +410,11 @@ let UserService = class UserService extends _classes.ApiService {
401
410
  }
402
411
  }
403
412
  await queryRunner.commitTransaction();
404
- await this.clearCacheForId([
405
- savedUser
413
+ await Promise.all([
414
+ this.clearCacheForAll(),
415
+ this.clearCacheForId([
416
+ savedUser
417
+ ])
406
418
  ]);
407
419
  return this.convertEntityToResponseDto(savedUser, false);
408
420
  } catch (error) {
@@ -471,8 +483,11 @@ let UserService = class UserService extends _classes.ApiService {
471
483
  try {
472
484
  await this.userEnricher.updateProfileSection(userId, sectionId, data, queryRunner);
473
485
  await queryRunner.commitTransaction();
474
- await this.clearCacheForId([
475
- userEntity
486
+ await Promise.all([
487
+ this.clearCacheForAll(),
488
+ this.clearCacheForId([
489
+ userEntity
490
+ ])
476
491
  ]);
477
492
  } catch (error) {
478
493
  await queryRunner.rollbackTransaction();
@@ -541,8 +556,11 @@ let UserService = class UserService extends _classes.ApiService {
541
556
  await this.userEnricher.updateProfileExtras(userId, extras, queryRunner);
542
557
  }
543
558
  await queryRunner.commitTransaction();
544
- await this.clearCacheForId([
545
- findUser
559
+ await Promise.all([
560
+ this.clearCacheForAll(),
561
+ this.clearCacheForId([
562
+ findUser
563
+ ])
546
564
  ]);
547
565
  return findUser.id;
548
566
  } catch (error) {
@@ -124,6 +124,13 @@ describe('UserService', ()=>{
124
124
  };
125
125
  service = new _userservice.UserService({}, mockUtilsService, mockDataSourceProvider, mockAuthConfig, mockUserEnricher);
126
126
  });
127
+ /**
128
+ * Every write path has to drop both the list cache and the row's own cache, or a
129
+ * stale user keeps being served from `get-all`.
130
+ */ function expectCacheCleared(id) {
131
+ expect(mockUtilsService.clearCache).toHaveBeenCalledWith('appuser', expect.anything());
132
+ expect(mockUtilsService.clearCache).toHaveBeenCalledWith('appuser', expect.anything(), id);
133
+ }
127
134
  describe('ensureDataSourceRepository', ()=>{
128
135
  it('does not load the permission repository when the company feature is disabled', async ()=>{
129
136
  await service.ensureDataSourceRepository();
@@ -142,13 +149,14 @@ describe('UserService', ()=>{
142
149
  expect(userRepo.update).toHaveBeenCalledWith('user-1', {
143
150
  emailVerified: true
144
151
  });
145
- expect(mockUtilsService.clearCache).toHaveBeenCalled();
152
+ expectCacheCleared('user-1');
146
153
  });
147
154
  it('marks the phone as verified and clears the cache', async ()=>{
148
155
  await service.verifyPhone('user-1');
149
156
  expect(userRepo.update).toHaveBeenCalledWith('user-1', {
150
157
  phoneVerified: true
151
158
  });
159
+ expectCacheCleared('user-1');
152
160
  });
153
161
  });
154
162
  describe('updateStatus', ()=>{
@@ -157,6 +165,7 @@ describe('UserService', ()=>{
157
165
  expect(userRepo.update).toHaveBeenCalledWith('user-1', {
158
166
  isActive: false
159
167
  });
168
+ expectCacheCleared('user-1');
160
169
  });
161
170
  it('throws NotFoundException when the company permission is missing', async ()=>{
162
171
  companyFeatureEnabled = true;
@@ -179,6 +188,7 @@ describe('UserService', ()=>{
179
188
  isActive: false
180
189
  }));
181
190
  expect(userRepo.update).not.toHaveBeenCalled();
191
+ expectCacheCleared('user-1');
182
192
  });
183
193
  });
184
194
  describe('convertSingleDtoToEntity', ()=>{
@@ -389,6 +399,7 @@ describe('UserService', ()=>{
389
399
  expect(result).toEqual(expect.objectContaining({
390
400
  id: 'user-1'
391
401
  }));
402
+ expectCacheCleared(savedUser.id);
392
403
  });
393
404
  it('rolls back the transaction if permission assignment fails', async ()=>{
394
405
  companyFeatureEnabled = true;
@@ -577,6 +588,7 @@ describe('UserService', ()=>{
577
588
  foo: 'bar'
578
589
  }, queryRunner);
579
590
  expect(queryRunner.commitTransaction).toHaveBeenCalled();
591
+ expectCacheCleared('user-1');
580
592
  });
581
593
  it('rolls back the transaction when the enricher throws', async ()=>{
582
594
  userRepo.findOne.mockResolvedValue(buildAppUser());
@@ -670,6 +682,7 @@ describe('UserService', ()=>{
670
682
  expect(queryRunner.manager.save).toHaveBeenCalled();
671
683
  expect(queryRunner.commitTransaction).toHaveBeenCalled();
672
684
  expect(result).toBe('user-1');
685
+ expectCacheCleared('user-1');
673
686
  });
674
687
  it('does not require the current password when an admin updates another user profile', async ()=>{
675
688
  service.dataSource = mockDataSource;
@@ -686,6 +699,7 @@ describe('UserService', ()=>{
686
699
  }));
687
700
  expect(queryRunner.manager.save).toHaveBeenCalled();
688
701
  expect(queryRunner.commitTransaction).toHaveBeenCalled();
702
+ expectCacheCleared('other-user');
689
703
  });
690
704
  it('rolls back the transaction when save fails', async ()=>{
691
705
  service.dataSource = mockDataSource;
@@ -79,10 +79,13 @@ export class UserService extends ApiService {
79
79
  await this.repository.update(id, {
80
80
  emailVerified: true
81
81
  });
82
- await this.clearCacheForId([
83
- {
84
- id
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 this.clearCacheForId([
94
- {
95
- id
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 this.clearCacheForId([
127
- {
128
- id
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 this.clearCacheForId([
354
- savedUser
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 this.clearCacheForId([
424
- userEntity
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 this.clearCacheForId([
494
- findUser
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
- expect(mockUtilsService.clearCache).toHaveBeenCalled();
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flusys/nestjs-auth",
3
- "version": "6.3.0",
3
+ "version": "6.4.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": "6.3.0",
102
- "@flusys/nestjs-shared": "6.3.0"
101
+ "@flusys/nestjs-core": "6.4.1",
102
+ "@flusys/nestjs-shared": "6.4.1"
103
103
  }
104
104
  }