@ahksolution/permissions-sdk 1.0.0 → 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.
- package/README.md +235 -58
- package/dist/client/permissions-grpc.client.d.ts +10 -1
- package/dist/client/permissions-grpc.client.d.ts.map +1 -1
- package/dist/client/permissions-grpc.client.js +42 -0
- package/dist/client/permissions-grpc.client.js.map +1 -1
- package/dist/decorators/current-user.decorator.d.ts +24 -0
- package/dist/decorators/current-user.decorator.d.ts.map +1 -0
- package/dist/decorators/current-user.decorator.js +31 -0
- package/dist/decorators/current-user.decorator.js.map +1 -0
- package/dist/decorators/index.d.ts +2 -0
- package/dist/decorators/index.d.ts.map +1 -1
- package/dist/decorators/index.js +2 -0
- package/dist/decorators/index.js.map +1 -1
- package/dist/decorators/public.decorator.d.ts +22 -0
- package/dist/decorators/public.decorator.d.ts.map +1 -0
- package/dist/decorators/public.decorator.js +26 -0
- package/dist/decorators/public.decorator.js.map +1 -0
- package/dist/guards/index.d.ts +1 -0
- package/dist/guards/index.d.ts.map +1 -1
- package/dist/guards/index.js +1 -0
- package/dist/guards/index.js.map +1 -1
- package/dist/guards/jwt-auth.guard.d.ts +39 -0
- package/dist/guards/jwt-auth.guard.d.ts.map +1 -0
- package/dist/guards/jwt-auth.guard.js +92 -0
- package/dist/guards/jwt-auth.guard.js.map +1 -0
- package/dist/guards/permissions.guard.d.ts.map +1 -1
- package/dist/guards/permissions.guard.js +3 -2
- package/dist/guards/permissions.guard.js.map +1 -1
- package/dist/proto/permissions.proto +47 -0
- package/dist/types/grpc.types.d.ts +27 -0
- package/dist/types/grpc.types.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/jwt.types.d.ts +26 -0
- package/dist/types/jwt.types.d.ts.map +1 -0
- package/dist/types/jwt.types.js +3 -0
- package/dist/types/jwt.types.js.map +1 -0
- package/package.json +1 -1
- package/src/proto/permissions.proto +47 -0
package/README.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# @ahksolution/permissions-sdk
|
|
2
2
|
|
|
3
|
-
gRPC client SDK for the AHK Solution Permissions Microservice. Provides NestJS integration for
|
|
3
|
+
gRPC client SDK for the AHK Solution Permissions Microservice. Provides NestJS integration for:
|
|
4
|
+
|
|
5
|
+
- **JWT Authentication** - Validate tokens via gRPC (no JWT secret needed in consuming services)
|
|
6
|
+
- **Permission Checks** - RBAC and ABAC support via gRPC
|
|
4
7
|
|
|
5
8
|
## Installation
|
|
6
9
|
|
|
@@ -61,105 +64,206 @@ import { PermissionsClientModule } from '@ahksolution/permissions-sdk';
|
|
|
61
64
|
export class AppModule {}
|
|
62
65
|
```
|
|
63
66
|
|
|
64
|
-
### 2.
|
|
67
|
+
### 2. Apply Guards Globally (Recommended)
|
|
65
68
|
|
|
66
|
-
|
|
69
|
+
For full authentication and authorization, apply both guards globally:
|
|
67
70
|
|
|
68
71
|
```typescript
|
|
69
|
-
|
|
70
|
-
import {
|
|
72
|
+
// app.module.ts
|
|
73
|
+
import { Module } from '@nestjs/common';
|
|
74
|
+
import { APP_GUARD } from '@nestjs/core';
|
|
75
|
+
import {
|
|
76
|
+
PermissionsClientModule,
|
|
77
|
+
JwtAuthGuard,
|
|
78
|
+
PermissionsGuard,
|
|
79
|
+
} from '@ahksolution/permissions-sdk';
|
|
71
80
|
|
|
72
|
-
@
|
|
73
|
-
|
|
74
|
-
|
|
81
|
+
@Module({
|
|
82
|
+
imports: [PermissionsClientModule.register({ url: 'localhost:50051' })],
|
|
83
|
+
providers: [
|
|
84
|
+
// Order matters: authentication first, then authorization
|
|
85
|
+
{ provide: APP_GUARD, useClass: JwtAuthGuard },
|
|
86
|
+
{ provide: APP_GUARD, useClass: PermissionsGuard },
|
|
87
|
+
],
|
|
88
|
+
})
|
|
89
|
+
export class AppModule {}
|
|
90
|
+
```
|
|
75
91
|
|
|
76
|
-
|
|
77
|
-
// Simple boolean check
|
|
78
|
-
const canCreate = await this.permissions.hasPermission(userId, 'orders:create');
|
|
79
|
-
if (!canCreate) {
|
|
80
|
-
throw new ForbiddenException('You do not have permission to create orders');
|
|
81
|
-
}
|
|
92
|
+
### 3. Use Decorators in Controllers
|
|
82
93
|
|
|
83
|
-
|
|
94
|
+
```typescript
|
|
95
|
+
import { Controller, Get, Post, Body } from '@nestjs/common';
|
|
96
|
+
import { Public, CurrentUser, RequirePermissions, JwtUserData } from '@ahksolution/permissions-sdk';
|
|
97
|
+
|
|
98
|
+
@Controller('orders')
|
|
99
|
+
export class OrdersController {
|
|
100
|
+
// Public route - bypasses JWT authentication
|
|
101
|
+
@Public()
|
|
102
|
+
@Get('health')
|
|
103
|
+
health() {
|
|
104
|
+
return { status: 'ok' };
|
|
84
105
|
}
|
|
85
106
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
107
|
+
// Authenticated route - no specific permission required
|
|
108
|
+
@Get('me')
|
|
109
|
+
getProfile(@CurrentUser() user: JwtUserData) {
|
|
110
|
+
return {
|
|
111
|
+
id: user.id,
|
|
112
|
+
email: user.email,
|
|
113
|
+
roles: user.roles,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
93
116
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
117
|
+
// Authenticated + requires specific permission
|
|
118
|
+
@Post()
|
|
119
|
+
@RequirePermissions('orders:create')
|
|
120
|
+
createOrder(@CurrentUser() user: JwtUserData, @Body() dto: CreateOrderDto) {
|
|
121
|
+
return this.orderService.create(user.id, dto);
|
|
122
|
+
}
|
|
97
123
|
|
|
98
|
-
|
|
124
|
+
// Get specific user property
|
|
125
|
+
@Get('my-orders')
|
|
126
|
+
@RequirePermissions('orders:read')
|
|
127
|
+
getMyOrders(@CurrentUser('id') userId: string) {
|
|
128
|
+
return this.orderService.findByUser(userId);
|
|
99
129
|
}
|
|
100
130
|
}
|
|
101
131
|
```
|
|
102
132
|
|
|
103
|
-
|
|
133
|
+
## JWT Authentication
|
|
134
|
+
|
|
135
|
+
The SDK provides JWT authentication that validates tokens via gRPC call to the permissions service. **No JWT secret is required in consuming services** - all validation happens centrally.
|
|
136
|
+
|
|
137
|
+
### How It Works
|
|
104
138
|
|
|
105
|
-
|
|
139
|
+
1. `JwtAuthGuard` extracts the token from `Authorization: Bearer <token>` header
|
|
140
|
+
2. Calls `ValidateToken` gRPC method on the permissions service
|
|
141
|
+
3. Permissions service verifies the token and returns user data
|
|
142
|
+
4. User data (with roles and permissions) is attached to `request.user`
|
|
143
|
+
|
|
144
|
+
### JwtUserData Type
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
interface JwtUserData {
|
|
148
|
+
id: string;
|
|
149
|
+
email: string | null;
|
|
150
|
+
phone: string | null;
|
|
151
|
+
userType: string;
|
|
152
|
+
status: string;
|
|
153
|
+
isProfileComplete: boolean;
|
|
154
|
+
roles: RoleInfo[]; // User's roles
|
|
155
|
+
permissions: string[]; // User's permission codes
|
|
156
|
+
hasAllAccess: boolean; // True if user has wildcard access
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
interface RoleInfo {
|
|
160
|
+
id: string;
|
|
161
|
+
code: string;
|
|
162
|
+
name: string;
|
|
163
|
+
isSystem: boolean;
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Decorators
|
|
168
|
+
|
|
169
|
+
| Decorator | Description |
|
|
170
|
+
| -------------------- | ------------------------------------------------ |
|
|
171
|
+
| `@Public()` | Mark route as public (bypass JWT authentication) |
|
|
172
|
+
| `@CurrentUser()` | Get full user object from request |
|
|
173
|
+
| `@CurrentUser('id')` | Get specific property from user |
|
|
174
|
+
|
|
175
|
+
## Permission Checking
|
|
176
|
+
|
|
177
|
+
### Using Decorators (Recommended)
|
|
106
178
|
|
|
107
179
|
```typescript
|
|
108
|
-
import { Controller, Post, Delete, Param, Body, UseGuards } from '@nestjs/common';
|
|
109
180
|
import {
|
|
110
|
-
PermissionsGuard,
|
|
111
181
|
RequirePermissions,
|
|
112
182
|
RequireAnyPermission,
|
|
113
183
|
RequireAllPermissions,
|
|
114
184
|
} from '@ahksolution/permissions-sdk';
|
|
115
|
-
import { JwtAuthGuard } from './your-auth-guard';
|
|
116
185
|
|
|
117
186
|
@Controller('orders')
|
|
118
|
-
@UseGuards(JwtAuthGuard, PermissionsGuard) // Auth guard must run first
|
|
119
187
|
export class OrdersController {
|
|
120
188
|
// Require a single permission
|
|
121
189
|
@Post()
|
|
122
190
|
@RequirePermissions('orders:create')
|
|
123
|
-
|
|
124
|
-
// Permission already verified by guard
|
|
125
|
-
return this.orderService.create(dto);
|
|
126
|
-
}
|
|
191
|
+
create() {}
|
|
127
192
|
|
|
128
|
-
// Require ALL permissions (AND logic)
|
|
193
|
+
// Require ALL permissions (AND logic) - default behavior
|
|
129
194
|
@Post(':id/approve')
|
|
130
195
|
@RequirePermissions(['orders:read', 'orders:approve'])
|
|
131
|
-
|
|
132
|
-
return this.orderService.approve(id);
|
|
133
|
-
}
|
|
196
|
+
approve() {}
|
|
134
197
|
|
|
135
198
|
// Require ANY of the permissions (OR logic)
|
|
136
199
|
@Delete(':id')
|
|
137
200
|
@RequirePermissions(['orders:delete', 'admin:full'], { mode: 'any' })
|
|
138
|
-
|
|
139
|
-
return this.orderService.delete(id);
|
|
140
|
-
}
|
|
201
|
+
delete() {}
|
|
141
202
|
|
|
142
203
|
// Using alias decorators for clarity
|
|
143
204
|
@Post(':id/export')
|
|
144
205
|
@RequireAllPermissions(['orders:read', 'orders:export'])
|
|
145
|
-
|
|
146
|
-
return this.orderService.export(id);
|
|
147
|
-
}
|
|
206
|
+
export() {}
|
|
148
207
|
|
|
149
208
|
@Post(':id/cancel')
|
|
150
209
|
@RequireAnyPermission(['orders:cancel', 'orders:manage'])
|
|
151
|
-
|
|
152
|
-
|
|
210
|
+
cancel() {}
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Using the Client Service
|
|
215
|
+
|
|
216
|
+
Inject `PermissionsGrpcClient` to check permissions programmatically:
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
import { Injectable } from '@nestjs/common';
|
|
220
|
+
import { PermissionsGrpcClient } from '@ahksolution/permissions-sdk';
|
|
221
|
+
|
|
222
|
+
@Injectable()
|
|
223
|
+
export class OrderService {
|
|
224
|
+
constructor(private readonly permissions: PermissionsGrpcClient) {}
|
|
225
|
+
|
|
226
|
+
async createOrder(userId: string, orderData: CreateOrderDto) {
|
|
227
|
+
// Simple boolean check
|
|
228
|
+
const canCreate = await this.permissions.hasPermission(userId, 'orders:create');
|
|
229
|
+
if (!canCreate) {
|
|
230
|
+
throw new ForbiddenException('You do not have permission to create orders');
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Continue with order creation...
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
async deleteOrder(userId: string, orderId: string) {
|
|
237
|
+
// Check multiple permissions (user needs ANY of these)
|
|
238
|
+
const canDelete = await this.permissions.hasAnyPermission(userId, [
|
|
239
|
+
'orders:delete',
|
|
240
|
+
'orders:manage',
|
|
241
|
+
'admin:full',
|
|
242
|
+
]);
|
|
243
|
+
|
|
244
|
+
if (!canDelete) {
|
|
245
|
+
throw new ForbiddenException('You do not have permission to delete orders');
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Continue with deletion...
|
|
153
249
|
}
|
|
154
250
|
}
|
|
155
251
|
```
|
|
156
252
|
|
|
157
253
|
## API Reference
|
|
158
254
|
|
|
255
|
+
### Guards
|
|
256
|
+
|
|
257
|
+
| Guard | Description |
|
|
258
|
+
| ------------------ | ------------------------------------------------------------ |
|
|
259
|
+
| `JwtAuthGuard` | Validates JWT tokens via gRPC. Attaches user to request. |
|
|
260
|
+
| `PermissionsGuard` | Checks permissions based on `@RequirePermissions` decorator. |
|
|
261
|
+
|
|
159
262
|
### PermissionsGrpcClient
|
|
160
263
|
|
|
161
264
|
| Method | Description |
|
|
162
265
|
| --------------------------------------------------------- | --------------------------------------------------- |
|
|
266
|
+
| `validateToken(token)` | Validates JWT and returns `ValidateTokenResult` |
|
|
163
267
|
| `hasPermission(userId, permissionCode)` | Returns `boolean` - does user have this permission? |
|
|
164
268
|
| `hasAllPermissions(userId, permissionCodes)` | Returns `boolean` - does user have ALL permissions? |
|
|
165
269
|
| `hasAnyPermission(userId, permissionCodes)` | Returns `boolean` - does user have ANY permission? |
|
|
@@ -171,6 +275,9 @@ export class OrdersController {
|
|
|
171
275
|
|
|
172
276
|
| Decorator | Description |
|
|
173
277
|
| -------------------------------------------- | -------------------------------------------- |
|
|
278
|
+
| `@Public()` | Mark route as public (bypass JWT auth) |
|
|
279
|
+
| `@CurrentUser()` | Get authenticated user from request |
|
|
280
|
+
| `@CurrentUser('property')` | Get specific property from user |
|
|
174
281
|
| `@RequirePermissions(permissions, options?)` | Require permission(s) with configurable mode |
|
|
175
282
|
| `@RequireAllPermissions(permissions)` | Shorthand for mode: 'all' |
|
|
176
283
|
| `@RequireAnyPermission(permissions)` | Shorthand for mode: 'any' |
|
|
@@ -268,22 +375,92 @@ throw new ForbiddenException('Access denied. Required permission(s): orders:crea
|
|
|
268
375
|
})
|
|
269
376
|
```
|
|
270
377
|
|
|
271
|
-
##
|
|
272
|
-
|
|
273
|
-
The `PermissionsGuard` expects the request to have a `user` object with an `id` property (typically set by your JWT auth guard):
|
|
378
|
+
## Complete Example
|
|
274
379
|
|
|
275
380
|
```typescript
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
381
|
+
// app.module.ts
|
|
382
|
+
import { Module } from '@nestjs/common';
|
|
383
|
+
import { APP_GUARD } from '@nestjs/core';
|
|
384
|
+
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
385
|
+
import {
|
|
386
|
+
PermissionsClientModule,
|
|
387
|
+
JwtAuthGuard,
|
|
388
|
+
PermissionsGuard,
|
|
389
|
+
} from '@ahksolution/permissions-sdk';
|
|
390
|
+
|
|
391
|
+
@Module({
|
|
392
|
+
imports: [
|
|
393
|
+
ConfigModule.forRoot(),
|
|
394
|
+
PermissionsClientModule.registerAsync({
|
|
395
|
+
imports: [ConfigModule],
|
|
396
|
+
useFactory: (config: ConfigService) => ({
|
|
397
|
+
url: config.get('PERMISSIONS_SERVICE_URL', 'localhost:50051'),
|
|
398
|
+
}),
|
|
399
|
+
inject: [ConfigService],
|
|
400
|
+
}),
|
|
401
|
+
],
|
|
402
|
+
providers: [
|
|
403
|
+
{ provide: APP_GUARD, useClass: JwtAuthGuard },
|
|
404
|
+
{ provide: APP_GUARD, useClass: PermissionsGuard },
|
|
405
|
+
],
|
|
406
|
+
})
|
|
407
|
+
export class AppModule {}
|
|
408
|
+
|
|
409
|
+
// users.controller.ts
|
|
410
|
+
import { Controller, Get, Post, Body, Param } from '@nestjs/common';
|
|
411
|
+
import {
|
|
412
|
+
Public,
|
|
413
|
+
CurrentUser,
|
|
414
|
+
RequirePermissions,
|
|
415
|
+
RequireAnyPermission,
|
|
416
|
+
JwtUserData,
|
|
417
|
+
} from '@ahksolution/permissions-sdk';
|
|
418
|
+
|
|
419
|
+
@Controller('users')
|
|
420
|
+
export class UsersController {
|
|
421
|
+
// Public endpoint - no auth required
|
|
422
|
+
@Public()
|
|
423
|
+
@Get('health')
|
|
424
|
+
health() {
|
|
425
|
+
return { status: 'ok' };
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Auth required, no specific permission
|
|
429
|
+
@Get('profile')
|
|
430
|
+
getProfile(@CurrentUser() user: JwtUserData) {
|
|
431
|
+
return user;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Auth + specific permission required
|
|
435
|
+
@Get()
|
|
436
|
+
@RequirePermissions('users:list')
|
|
437
|
+
findAll() {
|
|
438
|
+
return this.userService.findAll();
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
@Post()
|
|
442
|
+
@RequirePermissions('users:create')
|
|
443
|
+
create(@Body() dto: CreateUserDto, @CurrentUser('id') createdBy: string) {
|
|
444
|
+
return this.userService.create(dto, createdBy);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
@Get(':id')
|
|
448
|
+
@RequireAnyPermission(['users:read', 'users:manage'])
|
|
449
|
+
findOne(@Param('id') id: string) {
|
|
450
|
+
return this.userService.findOne(id);
|
|
451
|
+
}
|
|
281
452
|
}
|
|
282
453
|
```
|
|
283
454
|
|
|
284
|
-
## Important
|
|
455
|
+
## Important Notes
|
|
456
|
+
|
|
457
|
+
1. **No JWT Secret Required**: The SDK validates tokens via gRPC call to the permissions service. You don't need to configure JWT secrets in consuming services.
|
|
458
|
+
|
|
459
|
+
2. **Guard Order Matters**: When using both guards globally, `JwtAuthGuard` must run before `PermissionsGuard` (authentication before authorization).
|
|
460
|
+
|
|
461
|
+
3. **Permissions Service Required**: This SDK is a client for the AHK Solution Permissions Microservice. It will not function without a running instance exposing a gRPC endpoint.
|
|
285
462
|
|
|
286
|
-
|
|
463
|
+
4. **Same-Pod Deployment**: For optimal performance, deploy consuming services in the same pod/network as the permissions service to minimize gRPC latency.
|
|
287
464
|
|
|
288
465
|
## License
|
|
289
466
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { OnModuleInit } from '@nestjs/common';
|
|
2
2
|
import { ClientGrpc } from '@nestjs/microservices';
|
|
3
|
-
import type { BulkPermissionResultRecord, EffectivePermissions, EvaluationResult, RequestContext, ResourceContext } from '../types';
|
|
3
|
+
import type { BulkPermissionResultRecord, EffectivePermissions, EvaluationResult, RequestContext, ResourceContext, ValidateTokenResult } from '../types';
|
|
4
4
|
/**
|
|
5
5
|
* gRPC client for the Permissions Service
|
|
6
6
|
* Provides methods to check permissions via gRPC calls to the permissions microservice
|
|
@@ -41,5 +41,14 @@ export declare class PermissionsGrpcClient implements OnModuleInit {
|
|
|
41
41
|
* Check if user has ANY of the specified permissions
|
|
42
42
|
*/
|
|
43
43
|
hasAnyPermission(userId: string, permissionCodes: string[]): Promise<boolean>;
|
|
44
|
+
/**
|
|
45
|
+
* Validate a JWT token via gRPC and return user data
|
|
46
|
+
* Used by JwtAuthGuard to authenticate requests
|
|
47
|
+
*/
|
|
48
|
+
validateToken(token: string): Promise<ValidateTokenResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Maps gRPC user data to JwtUserData type
|
|
51
|
+
*/
|
|
52
|
+
private mapToJwtUserData;
|
|
44
53
|
}
|
|
45
54
|
//# sourceMappingURL=permissions-grpc.client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissions-grpc.client.d.ts","sourceRoot":"","sources":["../../src/client/permissions-grpc.client.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAInD,OAAO,KAAK,EACV,0BAA0B,EAC1B,oBAAoB,EACpB,gBAAgB,
|
|
1
|
+
{"version":3,"file":"permissions-grpc.client.d.ts","sourceRoot":"","sources":["../../src/client/permissions-grpc.client.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAInD,OAAO,KAAK,EACV,0BAA0B,EAC1B,oBAAoB,EACpB,gBAAgB,EAGhB,cAAc,EACd,eAAe,EACf,mBAAmB,EACpB,MAAM,UAAU,CAAC;AAmGlB;;;GAGG;AACH,qBACa,qBAAsB,YAAW,YAAY;IAMtD,OAAO,CAAC,QAAQ,CAAC,MAAM;IALzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0C;IACjE,OAAO,CAAC,kBAAkB,CAA0B;gBAIjC,MAAM,EAAE,UAAU;IAGrC,YAAY,IAAI,IAAI;IAMpB;;OAEG;IACG,eAAe,CACnB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,EAAE,eAAe,CAAC;QAC3B,OAAO,CAAC,EAAE,cAAc,CAAC;KAC1B,GACA,OAAO,CAAC,gBAAgB,CAAC;IAY5B;;OAEG;IACG,oBAAoB,CACxB,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,MAAM,EAAE,EACzB,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,EAAE,eAAe,CAAC;QAC3B,OAAO,CAAC,EAAE,cAAc,CAAC;KAC1B,GACA,OAAO,CAAC,0BAA0B,CAAC;IAmBtC;;OAEG;IACG,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAiB5E;;OAEG;IACG,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAO7E;;OAEG;IACG,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAOpF;;OAEG;IACG,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAOnF;;;OAGG;IACG,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAiBhE;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAsBzB"}
|
|
@@ -172,6 +172,48 @@ let PermissionsGrpcClient = PermissionsGrpcClient_1 = class PermissionsGrpcClien
|
|
|
172
172
|
const response = await (0, rxjs_1.firstValueFrom)(this.permissionsService.hasAnyPermission({ userId, permissionCodes }));
|
|
173
173
|
return response.hasPermission;
|
|
174
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* Validate a JWT token via gRPC and return user data
|
|
177
|
+
* Used by JwtAuthGuard to authenticate requests
|
|
178
|
+
*/
|
|
179
|
+
async validateToken(token) {
|
|
180
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.permissionsService.validateToken({ token }));
|
|
181
|
+
if (!response.valid) {
|
|
182
|
+
return {
|
|
183
|
+
valid: false,
|
|
184
|
+
errorCode: response.errorCode,
|
|
185
|
+
errorMessage: response.errorMessage,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
valid: true,
|
|
190
|
+
user: this.mapToJwtUserData(response.user),
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Maps gRPC user data to JwtUserData type
|
|
195
|
+
*/
|
|
196
|
+
mapToJwtUserData(userData) {
|
|
197
|
+
if (userData === undefined) {
|
|
198
|
+
return undefined;
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
id: userData.id,
|
|
202
|
+
email: userData.email !== '' ? userData.email : null,
|
|
203
|
+
phone: userData.phone !== '' ? userData.phone : null,
|
|
204
|
+
userType: userData.userType,
|
|
205
|
+
status: userData.status,
|
|
206
|
+
isProfileComplete: userData.isProfileComplete,
|
|
207
|
+
roles: userData.roles.map((role) => ({
|
|
208
|
+
id: role.id,
|
|
209
|
+
code: role.code,
|
|
210
|
+
name: role.name,
|
|
211
|
+
isSystem: role.isSystem,
|
|
212
|
+
})),
|
|
213
|
+
permissions: userData.permissions,
|
|
214
|
+
hasAllAccess: userData.hasAllAccess,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
175
217
|
};
|
|
176
218
|
exports.PermissionsGrpcClient = PermissionsGrpcClient;
|
|
177
219
|
exports.PermissionsGrpcClient = PermissionsGrpcClient = PermissionsGrpcClient_1 = __decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissions-grpc.client.js","sourceRoot":"","sources":["../../src/client/permissions-grpc.client.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAA0E;AAE1E,+BAAsC;AAEtC,4CAAiF;
|
|
1
|
+
{"version":3,"file":"permissions-grpc.client.js","sourceRoot":"","sources":["../../src/client/permissions-grpc.client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { JwtUserData } from '../types/jwt.types';
|
|
2
|
+
/**
|
|
3
|
+
* Get the current authenticated user from the request
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```typescript
|
|
7
|
+
* // Get full user object
|
|
8
|
+
* @Get('profile')
|
|
9
|
+
* getProfile(@CurrentUser() user: JwtUserData) {
|
|
10
|
+
* return user;
|
|
11
|
+
* }
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* // Get specific property
|
|
17
|
+
* @Get('my-id')
|
|
18
|
+
* getMyId(@CurrentUser('id') userId: string) {
|
|
19
|
+
* return { userId };
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare const CurrentUser: (...dataOrPipes: (keyof JwtUserData | import("@nestjs/common").PipeTransform<any, any> | import("@nestjs/common").Type<import("@nestjs/common").PipeTransform<any, any>> | undefined)[]) => ParameterDecorator;
|
|
24
|
+
//# sourceMappingURL=current-user.decorator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"current-user.decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/current-user.decorator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,WAAW,gNAMvB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CurrentUser = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
/**
|
|
6
|
+
* Get the current authenticated user from the request
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* // Get full user object
|
|
11
|
+
* @Get('profile')
|
|
12
|
+
* getProfile(@CurrentUser() user: JwtUserData) {
|
|
13
|
+
* return user;
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* // Get specific property
|
|
20
|
+
* @Get('my-id')
|
|
21
|
+
* getMyId(@CurrentUser('id') userId: string) {
|
|
22
|
+
* return { userId };
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
exports.CurrentUser = (0, common_1.createParamDecorator)((data, ctx) => {
|
|
27
|
+
const request = ctx.switchToHttp().getRequest();
|
|
28
|
+
const { user } = request;
|
|
29
|
+
return data !== undefined ? user?.[data] : user;
|
|
30
|
+
});
|
|
31
|
+
//# sourceMappingURL=current-user.decorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"current-user.decorator.js","sourceRoot":"","sources":["../../src/decorators/current-user.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA6E;AAI7E;;;;;;;;;;;;;;;;;;;;GAoBG;AACU,QAAA,WAAW,GAAG,IAAA,6BAAoB,EAC7C,CAAC,IAAmC,EAAE,GAAqB,EAAE,EAAE;IAC7D,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC,UAAU,EAA0B,CAAC;IACxE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IACzB,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAClD,CAAC,CACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iCAAiC,CAAC"}
|
package/dist/decorators/index.js
CHANGED
|
@@ -14,5 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./current-user.decorator"), exports);
|
|
18
|
+
__exportStar(require("./public.decorator"), exports);
|
|
17
19
|
__exportStar(require("./require-permissions.decorator"), exports);
|
|
18
20
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,kEAAgD"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2DAAyC;AACzC,qDAAmC;AACnC,kEAAgD"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { SetMetadata } from '@nestjs/common';
|
|
2
|
+
/**
|
|
3
|
+
* Metadata key for public routes
|
|
4
|
+
*/
|
|
5
|
+
export declare const IS_PUBLIC_KEY = "permissions-sdk:isPublic";
|
|
6
|
+
/**
|
|
7
|
+
* Mark a route as public (bypass JWT authentication)
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* @Controller('health')
|
|
12
|
+
* export class HealthController {
|
|
13
|
+
* @Public()
|
|
14
|
+
* @Get()
|
|
15
|
+
* check() {
|
|
16
|
+
* return { status: 'ok' };
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare const Public: () => ReturnType<typeof SetMetadata>;
|
|
22
|
+
//# sourceMappingURL=public.decorator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public.decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/public.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C;;GAEG;AACH,eAAO,MAAM,aAAa,6BAA6B,CAAC;AAExD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,MAAM,QAAO,UAAU,CAAC,OAAO,WAAW,CAAqC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Public = exports.IS_PUBLIC_KEY = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
/**
|
|
6
|
+
* Metadata key for public routes
|
|
7
|
+
*/
|
|
8
|
+
exports.IS_PUBLIC_KEY = 'permissions-sdk:isPublic';
|
|
9
|
+
/**
|
|
10
|
+
* Mark a route as public (bypass JWT authentication)
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* @Controller('health')
|
|
15
|
+
* export class HealthController {
|
|
16
|
+
* @Public()
|
|
17
|
+
* @Get()
|
|
18
|
+
* check() {
|
|
19
|
+
* return { status: 'ok' };
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
const Public = () => (0, common_1.SetMetadata)(exports.IS_PUBLIC_KEY, true);
|
|
25
|
+
exports.Public = Public;
|
|
26
|
+
//# sourceMappingURL=public.decorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public.decorator.js","sourceRoot":"","sources":["../../src/decorators/public.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA6C;AAE7C;;GAEG;AACU,QAAA,aAAa,GAAG,0BAA0B,CAAC;AAExD;;;;;;;;;;;;;;GAcG;AACI,MAAM,MAAM,GAAG,GAAmC,EAAE,CAAC,IAAA,oBAAW,EAAC,qBAAa,EAAE,IAAI,CAAC,CAAC;AAAhF,QAAA,MAAM,UAA0E"}
|
package/dist/guards/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/guards/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/guards/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC"}
|
package/dist/guards/index.js
CHANGED
|
@@ -14,5 +14,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./jwt-auth.guard"), exports);
|
|
17
18
|
__exportStar(require("./permissions.guard"), exports);
|
|
18
19
|
//# sourceMappingURL=index.js.map
|
package/dist/guards/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/guards/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sDAAoC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/guards/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mDAAiC;AACjC,sDAAoC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import { Reflector } from '@nestjs/core';
|
|
3
|
+
import { PermissionsGrpcClient } from '../client/permissions-grpc.client';
|
|
4
|
+
/**
|
|
5
|
+
* JWT Authentication Guard
|
|
6
|
+
*
|
|
7
|
+
* Validates JWT tokens via gRPC call to the permissions service.
|
|
8
|
+
* This guard extracts the token from the Authorization header,
|
|
9
|
+
* validates it via gRPC, and attaches the user data to the request.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* // Apply globally in app.module.ts
|
|
14
|
+
* @Module({
|
|
15
|
+
* imports: [PermissionsClientModule.register({ url: 'localhost:50051' })],
|
|
16
|
+
* providers: [
|
|
17
|
+
* { provide: APP_GUARD, useClass: JwtAuthGuard },
|
|
18
|
+
* ],
|
|
19
|
+
* })
|
|
20
|
+
* export class AppModule {}
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* // Or apply to specific routes
|
|
26
|
+
* @Controller('orders')
|
|
27
|
+
* @UseGuards(JwtAuthGuard)
|
|
28
|
+
* export class OrdersController {}
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare class JwtAuthGuard implements CanActivate {
|
|
32
|
+
private readonly reflector;
|
|
33
|
+
private readonly permissionsClient;
|
|
34
|
+
private readonly logger;
|
|
35
|
+
constructor(reflector: Reflector, permissionsClient: PermissionsGrpcClient);
|
|
36
|
+
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
37
|
+
private extractTokenFromHeader;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=jwt-auth.guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt-auth.guard.d.ts","sourceRoot":"","sources":["../../src/guards/jwt-auth.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,gBAAgB,EAIjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAG1E;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBACa,YAAa,YAAW,WAAW;IAI5C,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAJpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;gBAGrC,SAAS,EAAE,SAAS,EACpB,iBAAiB,EAAE,qBAAqB;IAGrD,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAmC9D,OAAO,CAAC,sBAAsB;CAW/B"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var JwtAuthGuard_1;
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.JwtAuthGuard = void 0;
|
|
14
|
+
const common_1 = require("@nestjs/common");
|
|
15
|
+
const core_1 = require("@nestjs/core");
|
|
16
|
+
const permissions_grpc_client_1 = require("../client/permissions-grpc.client");
|
|
17
|
+
const public_decorator_1 = require("../decorators/public.decorator");
|
|
18
|
+
/**
|
|
19
|
+
* JWT Authentication Guard
|
|
20
|
+
*
|
|
21
|
+
* Validates JWT tokens via gRPC call to the permissions service.
|
|
22
|
+
* This guard extracts the token from the Authorization header,
|
|
23
|
+
* validates it via gRPC, and attaches the user data to the request.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* // Apply globally in app.module.ts
|
|
28
|
+
* @Module({
|
|
29
|
+
* imports: [PermissionsClientModule.register({ url: 'localhost:50051' })],
|
|
30
|
+
* providers: [
|
|
31
|
+
* { provide: APP_GUARD, useClass: JwtAuthGuard },
|
|
32
|
+
* ],
|
|
33
|
+
* })
|
|
34
|
+
* export class AppModule {}
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* // Or apply to specific routes
|
|
40
|
+
* @Controller('orders')
|
|
41
|
+
* @UseGuards(JwtAuthGuard)
|
|
42
|
+
* export class OrdersController {}
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
let JwtAuthGuard = JwtAuthGuard_1 = class JwtAuthGuard {
|
|
46
|
+
reflector;
|
|
47
|
+
permissionsClient;
|
|
48
|
+
logger = new common_1.Logger(JwtAuthGuard_1.name);
|
|
49
|
+
constructor(reflector, permissionsClient) {
|
|
50
|
+
this.reflector = reflector;
|
|
51
|
+
this.permissionsClient = permissionsClient;
|
|
52
|
+
}
|
|
53
|
+
async canActivate(context) {
|
|
54
|
+
// Check if route is marked as public
|
|
55
|
+
const isPublic = this.reflector.getAllAndOverride(public_decorator_1.IS_PUBLIC_KEY, [
|
|
56
|
+
context.getHandler(),
|
|
57
|
+
context.getClass(),
|
|
58
|
+
]);
|
|
59
|
+
if (isPublic) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
const request = context.switchToHttp().getRequest();
|
|
63
|
+
const token = this.extractTokenFromHeader(request);
|
|
64
|
+
if (token === undefined) {
|
|
65
|
+
throw new common_1.UnauthorizedException('No token provided');
|
|
66
|
+
}
|
|
67
|
+
// Validate token via gRPC call to permissions service
|
|
68
|
+
const result = await this.permissionsClient.validateToken(token);
|
|
69
|
+
if (!result.valid) {
|
|
70
|
+
this.logger.debug(`Token validation failed: ${result.errorCode ?? 'UNKNOWN'}`);
|
|
71
|
+
throw new common_1.UnauthorizedException(result.errorMessage ?? 'Invalid token');
|
|
72
|
+
}
|
|
73
|
+
// Attach user to request
|
|
74
|
+
request.user = result.user;
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
extractTokenFromHeader(request) {
|
|
78
|
+
const authHeader = request.headers.authorization;
|
|
79
|
+
if (authHeader === undefined) {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
const [type, token] = authHeader.split(' ');
|
|
83
|
+
return type === 'Bearer' ? token : undefined;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
exports.JwtAuthGuard = JwtAuthGuard;
|
|
87
|
+
exports.JwtAuthGuard = JwtAuthGuard = JwtAuthGuard_1 = __decorate([
|
|
88
|
+
(0, common_1.Injectable)(),
|
|
89
|
+
__metadata("design:paramtypes", [core_1.Reflector,
|
|
90
|
+
permissions_grpc_client_1.PermissionsGrpcClient])
|
|
91
|
+
], JwtAuthGuard);
|
|
92
|
+
//# sourceMappingURL=jwt-auth.guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt-auth.guard.js","sourceRoot":"","sources":["../../src/guards/jwt-auth.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAMwB;AACxB,uCAAyC;AAEzC,+EAA0E;AAC1E,qEAA+D;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEI,IAAM,YAAY,oBAAlB,MAAM,YAAY;IAIJ;IACA;IAJF,MAAM,GAAG,IAAI,eAAM,CAAC,cAAY,CAAC,IAAI,CAAC,CAAC;IAExD,YACmB,SAAoB,EACpB,iBAAwC;QADxC,cAAS,GAAT,SAAS,CAAW;QACpB,sBAAiB,GAAjB,iBAAiB,CAAuB;IACxD,CAAC;IAEJ,KAAK,CAAC,WAAW,CAAC,OAAyB;QACzC,qCAAqC;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAU,gCAAa,EAAE;YACxE,OAAO,CAAC,UAAU,EAAE;YACpB,OAAO,CAAC,QAAQ,EAAE;SACnB,CAAC,CAAC;QAEH,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAG7C,CAAC;QACL,MAAM,KAAK,GAAG,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAEnD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,IAAI,8BAAqB,CAAC,mBAAmB,CAAC,CAAC;QACvD,CAAC;QAED,sDAAsD;QACtD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAEjE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAClB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,MAAM,CAAC,SAAS,IAAI,SAAS,EAAE,CAAC,CAAC;YAC/E,MAAM,IAAI,8BAAqB,CAAC,MAAM,CAAC,YAAY,IAAI,eAAe,CAAC,CAAC;QAC1E,CAAC;QAED,yBAAyB;QACzB,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QAE3B,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,sBAAsB,CAAC,OAE9B;QACC,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC;QACjD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC5C,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/C,CAAC;CACF,CAAA;AAtDY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;qCAKmB,gBAAS;QACD,+CAAqB;GALhD,YAAY,CAsDxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissions.guard.d.ts","sourceRoot":"","sources":["../../src/guards/permissions.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,gBAAgB,EAIjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AA0B1E;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBACa,gBAAiB,YAAW,WAAW;IAIhD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAJpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqC;gBAGzC,SAAS,EAAE,SAAS,EACpB,iBAAiB,EAAE,qBAAqB;IAGrD,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IA2C9D;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAO9B;;OAEG;YACW,mBAAmB;IAuBjC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAU3B;;OAEG;IACH,OAAO,CAAC,oBAAoB;
|
|
1
|
+
{"version":3,"file":"permissions.guard.d.ts","sourceRoot":"","sources":["../../src/guards/permissions.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,gBAAgB,EAIjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AA0B1E;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBACa,gBAAiB,YAAW,WAAW;IAIhD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAJpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqC;gBAGzC,SAAS,EAAE,SAAS,EACpB,iBAAiB,EAAE,qBAAqB;IAGrD,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IA2C9D;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAO9B;;OAEG;YACW,mBAAmB;IAuBjC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAU3B;;OAEG;IACH,OAAO,CAAC,oBAAoB;CAQ7B"}
|
|
@@ -95,7 +95,7 @@ let PermissionsGuard = PermissionsGuard_1 = class PermissionsGuard {
|
|
|
95
95
|
const requestContext = this.buildRequestContext(request);
|
|
96
96
|
const resourceContext = includeResourceContext ? this.buildResourceContext(request) : undefined;
|
|
97
97
|
if (permissions.length === 1) {
|
|
98
|
-
const [firstPermission] = permissions;
|
|
98
|
+
const [firstPermission = ''] = permissions;
|
|
99
99
|
const result = await this.permissionsClient.checkPermission(userId, firstPermission, {
|
|
100
100
|
request: requestContext,
|
|
101
101
|
resource: resourceContext,
|
|
@@ -124,7 +124,8 @@ let PermissionsGuard = PermissionsGuard_1 = class PermissionsGuard {
|
|
|
124
124
|
*/
|
|
125
125
|
buildResourceContext(request) {
|
|
126
126
|
return {
|
|
127
|
-
|
|
127
|
+
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
128
|
+
id: request.params?.['id'],
|
|
128
129
|
...request.params,
|
|
129
130
|
...request.query,
|
|
130
131
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissions.guard.js","sourceRoot":"","sources":["../../src/guards/permissions.guard.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"permissions.guard.js","sourceRoot":"","sources":["../../src/guards/permissions.guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -37,6 +37,12 @@ service PermissionsService {
|
|
|
37
37
|
* Check if user has ANY of the specified permissions
|
|
38
38
|
*/
|
|
39
39
|
rpc HasAnyPermission(HasMultiplePermissionsRequest) returns (HasPermissionResponse);
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Validate a JWT token and return user data with roles and permissions
|
|
43
|
+
* Used by consuming services to authenticate requests via gRPC
|
|
44
|
+
*/
|
|
45
|
+
rpc ValidateToken(ValidateTokenRequest) returns (ValidateTokenResponse);
|
|
40
46
|
}
|
|
41
47
|
|
|
42
48
|
// ============================================================================
|
|
@@ -148,3 +154,44 @@ message RequestContext {
|
|
|
148
154
|
optional string path = 4;
|
|
149
155
|
map<string, string> attributes = 5;
|
|
150
156
|
}
|
|
157
|
+
|
|
158
|
+
// ============================================================================
|
|
159
|
+
// JWT Token Validation Messages
|
|
160
|
+
// ============================================================================
|
|
161
|
+
|
|
162
|
+
message ValidateTokenRequest {
|
|
163
|
+
string token = 1;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
message ValidateTokenResponse {
|
|
167
|
+
bool valid = 1;
|
|
168
|
+
string error_code = 2; // "EXPIRED", "INVALID", "USER_INACTIVE", "USER_NOT_FOUND"
|
|
169
|
+
string error_message = 3;
|
|
170
|
+
UserData user = 4; // Only populated if valid=true
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* User data returned from token validation
|
|
175
|
+
* Contains user info with roles and permissions
|
|
176
|
+
*/
|
|
177
|
+
message UserData {
|
|
178
|
+
string id = 1;
|
|
179
|
+
string email = 2;
|
|
180
|
+
string phone = 3;
|
|
181
|
+
string user_type = 4;
|
|
182
|
+
string status = 5;
|
|
183
|
+
bool is_profile_complete = 6;
|
|
184
|
+
repeated UserRoleInfo roles = 7;
|
|
185
|
+
repeated string permissions = 8;
|
|
186
|
+
bool has_all_access = 9;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Role info for user data (simplified version of RoleInfo)
|
|
191
|
+
*/
|
|
192
|
+
message UserRoleInfo {
|
|
193
|
+
string id = 1;
|
|
194
|
+
string code = 2;
|
|
195
|
+
string name = 3;
|
|
196
|
+
bool is_system = 4;
|
|
197
|
+
}
|
|
@@ -82,6 +82,32 @@ export interface GetEffectivePermissionsResponse {
|
|
|
82
82
|
export interface HasPermissionResponse {
|
|
83
83
|
hasPermission: boolean;
|
|
84
84
|
}
|
|
85
|
+
export interface ValidateTokenRequest {
|
|
86
|
+
token: string;
|
|
87
|
+
}
|
|
88
|
+
export interface GrpcUserRoleInfo {
|
|
89
|
+
id: string;
|
|
90
|
+
code: string;
|
|
91
|
+
name: string;
|
|
92
|
+
isSystem: boolean;
|
|
93
|
+
}
|
|
94
|
+
export interface GrpcUserData {
|
|
95
|
+
id: string;
|
|
96
|
+
email: string;
|
|
97
|
+
phone: string;
|
|
98
|
+
userType: string;
|
|
99
|
+
status: string;
|
|
100
|
+
isProfileComplete: boolean;
|
|
101
|
+
roles: GrpcUserRoleInfo[];
|
|
102
|
+
permissions: string[];
|
|
103
|
+
hasAllAccess: boolean;
|
|
104
|
+
}
|
|
105
|
+
export interface ValidateTokenResponse {
|
|
106
|
+
valid: boolean;
|
|
107
|
+
errorCode: string;
|
|
108
|
+
errorMessage: string;
|
|
109
|
+
user?: GrpcUserData;
|
|
110
|
+
}
|
|
85
111
|
/**
|
|
86
112
|
* gRPC Permissions Service client interface
|
|
87
113
|
* This interface is used by NestJS microservices to define the client methods
|
|
@@ -93,5 +119,6 @@ export interface PermissionsGrpcService {
|
|
|
93
119
|
hasPermission: (request: HasPermissionRequest) => Observable<HasPermissionResponse>;
|
|
94
120
|
hasAllPermissions: (request: HasMultiplePermissionsRequest) => Observable<HasPermissionResponse>;
|
|
95
121
|
hasAnyPermission: (request: HasMultiplePermissionsRequest) => Observable<HasPermissionResponse>;
|
|
122
|
+
validateToken: (request: ValidateTokenRequest) => Observable<ValidateTokenResponse>;
|
|
96
123
|
}
|
|
97
124
|
//# sourceMappingURL=grpc.types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grpc.types.d.ts","sourceRoot":"","sources":["../../src/types/grpc.types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"grpc.types.d.ts","sourceRoot":"","sources":["../../src/types/grpc.types.ts"],"names":[],"mappings":"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"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,mBAAmB,aAAa,CAAC;AACjC,cAAc,oBAAoB,CAAC"}
|
package/dist/types/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAmC;AACnC,+CAA6B;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAmC;AACnC,+CAA6B;AAE7B,qDAAmC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { RoleInfo } from './permission.types';
|
|
2
|
+
/**
|
|
3
|
+
* User data returned from JWT validation via gRPC
|
|
4
|
+
* Contains full user information with roles and permissions
|
|
5
|
+
*/
|
|
6
|
+
export interface JwtUserData {
|
|
7
|
+
readonly id: string;
|
|
8
|
+
readonly email: string | null;
|
|
9
|
+
readonly phone: string | null;
|
|
10
|
+
readonly userType: string;
|
|
11
|
+
readonly status: string;
|
|
12
|
+
readonly isProfileComplete: boolean;
|
|
13
|
+
readonly roles: readonly RoleInfo[];
|
|
14
|
+
readonly permissions: readonly string[];
|
|
15
|
+
readonly hasAllAccess: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Result of token validation from gRPC
|
|
19
|
+
*/
|
|
20
|
+
export interface ValidateTokenResult {
|
|
21
|
+
readonly valid: boolean;
|
|
22
|
+
readonly errorCode?: string;
|
|
23
|
+
readonly errorMessage?: string;
|
|
24
|
+
readonly user?: JwtUserData;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=jwt.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt.types.d.ts","sourceRoot":"","sources":["../../src/types/jwt.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IACpC,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC;CAC7B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt.types.js","sourceRoot":"","sources":["../../src/types/jwt.types.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ahksolution/permissions-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "gRPC client SDK for AHK Solution Permissions Microservice - provides NestJS guard, decorators, and client for inter-service permission checks",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -37,6 +37,12 @@ service PermissionsService {
|
|
|
37
37
|
* Check if user has ANY of the specified permissions
|
|
38
38
|
*/
|
|
39
39
|
rpc HasAnyPermission(HasMultiplePermissionsRequest) returns (HasPermissionResponse);
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Validate a JWT token and return user data with roles and permissions
|
|
43
|
+
* Used by consuming services to authenticate requests via gRPC
|
|
44
|
+
*/
|
|
45
|
+
rpc ValidateToken(ValidateTokenRequest) returns (ValidateTokenResponse);
|
|
40
46
|
}
|
|
41
47
|
|
|
42
48
|
// ============================================================================
|
|
@@ -148,3 +154,44 @@ message RequestContext {
|
|
|
148
154
|
optional string path = 4;
|
|
149
155
|
map<string, string> attributes = 5;
|
|
150
156
|
}
|
|
157
|
+
|
|
158
|
+
// ============================================================================
|
|
159
|
+
// JWT Token Validation Messages
|
|
160
|
+
// ============================================================================
|
|
161
|
+
|
|
162
|
+
message ValidateTokenRequest {
|
|
163
|
+
string token = 1;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
message ValidateTokenResponse {
|
|
167
|
+
bool valid = 1;
|
|
168
|
+
string error_code = 2; // "EXPIRED", "INVALID", "USER_INACTIVE", "USER_NOT_FOUND"
|
|
169
|
+
string error_message = 3;
|
|
170
|
+
UserData user = 4; // Only populated if valid=true
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* User data returned from token validation
|
|
175
|
+
* Contains user info with roles and permissions
|
|
176
|
+
*/
|
|
177
|
+
message UserData {
|
|
178
|
+
string id = 1;
|
|
179
|
+
string email = 2;
|
|
180
|
+
string phone = 3;
|
|
181
|
+
string user_type = 4;
|
|
182
|
+
string status = 5;
|
|
183
|
+
bool is_profile_complete = 6;
|
|
184
|
+
repeated UserRoleInfo roles = 7;
|
|
185
|
+
repeated string permissions = 8;
|
|
186
|
+
bool has_all_access = 9;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Role info for user data (simplified version of RoleInfo)
|
|
191
|
+
*/
|
|
192
|
+
message UserRoleInfo {
|
|
193
|
+
string id = 1;
|
|
194
|
+
string code = 2;
|
|
195
|
+
string name = 3;
|
|
196
|
+
bool is_system = 4;
|
|
197
|
+
}
|