@flusys/nestjs-auth 1.0.0-beta → 1.0.0-rc

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 (95) hide show
  1. package/README.md +274 -291
  2. package/cjs/config/auth.constants.js +12 -0
  3. package/cjs/controllers/authentication.controller.js +219 -10
  4. package/cjs/controllers/branch.controller.js +44 -1
  5. package/cjs/controllers/company-selection.controller.js +27 -20
  6. package/cjs/controllers/company.controller.js +44 -1
  7. package/cjs/controllers/user-permission.controller.js +40 -25
  8. package/cjs/controllers/user.controller.js +211 -7
  9. package/cjs/dtos/authentication.dto.js +119 -13
  10. package/cjs/dtos/user-permission.dto.js +28 -0
  11. package/cjs/dtos/user.dto.js +19 -4
  12. package/cjs/entities/index.js +5 -1
  13. package/cjs/entities/pending-registration.entity.js +125 -0
  14. package/cjs/entities/user-company-permission.entity.js +0 -6
  15. package/cjs/entities/user-token.entity.js +129 -0
  16. package/cjs/guards/auth-throttler.guard.js +53 -0
  17. package/cjs/interceptors/clear-token.interceptor.js +3 -6
  18. package/cjs/interceptors/set-token.interceptor.js +38 -31
  19. package/cjs/interfaces/auth-email-provider.interface.js +45 -0
  20. package/cjs/interfaces/index.js +2 -0
  21. package/cjs/interfaces/user-enricher.interface.js +4 -0
  22. package/cjs/modules/auth.module.js +8 -20
  23. package/cjs/services/auth-config.service.js +23 -2
  24. package/cjs/services/auth-datasource.provider.js +5 -3
  25. package/cjs/services/auth-email.service.js +471 -0
  26. package/cjs/services/authentication.service.js +169 -77
  27. package/cjs/services/branch.service.js +6 -5
  28. package/cjs/services/company-selection-session.service.js +1 -1
  29. package/cjs/services/index.js +1 -0
  30. package/cjs/services/user-permission.service.js +0 -2
  31. package/cjs/services/user.service.js +213 -34
  32. package/cjs/validators/password.validator.js +45 -0
  33. package/config/auth.constants.d.ts +3 -0
  34. package/controllers/authentication.controller.d.ts +13 -9
  35. package/controllers/company-selection.controller.d.ts +6 -2
  36. package/controllers/user.controller.d.ts +33 -0
  37. package/dtos/authentication.dto.d.ts +21 -3
  38. package/dtos/company-branch.dto.d.ts +0 -1
  39. package/dtos/company.dto.d.ts +0 -1
  40. package/dtos/user-permission.dto.d.ts +4 -0
  41. package/dtos/user.dto.d.ts +1 -2
  42. package/entities/index.d.ts +7 -3
  43. package/entities/pending-registration.entity.d.ts +17 -0
  44. package/entities/user-company-permission.entity.d.ts +0 -2
  45. package/entities/user-token.entity.d.ts +15 -0
  46. package/fesm/config/auth.constants.js +6 -2
  47. package/fesm/controllers/authentication.controller.js +221 -12
  48. package/fesm/controllers/branch.controller.js +45 -2
  49. package/fesm/controllers/company-selection.controller.js +28 -21
  50. package/fesm/controllers/company.controller.js +45 -2
  51. package/fesm/controllers/user-permission.controller.js +41 -26
  52. package/fesm/controllers/user.controller.js +214 -10
  53. package/fesm/dtos/authentication.dto.js +106 -14
  54. package/fesm/dtos/user-permission.dto.js +28 -0
  55. package/fesm/dtos/user.dto.js +20 -5
  56. package/fesm/entities/index.js +7 -1
  57. package/fesm/entities/pending-registration.entity.js +115 -0
  58. package/fesm/entities/user-company-permission.entity.js +0 -6
  59. package/fesm/entities/user-token.entity.js +113 -0
  60. package/fesm/guards/auth-throttler.guard.js +43 -0
  61. package/fesm/interceptors/clear-token.interceptor.js +2 -5
  62. package/fesm/interceptors/set-token.interceptor.js +37 -30
  63. package/fesm/interfaces/auth-email-provider.interface.js +38 -0
  64. package/fesm/interfaces/authentication.interface.js +1 -1
  65. package/fesm/interfaces/index.js +2 -0
  66. package/fesm/interfaces/user-enricher.interface.js +26 -0
  67. package/fesm/modules/auth.module.js +10 -22
  68. package/fesm/services/auth-config.service.js +24 -3
  69. package/fesm/services/auth-datasource.provider.js +6 -4
  70. package/fesm/services/auth-email.service.js +420 -0
  71. package/fesm/services/authentication.service.js +169 -77
  72. package/fesm/services/branch.service.js +6 -5
  73. package/fesm/services/company-selection-session.service.js +1 -1
  74. package/fesm/services/index.js +1 -0
  75. package/fesm/services/user-permission.service.js +1 -3
  76. package/fesm/services/user.service.js +215 -36
  77. package/fesm/validators/password.validator.js +48 -0
  78. package/guards/auth-throttler.guard.d.ts +7 -0
  79. package/interceptors/set-token.interceptor.d.ts +1 -0
  80. package/interfaces/auth-email-provider.interface.d.ts +6 -0
  81. package/interfaces/auth-module-options.interface.d.ts +4 -1
  82. package/interfaces/authentication.interface.d.ts +14 -0
  83. package/interfaces/index.d.ts +2 -0
  84. package/interfaces/user-enricher.interface.d.ts +64 -0
  85. package/interfaces/user.interface.d.ts +1 -0
  86. package/modules/auth.module.d.ts +0 -1
  87. package/package.json +4 -4
  88. package/services/auth-config.service.d.ts +5 -1
  89. package/services/auth-email.service.d.ts +51 -0
  90. package/services/authentication.service.d.ts +16 -11
  91. package/services/company-selection-session.service.d.ts +1 -1
  92. package/services/index.d.ts +1 -0
  93. package/services/user-permission.service.d.ts +0 -1
  94. package/services/user.service.d.ts +19 -3
  95. package/validators/password.validator.d.ts +10 -0
