@ahksolution/permissions-sdk 1.0.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 +290 -0
- package/dist/client/index.d.ts +3 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +19 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/permissions-client.module.d.ts +74 -0
- package/dist/client/permissions-client.module.d.ts.map +1 -0
- package/dist/client/permissions-client.module.js +109 -0
- package/dist/client/permissions-client.module.js.map +1 -0
- package/dist/client/permissions-grpc.client.d.ts +45 -0
- package/dist/client/permissions-grpc.client.d.ts.map +1 -0
- package/dist/client/permissions-grpc.client.js +182 -0
- package/dist/client/permissions-grpc.client.js.map +1 -0
- package/dist/constants.d.ts +44 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +48 -0
- package/dist/constants.js.map +1 -0
- package/dist/decorators/index.d.ts +2 -0
- package/dist/decorators/index.d.ts.map +1 -0
- package/dist/decorators/index.js +18 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators/require-permissions.decorator.d.ts +51 -0
- package/dist/decorators/require-permissions.decorator.d.ts.map +1 -0
- package/dist/decorators/require-permissions.decorator.js +69 -0
- package/dist/decorators/require-permissions.decorator.js.map +1 -0
- package/dist/guards/index.d.ts +2 -0
- package/dist/guards/index.d.ts.map +1 -0
- package/dist/guards/index.js +18 -0
- package/dist/guards/index.js.map +1 -0
- package/dist/guards/permissions.guard.d.ts +55 -0
- package/dist/guards/permissions.guard.d.ts.map +1 -0
- package/dist/guards/permissions.guard.js +139 -0
- package/dist/guards/permissions.guard.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/proto/permissions.proto +150 -0
- package/dist/types/evaluation.types.d.ts +80 -0
- package/dist/types/evaluation.types.d.ts.map +1 -0
- package/dist/types/evaluation.types.js +14 -0
- package/dist/types/evaluation.types.js.map +1 -0
- package/dist/types/grpc.types.d.ts +97 -0
- package/dist/types/grpc.types.d.ts.map +1 -0
- package/dist/types/grpc.types.js +15 -0
- package/dist/types/grpc.types.js.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +20 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/permission.types.d.ts +51 -0
- package/dist/types/permission.types.d.ts.map +1 -0
- package/dist/types/permission.types.js +8 -0
- package/dist/types/permission.types.js.map +1 -0
- package/package.json +60 -0
- package/src/proto/permissions.proto +150 -0
package/README.md
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# @ahksolution/permissions-sdk
|
|
2
|
+
|
|
3
|
+
gRPC client SDK for the AHK Solution Permissions Microservice. Provides NestJS integration for inter-service permission checks with RBAC and ABAC support.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# From private npm registry
|
|
9
|
+
npm install @ahksolution/permissions-sdk
|
|
10
|
+
|
|
11
|
+
# Or using pnpm
|
|
12
|
+
pnpm add @ahksolution/permissions-sdk
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
**Peer Dependencies** (must be installed in your project):
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pnpm add @nestjs/microservices @grpc/grpc-js @grpc/proto-loader
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
### 1. Register the Module
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
// app.module.ts
|
|
27
|
+
import { Module } from '@nestjs/common';
|
|
28
|
+
import { PermissionsClientModule } from '@ahksolution/permissions-sdk';
|
|
29
|
+
|
|
30
|
+
@Module({
|
|
31
|
+
imports: [
|
|
32
|
+
// Static configuration
|
|
33
|
+
PermissionsClientModule.register({
|
|
34
|
+
url: 'localhost:50051',
|
|
35
|
+
}),
|
|
36
|
+
],
|
|
37
|
+
})
|
|
38
|
+
export class AppModule {}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**With async configuration (recommended for production):**
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
// app.module.ts
|
|
45
|
+
import { Module } from '@nestjs/common';
|
|
46
|
+
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
47
|
+
import { PermissionsClientModule } from '@ahksolution/permissions-sdk';
|
|
48
|
+
|
|
49
|
+
@Module({
|
|
50
|
+
imports: [
|
|
51
|
+
ConfigModule.forRoot(),
|
|
52
|
+
PermissionsClientModule.registerAsync({
|
|
53
|
+
imports: [ConfigModule],
|
|
54
|
+
useFactory: (config: ConfigService) => ({
|
|
55
|
+
url: config.get<string>('PERMISSIONS_SERVICE_URL', 'localhost:50051'),
|
|
56
|
+
}),
|
|
57
|
+
inject: [ConfigService],
|
|
58
|
+
}),
|
|
59
|
+
],
|
|
60
|
+
})
|
|
61
|
+
export class AppModule {}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 2. Use the Client Service
|
|
65
|
+
|
|
66
|
+
Inject `PermissionsGrpcClient` to check permissions programmatically:
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
import { Injectable } from '@nestjs/common';
|
|
70
|
+
import { PermissionsGrpcClient } from '@ahksolution/permissions-sdk';
|
|
71
|
+
|
|
72
|
+
@Injectable()
|
|
73
|
+
export class OrderService {
|
|
74
|
+
constructor(private readonly permissions: PermissionsGrpcClient) {}
|
|
75
|
+
|
|
76
|
+
async createOrder(userId: string, orderData: CreateOrderDto) {
|
|
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
|
+
}
|
|
82
|
+
|
|
83
|
+
// Continue with order creation...
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async deleteOrder(userId: string, orderId: string) {
|
|
87
|
+
// Check multiple permissions (user needs ANY of these)
|
|
88
|
+
const canDelete = await this.permissions.hasAnyPermission(userId, [
|
|
89
|
+
'orders:delete',
|
|
90
|
+
'orders:manage',
|
|
91
|
+
'admin:full',
|
|
92
|
+
]);
|
|
93
|
+
|
|
94
|
+
if (!canDelete) {
|
|
95
|
+
throw new ForbiddenException('You do not have permission to delete orders');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Continue with deletion...
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 3. Use Guard and Decorator (Recommended)
|
|
104
|
+
|
|
105
|
+
For declarative permission checks on controller routes:
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
import { Controller, Post, Delete, Param, Body, UseGuards } from '@nestjs/common';
|
|
109
|
+
import {
|
|
110
|
+
PermissionsGuard,
|
|
111
|
+
RequirePermissions,
|
|
112
|
+
RequireAnyPermission,
|
|
113
|
+
RequireAllPermissions,
|
|
114
|
+
} from '@ahksolution/permissions-sdk';
|
|
115
|
+
import { JwtAuthGuard } from './your-auth-guard';
|
|
116
|
+
|
|
117
|
+
@Controller('orders')
|
|
118
|
+
@UseGuards(JwtAuthGuard, PermissionsGuard) // Auth guard must run first
|
|
119
|
+
export class OrdersController {
|
|
120
|
+
// Require a single permission
|
|
121
|
+
@Post()
|
|
122
|
+
@RequirePermissions('orders:create')
|
|
123
|
+
async createOrder(@Body() dto: CreateOrderDto) {
|
|
124
|
+
// Permission already verified by guard
|
|
125
|
+
return this.orderService.create(dto);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Require ALL permissions (AND logic)
|
|
129
|
+
@Post(':id/approve')
|
|
130
|
+
@RequirePermissions(['orders:read', 'orders:approve'])
|
|
131
|
+
async approveOrder(@Param('id') id: string) {
|
|
132
|
+
return this.orderService.approve(id);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Require ANY of the permissions (OR logic)
|
|
136
|
+
@Delete(':id')
|
|
137
|
+
@RequirePermissions(['orders:delete', 'admin:full'], { mode: 'any' })
|
|
138
|
+
async deleteOrder(@Param('id') id: string) {
|
|
139
|
+
return this.orderService.delete(id);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Using alias decorators for clarity
|
|
143
|
+
@Post(':id/export')
|
|
144
|
+
@RequireAllPermissions(['orders:read', 'orders:export'])
|
|
145
|
+
async exportOrder(@Param('id') id: string) {
|
|
146
|
+
return this.orderService.export(id);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
@Post(':id/cancel')
|
|
150
|
+
@RequireAnyPermission(['orders:cancel', 'orders:manage'])
|
|
151
|
+
async cancelOrder(@Param('id') id: string) {
|
|
152
|
+
return this.orderService.cancel(id);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## API Reference
|
|
158
|
+
|
|
159
|
+
### PermissionsGrpcClient
|
|
160
|
+
|
|
161
|
+
| Method | Description |
|
|
162
|
+
| --------------------------------------------------------- | --------------------------------------------------- |
|
|
163
|
+
| `hasPermission(userId, permissionCode)` | Returns `boolean` - does user have this permission? |
|
|
164
|
+
| `hasAllPermissions(userId, permissionCodes)` | Returns `boolean` - does user have ALL permissions? |
|
|
165
|
+
| `hasAnyPermission(userId, permissionCodes)` | Returns `boolean` - does user have ANY permission? |
|
|
166
|
+
| `checkPermission(userId, permissionCode, options?)` | Returns full `EvaluationResult` with details |
|
|
167
|
+
| `checkBulkPermissions(userId, permissionCodes, options?)` | Returns results for multiple permissions |
|
|
168
|
+
| `getEffectivePermissions(userId)` | Returns all permissions and roles for a user |
|
|
169
|
+
|
|
170
|
+
### Decorators
|
|
171
|
+
|
|
172
|
+
| Decorator | Description |
|
|
173
|
+
| -------------------------------------------- | -------------------------------------------- |
|
|
174
|
+
| `@RequirePermissions(permissions, options?)` | Require permission(s) with configurable mode |
|
|
175
|
+
| `@RequireAllPermissions(permissions)` | Shorthand for mode: 'all' |
|
|
176
|
+
| `@RequireAnyPermission(permissions)` | Shorthand for mode: 'any' |
|
|
177
|
+
|
|
178
|
+
### Options
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
interface RequirePermissionsOptions {
|
|
182
|
+
// 'all' = user must have ALL permissions (default)
|
|
183
|
+
// 'any' = user must have at least ONE permission
|
|
184
|
+
mode?: 'all' | 'any';
|
|
185
|
+
|
|
186
|
+
// Custom error message when denied
|
|
187
|
+
errorMessage?: string;
|
|
188
|
+
|
|
189
|
+
// Include request params as resource context for ABAC
|
|
190
|
+
includeResourceContext?: boolean;
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Advanced Usage
|
|
195
|
+
|
|
196
|
+
### Full Evaluation Result
|
|
197
|
+
|
|
198
|
+
Get detailed information about permission decisions:
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
const result = await this.permissions.checkPermission(userId, 'orders:create');
|
|
202
|
+
|
|
203
|
+
console.log(result);
|
|
204
|
+
// {
|
|
205
|
+
// allowed: true,
|
|
206
|
+
// source: 'rbac', // 'rbac' | 'abac' | 'break-glass' | 'denied'
|
|
207
|
+
// matchedRoles: ['ADMIN'],
|
|
208
|
+
// matchedPolicies: [],
|
|
209
|
+
// reason: 'Permission granted via role(s): ADMIN',
|
|
210
|
+
// evaluationTimeMs: 3
|
|
211
|
+
// }
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### ABAC Context
|
|
215
|
+
|
|
216
|
+
Pass resource and request context for attribute-based access control:
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
const result = await this.permissions.checkPermission(userId, 'documents:read', {
|
|
220
|
+
resource: {
|
|
221
|
+
id: 'doc-123',
|
|
222
|
+
type: 'document',
|
|
223
|
+
ownerId: 'user-456',
|
|
224
|
+
department: 'engineering',
|
|
225
|
+
},
|
|
226
|
+
request: {
|
|
227
|
+
ip: '192.168.1.100',
|
|
228
|
+
method: 'GET',
|
|
229
|
+
path: '/api/documents/doc-123',
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Get All User Permissions
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
const effective = await this.permissions.getEffectivePermissions(userId);
|
|
238
|
+
|
|
239
|
+
console.log(effective);
|
|
240
|
+
// {
|
|
241
|
+
// permissions: ['users:read', 'users:create', 'orders:read'],
|
|
242
|
+
// roles: [
|
|
243
|
+
// { id: '...', code: 'USER', name: 'User', isSystem: false },
|
|
244
|
+
// { id: '...', code: 'ORDER_VIEWER', name: 'Order Viewer', isSystem: false }
|
|
245
|
+
// ],
|
|
246
|
+
// version: 1,
|
|
247
|
+
// computedAt: Date
|
|
248
|
+
// }
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Environment Variables
|
|
252
|
+
|
|
253
|
+
| Variable | Description | Default |
|
|
254
|
+
| ------------------------- | ------------------- | ----------------- |
|
|
255
|
+
| `PERMISSIONS_SERVICE_URL` | gRPC server address | `localhost:50051` |
|
|
256
|
+
|
|
257
|
+
## Error Handling
|
|
258
|
+
|
|
259
|
+
The guard throws `ForbiddenException` when permission is denied:
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
// Default error
|
|
263
|
+
throw new ForbiddenException('Access denied. Required permission(s): orders:create');
|
|
264
|
+
|
|
265
|
+
// Custom error message
|
|
266
|
+
@RequirePermissions('orders:create', {
|
|
267
|
+
errorMessage: 'You need order creation privileges'
|
|
268
|
+
})
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Request Requirements
|
|
272
|
+
|
|
273
|
+
The `PermissionsGuard` expects the request to have a `user` object with an `id` property (typically set by your JWT auth guard):
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
interface Request {
|
|
277
|
+
user: {
|
|
278
|
+
id: string; // Required - the user ID to check permissions for
|
|
279
|
+
// ... other properties
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## Important Note
|
|
285
|
+
|
|
286
|
+
This SDK is a client for the AHK Solution Permissions Microservice. It will not function without a running instance of the permissions service exposing a gRPC endpoint. The SDK only provides the client-side integration.
|
|
287
|
+
|
|
288
|
+
## License
|
|
289
|
+
|
|
290
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./permissions-client.module"), exports);
|
|
18
|
+
__exportStar(require("./permissions-grpc.client"), exports);
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8DAA4C;AAC5C,4DAA0C"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { DynamicModule } from '@nestjs/common';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration options for the Permissions Client Module
|
|
4
|
+
*/
|
|
5
|
+
export interface PermissionsClientModuleOptions {
|
|
6
|
+
/**
|
|
7
|
+
* gRPC server URL (host:port)
|
|
8
|
+
* @default 'localhost:50051'
|
|
9
|
+
*/
|
|
10
|
+
url?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Path to the proto file
|
|
13
|
+
* @default Uses the bundled proto file from the SDK
|
|
14
|
+
*/
|
|
15
|
+
protoPath?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Async configuration options for the Permissions Client Module
|
|
19
|
+
*/
|
|
20
|
+
export interface PermissionsClientModuleAsyncOptions {
|
|
21
|
+
/**
|
|
22
|
+
* Imports required for the factory function
|
|
23
|
+
*/
|
|
24
|
+
imports?: DynamicModule['imports'];
|
|
25
|
+
/**
|
|
26
|
+
* Factory function to create the module options
|
|
27
|
+
*/
|
|
28
|
+
useFactory: (...args: unknown[]) => PermissionsClientModuleOptions | Promise<PermissionsClientModuleOptions>;
|
|
29
|
+
/**
|
|
30
|
+
* Dependencies to inject into the factory function
|
|
31
|
+
*/
|
|
32
|
+
inject?: unknown[];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* NestJS module for integrating the Permissions gRPC client
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* // Synchronous configuration
|
|
40
|
+
* @Module({
|
|
41
|
+
* imports: [
|
|
42
|
+
* PermissionsClientModule.register({
|
|
43
|
+
* url: 'permissions-service:50051',
|
|
44
|
+
* }),
|
|
45
|
+
* ],
|
|
46
|
+
* })
|
|
47
|
+
* export class AppModule {}
|
|
48
|
+
*
|
|
49
|
+
* // Async configuration with ConfigService
|
|
50
|
+
* @Module({
|
|
51
|
+
* imports: [
|
|
52
|
+
* PermissionsClientModule.registerAsync({
|
|
53
|
+
* imports: [ConfigModule],
|
|
54
|
+
* useFactory: (config: ConfigService) => ({
|
|
55
|
+
* url: config.get('PERMISSIONS_SERVICE_URL'),
|
|
56
|
+
* }),
|
|
57
|
+
* inject: [ConfigService],
|
|
58
|
+
* }),
|
|
59
|
+
* ],
|
|
60
|
+
* })
|
|
61
|
+
* export class AppModule {}
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export declare class PermissionsClientModule {
|
|
65
|
+
/**
|
|
66
|
+
* Register the module with static configuration
|
|
67
|
+
*/
|
|
68
|
+
static register(options?: PermissionsClientModuleOptions): DynamicModule;
|
|
69
|
+
/**
|
|
70
|
+
* Register the module with async configuration
|
|
71
|
+
*/
|
|
72
|
+
static registerAsync(options: PermissionsClientModuleAsyncOptions): DynamicModule;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=permissions-client.module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions-client.module.d.ts","sourceRoot":"","sources":["../../src/client/permissions-client.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,MAAM,gBAAgB,CAAC;AAWvD;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC7C;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,mCAAmC;IAClD;;OAEG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAEnC;;OAEG;IACH,UAAU,EAAE,CACV,GAAG,IAAI,EAAE,OAAO,EAAE,KACf,8BAA8B,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC;IAE9E;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBACa,uBAAuB;IAClC;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,8BAA8B,GAAG,aAAa;IAwBxE;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,mCAAmC,GAAG,aAAa;CA+BlF"}
|
|
@@ -0,0 +1,109 @@
|
|
|
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 PermissionsClientModule_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.PermissionsClientModule = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const microservices_1 = require("@nestjs/microservices");
|
|
13
|
+
const path_1 = require("path");
|
|
14
|
+
const constants_1 = require("../constants");
|
|
15
|
+
const permissions_grpc_client_1 = require("./permissions-grpc.client");
|
|
16
|
+
/**
|
|
17
|
+
* NestJS module for integrating the Permissions gRPC client
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* // Synchronous configuration
|
|
22
|
+
* @Module({
|
|
23
|
+
* imports: [
|
|
24
|
+
* PermissionsClientModule.register({
|
|
25
|
+
* url: 'permissions-service:50051',
|
|
26
|
+
* }),
|
|
27
|
+
* ],
|
|
28
|
+
* })
|
|
29
|
+
* export class AppModule {}
|
|
30
|
+
*
|
|
31
|
+
* // Async configuration with ConfigService
|
|
32
|
+
* @Module({
|
|
33
|
+
* imports: [
|
|
34
|
+
* PermissionsClientModule.registerAsync({
|
|
35
|
+
* imports: [ConfigModule],
|
|
36
|
+
* useFactory: (config: ConfigService) => ({
|
|
37
|
+
* url: config.get('PERMISSIONS_SERVICE_URL'),
|
|
38
|
+
* }),
|
|
39
|
+
* inject: [ConfigService],
|
|
40
|
+
* }),
|
|
41
|
+
* ],
|
|
42
|
+
* })
|
|
43
|
+
* export class AppModule {}
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
let PermissionsClientModule = PermissionsClientModule_1 = class PermissionsClientModule {
|
|
47
|
+
/**
|
|
48
|
+
* Register the module with static configuration
|
|
49
|
+
*/
|
|
50
|
+
static register(options) {
|
|
51
|
+
const url = options?.url ?? constants_1.DEFAULT_GRPC_OPTIONS.url;
|
|
52
|
+
const protoPath = options?.protoPath ?? (0, path_1.join)(__dirname, '..', 'proto', 'permissions.proto');
|
|
53
|
+
return {
|
|
54
|
+
module: PermissionsClientModule_1,
|
|
55
|
+
imports: [
|
|
56
|
+
microservices_1.ClientsModule.register([
|
|
57
|
+
{
|
|
58
|
+
name: constants_1.PERMISSIONS_GRPC_CLIENT,
|
|
59
|
+
transport: microservices_1.Transport.GRPC,
|
|
60
|
+
options: {
|
|
61
|
+
url,
|
|
62
|
+
package: constants_1.PERMISSIONS_PACKAGE_NAME,
|
|
63
|
+
protoPath,
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
]),
|
|
67
|
+
],
|
|
68
|
+
providers: [permissions_grpc_client_1.PermissionsGrpcClient],
|
|
69
|
+
exports: [permissions_grpc_client_1.PermissionsGrpcClient],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Register the module with async configuration
|
|
74
|
+
*/
|
|
75
|
+
static registerAsync(options) {
|
|
76
|
+
return {
|
|
77
|
+
module: PermissionsClientModule_1,
|
|
78
|
+
imports: [
|
|
79
|
+
...(options.imports ?? []),
|
|
80
|
+
microservices_1.ClientsModule.registerAsync([
|
|
81
|
+
{
|
|
82
|
+
name: constants_1.PERMISSIONS_GRPC_CLIENT,
|
|
83
|
+
useFactory: async (...args) => {
|
|
84
|
+
const config = await options.useFactory(...args);
|
|
85
|
+
const url = config.url ?? constants_1.DEFAULT_GRPC_OPTIONS.url;
|
|
86
|
+
const protoPath = config.protoPath ?? (0, path_1.join)(__dirname, '..', 'proto', 'permissions.proto');
|
|
87
|
+
return {
|
|
88
|
+
transport: microservices_1.Transport.GRPC,
|
|
89
|
+
options: {
|
|
90
|
+
url,
|
|
91
|
+
package: constants_1.PERMISSIONS_PACKAGE_NAME,
|
|
92
|
+
protoPath,
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
},
|
|
96
|
+
inject: options.inject ?? [],
|
|
97
|
+
},
|
|
98
|
+
]),
|
|
99
|
+
],
|
|
100
|
+
providers: [permissions_grpc_client_1.PermissionsGrpcClient],
|
|
101
|
+
exports: [permissions_grpc_client_1.PermissionsGrpcClient],
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
exports.PermissionsClientModule = PermissionsClientModule;
|
|
106
|
+
exports.PermissionsClientModule = PermissionsClientModule = PermissionsClientModule_1 = __decorate([
|
|
107
|
+
(0, common_1.Module)({})
|
|
108
|
+
], PermissionsClientModule);
|
|
109
|
+
//# sourceMappingURL=permissions-client.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions-client.module.js","sourceRoot":"","sources":["../../src/client/permissions-client.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAuD;AACvD,yDAAiE;AACjE,+BAA4B;AAE5B,4CAIsB;AACtB,uEAAkE;AAyClE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEI,IAAM,uBAAuB,+BAA7B,MAAM,uBAAuB;IAClC;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,OAAwC;QACtD,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,gCAAoB,CAAC,GAAG,CAAC;QACrD,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,IAAA,WAAI,EAAC,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAAC;QAE5F,OAAO;YACL,MAAM,EAAE,yBAAuB;YAC/B,OAAO,EAAE;gBACP,6BAAa,CAAC,QAAQ,CAAC;oBACrB;wBACE,IAAI,EAAE,mCAAuB;wBAC7B,SAAS,EAAE,yBAAS,CAAC,IAAI;wBACzB,OAAO,EAAE;4BACP,GAAG;4BACH,OAAO,EAAE,oCAAwB;4BACjC,SAAS;yBACV;qBACF;iBACF,CAAC;aACH;YACD,SAAS,EAAE,CAAC,+CAAqB,CAAC;YAClC,OAAO,EAAE,CAAC,+CAAqB,CAAC;SACjC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,OAA4C;QAC/D,OAAO;YACL,MAAM,EAAE,yBAAuB;YAC/B,OAAO,EAAE;gBACP,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;gBAC1B,6BAAa,CAAC,aAAa,CAAC;oBAC1B;wBACE,IAAI,EAAE,mCAAuB;wBAC7B,UAAU,EAAE,KAAK,EAAE,GAAG,IAAe,EAAE,EAAE;4BACvC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC;4BACjD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,IAAI,gCAAoB,CAAC,GAAG,CAAC;4BACnD,MAAM,SAAS,GACb,MAAM,CAAC,SAAS,IAAI,IAAA,WAAI,EAAC,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAAC;4BAE1E,OAAO;gCACL,SAAS,EAAE,yBAAS,CAAC,IAAI;gCACzB,OAAO,EAAE;oCACP,GAAG;oCACH,OAAO,EAAE,oCAAwB;oCACjC,SAAS;iCACV;6BACF,CAAC;wBACJ,CAAC;wBACD,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;qBAC7B;iBACF,CAAC;aACH;YACD,SAAS,EAAE,CAAC,+CAAqB,CAAC;YAClC,OAAO,EAAE,CAAC,+CAAqB,CAAC;SACjC,CAAC;IACJ,CAAC;CACF,CAAA;AA9DY,0DAAuB;kCAAvB,uBAAuB;IADnC,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,uBAAuB,CA8DnC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { OnModuleInit } from '@nestjs/common';
|
|
2
|
+
import { ClientGrpc } from '@nestjs/microservices';
|
|
3
|
+
import type { BulkPermissionResultRecord, EffectivePermissions, EvaluationResult, RequestContext, ResourceContext } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* gRPC client for the Permissions Service
|
|
6
|
+
* Provides methods to check permissions via gRPC calls to the permissions microservice
|
|
7
|
+
*/
|
|
8
|
+
export declare class PermissionsGrpcClient implements OnModuleInit {
|
|
9
|
+
private readonly client;
|
|
10
|
+
private readonly logger;
|
|
11
|
+
private permissionsService;
|
|
12
|
+
constructor(client: ClientGrpc);
|
|
13
|
+
onModuleInit(): void;
|
|
14
|
+
/**
|
|
15
|
+
* Check if a user has a specific permission
|
|
16
|
+
*/
|
|
17
|
+
checkPermission(userId: string, permissionCode: string, options?: {
|
|
18
|
+
resource?: ResourceContext;
|
|
19
|
+
request?: RequestContext;
|
|
20
|
+
}): Promise<EvaluationResult>;
|
|
21
|
+
/**
|
|
22
|
+
* Check multiple permissions at once
|
|
23
|
+
*/
|
|
24
|
+
checkBulkPermissions(userId: string, permissionCodes: string[], options?: {
|
|
25
|
+
resource?: ResourceContext;
|
|
26
|
+
request?: RequestContext;
|
|
27
|
+
}): Promise<BulkPermissionResultRecord>;
|
|
28
|
+
/**
|
|
29
|
+
* Get all effective permissions for a user
|
|
30
|
+
*/
|
|
31
|
+
getEffectivePermissions(userId: string): Promise<EffectivePermissions>;
|
|
32
|
+
/**
|
|
33
|
+
* Simple boolean check - does user have this permission?
|
|
34
|
+
*/
|
|
35
|
+
hasPermission(userId: string, permissionCode: string): Promise<boolean>;
|
|
36
|
+
/**
|
|
37
|
+
* Check if user has ALL of the specified permissions
|
|
38
|
+
*/
|
|
39
|
+
hasAllPermissions(userId: string, permissionCodes: string[]): Promise<boolean>;
|
|
40
|
+
/**
|
|
41
|
+
* Check if user has ANY of the specified permissions
|
|
42
|
+
*/
|
|
43
|
+
hasAnyPermission(userId: string, permissionCodes: string[]): Promise<boolean>;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=permissions-grpc.client.d.ts.map
|
|
@@ -0,0 +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,EAEhB,cAAc,EACd,eAAe,EAChB,MAAM,UAAU,CAAC;AAkGlB;;;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;CAMpF"}
|