@flusys/nestjs-auth 2.0.0 → 3.0.0

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.
Files changed (43) hide show
  1. package/README.md +610 -95
  2. package/cjs/controllers/authentication.controller.js +2 -173
  3. package/cjs/controllers/email-verification.controller.js +220 -0
  4. package/cjs/controllers/index.js +1 -0
  5. package/cjs/dtos/authentication.dto.js +12 -2
  6. package/cjs/entities/index.js +16 -17
  7. package/cjs/entities/pending-registration.entity.js +9 -0
  8. package/cjs/entities/user-company-permission.entity.js +3 -3
  9. package/cjs/modules/auth.module.js +33 -24
  10. package/cjs/services/auth-config.service.js +11 -7
  11. package/cjs/services/auth-datasource.provider.js +15 -27
  12. package/cjs/services/auth-email.service.js +8 -33
  13. package/cjs/services/authentication.service.js +123 -99
  14. package/cjs/services/user.service.js +28 -83
  15. package/controllers/authentication.controller.d.ts +2 -10
  16. package/controllers/email-verification.controller.d.ts +20 -0
  17. package/controllers/index.d.ts +1 -0
  18. package/dtos/authentication.dto.d.ts +1 -0
  19. package/entities/index.d.ts +5 -10
  20. package/entities/pending-registration.entity.d.ts +1 -0
  21. package/entities/user-company-permission.entity.d.ts +1 -1
  22. package/fesm/controllers/authentication.controller.js +3 -174
  23. package/fesm/controllers/email-verification.controller.js +210 -0
  24. package/fesm/controllers/index.js +1 -0
  25. package/fesm/dtos/authentication.dto.js +32 -25
  26. package/fesm/entities/index.js +17 -9
  27. package/fesm/entities/pending-registration.entity.js +9 -0
  28. package/fesm/entities/user-company-permission.entity.js +3 -3
  29. package/fesm/interfaces/user-enricher.interface.js +2 -24
  30. package/fesm/modules/auth.module.js +35 -26
  31. package/fesm/services/auth-config.service.js +11 -7
  32. package/fesm/services/auth-datasource.provider.js +15 -27
  33. package/fesm/services/auth-email.service.js +8 -33
  34. package/fesm/services/authentication.service.js +124 -100
  35. package/fesm/services/user.service.js +28 -83
  36. package/interfaces/user-enricher.interface.d.ts +3 -2
  37. package/modules/auth.module.d.ts +3 -1
  38. package/package.json +3 -3
  39. package/services/auth-config.service.d.ts +1 -0
  40. package/services/auth-datasource.provider.d.ts +1 -0
  41. package/services/auth-email.service.d.ts +1 -0
  42. package/services/authentication.service.d.ts +4 -1
  43. package/services/user.service.d.ts +5 -0
@@ -46,23 +46,17 @@ export class UserService extends RequestScopedApiService {
46
46
  }
47
47
  async ensureRepositoryInitialized() {
48
48
  await super.ensureRepositoryInitialized();
49
- // Initialize permission repository if company feature is enabled
50
49
  const isCompanyFeatureEnabled = this.authConfig.isCompanyFeatureEnabled();
51
50
  if (isCompanyFeatureEnabled && !this.permissionRepository) {
52
51
  [this.permissionRepository] = await this.initializeAdditionalRepositories([
53
52
  UserCompanyPermission
54
53
  ]);
55
54
  }
56
- // Initialize DataSource for transaction support
57
55
  if (!this.dataSource) {
58
56
  this.dataSource = await this.getDataSourceForService();
59
57
  }
60
58
  }
