@flusys/nestjs-auth 1.1.0-beta → 1.1.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 (94) hide show
  1. package/README.md +633 -468
  2. package/cjs/config/auth.constants.js +8 -0
  3. package/cjs/controllers/authentication.controller.js +175 -167
  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/email-verification.controller.js +220 -0
  8. package/cjs/controllers/index.js +1 -0
  9. package/cjs/controllers/user-permission.controller.js +82 -154
  10. package/cjs/controllers/user.controller.js +68 -15
  11. package/cjs/docs/auth-swagger.config.js +14 -7
  12. package/cjs/dtos/authentication.dto.js +16 -43
  13. package/cjs/dtos/index.js +0 -1
  14. package/cjs/dtos/user-permission.dto.js +28 -0
  15. package/cjs/dtos/user.dto.js +19 -4
  16. package/cjs/entities/index.js +16 -17
  17. package/cjs/entities/user-company-permission.entity.js +3 -9
  18. package/cjs/interceptors/clear-token.interceptor.js +10 -23
  19. package/cjs/interceptors/set-token.interceptor.js +15 -55
  20. package/cjs/interfaces/auth-email-provider.interface.js +1 -1
  21. package/cjs/modules/auth.module.js +79 -154
  22. package/cjs/services/auth-config.service.js +33 -35
  23. package/cjs/services/auth-datasource.provider.js +18 -42
  24. package/cjs/services/auth-email.service.js +89 -85
  25. package/cjs/services/authentication.service.js +248 -414
  26. package/cjs/services/branch.service.js +9 -4
  27. package/cjs/services/company-selection-session.service.js +1 -1
  28. package/cjs/services/user-permission.service.js +43 -73
  29. package/cjs/services/user.service.js +78 -64
  30. package/cjs/strategies/jwt.strategy.js +44 -44
  31. package/cjs/validators/password.validator.js +45 -0
  32. package/config/auth.constants.d.ts +2 -0
  33. package/controllers/authentication.controller.d.ts +4 -10
  34. package/controllers/company-selection.controller.d.ts +6 -2
  35. package/controllers/email-verification.controller.d.ts +20 -0
  36. package/controllers/index.d.ts +1 -0
  37. package/controllers/user-permission.controller.d.ts +5 -4
  38. package/controllers/user.controller.d.ts +6 -0
  39. package/dtos/authentication.dto.d.ts +0 -4
  40. package/dtos/company-branch.dto.d.ts +0 -1
  41. package/dtos/company.dto.d.ts +0 -1
  42. package/dtos/index.d.ts +0 -1
  43. package/dtos/user-permission.dto.d.ts +4 -0
  44. package/dtos/user.dto.d.ts +1 -3
  45. package/entities/index.d.ts +5 -10
  46. package/entities/user-company-permission.entity.d.ts +1 -3
  47. package/fesm/config/auth.constants.js +6 -13
  48. package/fesm/controllers/authentication.controller.js +178 -170
  49. package/fesm/controllers/branch.controller.js +45 -2
  50. package/fesm/controllers/company-selection.controller.js +28 -21
  51. package/fesm/controllers/company.controller.js +45 -2
  52. package/fesm/controllers/email-verification.controller.js +210 -0
  53. package/fesm/controllers/index.js +1 -0
  54. package/fesm/controllers/user-permission.controller.js +84 -156
  55. package/fesm/controllers/user.controller.js +71 -18
  56. package/fesm/docs/auth-swagger.config.js +14 -7
  57. package/fesm/dtos/authentication.dto.js +17 -44
  58. package/fesm/dtos/index.js +0 -1
  59. package/fesm/dtos/user-permission.dto.js +28 -0
  60. package/fesm/dtos/user.dto.js +20 -5
  61. package/fesm/entities/index.js +17 -9
  62. package/fesm/entities/user-company-permission.entity.js +3 -9
  63. package/fesm/interceptors/clear-token.interceptor.js +9 -22
  64. package/fesm/interceptors/set-token.interceptor.js +14 -54
  65. package/fesm/interfaces/auth-email-provider.interface.js +1 -1
  66. package/fesm/modules/auth.module.js +82 -157
  67. package/fesm/services/auth-config.service.js +34 -36
  68. package/fesm/services/auth-datasource.provider.js +19 -43
  69. package/fesm/services/auth-email.service.js +90 -86
  70. package/fesm/services/authentication.service.js +248 -414
  71. package/fesm/services/branch.service.js +9 -4
  72. package/fesm/services/company-selection-session.service.js +1 -1
  73. package/fesm/services/user-permission.service.js +44 -74
  74. package/fesm/services/user.service.js +79 -65
  75. package/fesm/strategies/jwt.strategy.js +44 -44
  76. package/fesm/validators/password.validator.js +48 -0
  77. package/interceptors/clear-token.interceptor.d.ts +0 -1
  78. package/interceptors/set-token.interceptor.d.ts +1 -1
  79. package/interfaces/authentication.interface.d.ts +0 -4
  80. package/interfaces/user-enricher.interface.d.ts +1 -4
  81. package/modules/auth.module.d.ts +9 -4
  82. package/package.json +4 -4
  83. package/services/auth-config.service.d.ts +7 -8
  84. package/services/auth-datasource.provider.d.ts +3 -4
  85. package/services/auth-email.service.d.ts +8 -4
  86. package/services/authentication.service.d.ts +16 -16
  87. package/services/company-selection-session.service.d.ts +1 -1
  88. package/services/user-permission.service.d.ts +6 -9
  89. package/services/user.service.d.ts +3 -0
  90. package/strategies/jwt.strategy.d.ts +4 -1
  91. package/validators/password.validator.d.ts +10 -0
  92. package/cjs/dtos/user-company-permission.dto.js +0 -110
  93. package/dtos/user-company-permission.dto.d.ts +0 -10
  94. package/fesm/dtos/user-company-permission.dto.js +0 -98
