ecrs-auth-core 1.0.83 → 1.0.84

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.
package/README.md CHANGED
@@ -1,263 +1,263 @@
1
- # ECRS Auth Core
2
-
3
- A centralized authentication and authorization module for NestJS applications, providing JWT-based authentication, role-based access control, and feature-level permissions.
4
-
5
- ## Features
6
-
7
- - 🔐 JWT-based authentication
8
- - 👥 Role-based access control (RBAC)
9
- - 🎯 Feature-level permissions
10
- - 🛡️ Route-level security guards
11
- - 📊 Module and screen permissions
12
- - 🔧 Easy integration with TypeORM
13
- - 📦 Fully typed with TypeScript
14
-
15
- ## Installation
16
-
17
- ```bash
18
- npm install ecrs-auth-core
19
- ```
20
-
21
- ## Peer Dependencies
22
-
23
- Make sure you have the following peer dependencies installed:
24
-
25
- ```bash
26
- npm install @nestjs/common @nestjs/core @nestjs/passport @nestjs/typeorm bcrypt passport passport-jwt typeorm
27
- ```
28
-
29
- ## Quick Start
30
-
31
- ### 1. Import the Auth Module
32
-
33
- ```typescript
34
- import { Module } from '@nestjs/common';
35
- import { TypeOrmModule } from '@nestjs/typeorm';
36
- import { AuthCoreModule } from 'ecrs-auth-core';
37
-
38
- @Module({
39
- imports: [
40
- TypeOrmModule.forRoot({
41
- // your database configuration
42
- }),
43
- AuthCoreModule.forRoot({
44
- jwtSecret: 'your-jwt-secret',
45
- jwtExpiresIn: '1h',
46
- }),
47
- ],
48
- })
49
- export class AppModule {}
50
- ```
51
-
52
- ### 2. Include Entities in TypeORM
53
-
54
- ```typescript
55
- import {
56
- User,
57
- Role,
58
- Module as AuthModule,
59
- Feature,
60
- ModuleRoute,
61
- UserFeatureAccess,
62
- UserModuleAccess,
63
- ModuleScreenPermission,
64
- } from 'ecrs-auth-core';
65
-
66
- TypeOrmModule.forRoot({
67
- // ... other config
68
- entities: [
69
- User,
70
- Role,
71
- AuthModule,
72
- Feature,
73
- ModuleRoute,
74
- UserFeatureAccess,
75
- UserModuleAccess,
76
- ModuleScreenPermission,
77
- ],
78
- });
79
- ```
80
-
81
- ### 3. Use Guards and Decorators
82
-
83
- ```typescript
84
- import { Controller, Get, Post, UseGuards } from '@nestjs/common';
85
- import {
86
- JwtAuthGuard,
87
- RolesGuard,
88
- FeatureGuard,
89
- Roles,
90
- Feature,
91
- CurrentUser,
92
- User
93
- } from 'ecrs-auth-core';
94
-
95
- @Controller('protected')
96
- @UseGuards(JwtAuthGuard)
97
- export class ProtectedController {
98
-
99
- @Get('admin-only')
100
- @UseGuards(RolesGuard)
101
- @Roles('admin')
102
- adminOnlyEndpoint(@CurrentUser() user: User) {
103
- return { message: 'Admin access granted', user: user.username };
104
- }
105
-
106
- @Get('feature-protected')
107
- @UseGuards(FeatureGuard)
108
- @Feature('user-management')
109
- featureProtectedEndpoint(@CurrentUser() user: User) {
110
- return { message: 'Feature access granted' };
111
- }
112
- }
113
- ```
114
-
115
- ## Available Decorators
116
-
117
- ### @CurrentUser()
118
- Get the current authenticated user in your controller methods.
119
-
120
- ```typescript
121
- @Get('profile')
122
- getProfile(@CurrentUser() user: User) {
123
- return user;
124
- }
125
- ```
126
-
127
- ### @Roles()
128
- Restrict access based on user roles.
129
-
130
- ```typescript
131
- @Roles('admin', 'manager')
132
- @UseGuards(RolesGuard)
133
- adminEndpoint() {
134
- // Only admin and manager roles can access
135
- }
136
- ```
137
-
138
- ### @Feature()
139
- Restrict access based on feature permissions.
140
-
141
- ```typescript
142
- @Feature('user-management')
143
- @UseGuards(FeatureGuard)
144
- userManagementEndpoint() {
145
- // Only users with user-management feature access
146
- }
147
- ```
148
-
149
- ### @HasPermission()
150
- Check for specific permissions.
151
-
152
- ```typescript
153
- @HasPermission('CREATE_USER')
154
- @UseGuards(PermissionGuard)
155
- createUserEndpoint() {
156
- // Only users with CREATE_USER permission
157
- }
158
- ```
159
-
160
- ### @RoutePermission()
161
- Route-level permission checking.
162
-
163
- ```typescript
164
- @RoutePermission('users', 'create')
165
- @UseGuards(RouteGuard)
166
- createUser() {
167
- // Route-specific permission checking
168
- }
169
- ```
170
-
171
- ## Available Guards
172
-
173
- - **JwtAuthGuard**: JWT token validation
174
- - **RolesGuard**: Role-based access control
175
- - **FeatureGuard**: Feature-based access control
176
- - **PermissionGuard**: Permission-based access control
177
- - **RouteGuard**: Route-level access control
178
- - **ModuleGuard**: Module-based access control
179
-
180
- ## Authentication Service
181
-
182
- The `AuthService` provides methods for user authentication and token management:
183
-
184
- ```typescript
185
- import { AuthService } from 'ecrs-auth-core';
186
-
187
- @Injectable()
188
- export class MyService {
189
- constructor(private authService: AuthService) {}
190
-
191
- async login(username: string, password: string) {
192
- return this.authService.validateUser(username, password);
193
- }
194
-
195
- async generateToken(user: User) {
196
- return this.authService.generateToken(user);
197
- }
198
- }
199
- ```
200
-
201
- ## Database Entities
202
-
203
- The package includes the following TypeORM entities:
204
-
205
- - **User**: User account information
206
- - **Role**: User roles (admin, user, etc.)
207
- - **Module**: Application modules
208
- - **Feature**: Feature definitions
209
- - **ModuleRoute**: Module route mappings
210
- - **UserFeatureAccess**: User-feature access permissions
211
- - **UserModuleAccess**: User-module access permissions
212
- - **ModuleScreenPermission**: Screen-level permissions
213
-
214
- ## Configuration Options
215
-
216
- ```typescript
217
- interface AuthCoreOptions {
218
- jwtSecret: string;
219
- jwtExpiresIn?: string;
220
- bcryptRounds?: number;
221
- // ... other options
222
- }
223
- ```
224
-
225
- ## Examples
226
-
227
- ### Basic Setup with Custom Configuration
228
-
229
- ```typescript
230
- AuthCoreModule.forRoot({
231
- jwtSecret: process.env.JWT_SECRET,
232
- jwtExpiresIn: '24h',
233
- bcryptRounds: 12,
234
- })
235
- ```
236
-
237
- ### Using Multiple Guards
238
-
239
- ```typescript
240
- @UseGuards(JwtAuthGuard, RolesGuard, FeatureGuard)
241
- @Roles('admin')
242
- @Feature('advanced-settings')
243
- @Get('advanced-admin')
244
- advancedAdminEndpoint() {
245
- return { message: 'Multi-level security passed' };
246
- }
247
- ```
248
-
249
- ## License
250
-
251
- MIT
252
-
253
- ## Author
254
-
255
- Chetan Yadnik
256
-
257
- ## Contributing
258
-
259
- Contributions are welcome! Please feel free to submit a Pull Request.
260
-
261
- ## Support
262
-
1
+ # ECRS Auth Core
2
+
3
+ A centralized authentication and authorization module for NestJS applications, providing JWT-based authentication, role-based access control, and feature-level permissions.
4
+
5
+ ## Features
6
+
7
+ - 🔐 JWT-based authentication
8
+ - 👥 Role-based access control (RBAC)
9
+ - 🎯 Feature-level permissions
10
+ - 🛡️ Route-level security guards
11
+ - 📊 Module and screen permissions
12
+ - 🔧 Easy integration with TypeORM
13
+ - 📦 Fully typed with TypeScript
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install ecrs-auth-core
19
+ ```
20
+
21
+ ## Peer Dependencies
22
+
23
+ Make sure you have the following peer dependencies installed:
24
+
25
+ ```bash
26
+ npm install @nestjs/common @nestjs/core @nestjs/passport @nestjs/typeorm bcrypt passport passport-jwt typeorm
27
+ ```
28
+
29
+ ## Quick Start
30
+
31
+ ### 1. Import the Auth Module
32
+
33
+ ```typescript
34
+ import { Module } from '@nestjs/common';
35
+ import { TypeOrmModule } from '@nestjs/typeorm';
36
+ import { AuthCoreModule } from 'ecrs-auth-core';
37
+
38
+ @Module({
39
+ imports: [
40
+ TypeOrmModule.forRoot({
41
+ // your database configuration
42
+ }),
43
+ AuthCoreModule.forRoot({
44
+ jwtSecret: 'your-jwt-secret',
45
+ jwtExpiresIn: '1h',
46
+ }),
47
+ ],
48
+ })
49
+ export class AppModule {}
50
+ ```
51
+
52
+ ### 2. Include Entities in TypeORM
53
+
54
+ ```typescript
55
+ import {
56
+ User,
57
+ Role,
58
+ Module as AuthModule,
59
+ Feature,
60
+ ModuleRoute,
61
+ UserFeatureAccess,
62
+ UserModuleAccess,
63
+ ModuleScreenPermission,
64
+ } from 'ecrs-auth-core';
65
+
66
+ TypeOrmModule.forRoot({
67
+ // ... other config
68
+ entities: [
69
+ User,
70
+ Role,
71
+ AuthModule,
72
+ Feature,
73
+ ModuleRoute,
74
+ UserFeatureAccess,
75
+ UserModuleAccess,
76
+ ModuleScreenPermission,
77
+ ],
78
+ });
79
+ ```
80
+
81
+ ### 3. Use Guards and Decorators
82
+
83
+ ```typescript
84
+ import { Controller, Get, Post, UseGuards } from '@nestjs/common';
85
+ import {
86
+ JwtAuthGuard,
87
+ RolesGuard,
88
+ FeatureGuard,
89
+ Roles,
90
+ Feature,
91
+ CurrentUser,
92
+ User
93
+ } from 'ecrs-auth-core';
94
+
95
+ @Controller('protected')
96
+ @UseGuards(JwtAuthGuard)
97
+ export class ProtectedController {
98
+
99
+ @Get('admin-only')
100
+ @UseGuards(RolesGuard)
101
+ @Roles('admin')
102
+ adminOnlyEndpoint(@CurrentUser() user: User) {
103
+ return { message: 'Admin access granted', user: user.username };
104
+ }
105
+
106
+ @Get('feature-protected')
107
+ @UseGuards(FeatureGuard)
108
+ @Feature('user-management')
109
+ featureProtectedEndpoint(@CurrentUser() user: User) {
110
+ return { message: 'Feature access granted' };
111
+ }
112
+ }
113
+ ```
114
+
115
+ ## Available Decorators
116
+
117
+ ### @CurrentUser()
118
+ Get the current authenticated user in your controller methods.
119
+
120
+ ```typescript
121
+ @Get('profile')
122
+ getProfile(@CurrentUser() user: User) {
123
+ return user;
124
+ }
125
+ ```
126
+
127
+ ### @Roles()
128
+ Restrict access based on user roles.
129
+
130
+ ```typescript
131
+ @Roles('admin', 'manager')
132
+ @UseGuards(RolesGuard)
133
+ adminEndpoint() {
134
+ // Only admin and manager roles can access
135
+ }
136
+ ```
137
+
138
+ ### @Feature()
139
+ Restrict access based on feature permissions.
140
+
141
+ ```typescript
142
+ @Feature('user-management')
143
+ @UseGuards(FeatureGuard)
144
+ userManagementEndpoint() {
145
+ // Only users with user-management feature access
146
+ }
147
+ ```
148
+
149
+ ### @HasPermission()
150
+ Check for specific permissions.
151
+
152
+ ```typescript
153
+ @HasPermission('CREATE_USER')
154
+ @UseGuards(PermissionGuard)
155
+ createUserEndpoint() {
156
+ // Only users with CREATE_USER permission
157
+ }
158
+ ```
159
+
160
+ ### @RoutePermission()
161
+ Route-level permission checking.
162
+
163
+ ```typescript
164
+ @RoutePermission('users', 'create')
165
+ @UseGuards(RouteGuard)
166
+ createUser() {
167
+ // Route-specific permission checking
168
+ }
169
+ ```
170
+
171
+ ## Available Guards
172
+
173
+ - **JwtAuthGuard**: JWT token validation
174
+ - **RolesGuard**: Role-based access control
175
+ - **FeatureGuard**: Feature-based access control
176
+ - **PermissionGuard**: Permission-based access control
177
+ - **RouteGuard**: Route-level access control
178
+ - **ModuleGuard**: Module-based access control
179
+
180
+ ## Authentication Service
181
+
182
+ The `AuthService` provides methods for user authentication and token management:
183
+
184
+ ```typescript
185
+ import { AuthService } from 'ecrs-auth-core';
186
+
187
+ @Injectable()
188
+ export class MyService {
189
+ constructor(private authService: AuthService) {}
190
+
191
+ async login(username: string, password: string) {
192
+ return this.authService.validateUser(username, password);
193
+ }
194
+
195
+ async generateToken(user: User) {
196
+ return this.authService.generateToken(user);
197
+ }
198
+ }
199
+ ```
200
+
201
+ ## Database Entities
202
+
203
+ The package includes the following TypeORM entities:
204
+
205
+ - **User**: User account information
206
+ - **Role**: User roles (admin, user, etc.)
207
+ - **Module**: Application modules
208
+ - **Feature**: Feature definitions
209
+ - **ModuleRoute**: Module route mappings
210
+ - **UserFeatureAccess**: User-feature access permissions
211
+ - **UserModuleAccess**: User-module access permissions
212
+ - **ModuleScreenPermission**: Screen-level permissions
213
+
214
+ ## Configuration Options
215
+
216
+ ```typescript
217
+ interface AuthCoreOptions {
218
+ jwtSecret: string;
219
+ jwtExpiresIn?: string;
220
+ bcryptRounds?: number;
221
+ // ... other options
222
+ }
223
+ ```
224
+
225
+ ## Examples
226
+
227
+ ### Basic Setup with Custom Configuration
228
+
229
+ ```typescript
230
+ AuthCoreModule.forRoot({
231
+ jwtSecret: process.env.JWT_SECRET,
232
+ jwtExpiresIn: '24h',
233
+ bcryptRounds: 12,
234
+ })
235
+ ```
236
+
237
+ ### Using Multiple Guards
238
+
239
+ ```typescript
240
+ @UseGuards(JwtAuthGuard, RolesGuard, FeatureGuard)
241
+ @Roles('admin')
242
+ @Feature('advanced-settings')
243
+ @Get('advanced-admin')
244
+ advancedAdminEndpoint() {
245
+ return { message: 'Multi-level security passed' };
246
+ }
247
+ ```
248
+
249
+ ## License
250
+
251
+ MIT
252
+
253
+ ## Author
254
+
255
+ Chetan Yadnik
256
+
257
+ ## Contributing
258
+
259
+ Contributions are welcome! Please feel free to submit a Pull Request.
260
+
261
+ ## Support
262
+
263
263
  For questions and support, please open an issue on GitHub.
@@ -30,7 +30,6 @@ export declare class AuthController {
30
30
  designationId: any;
31
31
  lastLoginTime: any;
32
32
  is_reset_password: number;
33
- profile_photo_url: string;
34
33
  };
35
34
  };
36
35
  access_token: string;
@@ -108,7 +108,6 @@ export declare class AuthService {
108
108
  designationId: any;
109
109
  lastLoginTime: any;
110
110
  is_reset_password: number;
111
- profile_photo_url: string;
112
111
  };
113
112
  };
114
113
  access_token: string;
@@ -120,5 +119,6 @@ export declare class AuthService {
120
119
  extractUserIpv4(clientIp: string | undefined): string;
121
120
  findUserById(id: number): Promise<User | null>;
122
121
  private loadPermissions;
122
+ private loadModulePermissions;
123
123
  }
124
124
  export {};
@@ -72,24 +72,18 @@ let AuthService = class AuthService {
72
72
  }
73
73
  async validateUser(email, password, clientIp) {
74
74
  const user = await this.userRepo.findOne({ where: { email } });
75
- if (!user) {
76
- throw new common_1.UnauthorizedException('The email address is invalid or not registered.');
77
- }
75
+ if (!user)
76
+ return null;
78
77
  const isValid = await bcrypt.compare(password, user.password);
79
- if (!isValid) {
80
- throw new common_1.UnauthorizedException('The password is incorrect. Please try again.');
81
- }
82
- ;
83
- if (user.status !== 1) {
84
- throw new common_1.UnauthorizedException('Your account is inactive. Please contact support.');
85
- }
78
+ if (!isValid)
79
+ return null;
86
80
  // console.log(this.ipRestrictionsRepo);
87
81
  // Check IP restrictions if provided and repository is available
88
82
  if (clientIp && this.ipRestrictionsRepo) {
89
83
  const ipAllowed = await this.validateIpRestriction(user.id, clientIp);
90
84
  if (!ipAllowed) {
91
- // IP restriction exists but doesn't match - throw UnauthorizedException to block login
92
- throw new common_1.UnauthorizedException('Login denied: Your IP address is not allowed.');
85
+ // IP restriction exists but doesn't match - return null to block login
86
+ return null;
93
87
  }
94
88
  }
95
89
  return user;
@@ -420,7 +414,7 @@ let AuthService = class AuthService {
420
414
  }
421
415
  }
422
416
  async login(user, selectedModuleId) {
423
- const permissionTree = await this.loadPermissions(user.id);
417
+ const permissionTree = await this.loadModulePermissions(user.id, selectedModuleId);
424
418
  const role = await this.roleRepo.findOne({ where: { id: user.roleId } });
425
419
  const roleName = role?.roleName || null;
426
420
  const effectiveModuleId = Number.isFinite(selectedModuleId) ? selectedModuleId : user.moduleId ?? null;
@@ -494,10 +488,6 @@ let AuthService = class AuthService {
494
488
  lastLoginTime: lastLoginTime,
495
489
  is_reset_password: is_reset_password,
496
490
  };
497
- // Generate JWT token
498
- const accessToken = this.jwtService.sign(payload);
499
- // Update user's apiToken in the database
500
- await this.userRepo.update({ id: user.id }, { apiToken: accessToken });
501
491
  return {
502
492
  status: true,
503
493
  message: 'Login successful',
@@ -522,10 +512,10 @@ let AuthService = class AuthService {
522
512
  designationId,
523
513
  lastLoginTime: lastLoginTime,
524
514
  is_reset_password: is_reset_password,
525
- profile_photo_url: `${this.uploadPhotoDir}/${user.userImage}`,
515
+ // profile_photo_url: `${this.uploadPhotoDir}/${user.userImage}`,
526
516
  },
527
517
  },
528
- access_token: accessToken,
518
+ access_token: this.jwtService.sign(payload),
529
519
  };
530
520
  }
531
521
  /**
@@ -602,6 +592,18 @@ let AuthService = class AuthService {
602
592
  routes: routePermissions,
603
593
  };
604
594
  }
595
+ async loadModulePermissions(userId, moduleId) {
596
+ if (!Number.isFinite(moduleId)) {
597
+ return [];
598
+ }
599
+ const access = await this.moduleAccessRepo.findOne({
600
+ where: { userId, moduleId: moduleId, isDeleted: 0, status: 1 },
601
+ });
602
+ if (!access) {
603
+ return [];
604
+ }
605
+ return Array.isArray(access.permissions) ? access.permissions : [];
606
+ }
605
607
  };
606
608
  exports.AuthService = AuthService;
607
609
  exports.AuthService = AuthService = __decorate([
@@ -4,6 +4,7 @@ export declare class UserModuleAccess {
4
4
  moduleId: number;
5
5
  accessLevel: string;
6
6
  status: number;
7
+ permissions: string[];
7
8
  createdAt: Date;
8
9
  updatedAt: Date;
9
10
  createdBy: number;
@@ -35,6 +35,14 @@ __decorate([
35
35
  (0, typeorm_1.Column)({ type: 'smallint', default: 1 }),
36
36
  __metadata("design:type", Number)
37
37
  ], UserModuleAccess.prototype, "status", void 0);
38
+ __decorate([
39
+ (0, typeorm_1.Column)({
40
+ name: 'permissions',
41
+ type: 'json',
42
+ nullable: true,
43
+ }),
44
+ __metadata("design:type", Array)
45
+ ], UserModuleAccess.prototype, "permissions", void 0);
38
46
  __decorate([
39
47
  (0, typeorm_1.Column)({ name: 'created_at', type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }),
40
48
  __metadata("design:type", Date)
@@ -34,10 +34,6 @@ let JwtStrategy = class JwtStrategy extends (0, passport_1.PassportStrategy)(pas
34
34
  console.log(`✅ User ${user.id} has access to module ${payload.moduleId}`);
35
35
  }
36
36
  console.log(`✅ JWT validated for user ${user.id}`);
37
- if (user.status !== 1) {
38
- console.log(`❌ User ${user.id} is not active`);
39
- throw new common_1.UnauthorizedException('Your account is inactive. Please contact support.');
40
- }
41
37
  return {
42
38
  id: user.id,
43
39
  email: user.email,
package/package.json CHANGED
@@ -1,51 +1,51 @@
1
- {
2
- "name": "ecrs-auth-core",
3
- "version": "1.0.83",
4
- "description": "Centralized authentication and authorization module for ECRS apps",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "files": [
8
- "dist"
9
- ],
10
- "scripts": {
11
- "build": "tsc -p tsconfig.json"
12
- },
13
- "keywords": [
14
- "nestjs",
15
- "auth",
16
- "jwt",
17
- "module",
18
- "ecrs"
19
- ],
20
- "author": "Chetan Yadnik",
21
- "license": "MIT",
22
- "peerDependencies": {
23
- "@nestjs/common": "^10.2.7 || ^11.0.0",
24
- "@nestjs/core": "^10.2.7 || ^11.0.0",
25
- "@nestjs/passport": "^10.0.3 || ^11.0.0",
26
- "bcrypt": "^5.1.1",
27
- "passport": "^0.6.0",
28
- "passport-jwt": "^4.0.1",
29
- "typeorm": "^0.3.25"
30
- },
31
- "dependencies": {
32
- "@nestjs/jwt": "^11.0.0",
33
- "@nestjs/swagger": "^7.1.14",
34
- "@nestjs/typeorm": "^11.0.0",
35
- "class-transformer": "^0.5.1",
36
- "class-validator": "^0.14.3",
37
- "jsonwebtoken": "^9.0.2",
38
- "rxjs": "^7.8.1",
39
- "swagger-ui-express": "^5.0.0"
40
- },
41
- "devDependencies": {
42
- "@nestjs/common": "^10.2.7",
43
- "@nestjs/core": "^10.2.7",
44
- "@nestjs/passport": "^10.0.3",
45
- "@types/bcrypt": "^6.0.0",
46
- "@types/passport-jwt": "^4.0.1",
47
- "reflect-metadata": "^0.1.13",
48
- "typeorm": "^0.3.17",
49
- "typescript": "^5.8.3"
50
- }
51
- }
1
+ {
2
+ "name": "ecrs-auth-core",
3
+ "version": "1.0.84",
4
+ "description": "Centralized authentication and authorization module for ECRS apps",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "scripts": {
11
+ "build": "tsc -p tsconfig.json"
12
+ },
13
+ "keywords": [
14
+ "nestjs",
15
+ "auth",
16
+ "jwt",
17
+ "module",
18
+ "ecrs"
19
+ ],
20
+ "author": "Chetan Yadnik",
21
+ "license": "MIT",
22
+ "peerDependencies": {
23
+ "@nestjs/common": "^10.2.7 || ^11.0.0",
24
+ "@nestjs/core": "^10.2.7 || ^11.0.0",
25
+ "@nestjs/passport": "^10.0.3 || ^11.0.0",
26
+ "bcrypt": "^5.1.1",
27
+ "passport": "^0.6.0",
28
+ "passport-jwt": "^4.0.1",
29
+ "typeorm": "^0.3.25"
30
+ },
31
+ "dependencies": {
32
+ "@nestjs/jwt": "^11.0.0",
33
+ "@nestjs/swagger": "^7.1.14",
34
+ "@nestjs/typeorm": "^11.0.0",
35
+ "class-transformer": "^0.5.1",
36
+ "class-validator": "^0.14.3",
37
+ "jsonwebtoken": "^9.0.2",
38
+ "rxjs": "^7.8.1",
39
+ "swagger-ui-express": "^5.0.0"
40
+ },
41
+ "devDependencies": {
42
+ "@nestjs/common": "^10.2.7",
43
+ "@nestjs/core": "^10.2.7",
44
+ "@nestjs/passport": "^10.0.3",
45
+ "@types/bcrypt": "^6.0.0",
46
+ "@types/passport-jwt": "^4.0.1",
47
+ "reflect-metadata": "^0.1.13",
48
+ "typeorm": "^0.3.17",
49
+ "typescript": "^5.8.3"
50
+ }
51
+ }