61
- // Custom Methods
62
- /**
63
- * Validate profile ownership, ensure repository initialized, and fetch user.
64
- * Throws ForbiddenException if not owner, NotFoundException if user not found.
65
- */ async getUserForProfile(userId, user) {
59
+ async getUserForProfile(userId, user) {
66
60
  if (userId !== user.id) {
67
61
  throw new ForbiddenException('Cannot access another user\'s profile');
68
62
  }
@@ -77,38 +71,32 @@ export class UserService extends RequestScopedApiService {
77
71
  }
78
72
  return userEntity;
79
73
  }
80
- /** Verify email */ async verifyEmail(id) {
81
- // Ensure repository is initialized for custom method
74
+ async verifyEmail(id) {
82
75
  await this.ensureRepositoryInitialized();
83
76
  await this.repository.update(id, {
84
77
  emailVerified: true
85
78
  });
86
- // Clear cache for this user
87
79
  await this.clearCacheForId([
88
80
  {
89
81
  id
90
82
  }
91
83
  ]);
92
84
  }
93
- /** Verify phone */ async verifyPhone(id) {
94
- // Ensure repository is initialized for custom method
85
+ async verifyPhone(id) {
95
86
  await this.ensureRepositoryInitialized();
96
87
  await this.repository.update(id, {
97
88
  phoneVerified: true
98
89
  });
99
- // Clear cache for this user
100
90
  await this.clearCacheForId([
101
91
  {
102
92
  id
103
93
  }
104
94
  ]);
105
95
  }
106
- /** Update user status. When company feature enabled, updates permission isActive for logged user's company. */ async updateStatus(id, isActive, user) {
107
- // Ensure repository is initialized for custom method
96
+ async updateStatus(id, isActive, user) {
108
97
  await this.ensureRepositoryInitialized();
109
98
  const isCompanyFeatureEnabled = this.authConfig.isCompanyFeatureEnabled();
110
99
  if (isCompanyFeatureEnabled && user?.companyId && this.permissionRepository) {
111
- // Company feature enabled - update permission isActive
112
100
  const permission = await this.permissionRepository.findOne({
113
101
  where: {
114
102
  userId: id,
@@ -122,36 +110,30 @@ export class UserService extends RequestScopedApiService {
122
110
  permission.isActive = isActive;
123
111
  await this.permissionRepository.save(permission);
124
112
  } else {
125
- // Company feature disabled - update User.isActive directly
126
113
  await this.repository.update(id, {
127
114
  isActive
128
115
  });
129
116
  }
130
- // Clear cache for this user
131
117
  await this.clearCacheForId([
132
118
  {
133
119
  id
134
120
  }
135
121
  ]);
136
122
  }
137
- // ApiService Overrides
138
- /** Convert DTO to entity (hash password before saving) */ async convertSingleDtoToEntity(dto, user) {
139
- // Repository initialization is handled automatically by RequestScopedApiService
123
+ async convertSingleDtoToEntity(dto, user) {
140
124
  const entity = await super.convertSingleDtoToEntity(dto, user);
141
- // Hash password if provided (CreateUserDto has password field)
142
125
  if ('password' in dto && dto.password) {
143
126
  entity.password = await bcrypt.hash(dto.password, BCRYPT_SALT_ROUNDS);
144
127
  }
145
128
  return entity;
146
129
  }
147
- /** Convert entity to response DTO (removes password). In raw mode with company feature, isActive comes from permission table. */ convertEntityToResponseDto(entity, isRaw) {
130
+ convertEntityToResponseDto(entity, isRaw) {
148
131
  if (isRaw) {
149
132
  return this.convertRawToResponseDto(entity);
150
133
  }
151
134
  return this.convertEntityToDto(entity);
152
135
  }
153
- /** Convert raw query result to response DTO */ convertRawToResponseDto(raw) {
154
- // When raw mode is used with company feature, isActive comes from computed field
136
+ convertRawToResponseDto(raw) {
155
137
  const isActive = raw.user_companyIsActive !== undefined ? Boolean(raw.user_companyIsActive) : raw.user_is_active;
156
138
  return {
157
139
  id: raw.user_id,
@@ -172,7 +154,7 @@ export class UserService extends RequestScopedApiService {
172
154
  deletedById: raw.user_deleted_by_id
173
155
  };
174
156
  }
175
- /** Convert entity to response DTO */ convertEntityToDto(entity) {
157
+ convertEntityToDto(entity) {
176
158
  return {
177
159
  id: entity.id,
178
160
  name: entity.name,
@@ -192,10 +174,10 @@ export class UserService extends RequestScopedApiService {
192
174
  deletedById: entity.deletedById
193
175
  };
194
176
  }
195
- /** Convert entity list to response DTO list */ convertEntityListToResponseListDto(entities, isRaw) {
177
+ convertEntityListToResponseListDto(entities, isRaw) {
196
178
  return entities.map((entity)=>this.convertEntityToResponseDto(entity, isRaw));
197
179
  }
198
- /** Global search - search by name, email, or phone */ async getGlobalSearchQuery(query, search, _user) {
180
+ async getGlobalSearchQuery(query, search, _user) {
199
181
  query.andWhere('(user.name LIKE :search OR user.email LIKE :search OR user.phone LIKE :search)', {
200
182
  search: `%${search}%`
201
183
  });
@@ -204,26 +186,16 @@ export class UserService extends RequestScopedApiService {
204
186
  isRaw: false
205
187
  };
206
188
  }
207
- /** Add company permission-based isActive check when company feature enabled. Returns isRaw: true for computed fields. */ async getExtraManipulateQuery(query, filterAndPaginationDto, user) {
208
- // Repository initialization is handled automatically by RequestScopedApiService
189
+ async getExtraManipulateQuery(query, filterAndPaginationDto, user) {
209
190
  let result = await super.getExtraManipulateQuery(query, filterAndPaginationDto, user);
210
- // Apply user enricher query modifications if available
211
191
  if (this.userEnricher?.enrichListQuery) {
212
192
  await this.userEnricher.enrichListQuery(query, user);
213
193
  }
214
- // Only apply company filtering if:
215
- // 1. Company feature is enabled at bootstrap
216
- // 2. User has company context
217
- // 3. Permission repository is available
218
194
  const isCompanyFeatureEnabled = this.authConfig.isCompanyFeatureEnabled();
219
195
  if (!isCompanyFeatureEnabled) {
220
- // Company feature disabled - return without any company-related modifications
221
- // isActive will come from User entity directly
222
196
  return result;
223
197
  }
224
- // Company feature is enabled - apply company-based filtering
225
198
  if (user?.companyId && this.permissionRepository) {
226
- // Add computed isActive field from permission table
227
199
  query.addSelect(`(SELECT perm.is_active FROM user_company_permissions perm
228
200
  WHERE perm.user_id = user.id
229
201
  AND perm.permission_type = :permissionType
@@ -231,7 +203,6 @@ export class UserService extends RequestScopedApiService {
231
203
  LIMIT 1)`, 'user_companyIsActive');
232
204
  query.setParameter('permissionType', PermissionType.COMPANY);
233
205
  query.setParameter('companyId', user.companyId);
234
- // Add filter for isActive if provided (filters by permission isActive)
235
206
  if (filterAndPaginationDto.filter?.isActive !== undefined) {
236
207
  query.andWhere(`EXISTS (
237
208
  SELECT 1 FROM user_company_permissions perm
@@ -245,7 +216,6 @@ export class UserService extends RequestScopedApiService {
245
216
  isActiveValue: filterAndPaginationDto.filter.isActive
246
217
  });
247
218
  }
248
- // Filter users to only show those with company permission
249
219
  query.andWhere(`EXISTS (
250
220
  SELECT 1 FROM user_company_permissions perm
251
221
  WHERE perm.user_id = user.id
@@ -255,7 +225,6 @@ export class UserService extends RequestScopedApiService {
255
225
  permissionType: PermissionType.COMPANY,
256
226
  companyId: user.companyId
257
227
  });
258
- // Return with isRaw: true to get the computed field
259
228
  return {
260
229
  query,
261
230
  isRaw: true
@@ -263,11 +232,8 @@ export class UserService extends RequestScopedApiService {
263
232
  }
264
233
  return result;
265
234
  }
266
- /** Insert user. Creates company permission when company feature is enabled. */ async insert(dto, user) {
267
- // Repository initialization is handled automatically by RequestScopedApiService
268
- // Check if company feature is enabled
235
+ async insert(dto, user) {
269
236
  const isCompanyFeatureEnabled = this.authConfig.isCompanyFeatureEnabled();
270
- // If company feature is disabled OR missing dependencies, use parent implementation
271
237
  if (!isCompanyFeatureEnabled || !this.dataSource || !user?.companyId || !this.permissionRepository) {
272
238
  return super.insert(dto, user);
273
239
  }
@@ -275,11 +241,8 @@ export class UserService extends RequestScopedApiService {
275
241
  await queryRunner.connect();
276
242
  await queryRunner.startTransaction();
277
243
  try {
278
- // First, insert the user using parent method logic
279
244
  const userEntity = await this.convertSingleDtoToEntity(dto, user);
280
245
  const savedUser = await queryRunner.manager.save(this.repository.target, userEntity);
281
- // Create company permission (repository is guaranteed to exist due to check above)
282
- // Check if permission already exists
283
246
  const existingPermission = await queryRunner.manager.findOne(this.permissionRepository.target, {
284
247
  where: {
285
248
  userId: savedUser.id,
@@ -296,7 +259,6 @@ export class UserService extends RequestScopedApiService {
296
259
  });
297
260
  await queryRunner.manager.save(this.permissionRepository.target, permission);
298
261
  }
299
- // Also create branch permission if user has branch context
300
262
  if (user.branchId) {
301
263
  const existingBranchPermission = await queryRunner.manager.findOne(this.permissionRepository.target, {
302
264
  where: {
@@ -330,13 +292,9 @@ export class UserService extends RequestScopedApiService {
330
292
  await queryRunner.release();
331
293
  }
332
294
  }
333
- /**
334
- * Get user profile with extras from enricher
335
- * Returns base user data plus any extra data provided by enricher (roles, permissions, etc.)
336
- */ async getProfileWithExtras(userId, user) {
295
+ async getProfileWithExtras(userId, user) {
337
296
  const userEntity = await this.getUserForProfile(userId, user);
338
297
  const userData = this.convertEntityToResponseDto(userEntity, false);
339
- // Get extras from enricher if available
340
298
  let extras;
341
299
  if (this.userEnricher?.getProfileExtras) {
342
300
  extras = await this.userEnricher.getProfileExtras(userId, user);
@@ -346,38 +304,34 @@ export class UserService extends RequestScopedApiService {
346
304
  extras
347
305
  };
348
306
  }
349
- /**
350
- * Get enriched user list
351
- * Applies enricher transformations after query execution
352
- */ async getEnrichedList(users, user) {
307
+ async getAll(search, filterAndPaginationDto, user) {
308
+ const result = await super.getAll(search, filterAndPaginationDto, user);
309
+ const enrichedData = await this.getEnrichedList(result.data, user);
310
+ return {
311
+ data: enrichedData,
312
+ total: result.total
313
+ };
314
+ }
315
+ async getEnrichedList(users, user) {
353
316
  if (this.userEnricher?.enrichListItems) {
354
317
  return this.userEnricher.enrichListItems(users, user);
355
318
  }
356
319
  return users;
357
320
  }
358
- // ============================================
359
- // Multi-Step Profile Methods (via Enricher)
360
- // ============================================
361
- /**
362
- * Get profile section definitions from enricher
363
- */ async getProfileSections() {
321
+ async getProfileSections() {
364
322
  if (this.userEnricher?.getProfileSections) {
365
323
  return this.userEnricher.getProfileSections();
366
324
  }
367
325
  return [];
368
326
  }
369
- /**
370
- * Get specific profile section data
371
- */ async getProfileSectionData(userId, sectionId, user) {
327
+ async getProfileSectionData(userId, sectionId, user) {
372
328
  await this.getUserForProfile(userId, user);
373
329
  if (this.userEnricher?.getProfileSectionData) {
374
330
  return this.userEnricher.getProfileSectionData(userId, sectionId, user);
375
331
  }
376
332
  return null;
377
333
  }
378
- /**
379
- * Update specific profile section
380
- */ async updateProfileSection(userId, sectionId, data, user) {
334
+ async updateProfileSection(userId, sectionId, data, user) {
381
335
  const userEntity = await this.getUserForProfile(userId, user);
382
336
  if (!this.dataSource) {
383
337
  throw new BadRequestException('DataSource not available');
@@ -405,23 +359,19 @@ export class UserService extends RequestScopedApiService {
405
359
  await queryRunner.release();
406
360
  }
407
361
  }
408
- /**
409
- * Get profile completion percentage
410
- */ async getProfileCompletion(userId, user) {
362
+ async getProfileCompletion(userId, user) {
411
363
  await this.getUserForProfile(userId, user);
412
364
  if (this.userEnricher?.calculateProfileCompletion) {
413
365
  return this.userEnricher.calculateProfileCompletion(userId, user);
414
366
  }
415
- return 100; // Default to 100% if no enricher
367
+ return 100;
416
368
  }
417
- /** Update user profile with password handling and extras */ async profile(dto, user) {
418
- // Ensure repository and dataSource are initialized
369
+ async profile(dto, user) {
419
370
  await this.ensureRepositoryInitialized();
420
371
  if (!this.dataSource) {
421
372
  throw new BadRequestException('DataSource not available');
422
373
  }
423
374
  const userId = dto.id ?? user.id;
424
- // Validate extras if enricher provides validation
425
375
  if (dto.extras && this.userEnricher?.validateProfileExtras) {
426
376
  await this.userEnricher.validateProfileExtras(userId, dto.extras, user);
427
377
  }
@@ -437,9 +387,7 @@ export class UserService extends RequestScopedApiService {
437
387
  if (!findUser) {
438
388
  throw new NotFoundException('User not found');
439
389
  }
440
- // Handle password update
441
390
  if (dto.password) {
442
- // If updating own profile, require old password verification
443
391
  const isOwnProfile = !dto.id || dto.id === user.id;
444
392
  if (isOwnProfile) {
445
393
  if (!dto.oldPassword) {
@@ -452,12 +400,9 @@ export class UserService extends RequestScopedApiService {
452
400
  }
453
401
  findUser.password = await bcrypt.hash(dto.password, BCRYPT_SALT_ROUNDS);
454
402
  }
455
- // Merge other fields (excluding password, oldPassword, extras, and sensitive flags)
456
- // Users cannot self-modify emailVerified, phoneVerified, or isActive via profile update
457
403
  const { password, oldPassword, extras, emailVerified, phoneVerified, isActive, ...restDto } = dto;
458
404
  Object.assign(findUser, restDto);
459
405
  await queryRunner.manager.save(this.repository.target, findUser);
460
- // Handle extras update via enricher
461
406
  if (extras && this.userEnricher?.updateProfileExtras) {
462
407
  await this.userEnricher.updateProfileExtras(userId, extras, queryRunner);
463
408
  }
@@ -1,4 +1,4 @@
1
- import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
1
+ import { ILoggedUserInfo, IPermissionLogic } from '@flusys/nestjs-shared/interfaces';
2
2
  import { QueryRunner, SelectQueryBuilder } from 'typeorm';
3
3
  import { User } from '../entities/user.entity';
4
4
  import { IUser } from './user.interface';
@@ -9,7 +9,7 @@ export interface IProfileSection {
9
9
  icon?: string;
10
10
  required?: boolean;
11
11
  hasFileUpload?: boolean;
12
- editPermission?: string;
12
+ editPermission?: IPermissionLogic;
13
13
  }
14
14
  export interface IProfileSectionData {
15
15
  sectionId: string;
@@ -61,4 +61,5 @@ export interface IUserEnricher {
61
61
  }, queryRunner: QueryRunner): Promise<IProfileFile>;
62
62
  handleSectionFileDelete?(userId: string, sectionId: string, field: string, fileId: string, queryRunner: QueryRunner): Promise<void>;
63
63
  calculateProfileCompletion?(userId: string, user: ILoggedUserInfo): Promise<number>;
64
+ onUserCreated?(userId: string, additionalFields: Record<string, any> | null, queryRunner: QueryRunner): Promise<void>;
64
65
  }
@@ -1,13 +1,15 @@
1
+ import { IBootstrapAppConfig } from '@flusys/nestjs-core';
1
2
  import { DynamicModule } from '@nestjs/common';
2
3
  import { AuthModuleAsyncOptions, AuthModuleOptions } from '../interfaces/auth-module-options.interface';
3
4
  export declare class AuthModule {
4
5
  static forRoot(options: AuthModuleOptions): DynamicModule;
5
6
  static forRootAsync(options: AuthModuleAsyncOptions): DynamicModule;
6
7
  private static buildModule;
8
+ private static getFeatureFlags;
7
9
  private static buildImports;
8
10
  private static buildControllers;
9
11
  private static buildProviders;
10
12
  private static buildExports;
11
13
  private static createAsyncProviders;
12
- static getEntities(enableCompanyFeature?: boolean): any[];
14
+ static getEntities(config: IBootstrapAppConfig): any[];
13
15
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flusys/nestjs-auth",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "Authentication and authorization infrastructure for NestJS applications",
5
5
  "main": "cjs/index.js",
6
6
  "module": "fesm/index.js",
@@ -91,7 +91,7 @@
91
91
  "typeorm": "^0.3.0"
92
92
  },
93
93
  "dependencies": {
94
- "@flusys/nestjs-core": "2.0.0",
95
- "@flusys/nestjs-shared": "2.0.0"
94
+ "@flusys/nestjs-core": "3.0.0",
95
+ "@flusys/nestjs-shared": "3.0.0"
96
96
  }
97
97
  }
@@ -10,6 +10,7 @@ export declare class AuthConfigService implements IModuleConfigService {
10
10
  getDatabaseMode(): DatabaseMode;
11
11
  isMultiTenant(): boolean;
12
12
  isCompanyFeatureEnabled(): boolean;
13
+ isEmailVerificationEnabled(): boolean;
13
14
  getJwtSecret(): string;
14
15
  getJwtExpiration(): string;
15
16
  getRefreshTokenSecret(): string;
@@ -18,6 +18,7 @@ export declare class AuthDataSourceProvider extends MultiTenantDataSourceService
18
18
  protected getOrCreateTenantConnection(tenant: ITenantDatabaseConfig): Promise<DataSource>;
19
19
  private static buildParentOptions;
20
20
  isCompanyFeatureEnabled(tenant?: ITenantDatabaseConfig): boolean;
21
+ isEmailVerificationEnabled(tenant?: ITenantDatabaseConfig): boolean;
21
22
  getAuthEntities(): Promise<any[]>;
22
23
  protected createDataSourceFromConfig(config: IDatabaseConfig): Promise<DataSource>;
23
24
  }
@@ -23,6 +23,7 @@ export declare class AuthEmailService {
23
23
  phone?: string;
24
24
  password: string;
25
25
  companyData?: PendingRegistration['companyData'];
26
+ additionalFields?: Record<string, any>;
26
27
  verifyUrlBase: string;
27
28
  }): Promise<{
28
29
  success: boolean;
@@ -1,5 +1,6 @@
1
1
  import { HybridCache } from '@flusys/nestjs-shared/classes';
2
2
  import { JwtService } from '@nestjs/jwt';
3
+ import { IUserEnricher } from '../interfaces/user-enricher.interface';
3
4
  import { RegistrationDto } from '../dtos/authentication.dto';
4
5
  import { CompanyBranch } from '../entities/company-branch.entity';
5
6
  import { Company } from '../entities/company.entity';
@@ -16,9 +17,11 @@ export declare class AuthenticationService {
16
17
  private readonly dataSourceProvider?;
17
18
  private readonly sessionService?;
18
19
  private readonly authEmailService?;
20
+ private readonly userEnricher?;
19
21
  private readonly logger;
20
- constructor(jwtService: JwtService, authConfig: AuthConfigService, cacheManager?: HybridCache, dataSourceProvider?: AuthDataSourceProvider, sessionService?: CompanySelectionSessionService, authEmailService?: AuthEmailService);
22
+ constructor(jwtService: JwtService, authConfig: AuthConfigService, cacheManager?: HybridCache, dataSourceProvider?: AuthDataSourceProvider, sessionService?: CompanySelectionSessionService, authEmailService?: AuthEmailService, userEnricher?: IUserEnricher);
21
23
  private isCompanyFeatureEnabled;
24
+ private isEmailVerificationEnabled;
22
25
  private getUserRepository;
23
26
  private getPermissionRepository;
24
27
  private getCompanyRepository;
@@ -1,4 +1,5 @@
1
1
  import { RequestScopedApiService, HybridCache } from '@flusys/nestjs-shared/classes';
2
+ import { FilterAndPaginationDto } from '@flusys/nestjs-shared/dtos';
2
3
  import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
3
4
  import { UtilsService } from '@flusys/nestjs-shared/modules';
4
5
  import { EntityTarget, Repository } from 'typeorm';
@@ -42,6 +43,10 @@ export declare class UserService extends RequestScopedApiService<CreateUserDto,
42
43
  user: IUser;
43
44
  extras?: IProfileExtras;
44
45
  }>;
46
+ getAll(search: string, filterAndPaginationDto: FilterAndPaginationDto, user: ILoggedUserInfo | null): Promise<{
47
+ data: Array<IUser>;
48
+ total: number;
49
+ }>;
45
50
  getEnrichedList(users: IUser[], user: ILoggedUserInfo | null): Promise<IEnrichedUser[]>;
46
51
  getProfileSections(): Promise<IProfileSection[]>;
47
52
  getProfileSectionData(userId: string, sectionId: string, user: ILoggedUserInfo): Promise<IProfileSectionData | null>;