@flusys/nestjs-auth 6.2.2 → 6.3.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.
@@ -84,7 +84,8 @@ const USER_MESSAGES = {
84
84
  PROFILE_COMPLETION_SUCCESS: 'user.profile.completion.success',
85
85
  EMAIL_VERIFY_SUCCESS: 'user.email.verify.success',
86
86
  PHONE_VERIFY_SUCCESS: 'user.phone.verify.success',
87
- STATUS_UPDATE_SUCCESS: 'user.status.update.success'
87
+ STATUS_UPDATE_SUCCESS: 'user.status.update.success',
88
+ LOOKUP_SUCCESS: 'user.lookup.success'
88
89
  };
89
90
  const USER_PERMISSION_MESSAGES = {
90
91
  COMPANY_LIST_SUCCESS: 'user.permission.company.list.success',
@@ -10,10 +10,12 @@ Object.defineProperty(exports, "UserController", {
10
10
  });
11
11
  const _classes = require("@flusys/nestjs-shared/classes");
12
12
  const _decorators = require("@flusys/nestjs-shared/decorators");
13
+ const _dtos = require("@flusys/nestjs-shared/dtos");
13
14
  const _guards = require("@flusys/nestjs-shared/guards");
14
15
  const _interfaces = require("@flusys/nestjs-shared/interfaces");
15
16
  const _common = require("@nestjs/common");
16
17
  const _swagger = require("@nestjs/swagger");
18
+ const _classtransformer = require("class-transformer");
17
19
  const _config = require("../config");
18
20
  const _userdto = require("../dtos/user.dto");
19
21
  const _userservice = require("../services/user.service");
@@ -91,6 +93,29 @@ let UserController = class UserController extends (0, _classes.createApiControll
91
93
  }
92
94
  }