@@ -16,6 +16,12 @@ _export(exports, {
16
16
  get BCRYPT_SALT_ROUNDS () {
17
17
  return BCRYPT_SALT_ROUNDS;
18
18
  },
19
+ get DEFAULT_COOKIE_NAME () {
20
+ return DEFAULT_COOKIE_NAME;
21
+ },
22
+ get MAX_COOKIE_BYTES () {
23
+ return MAX_COOKIE_BYTES;
24
+ },
19
25
  get SESSION_CACHE_PREFIX () {
20
26
  return SESSION_CACHE_PREFIX;
21
27
  },
@@ -29,5 +35,7 @@ _export(exports, {
29
35
  const AUTH_MODULE_OPTIONS = 'AUTH_MODULE_OPTIONS';
30
36
  const USER_ENRICHER = 'USER_ENRICHER';
31
37
  const BCRYPT_SALT_ROUNDS = 12;
38
+ const DEFAULT_COOKIE_NAME = 'fsn_refresh_token';
39
+ const MAX_COOKIE_BYTES = 3500;
32
40
  const SESSION_CACHE_PREFIX = 'auth:session';
33
41
  const TOKEN_REVOKED_PREFIX = 'auth:revoked';
@@ -9,17 +9,18 @@ Object.defineProperty(exports, "AuthenticationController", {
9
9
  }
10
10
  });
11
11
  const _decorators = require("@flusys/nestjs-shared/decorators");
12
+ const _dtos = require("@flusys/nestjs-shared/dtos");
12
13
  const _guards = require("@flusys/nestjs-shared/guards");
13
14
  const _interfaces = require("@flusys/nestjs-shared/interfaces");
14
15
  const _common = require("@nestjs/common");
15
16
  const _swagger = require("@nestjs/swagger");
17
+ const _throttler = require("@nestjs/throttler");
16
18
  const _express = require("express");
19
+ const _config = require("../config");
17
20
  const _authenticationdto = require("../dtos/authentication.dto");
18
- const _dtos = require("@flusys/nestjs-shared/dtos");
19
21
  const _cleartokeninterceptor = require("../interceptors/clear-token.interceptor");
20
22
  const _settokeninterceptor = require("../interceptors/set-token.interceptor");
21
23
  const _authconfigservice = require("../services/auth-config.service");
22
- const _authemailservice = require("../services/auth-email.service");
23
24
  const _authenticationservice = require("../services/authentication.service");
24
25
  function _define_property(obj, key, value) {
25
26
  if (key in obj) {
@@ -49,13 +50,15 @@ function _ts_param(paramIndex, decorator) {
49
50
  };
50
51
  }
51
52
  let AuthenticationController = class AuthenticationController {
52
- /** Build auth URL for email links */ buildAuthUrl(req, path) {
53
+ buildAuthUrl(req, path) {
53
54
  const frontendUrl = this.authConfig?.getFrontendUrl();
54
55
  return frontendUrl ? `${frontendUrl}${path}` : `${req.protocol}://${req.get('host')}${path}`;
55
56
  }
56
- // Core Endpoints
57
- /** Login - Returns tokens or company/branch selection requirement */ async login(loginDto) {
57
+ async login(loginDto) {
58
58
  const result = await this.authService.login(loginDto.email, loginDto.password);
59
+ if ('requiresEmailVerification' in result) {
60
+ return result;
61
+ }
59
62
  if ('requiresSelection' in result) {
60
63
  return result;
61
64
  }
@@ -64,14 +67,15 @@ let AuthenticationController = class AuthenticationController {
64
67
  /** Register new user. If company feature enabled, can join/create company. */ async register(req, registrationDto) {
65
68
  const verifyUrlBase = this.buildAuthUrl(req, '/auth/verify-email');
66
69
  const result = await this.authService.register(registrationDto, verifyUrlBase);
67
- return {
68
- ...result,
69
- companyFeatureEnabled: this.authConfig?.isCompanyFeatureEnabled() ?? false
70
- };
70
+ return result;
71
71
  }
72
- /** Refresh access token. Browser uses HTTP-only cookie, API/Mobile uses request body. */ async refreshToken(req, refreshTokenDto) {
73
- // Get refresh token from cookie (browser) or body (API/mobile)
74
- const cookieName = this.authConfig?.getRefreshTokenCookieName() ?? 'fsn_refresh_token';
72
+ /**
73
+ * Refresh access token.
74
+ * - **Browser**: Prefers HTTP-only cookie, falls back to body if cookie missing.
75
+ * - **API/Mobile**: Must send `refreshToken` in request body. Set header `x-client-type: mobile` or `x-client-type: api`.
76
+ */ async refreshToken(req, refreshTokenDto) {
77
+ const cookieName = this.authConfig?.getRefreshTokenCookieName() ?? _config.DEFAULT_COOKIE_NAME;
78
+ // Always check cookie first, then body - handles Browser, SSR, and Mobile/API
75
79
  const refreshToken = req.cookies?.[cookieName] || refreshTokenDto.refreshToken;
76
80
  if (!refreshToken) {
77
81
  throw new _common.UnauthorizedException('Refresh token is required');
@@ -88,75 +92,29 @@ let AuthenticationController = class AuthenticationController {
88
92
  message: 'Logged out successfully'
89
93
  };
90
94
  }
91
- /** Change password */ async changePassword(userId, dto) {
95
+ async changePassword(userId, dto) {
92
96
  await this.authService.changePassword(userId, dto.currentPassword, dto.newPassword);
93
97
  return {
94
98
  success: true,
95
99
  message: 'Password changed successfully'
96
100
  };
97
101
  }
98
- // Email Auth Endpoints
99
- /** Forgot password - Request password reset email */ async forgotPassword(req, dto) {
100
- if (!this.authEmailService) {
101
- return {
102
- success: false,
103
- message: 'Email service is not configured'
104
- };
105
- }
106
- return this.authEmailService.forgotPassword(dto.email, this.buildAuthUrl(req, '/auth/reset-password'));
107
- }
108
- /** Reset password - Reset password using token */ async resetPassword(dto) {
109
- if (!this.authEmailService) {
110
- return {
111
- success: false,
112
- message: 'Email service is not configured'
113
- };
114
- }
115
- return this.authEmailService.resetPassword(dto.token, dto.newPassword);
116
- }
117
- /** Resend verification email - For unauthenticated users (handles both pending registration and existing users) */ async resendVerification(req, dto) {
118
- if (!this.authEmailService) {
119
- return {
120
- success: false,
121
- message: 'Email service is not configured'
122
- };
123
- }
124
- return this.authEmailService.resendVerificationEmail(dto.email, this.buildAuthUrl(req, '/auth/verify-email'));
125
- }
126
- /** Verify email - Verify email using token. Handles both pending registration and existing user verification. */ async verifyEmail(dto) {
127
- if (!this.authEmailService) {
128
- return {
129
- success: false,
130
- message: 'Email service is not configured'
131
- };
132
- }
133
- const result = await this.authEmailService.verifyEmail(dto.token);
134
- if (result.type === 'pending') {
135
- // Create user from pending registration
136
- const registrationResult = await this.authService.createUserFromPendingRegistration(result.pending);
137
- return {
138
- ...registrationResult,
139
- companyFeatureEnabled: this.authConfig?.isCompanyFeatureEnabled() ?? false
140
- };
141
- }
142
- return {
143
- success: true,
144
- message: result.message
145
- };
146
- }
147
- // NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
148
- constructor(authService, authConfig, authEmailService){
102
+ constructor(authService, authConfig){
149
103
  _define_property(this, "authService", void 0);
150
104
  _define_property(this, "authConfig", void 0);
151
- _define_property(this, "authEmailService", void 0);
152
105
  this.authService = authService;
153
106
  this.authConfig = authConfig;
154
- this.authEmailService = authEmailService;
155
107
  }
156
108
  };
157
109
  _ts_decorate([
158
110
  (0, _common.Post)('login'),
159
111
  (0, _common.HttpCode)(_common.HttpStatus.OK),
112
+ (0, _throttler.Throttle)({
113
+ default: {
114
+ limit: 5,
115
+ ttl: 60000
116
+ }
117
+ }),
160
118
  (0, _common.UseInterceptors)(_settokeninterceptor.SetToken),
161
119
  (0, _swagger.ApiOperation)({
162
120
  summary: 'User login'
@@ -164,13 +122,102 @@ _ts_decorate([
164
122
  (0, _swagger.ApiBody)({
165
123
  type: _authenticationdto.LoginDto
166
124
  }),
125
+ (0, _swagger.ApiExtraModels)(_authenticationdto.LoginResponseDto, _authenticationdto.CompanySelectionResponseDto, _authenticationdto.LoginResponseRequiresEmailVerificationDto),
167
126
  (0, _swagger.ApiResponse)({
168
127
  status: 200,
169
- type: _authenticationdto.LoginResponseDto
170
- }),
171
- (0, _swagger.ApiResponse)({
172
- status: 200,
173
- type: _authenticationdto.CompanySelectionResponseDto
128
+ description: 'Login successful, requires company selection, or requires email verification',
129
+ content: {
130
+ 'application/json': {
131
+ schema: {
132
+ oneOf: [
133
+ {
134
+ $ref: (0, _swagger.getSchemaPath)(_authenticationdto.LoginResponseDto)
135
+ },
136
+ {
137
+ $ref: (0, _swagger.getSchemaPath)(_authenticationdto.CompanySelectionResponseDto)
138
+ },
139
+ {
140
+ $ref: (0, _swagger.getSchemaPath)(_authenticationdto.LoginResponseRequiresEmailVerificationDto)
141
+ }
142
+ ]
143
+ },
144
+ examples: {
145
+ loginSuccess: {
146
+ summary: 'Login Success',
147
+ description: 'Successful login with tokens (company/branch included when company feature enabled)',
148
+ value: {
149
+ accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
150
+ refreshToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
151
+ user: {
152
+ id: '550e8400-e29b-41d4-a716-446655440000',
153
+ email: 'john@example.com',
154
+ name: 'John Doe'
155
+ }
156
+ }
157
+ },
158
+ loginSuccessWithCompany: {
159
+ summary: 'Login Success (Company Feature)',
160
+ description: 'Login with company/branch - only when company feature is enabled',
161
+ value: {
162
+ accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
163
+ refreshToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
164
+ user: {
165
+ id: '550e8400-e29b-41d4-a716-446655440000',
166
+ email: 'john@example.com',
167
+ name: 'John Doe'
168
+ },
169
+ company: {
170
+ id: '550e8400-e29b-41d4-a716-446655440001',
171
+ name: 'Acme Corporation',
172
+ slug: 'acme-corp'
173
+ },
174
+ branch: {
175
+ id: '550e8400-e29b-41d4-a716-446655440002',
176
+ name: 'Main Branch',
177
+ slug: 'main-branch'
178
+ }
179
+ }
180
+ },
181
+ companySelection: {
182
+ summary: 'Company Selection Required (Company Feature)',
183
+ description: 'User has multiple companies/branches - only when company feature is enabled',
184
+ value: {
185
+ requiresSelection: true,
186
+ sessionId: 'sess_abc123def456',
187
+ expiresAt: '2024-12-18T15:30:00.000Z',
188
+ user: {
189
+ id: '550e8400-e29b-41d4-a716-446655440000',
190
+ email: 'john@example.com',
191
+ name: 'John Doe'
192
+ },
193
+ companies: [
194
+ {
195
+ id: '550e8400-e29b-41d4-a716-446655440001',
196
+ name: 'Company A',
197
+ slug: 'company-a',
198
+ branches: [
199
+ {
200
+ id: '550e8400-e29b-41d4-a716-446655440010',
201
+ name: 'Branch 1',
202
+ slug: 'branch-1'
203
+ }
204
+ ]
205
+ }
206
+ ]
207
+ }
208
+ },
209
+ emailVerification: {
210
+ summary: 'Email Verification Required',
211
+ description: 'User must verify email before logging in',
212
+ value: {
213
+ requiresEmailVerification: true,
214
+ email: 'john@example.com',
215
+ message: 'Please verify your email address before logging in.'
216
+ }
217
+ }
218
+ }
219
+ }
220
+ }
174
221
  }),
175
222
  _ts_param(0, (0, _common.Body)()),
176
223
  _ts_metadata("design:type", Function),
@@ -182,6 +229,12 @@ _ts_decorate([
182
229
  _ts_decorate([
183
230
  (0, _common.Post)('register'),
184
231
  (0, _common.HttpCode)(_common.HttpStatus.CREATED),
232
+ (0, _throttler.Throttle)({
233
+ default: {
234
+ limit: 3,
235
+ ttl: 60000
236
+ }
237
+ }),
185
238
  (0, _common.UseInterceptors)(_settokeninterceptor.SetToken),
186
239
  (0, _swagger.ApiOperation)({
187
240
  summary: 'Register new user'
@@ -205,11 +258,50 @@ _ts_decorate([
205
258
  _ts_decorate([
206
259
  (0, _common.Post)('refresh'),
207
260
  (0, _common.HttpCode)(_common.HttpStatus.OK),
261
+ (0, _throttler.Throttle)({
262
+ default: {
263
+ limit: 30,
264
+ ttl: 60000
265
+ }
266
+ }),
208
267
  (0, _swagger.ApiOperation)({
209
- summary: 'Refresh access token'
268
+ summary: 'Refresh access token',
269
+ description: `
270
+ **Browser clients**: Refresh token is read from HTTP-only cookie (automatically set on login/register).
271
+ Falls back to request body if cookie is not available.
272
+
273
+ **API/Mobile clients**: Must send \`refreshToken\` in request body.
274
+ Set header \`x-client-type: mobile\` or \`x-client-type: api\` to identify as non-browser client.
275
+
276
+ **Client detection**: Uses \`x-client-type\` header first, then falls back to User-Agent detection.
277
+ `
278
+ }),
279
+ (0, _swagger.ApiHeader)({
280
+ name: 'x-client-type',
281
+ required: false,
282
+ description: 'Client type: "browser"/"web" for cookie-based auth, "mobile"/"api" for body-based auth',
283
+ example: 'mobile'
210
284
  }),
211
285
  (0, _swagger.ApiBody)({
212
- type: _authenticationdto.RefreshTokenDto
286
+ type: _authenticationdto.RefreshTokenDto,
287
+ description: 'Required for API/Mobile clients. Browser clients prefer HTTP-only cookie with body fallback.'
288
+ }),
289
+ (0, _swagger.ApiResponse)({
290
+ status: 200,
291
+ description: 'New access token',
292
+ schema: {
293
+ type: 'object',
294
+ properties: {
295
+ accessToken: {
296
+ type: 'string',
297
+ example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
298
+ }
299
+ }
300
+ }
301
+ }),
302
+ (0, _swagger.ApiResponse)({
303
+ status: 401,
304
+ description: 'Invalid or missing refresh token'
213
305
  }),
214
306
  _ts_param(0, (0, _common.Req)()),
215
307
  _ts_param(1, (0, _common.Body)()),
@@ -222,7 +314,8 @@ _ts_decorate([
222
314
  ], AuthenticationController.prototype, "refreshToken", null);
223
315
  _ts_decorate([
224
316
  (0, _common.UseGuards)(_guards.JwtAuthGuard),
225
- (0, _common.Get)('me'),
317
+ (0, _common.Post)('me'),
318
+ (0, _throttler.SkipThrottle)(),
226
319
  (0, _swagger.ApiBearerAuth)(),
227
320
  (0, _swagger.ApiOperation)({
228
321
  summary: 'Get current user info'
@@ -242,6 +335,7 @@ _ts_decorate([
242
335
  (0, _common.UseGuards)(_guards.JwtAuthGuard),
243
336
  (0, _common.Post)('logout'),
244
337
  (0, _common.HttpCode)(_common.HttpStatus.OK),
338
+ (0, _throttler.SkipThrottle)(),
245
339
  (0, _common.UseInterceptors)(_cleartokeninterceptor.ClearToken),
246
340
  (0, _swagger.ApiBearerAuth)(),
247
341
  (0, _swagger.ApiOperation)({
@@ -262,6 +356,12 @@ _ts_decorate([
262
356
  (0, _common.UseGuards)(_guards.JwtAuthGuard),
263
357
  (0, _common.Post)('change-password'),
264
358
  (0, _common.HttpCode)(_common.HttpStatus.OK),
359
+ (0, _throttler.Throttle)({
360
+ default: {
361
+ limit: 5,
362
+ ttl: 60000
363
+ }
364
+ }),
265
365
  (0, _swagger.ApiBearerAuth)(),
266
366
  (0, _swagger.ApiOperation)({
267
367
  summary: 'Change password'
@@ -282,107 +382,15 @@ _ts_decorate([
282
382
  ]),
283
383
  _ts_metadata("design:returntype", Promise)
284
384
  ], AuthenticationController.prototype, "changePassword", null);
285
- _ts_decorate([
286
- (0, _common.Post)('forgot-password'),
287
- (0, _common.HttpCode)(_common.HttpStatus.OK),
288
- (0, _swagger.ApiOperation)({
289
- summary: 'Request password reset email'
290
- }),
291
- (0, _swagger.ApiBody)({
292
- type: _authenticationdto.ForgotPasswordDto
293
- }),
294
- (0, _swagger.ApiResponse)({
295
- status: 200,
296
- type: _dtos.MessageResponseDto
297
- }),
298
- _ts_param(0, (0, _common.Req)()),
299
- _ts_param(1, (0, _common.Body)()),
300
- _ts_metadata("design:type", Function),
301
- _ts_metadata("design:paramtypes", [
302
- typeof _express.Request === "undefined" ? Object : _express.Request,
303
- typeof _authenticationdto.ForgotPasswordDto === "undefined" ? Object : _authenticationdto.ForgotPasswordDto
304
- ]),
305
- _ts_metadata("design:returntype", Promise)
306
- ], AuthenticationController.prototype, "forgotPassword", null);
307
- _ts_decorate([
308
- (0, _common.Post)('reset-password'),
309
- (0, _common.HttpCode)(_common.HttpStatus.OK),
310
- (0, _swagger.ApiOperation)({
311
- summary: 'Reset password using token'
312
- }),
313
- (0, _swagger.ApiBody)({
314
- type: _authenticationdto.ResetPasswordDto
315
- }),
316
- (0, _swagger.ApiResponse)({
317
- status: 200,
318
- type: _dtos.MessageResponseDto
319
- }),
320
- _ts_param(0, (0, _common.Body)()),
321
- _ts_metadata("design:type", Function),
322
- _ts_metadata("design:paramtypes", [
323
- typeof _authenticationdto.ResetPasswordDto === "undefined" ? Object : _authenticationdto.ResetPasswordDto
324
- ]),
325
- _ts_metadata("design:returntype", Promise)
326
- ], AuthenticationController.prototype, "resetPassword", null);
327
- _ts_decorate([
328
- (0, _common.Post)('resend-verification'),
329
- (0, _common.HttpCode)(_common.HttpStatus.OK),
330
- (0, _swagger.ApiOperation)({
331
- summary: 'Resend email verification link'
332
- }),
333
- (0, _swagger.ApiBody)({
334
- type: _authenticationdto.ResendVerificationDto
335
- }),
336
- (0, _swagger.ApiResponse)({
337
- status: 200,
338
- type: _dtos.MessageResponseDto
339
- }),
340
- _ts_param(0, (0, _common.Req)()),
341
- _ts_param(1, (0, _common.Body)()),
342
- _ts_metadata("design:type", Function),
343
- _ts_metadata("design:paramtypes", [
344
- typeof _express.Request === "undefined" ? Object : _express.Request,
345
- typeof _authenticationdto.ResendVerificationDto === "undefined" ? Object : _authenticationdto.ResendVerificationDto
346
- ]),
347
- _ts_metadata("design:returntype", Promise)
348
- ], AuthenticationController.prototype, "resendVerification", null);
349
- _ts_decorate([
350
- (0, _common.Post)('verify-email'),
351
- (0, _common.HttpCode)(_common.HttpStatus.OK),
352
- (0, _common.UseInterceptors)(_settokeninterceptor.SetToken),
353
- (0, _swagger.ApiOperation)({
354
- summary: 'Verify email using token'
355
- }),
356
- (0, _swagger.ApiBody)({
357
- type: _authenticationdto.VerifyEmailDto
358
- }),
359
- (0, _swagger.ApiResponse)({
360
- status: 200,
361
- type: _dtos.MessageResponseDto
362
- }),
363
- (0, _swagger.ApiResponse)({
364
- status: 200,
365
- type: _authenticationdto.RegistrationResponseDto
366
- }),
367
- _ts_param(0, (0, _common.Body)()),
368
- _ts_metadata("design:type", Function),
369
- _ts_metadata("design:paramtypes", [
370
- typeof _authenticationdto.VerifyEmailDto === "undefined" ? Object : _authenticationdto.VerifyEmailDto
371
- ]),
372
- _ts_metadata("design:returntype", Promise)
373
- ], AuthenticationController.prototype, "verifyEmail", null);
374
385
  AuthenticationController = _ts_decorate([
375
386
  (0, _swagger.ApiTags)('Authentication'),
376
387
  (0, _common.Controller)('auth'),
377
388
  _ts_param(0, (0, _common.Inject)(_authenticationservice.AuthenticationService)),
378
389
  _ts_param(1, (0, _common.Optional)()),
379
390
  _ts_param(1, (0, _common.Inject)(_authconfigservice.AuthConfigService)),
380
- _ts_param(2, (0, _common.Optional)()),
381
- _ts_param(2, (0, _common.Inject)(_authemailservice.AuthEmailService)),
382
391
  _ts_metadata("design:type", Function),
383
392
  _ts_metadata("design:paramtypes", [
384
393
  typeof _authenticationservice.AuthenticationService === "undefined" ? Object : _authenticationservice.AuthenticationService,
385
- typeof _authconfigservice.AuthConfigService === "undefined" ? Object : _authconfigservice.AuthConfigService,
386
- typeof _authemailservice.AuthEmailService === "undefined" ? Object : _authemailservice.AuthEmailService
394
+ typeof _authconfigservice.AuthConfigService === "undefined" ? Object : _authconfigservice.AuthConfigService
387
395
  ])
388
396
  ], AuthenticationController);
@@ -41,7 +41,50 @@ function _ts_param(paramIndex, decorator) {
41
41
  };
42
42
  }
43
43
  let BranchController = class BranchController extends (0, _classes.createApiController)(_companybranchdto.CreateCompanyBranchDto, _companybranchdto.UpdateCompanyBranchDto, _companybranchdto.CompanyBranchResponseDto, {
44
- security: 'jwt'
44
+ security: {
45
+ insert: {
46
+ level: 'permission',
47
+ permissions: [
48
+ _classes.BRANCH_PERMISSIONS.CREATE
49
+ ]
50
+ },
51
+ insertMany: {
52
+ level: 'permission',
53
+ permissions: [
54
+ _classes.BRANCH_PERMISSIONS.CREATE
55
+ ]
56
+ },
57
+ getById: {
58
+ level: 'permission',
59
+ permissions: [
60
+ _classes.BRANCH_PERMISSIONS.READ
61
+ ]
62
+ },
63
+ getAll: {
64
+ level: 'permission',
65
+ permissions: [
66
+ _classes.BRANCH_PERMISSIONS.READ
67
+ ]
68
+ },
69
+ update: {
70
+ level: 'permission',
71
+ permissions: [
72
+ _classes.BRANCH_PERMISSIONS.UPDATE
73
+ ]
74
+ },
75
+ updateMany: {
76
+ level: 'permission',
77
+ permissions: [
78
+ _classes.BRANCH_PERMISSIONS.UPDATE
79
+ ]
80
+ },
81
+ delete: {
82
+ level: 'permission',
83
+ permissions: [
84
+ _classes.BRANCH_PERMISSIONS.DELETE
85
+ ]
86
+ }
87
+ }
45
88
  }) {
46
89
  constructor(branchService){
47
90
  super(branchService), _define_property(this, "branchService", void 0), this.branchService = branchService;
@@ -43,35 +43,28 @@ function _ts_param(paramIndex, decorator) {
43
43
  };
44
44
  }
45
45
  let CompanySelectionController = class CompanySelectionController {
46
- /**
47
- * Select Company & Branch
48
- * Used after login when user needs to select company and branch
49
- */ async select(dto) {
46
+ async select(dto) {
50
47
  return this.authService.select(dto.sessionId, dto.companyId, dto.branchId);
51
48
  }
52
- /**
53
- * Switch Company/Branch
54
- * Used to switch company/branch after already logged in
55
- */ async switchCompany(userId, dto) {
49
+ async switchCompany(userId, dto) {
56
50
  return this.authService.switchCompany(userId, dto.companyId, dto.branchId);
57
51
  }
58
- /**
59
- * Get user's companies
60
- */ async getUserCompanies(userId) {
52
+ async getUserCompanies(userId) {
61
53
  const companies = await this.authService.getUserCompanies(userId);
62
54
  return {
63
- companies
55
+ success: true,
56
+ message: 'User companies retrieved successfully',
57
+ data: companies
64
58
  };
65
59
  }
66
- /**
67
- * Get branches for a specific company
68
- */ async getUserBranches(userId, companyId) {
60
+ async getUserBranches(userId, companyId) {
69
61
  const branches = await this.authService.getUserBranches(userId, companyId);
70
62
  return {
71
- branches
63
+ success: true,
64
+ message: 'Company branches retrieved successfully',
65
+ data: branches
72
66
  };
73
67
  }
74
- // NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
75
68
  constructor(authService){
76
69
  _define_property(this, "authService", void 0);
77
70
  this.authService = authService;
@@ -127,7 +120,8 @@ _ts_decorate([
127
120
  ], CompanySelectionController.prototype, "switchCompany", null);
128
121
  _ts_decorate([
129
122
  (0, _common.UseGuards)(_guards.JwtAuthGuard),
130
- (0, _common.Get)('companies'),
123
+ (0, _common.Post)('get-companies'),
124
+ (0, _common.HttpCode)(_common.HttpStatus.OK),
131
125
  (0, _swagger.ApiBearerAuth)(),
132
126
  (0, _swagger.ApiOperation)({
133
127
  summary: "Get user's available companies",
@@ -142,14 +136,27 @@ _ts_decorate([
142
136
  ], CompanySelectionController.prototype, "getUserCompanies", null);
143
137
  _ts_decorate([
144
138
  (0, _common.UseGuards)(_guards.JwtAuthGuard),
145
- (0, _common.Get)('companies/:companyId/branches'),
139
+ (0, _common.Post)('get-company-branches'),
140
+ (0, _common.HttpCode)(_common.HttpStatus.OK),
146
141
  (0, _swagger.ApiBearerAuth)(),
147
142
  (0, _swagger.ApiOperation)({
148
143
  summary: 'Get branches for a company',
149
144
  description: 'Get list of branches for a specific company that the user has access to'
150
145
  }),
146
+ (0, _swagger.ApiBody)({
147
+ schema: {
148
+ properties: {
149
+ companyId: {
150
+ type: 'string'
151
+ }
152
+ },
153
+ required: [
154
+ 'companyId'
155
+ ]
156
+ }
157
+ }),
151
158
  _ts_param(0, (0, _decorators.CurrentUser)('id')),
152
- _ts_param(1, (0, _common.Param)('companyId')),
159
+ _ts_param(1, (0, _common.Body)('companyId')),
153
160
  _ts_metadata("design:type", Function),
154
161
  _ts_metadata("design:paramtypes", [
155
162
  String,
@@ -41,7 +41,50 @@ function _ts_param(paramIndex, decorator) {
41
41
  };
42
42
  }
43
43
  let CompanyController = class CompanyController extends (0, _classes.createApiController)(_companydto.CreateCompanyDto, _companydto.UpdateCompanyDto, _companydto.CompanyResponseDto, {
44
- security: 'jwt'
44
+ security: {
45
+ insert: {
46
+ level: 'permission',
47
+ permissions: [
48
+ _classes.COMPANY_PERMISSIONS.CREATE
49
+ ]
50
+ },
51
+ insertMany: {
52
+ level: 'permission',
53
+ permissions: [
54
+ _classes.COMPANY_PERMISSIONS.CREATE
55
+ ]
56
+ },
57
+ getById: {
58
+ level: 'permission',
59
+ permissions: [
60
+ _classes.COMPANY_PERMISSIONS.READ
61
+ ]
62
+ },
63
+ getAll: {
64
+ level: 'permission',
65
+ permissions: [
66
+ _classes.COMPANY_PERMISSIONS.READ
67
+ ]
68
+ },
69
+ update: {
70
+ level: 'permission',
71
+ permissions: [
72
+ _classes.COMPANY_PERMISSIONS.UPDATE
73
+ ]
74
+ },
75
+ updateMany: {
76
+ level: 'permission',
77
+ permissions: [
78
+ _classes.COMPANY_PERMISSIONS.UPDATE
79
+ ]
80
+ },
81
+ delete: {
82
+ level: 'permission',
83
+ permissions: [
84
+ _classes.COMPANY_PERMISSIONS.DELETE
85
+ ]
86
+ }
87
+ }
45
88
  }) {
46
89
  constructor(companyService){
47
90
  super(companyService), _define_property(this, "companyService", void 0), this.companyService = companyService;