@@ -28,25 +28,32 @@ function _ts_param(paramIndex, decorator) {
28
28
  import { CurrentUser } from '@flusys/nestjs-shared/decorators';
29
29
  import { JwtAuthGuard } from '@flusys/nestjs-shared/guards';
30
30
  import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
31
- import { Body, Controller, Get, HttpCode, HttpStatus, Inject, Optional, Post, Req, UnauthorizedException, UseGuards, UseInterceptors } from '@nestjs/common';
31
+ import { Body, Controller, HttpCode, HttpStatus, Inject, Optional, Post, Req, UnauthorizedException, UseGuards, UseInterceptors } from '@nestjs/common';
32
32
  import { ApiBearerAuth, ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
33
+ import { SkipThrottle, Throttle } from '@nestjs/throttler';
33
34
  import { Request } from 'express';
34
- import { ChangePasswordDto, CompanySelectionResponseDto, LoginDto, LoginResponseDto, MeResponseDto, RefreshTokenDto, RegistrationDto, RegistrationResponseDto } from '../dtos/authentication.dto';
35
+ import { ChangePasswordDto, CompanySelectionResponseDto, ForgotPasswordDto, LoginDto, LoginResponseDto, MeResponseDto, RefreshTokenDto, RegistrationDto, RegistrationResponseDto, ResendVerificationDto, ResetPasswordDto, VerifyEmailDto } from '../dtos/authentication.dto';
36
+ import { MessageResponseDto } from '@flusys/nestjs-shared/dtos';
35
37
  import { ClearToken } from '../interceptors/clear-token.interceptor';
36
38
  import { SetToken } from '../interceptors/set-token.interceptor';
37
39
  import { AuthConfigService } from '../services/auth-config.service';
40
+ import { AuthEmailService } from '../services/auth-email.service';
38
41
  import { AuthenticationService } from '../services/authentication.service';
39
42
  export class AuthenticationController {
40
- // Core Endpoints
41
- /** Login - Returns tokens or company/branch selection requirement */ async login(loginDto) {
43
+ buildAuthUrl(req, path) {
44
+ const frontendUrl = this.authConfig?.getFrontendUrl();
45
+ return frontendUrl ? `${frontendUrl}${path}` : `${req.protocol}://${req.get('host')}${path}`;
46
+ }
47
+ async login(loginDto) {
42
48
  const result = await this.authService.login(loginDto.email, loginDto.password);
43
49
  if ('requiresSelection' in result) {
44
50
  return result;
45
51
  }
46
52
  return result;
47
53
  }
48
- /** Register new user. If company feature enabled, can join/create company. */ async register(registrationDto) {
49
- const result = await this.authService.register(registrationDto);
54
+ /** Register new user. If company feature enabled, can join/create company. */ async register(req, registrationDto) {
55
+ const verifyUrlBase = this.buildAuthUrl(req, '/auth/verify-email');
56
+ const result = await this.authService.register(registrationDto, verifyUrlBase);
50
57
  return {
51
58
  ...result,
52
59
  companyFeatureEnabled: this.authConfig?.isCompanyFeatureEnabled() ?? false
@@ -67,26 +74,82 @@ export class AuthenticationController {
67
74
  /** Logout - Clears refresh token cookie for browsers */ async logout(userId) {
68
75
  await this.authService.logout(userId);
69
76
  return {
77
+ success: true,
70
78
  message: 'Logged out successfully'
71
79
  };
72
80
  }
73
- /** Change password */ async changePassword(userId, dto) {
81
+ async changePassword(userId, dto) {
74
82
  await this.authService.changePassword(userId, dto.currentPassword, dto.newPassword);
75
83
  return {
84
+ success: true,
76
85
  message: 'Password changed successfully'
77
86
  };
78
87
  }
79
- // NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
80
- constructor(authService, authConfig){
88
+ async forgotPassword(req, dto) {
89
+ if (!this.authEmailService) {
90
+ return {
91
+ success: false,
92
+ message: 'Email service is not configured'
93
+ };
94
+ }
95
+ return this.authEmailService.forgotPassword(dto.email, this.buildAuthUrl(req, '/auth/reset-password'));
96
+ }
97
+ async resetPassword(dto) {
98
+ if (!this.authEmailService) {
99
+ return {
100
+ success: false,
101
+ message: 'Email service is not configured'
102
+ };
103
+ }
104
+ return this.authEmailService.resetPassword(dto.token, dto.newPassword);
105
+ }
106
+ async resendVerification(req, dto) {
107
+ if (!this.authEmailService) {
108
+ return {
109
+ success: false,
110
+ message: 'Email service is not configured'
111
+ };
112
+ }
113
+ return this.authEmailService.resendVerificationEmail(dto.email, this.buildAuthUrl(req, '/auth/verify-email'));
114
+ }
115
+ /** Verify email - Verify email using token. Handles both pending registration and existing user verification. */ async verifyEmail(dto) {
116
+ if (!this.authEmailService) {
117
+ return {
118
+ success: false,
119
+ message: 'Email service is not configured'
120
+ };
121
+ }
122
+ const result = await this.authEmailService.verifyEmail(dto.token);
123
+ if (result.type === 'pending') {
124
+ const registrationResult = await this.authService.createUserFromPendingRegistration(result.pending);
125
+ return {
126
+ ...registrationResult,
127
+ companyFeatureEnabled: this.authConfig?.isCompanyFeatureEnabled() ?? false
128
+ };
129
+ }
130
+ return {
131
+ success: true,
132
+ message: result.message
133
+ };
134
+ }
135
+ constructor(authService, authConfig, authEmailService){
81
136
  _define_property(this, "authService", void 0);
82
137
  _define_property(this, "authConfig", void 0);
138
+ _define_property(this, "authEmailService", void 0);
83
139
  this.authService = authService;
84
140
  this.authConfig = authConfig;
141
+ this.authEmailService = authEmailService;
85
142
  }
86
143
  }
87
144
  _ts_decorate([
88
145
  Post('login'),
89
146
  HttpCode(HttpStatus.OK),
147
+ Throttle({
148
+ default: {
149
+ limit: 5,
150
+ ttl: 60000
151
+ }
152
+ }),
90
153
  UseInterceptors(SetToken),
91
154
  ApiOperation({
92
155
  summary: 'User login'
@@ -112,6 +175,12 @@ _ts_decorate([
112
175
  _ts_decorate([
113
176
  Post('register'),
114
177
  HttpCode(HttpStatus.CREATED),
178
+ Throttle({
179
+ default: {
180
+ limit: 3,
181
+ ttl: 60000
182
+ }
183
+ }),
115
184
  UseInterceptors(SetToken),
116
185
  ApiOperation({
117
186
  summary: 'Register new user'
@@ -123,9 +192,11 @@ _ts_decorate([
123
192
  status: 201,
124
193
  type: RegistrationResponseDto
125
194
  }),
126
- _ts_param(0, Body()),
195
+ _ts_param(0, Req()),
196
+ _ts_param(1, Body()),
127
197
  _ts_metadata("design:type", Function),
128
198
  _ts_metadata("design:paramtypes", [
199
+ typeof Request === "undefined" ? Object : Request,
129
200
  typeof RegistrationDto === "undefined" ? Object : RegistrationDto
130
201
  ]),
131
202
  _ts_metadata("design:returntype", Promise)
@@ -133,6 +204,12 @@ _ts_decorate([
133
204
  _ts_decorate([
134
205
  Post('refresh'),
135
206
  HttpCode(HttpStatus.OK),
207
+ Throttle({
208
+ default: {
209
+ limit: 30,
210
+ ttl: 60000
211
+ }
212
+ }),
136
213
  ApiOperation({
137
214
  summary: 'Refresh access token'
138
215
  }),
@@ -150,7 +227,8 @@ _ts_decorate([
150
227
  ], AuthenticationController.prototype, "refreshToken", null);
151
228
  _ts_decorate([
152
229
  UseGuards(JwtAuthGuard),
153
- Get('me'),
230
+ Post('me'),
231
+ SkipThrottle(),
154
232
  ApiBearerAuth(),
155
233
  ApiOperation({
156
234
  summary: 'Get current user info'
@@ -170,11 +248,16 @@ _ts_decorate([
170
248
  UseGuards(JwtAuthGuard),
171
249
  Post('logout'),
172
250
  HttpCode(HttpStatus.OK),
251
+ SkipThrottle(),
173
252
  UseInterceptors(ClearToken),
174
253
  ApiBearerAuth(),
175
254
  ApiOperation({
176
255
  summary: 'Logout user'
177
256
  }),
257
+ ApiResponse({
258
+ status: 200,
259
+ type: MessageResponseDto
260
+ }),
178
261
  _ts_param(0, CurrentUser('id')),
179
262
  _ts_metadata("design:type", Function),
180
263
  _ts_metadata("design:paramtypes", [
@@ -186,6 +269,12 @@ _ts_decorate([
186
269
  UseGuards(JwtAuthGuard),
187
270
  Post('change-password'),
188
271
  HttpCode(HttpStatus.OK),
272
+ Throttle({
273
+ default: {
274
+ limit: 5,
275
+ ttl: 60000
276
+ }
277
+ }),
189
278
  ApiBearerAuth(),
190
279
  ApiOperation({
191
280
  summary: 'Change password'
@@ -193,6 +282,10 @@ _ts_decorate([
193
282
  ApiBody({
194
283
  type: ChangePasswordDto
195
284
  }),
285
+ ApiResponse({
286
+ status: 200,
287
+ type: MessageResponseDto
288
+ }),
196
289
  _ts_param(0, CurrentUser('id')),
197
290
  _ts_param(1, Body()),
198
291
  _ts_metadata("design:type", Function),
@@ -202,15 +295,131 @@ _ts_decorate([
202
295
  ]),
203
296
  _ts_metadata("design:returntype", Promise)
204
297
  ], AuthenticationController.prototype, "changePassword", null);
298
+ _ts_decorate([
299
+ Post('forgot-password'),
300
+ HttpCode(HttpStatus.OK),
301
+ Throttle({
302
+ default: {
303
+ limit: 3,
304
+ ttl: 300000
305
+ }
306
+ }),
307
+ ApiOperation({
308
+ summary: 'Request password reset email'
309
+ }),
310
+ ApiBody({
311
+ type: ForgotPasswordDto
312
+ }),
313
+ ApiResponse({
314
+ status: 200,
315
+ type: MessageResponseDto
316
+ }),
317
+ _ts_param(0, Req()),
318
+ _ts_param(1, Body()),
319
+ _ts_metadata("design:type", Function),
320
+ _ts_metadata("design:paramtypes", [
321
+ typeof Request === "undefined" ? Object : Request,
322
+ typeof ForgotPasswordDto === "undefined" ? Object : ForgotPasswordDto
323
+ ]),
324
+ _ts_metadata("design:returntype", Promise)
325
+ ], AuthenticationController.prototype, "forgotPassword", null);
326
+ _ts_decorate([
327
+ Post('reset-password'),
328
+ HttpCode(HttpStatus.OK),
329
+ Throttle({
330
+ default: {
331
+ limit: 5,
332
+ ttl: 900000
333
+ }
334
+ }),
335
+ ApiOperation({
336
+ summary: 'Reset password using token'
337
+ }),
338
+ ApiBody({
339
+ type: ResetPasswordDto
340
+ }),
341
+ ApiResponse({
342
+ status: 200,
343
+ type: MessageResponseDto
344
+ }),
345
+ _ts_param(0, Body()),
346
+ _ts_metadata("design:type", Function),
347
+ _ts_metadata("design:paramtypes", [
348
+ typeof ResetPasswordDto === "undefined" ? Object : ResetPasswordDto
349
+ ]),
350
+ _ts_metadata("design:returntype", Promise)
351
+ ], AuthenticationController.prototype, "resetPassword", null);
352
+ _ts_decorate([
353
+ Post('resend-verification'),
354
+ HttpCode(HttpStatus.OK),
355
+ Throttle({
356
+ default: {
357
+ limit: 3,
358
+ ttl: 300000
359
+ }
360
+ }),
361
+ ApiOperation({
362
+ summary: 'Resend email verification link'
363
+ }),
364
+ ApiBody({
365
+ type: ResendVerificationDto
366
+ }),
367
+ ApiResponse({
368
+ status: 200,
369
+ type: MessageResponseDto
370
+ }),
371
+ _ts_param(0, Req()),
372
+ _ts_param(1, Body()),
373
+ _ts_metadata("design:type", Function),
374
+ _ts_metadata("design:paramtypes", [
375
+ typeof Request === "undefined" ? Object : Request,
376
+ typeof ResendVerificationDto === "undefined" ? Object : ResendVerificationDto
377
+ ]),
378
+ _ts_metadata("design:returntype", Promise)
379
+ ], AuthenticationController.prototype, "resendVerification", null);
380
+ _ts_decorate([
381
+ Post('verify-email'),
382
+ HttpCode(HttpStatus.OK),
383
+ Throttle({
384
+ default: {
385
+ limit: 10,
386
+ ttl: 60000
387
+ }
388
+ }),
389
+ UseInterceptors(SetToken),
390
+ ApiOperation({
391
+ summary: 'Verify email using token'
392
+ }),
393
+ ApiBody({
394
+ type: VerifyEmailDto
395
+ }),
396
+ ApiResponse({
397
+ status: 200,
398
+ type: MessageResponseDto
399
+ }),
400
+ ApiResponse({
401
+ status: 200,
402
+ type: RegistrationResponseDto
403
+ }),
404
+ _ts_param(0, Body()),
405
+ _ts_metadata("design:type", Function),
406
+ _ts_metadata("design:paramtypes", [
407
+ typeof VerifyEmailDto === "undefined" ? Object : VerifyEmailDto
408
+ ]),
409
+ _ts_metadata("design:returntype", Promise)
410
+ ], AuthenticationController.prototype, "verifyEmail", null);
205
411
  AuthenticationController = _ts_decorate([
206
412
  ApiTags('Authentication'),
207
413
  Controller('auth'),
208
414
  _ts_param(0, Inject(AuthenticationService)),
209
415
  _ts_param(1, Optional()),
210
416
  _ts_param(1, Inject(AuthConfigService)),
417
+ _ts_param(2, Optional()),
418
+ _ts_param(2, Inject(AuthEmailService)),
211
419
  _ts_metadata("design:type", Function),
212
420
  _ts_metadata("design:paramtypes", [
213
421
  typeof AuthenticationService === "undefined" ? Object : AuthenticationService,
214
- typeof AuthConfigService === "undefined" ? Object : AuthConfigService
422
+ typeof AuthConfigService === "undefined" ? Object : AuthConfigService,
423
+ typeof AuthEmailService === "undefined" ? Object : AuthEmailService
215
424
  ])
216
425
  ], AuthenticationController);
@@ -25,13 +25,56 @@ function _ts_param(paramIndex, decorator) {
25
25
  decorator(target, key, paramIndex);
26
26
  };
27
27
  }
28
- import { createApiController } from '@flusys/nestjs-shared/classes';
28
+ import { createApiController, BRANCH_PERMISSIONS } from '@flusys/nestjs-shared/classes';
29
29
  import { Controller, Inject } from '@nestjs/common';
30
30
  import { ApiTags } from '@nestjs/swagger';
31
31
  import { CompanyBranchResponseDto, CreateCompanyBranchDto, UpdateCompanyBranchDto } from '../dtos/company-branch.dto';
32
32
  import { BranchService } from '../services/branch.service';
33
33
  export class BranchController extends createApiController(CreateCompanyBranchDto, UpdateCompanyBranchDto, CompanyBranchResponseDto, {
34
- security: 'jwt'
34
+ security: {
35
+ insert: {
36
+ level: 'permission',
37
+ permissions: [
38
+ BRANCH_PERMISSIONS.CREATE
39
+ ]
40
+ },
41
+ insertMany: {
42
+ level: 'permission',
43
+ permissions: [
44
+ BRANCH_PERMISSIONS.CREATE
45
+ ]
46
+ },
47
+ getById: {
48
+ level: 'permission',
49
+ permissions: [
50
+ BRANCH_PERMISSIONS.READ
51
+ ]
52
+ },
53
+ getAll: {
54
+ level: 'permission',
55
+ permissions: [
56
+ BRANCH_PERMISSIONS.READ
57
+ ]
58
+ },
59
+ update: {
60
+ level: 'permission',
61
+ permissions: [
62
+ BRANCH_PERMISSIONS.UPDATE
63
+ ]
64
+ },
65
+ updateMany: {
66
+ level: 'permission',
67
+ permissions: [
68
+ BRANCH_PERMISSIONS.UPDATE
69
+ ]
70
+ },
71
+ delete: {
72
+ level: 'permission',
73
+ permissions: [
74
+ BRANCH_PERMISSIONS.DELETE
75
+ ]
76
+ }
77
+ }
35
78
  }) {
36
79
  constructor(branchService){
37
80
  super(branchService), _define_property(this, "branchService", void 0), this.branchService = branchService;
@@ -26,42 +26,35 @@ function _ts_param(paramIndex, decorator) {
26
26
  };
27
27
  }
28
28
  import { CurrentUser } from '@flusys/nestjs-shared/decorators';
29
- import { Body, Controller, Get, HttpCode, HttpStatus, Inject, Param, Post, UseGuards, UseInterceptors } from '@nestjs/common';
29
+ import { Body, Controller, HttpCode, HttpStatus, Inject, Post, UseGuards, UseInterceptors } from '@nestjs/common';
30
30
  import { ApiBearerAuth, ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
31
31
  import { LoginResponseDto, SelectDto, SwitchCompanyDto } from '../dtos/authentication.dto';
32
32
  import { JwtAuthGuard } from '@flusys/nestjs-shared/guards';
33
33
  import { SetToken } from '../interceptors/set-token.interceptor';
34
34
  import { AuthenticationService } from '../services/authentication.service';
35
35
  export class CompanySelectionController {
36
- /**
37
- * Select Company & Branch
38
- * Used after login when user needs to select company and branch
39
- */ async select(dto) {
36
+ async select(dto) {
40
37
  return this.authService.select(dto.sessionId, dto.companyId, dto.branchId);
41
38
  }
42
- /**
43
- * Switch Company/Branch
44
- * Used to switch company/branch after already logged in
45
- */ async switchCompany(userId, dto) {
39
+ async switchCompany(userId, dto) {
46
40
  return this.authService.switchCompany(userId, dto.companyId, dto.branchId);
47
41
  }
48
- /**
49
- * Get user's companies
50
- */ async getUserCompanies(userId) {
42
+ async getUserCompanies(userId) {
51
43
  const companies = await this.authService.getUserCompanies(userId);
52
44
  return {
53
- companies
45
+ success: true,
46
+ message: 'User companies retrieved successfully',
47
+ data: companies
54
48
  };
55
49
  }
56
- /**
57
- * Get branches for a specific company
58
- */ async getUserBranches(userId, companyId) {
50
+ async getUserBranches(userId, companyId) {
59
51
  const branches = await this.authService.getUserBranches(userId, companyId);
60
52
  return {
61
- branches
53
+ success: true,
54
+ message: 'Company branches retrieved successfully',
55
+ data: branches
62
56
  };
63
57
  }
64
- // NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
65
58
  constructor(authService){
66
59
  _define_property(this, "authService", void 0);
67
60
  this.authService = authService;
@@ -117,7 +110,8 @@ _ts_decorate([
117
110
  ], CompanySelectionController.prototype, "switchCompany", null);
118
111
  _ts_decorate([
119
112
  UseGuards(JwtAuthGuard),
120
- Get('companies'),
113
+ Post('get-companies'),
114
+ HttpCode(HttpStatus.OK),
121
115
  ApiBearerAuth(),
122
116
  ApiOperation({
123
117
  summary: "Get user's available companies",
@@ -132,14 +126,27 @@ _ts_decorate([
132
126
  ], CompanySelectionController.prototype, "getUserCompanies", null);
133
127
  _ts_decorate([
134
128
  UseGuards(JwtAuthGuard),
135
- Get('companies/:companyId/branches'),
129
+ Post('get-company-branches'),
130
+ HttpCode(HttpStatus.OK),
136
131
  ApiBearerAuth(),
137
132
  ApiOperation({
138
133
  summary: 'Get branches for a company',
139
134
  description: 'Get list of branches for a specific company that the user has access to'
140
135
  }),
136
+ ApiBody({
137
+ schema: {
138
+ properties: {
139
+ companyId: {
140
+ type: 'string'
141
+ }
142
+ },
143
+ required: [
144
+ 'companyId'
145
+ ]
146
+ }
147
+ }),
141
148
  _ts_param(0, CurrentUser('id')),
142
- _ts_param(1, Param('companyId')),
149
+ _ts_param(1, Body('companyId')),
143
150
  _ts_metadata("design:type", Function),
144
151
  _ts_metadata("design:paramtypes", [
145
152
  String,
@@ -25,13 +25,56 @@ function _ts_param(paramIndex, decorator) {
25
25
  decorator(target, key, paramIndex);
26
26
  };
27
27
  }
28
- import { createApiController } from '@flusys/nestjs-shared/classes';
28
+ import { createApiController, COMPANY_PERMISSIONS } from '@flusys/nestjs-shared/classes';
29
29
  import { Controller, Inject } from '@nestjs/common';
30
30
  import { ApiTags } from '@nestjs/swagger';
31
31
  import { CompanyResponseDto, CreateCompanyDto, UpdateCompanyDto } from '../dtos/company.dto';
32
32
  import { CompanyService } from '../services/company.service';
33
33
  export class CompanyController extends createApiController(CreateCompanyDto, UpdateCompanyDto, CompanyResponseDto, {
34
- security: 'jwt'
34
+ security: {
35
+ insert: {
36
+ level: 'permission',
37
+ permissions: [
38
+ COMPANY_PERMISSIONS.CREATE
39
+ ]
40
+ },
41
+ insertMany: {
42
+ level: 'permission',
43
+ permissions: [
44
+ COMPANY_PERMISSIONS.CREATE
45
+ ]
46
+ },
47
+ getById: {
48
+ level: 'permission',
49
+ permissions: [
50
+ COMPANY_PERMISSIONS.READ
51
+ ]
52
+ },
53
+ getAll: {
54
+ level: 'permission',
55
+ permissions: [
56
+ COMPANY_PERMISSIONS.READ
57
+ ]
58
+ },
59
+ update: {
60
+ level: 'permission',
61
+ permissions: [
62
+ COMPANY_PERMISSIONS.UPDATE
63
+ ]
64
+ },
65
+ updateMany: {
66
+ level: 'permission',
67
+ permissions: [
68
+ COMPANY_PERMISSIONS.UPDATE
69
+ ]
70
+ },
71
+ delete: {
72
+ level: 'permission',
73
+ permissions: [
74
+ COMPANY_PERMISSIONS.DELETE
75
+ ]
76
+ }
77
+ }
35
78
  }) {
36
79
  constructor(companyService){
37
80
  super(companyService), _define_property(this, "companyService", void 0), this.companyService = companyService;