93
95
  }) {
96
+ async lookup(filterAndPaginationDto, user, search) {
97
+ const result = await this.service.getAll(search ?? '', filterAndPaginationDto, user);
98
+ const data = result.data.map((item)=>(0, _classtransformer.plainToInstance)(_userdto.UserLookupResponseDto, item, {
99
+ excludeExtraneousValues: true
100
+ }));
101
+ const page = filterAndPaginationDto.pagination?.currentPage ?? 0;
102
+ const pageSize = filterAndPaginationDto.pagination?.pageSize ?? data.length;
103
+ const totalPages = pageSize > 0 ? Math.ceil(result.total / pageSize) : 1;
104
+ return {
105
+ success: true,
106
+ message: 'Users retrieved successfully',
107
+ messageKey: _config.USER_MESSAGES.LOOKUP_SUCCESS,
108
+ data,
109
+ meta: {
110
+ total: result.total,
111
+ page,
112
+ pageSize,
113
+ count: data.length,
114
+ hasMore: page < totalPages - 1,
115
+ totalPages
116
+ }
117
+ };
118
+ }
94
119
  async getProfileWithExtras(id, user) {
95
120
  const data = await this.service.getProfileWithExtras(id, user);
96
121
  return {
@@ -174,6 +199,34 @@ let UserController = class UserController extends (0, _classes.createApiControll
174
199
  super(service), _define_property(this, "service", void 0), this.service = service;
175
200
  }
176
201
  };
202
+ _ts_decorate([
203
+ (0, _common.Post)('lookup'),
204
+ (0, _common.UseGuards)(_guards.JwtAuthGuard, _guards.PermissionGuard),
205
+ (0, _swagger.ApiBearerAuth)(),
206
+ (0, _decorators.RequireAnyPermission)(_classes.USER_PERMISSIONS.READ, _classes.USER_PERMISSIONS.LOOKUP),
207
+ (0, _swagger.ApiOperation)({
208
+ summary: 'Lookup users for pickers/directory',
209
+ description: 'Lightweight user directory search for selection widgets (event participants, assignees, etc.). ' + 'Returns only id/name/email. Accessible with USER_PERMISSIONS.READ or the narrower USER_PERMISSIONS.LOOKUP, ' + 'so panels that only need to pick a user do not require full user-management access.'
210
+ }),
211
+ (0, _swagger.ApiQuery)({
212
+ name: 'q',
213
+ required: false,
214
+ description: 'Global text search across searchable fields'
215
+ }),
216
+ (0, _swagger.ApiBody)({
217
+ type: _dtos.FilterAndPaginationDto
218
+ }),
219
+ _ts_param(0, (0, _common.Body)()),
220
+ _ts_param(1, (0, _decorators.CurrentUser)()),
221
+ _ts_param(2, (0, _common.Query)('q')),
222
+ _ts_metadata("design:type", Function),
223
+ _ts_metadata("design:paramtypes", [
224
+ typeof _dtos.FilterAndPaginationDto === "undefined" ? Object : _dtos.FilterAndPaginationDto,
225
+ typeof _interfaces.ILoggedUserInfo === "undefined" ? Object : _interfaces.ILoggedUserInfo,
226
+ String
227
+ ]),
228
+ _ts_metadata("design:returntype", Promise)
229
+ ], UserController.prototype, "lookup", null);
177
230
  _ts_decorate([
178
231
  (0, _common.Post)(':id/profile-extras'),
179
232
  (0, _common.UseGuards)(_guards.JwtAuthGuard, _guards.PermissionGuard),
@@ -15,6 +15,9 @@ _export(exports, {
15
15
  get UpdateUserDto () {
16
16
  return UpdateUserDto;
17
17
  },
18
+ get UserLookupResponseDto () {
19
+ return UserLookupResponseDto;
20
+ },
18
21
  get UserResponseDto () {
19
22
  return UserResponseDto;
20
23
  }
@@ -380,3 +383,31 @@ _ts_decorate([
380
383
  }),
381
384
  _ts_metadata("design:type", Object)
382
385
  ], UserResponseDto.prototype, "deletedAt", void 0);
386
+ let UserLookupResponseDto = class UserLookupResponseDto {
387
+ constructor(){
388
+ _define_property(this, "id", void 0);
389
+ _define_property(this, "name", void 0);
390
+ _define_property(this, "email", void 0);
391
+ }
392
+ };
393
+ _ts_decorate([
394
+ (0, _classtransformer.Expose)(),
395
+ (0, _swagger.ApiProperty)({
396
+ example: '550e8400-e29b-41d4-a716-446655440000'
397
+ }),
398
+ _ts_metadata("design:type", String)
399
+ ], UserLookupResponseDto.prototype, "id", void 0);
400
+ _ts_decorate([
401
+ (0, _classtransformer.Expose)(),
402
+ (0, _swagger.ApiProperty)({
403
+ example: 'John Doe'
404
+ }),
405
+ _ts_metadata("design:type", String)
406
+ ], UserLookupResponseDto.prototype, "name", void 0);
407
+ _ts_decorate([
408
+ (0, _classtransformer.Expose)(),
409
+ (0, _swagger.ApiProperty)({
410
+ example: 'john@example.com'
411
+ }),
412
+ _ts_metadata("design:type", String)
413
+ ], UserLookupResponseDto.prototype, "email", void 0);
@@ -60,6 +60,7 @@ export declare const USER_MESSAGES: {
60
60
  readonly EMAIL_VERIFY_SUCCESS: "user.email.verify.success";
61
61
  readonly PHONE_VERIFY_SUCCESS: "user.phone.verify.success";
62
62
  readonly STATUS_UPDATE_SUCCESS: "user.status.update.success";
63
+ readonly LOOKUP_SUCCESS: "user.lookup.success";
63
64
  };
64
65
  export declare const USER_PERMISSION_MESSAGES: {
65
66
  readonly COMPANY_LIST_SUCCESS: "user.permission.company.list.success";
@@ -1,5 +1,6 @@
1
+ import { FilterAndPaginationDto, ListResponseDto } from '@flusys/nestjs-shared/dtos';
1
2
  import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
2
- import { CreateUserDto, UpdateUserDto, UserResponseDto } from '../dtos/user.dto';
3
+ import { CreateUserDto, UpdateUserDto, UserLookupResponseDto, UserResponseDto } from '../dtos/user.dto';
3
4
  import { IUser } from '../interfaces/user.interface';
4
5
  import { UserService } from '../services/user.service';
5
6
  declare const UserController_base: abstract new (service: UserService) => {
@@ -9,17 +10,18 @@ declare const UserController_base: abstract new (service: UserService) => {
9
10
  insert(addDto: CreateUserDto, user: ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared").SingleResponseDto<UserResponseDto>>;
10
11
  insertMany(addDto: CreateUserDto[], user: ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared").BulkResponseDto<UserResponseDto>>;
11
12
  getById(id: string, body: import("@flusys/nestjs-shared").GetByIdBodyDto, user: ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared").SingleResponseDto<UserResponseDto>>;
12
- getByIds(body: import("@flusys/nestjs-shared").GetByIdsDto, user: ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared").ListResponseDto<UserResponseDto>>;
13
+ getByIds(body: import("@flusys/nestjs-shared").GetByIdsDto, user: ILoggedUserInfo | null): Promise<ListResponseDto<UserResponseDto>>;
13
14
  update(updateDto: UpdateUserDto, user: ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared").SingleResponseDto<UserResponseDto>>;
14
15
  updateMany(updateDtos: UpdateUserDto[], user: ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared").BulkResponseDto<UserResponseDto>>;
15
16
  bulkUpsert(dtos: (CreateUserDto | UpdateUserDto)[], user: ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared").BulkResponseDto<UserResponseDto>>;
16
17
  getByFilter(filter: Record<string, any>, user: ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared").SingleResponseDto<UserResponseDto>>;
17
- getAll(filterAndPaginationDto: import("@flusys/nestjs-shared").FilterAndPaginationDto, user: ILoggedUserInfo | null, search?: string): Promise<import("@flusys/nestjs-shared").ListResponseDto<UserResponseDto>>;
18
+ getAll(filterAndPaginationDto: FilterAndPaginationDto, user: ILoggedUserInfo | null, search?: string): Promise<ListResponseDto<UserResponseDto>>;
18
19
  delete(deleteDto: import("@flusys/nestjs-shared").DeleteDto, user: ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared").MessageResponseDto>;
19
20
  };
20
21
  export declare class UserController extends UserController_base {
21
22
  service: UserService;
22
23
  constructor(service: UserService);
24
+ lookup(filterAndPaginationDto: FilterAndPaginationDto, user: ILoggedUserInfo, search?: string): Promise<ListResponseDto<UserLookupResponseDto>>;
23
25
  getProfileWithExtras(id: string, user: ILoggedUserInfo): Promise<{
24
26
  success: boolean;
25
27
  message: string;
@@ -37,3 +37,8 @@ export declare class UserResponseDto {
37
37
  updatedAt: Date;
38
38
  deletedAt?: Date | null;
39
39
  }
40
+ export declare class UserLookupResponseDto {
41
+ id: string;
42
+ name: string;
43
+ email: string;
44
+ }
@@ -60,7 +60,8 @@ export const USER_MESSAGES = {
60
60
  PROFILE_COMPLETION_SUCCESS: 'user.profile.completion.success',
61
61
  EMAIL_VERIFY_SUCCESS: 'user.email.verify.success',
62
62
  PHONE_VERIFY_SUCCESS: 'user.phone.verify.success',
63
- STATUS_UPDATE_SUCCESS: 'user.status.update.success'
63
+ STATUS_UPDATE_SUCCESS: 'user.status.update.success',
64
+ LOOKUP_SUCCESS: 'user.lookup.success'
64
65
  };
65
66
  export const USER_PERMISSION_MESSAGES = {
66
67
  COMPANY_LIST_SUCCESS: 'user.permission.company.list.success',
@@ -26,13 +26,15 @@ function _ts_param(paramIndex, decorator) {
26
26
  };
27
27
  }
28
28
  import { createApiController, USER_PERMISSIONS } from '@flusys/nestjs-shared/classes';
29
- import { CurrentUser, RequirePermission } from '@flusys/nestjs-shared/decorators';
29
+ import { CurrentUser, RequireAnyPermission, RequirePermission } from '@flusys/nestjs-shared/decorators';
30
+ import { FilterAndPaginationDto } from '@flusys/nestjs-shared/dtos';
30
31
  import { JwtAuthGuard, PermissionGuard } from '@flusys/nestjs-shared/guards';
31
32
  import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
32
- import { Body, Controller, Inject, Param, Post, UseGuards } from '@nestjs/common';
33
- import { ApiBearerAuth, ApiBody, ApiOperation, ApiParam, ApiTags } from '@nestjs/swagger';
33
+ import { Body, Controller, Inject, Param, Post, Query, UseGuards } from '@nestjs/common';
34
+ import { ApiBearerAuth, ApiBody, ApiOperation, ApiParam, ApiQuery, ApiTags } from '@nestjs/swagger';
35
+ import { plainToInstance } from 'class-transformer';
34
36
  import { USER_MESSAGES } from '../config';
35
- import { CreateUserDto, UpdateUserDto, UserResponseDto } from '../dtos/user.dto';
37
+ import { CreateUserDto, UpdateUserDto, UserLookupResponseDto, UserResponseDto } from '../dtos/user.dto';
36
38
  import { UserService } from '../services/user.service';
37
39
  export class UserController extends createApiController(CreateUserDto, UpdateUserDto, UserResponseDto, {
38
40
  entityName: 'user',
@@ -81,6 +83,29 @@ export class UserController extends createApiController(CreateUserDto, UpdateUse
81
83
  }
82
84
  }
83
85
  }) {
86
+ async lookup(filterAndPaginationDto, user, search) {
87
+ const result = await this.service.getAll(search ?? '', filterAndPaginationDto, user);
88
+ const data = result.data.map((item)=>plainToInstance(UserLookupResponseDto, item, {
89
+ excludeExtraneousValues: true
90
+ }));
91
+ const page = filterAndPaginationDto.pagination?.currentPage ?? 0;
92
+ const pageSize = filterAndPaginationDto.pagination?.pageSize ?? data.length;
93
+ const totalPages = pageSize > 0 ? Math.ceil(result.total / pageSize) : 1;
94
+ return {
95
+ success: true,
96
+ message: 'Users retrieved successfully',
97
+ messageKey: USER_MESSAGES.LOOKUP_SUCCESS,
98
+ data,
99
+ meta: {
100
+ total: result.total,
101
+ page,
102
+ pageSize,
103
+ count: data.length,
104
+ hasMore: page < totalPages - 1,
105
+ totalPages
106
+ }
107
+ };
108
+ }
84
109
  async getProfileWithExtras(id, user) {
85
110
  const data = await this.service.getProfileWithExtras(id, user);
86
111
  return {
@@ -164,6 +189,34 @@ export class UserController extends createApiController(CreateUserDto, UpdateUse
164
189
  super(service), _define_property(this, "service", void 0), this.service = service;
165
190
  }
166
191
  }
192
+ _ts_decorate([
193
+ Post('lookup'),
194
+ UseGuards(JwtAuthGuard, PermissionGuard),
195
+ ApiBearerAuth(),
196
+ RequireAnyPermission(USER_PERMISSIONS.READ, USER_PERMISSIONS.LOOKUP),
197
+ ApiOperation({
198
+ summary: 'Lookup users for pickers/directory',
199
+ description: 'Lightweight user directory search for selection widgets (event participants, assignees, etc.). ' + 'Returns only id/name/email. Accessible with USER_PERMISSIONS.READ or the narrower USER_PERMISSIONS.LOOKUP, ' + 'so panels that only need to pick a user do not require full user-management access.'
200
+ }),
201
+ ApiQuery({
202
+ name: 'q',
203
+ required: false,
204
+ description: 'Global text search across searchable fields'
205
+ }),
206
+ ApiBody({
207
+ type: FilterAndPaginationDto
208
+ }),
209
+ _ts_param(0, Body()),
210
+ _ts_param(1, CurrentUser()),
211
+ _ts_param(2, Query('q')),
212
+ _ts_metadata("design:type", Function),
213
+ _ts_metadata("design:paramtypes", [
214
+ typeof FilterAndPaginationDto === "undefined" ? Object : FilterAndPaginationDto,
215
+ typeof ILoggedUserInfo === "undefined" ? Object : ILoggedUserInfo,
216
+ String
217
+ ]),
218
+ _ts_metadata("design:returntype", Promise)
219
+ ], UserController.prototype, "lookup", null);
167
220
  _ts_decorate([
168
221
  Post(':id/profile-extras'),
169
222
  UseGuards(JwtAuthGuard, PermissionGuard),
@@ -361,3 +361,31 @@ _ts_decorate([
361
361
  }),
362
362
  _ts_metadata("design:type", Object)
363
363
  ], UserResponseDto.prototype, "deletedAt", void 0);
364
+ export class UserLookupResponseDto {
365
+ constructor(){
366
+ _define_property(this, "id", void 0);
367
+ _define_property(this, "name", void 0);
368
+ _define_property(this, "email", void 0);
369
+ }
370
+ }
371
+ _ts_decorate([
372
+ Expose(),
373
+ ApiProperty({
374
+ example: '550e8400-e29b-41d4-a716-446655440000'
375
+ }),
376
+ _ts_metadata("design:type", String)
377
+ ], UserLookupResponseDto.prototype, "id", void 0);
378
+ _ts_decorate([
379
+ Expose(),
380
+ ApiProperty({
381
+ example: 'John Doe'
382
+ }),
383
+ _ts_metadata("design:type", String)
384
+ ], UserLookupResponseDto.prototype, "name", void 0);
385
+ _ts_decorate([
386
+ Expose(),
387
+ ApiProperty({
388
+ example: 'john@example.com'
389
+ }),
390
+ _ts_metadata("design:type", String)
391
+ ], UserLookupResponseDto.prototype, "email", void 0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flusys/nestjs-auth",
3
- "version": "6.2.2",
3
+ "version": "6.3.0",
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.2.2",
102
- "@flusys/nestjs-shared": "6.2.2"
101
+ "@flusys/nestjs-core": "6.3.0",
102
+ "@flusys/nestjs-shared": "6.3.0"
103
103
  }
104
104
  }