exguard-endpoint 1.0.1

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 ADDED
@@ -0,0 +1,71 @@
1
+ # ExGuard Endpoint
2
+
3
+ Simple RBAC permission guard for NestJS.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install exguard-endpoint
9
+ ```
10
+
11
+ ## Quick Setup
12
+
13
+ ### 1. Configure AppModule
14
+
15
+ ```typescript
16
+ import { Module } from '@nestjs/common';
17
+ import { ExGuardModule } from 'exguard-endpoint';
18
+
19
+ @Module({
20
+ imports: [
21
+ ExGuardModule.forRoot({
22
+ baseUrl: 'https://api.exguard.com',
23
+ apiKey: process.env.EXGUARD_API_KEY,
24
+ }),
25
+ ],
26
+ })
27
+ export class AppModule {}
28
+ ```
29
+
30
+ ### 2. Use in Controllers
31
+
32
+ ```typescript
33
+ import { Controller, Get, Post, UseGuards } from '@nestjs/common';
34
+ import { ExGuardPermissionGuard, RequirePermissions } from 'exguard-endpoint';
35
+
36
+ @Controller('items')
37
+ @UseGuards(ExGuardPermissionGuard)
38
+ export class ItemsController {
39
+
40
+ // User needs ANY of these permissions
41
+ @Get()
42
+ @RequirePermissions(['item:read'])
43
+ findAll() { }
44
+
45
+ @Post()
46
+ @RequirePermissions(['item:create'])
47
+ create() { }
48
+
49
+ // Multiple permissions - needs ALL
50
+ @Delete(':id')
51
+ @RequirePermissions(['item:delete', 'admin'], true)
52
+ delete() { }
53
+ }
54
+ ```
55
+
56
+ ## Decorators
57
+
58
+ | Decorator | Description |
59
+ |-----------|-------------|
60
+ | `@RequirePermissions(['perm1'])` | User needs ANY of the permissions |
61
+ | `@RequirePermissions(['perm1', 'perm2'], true)` | User needs ALL permissions |
62
+
63
+ ## Token
64
+
65
+ The guard extracts token from:
66
+ - `Authorization: Bearer <token>` header
67
+ - `x-access-token` header
68
+
69
+ ## License
70
+
71
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,238 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var __decorateClass = (decorators, target, key, kind) => {
20
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
21
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
22
+ if (decorator = decorators[i])
23
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
24
+ if (kind && result) __defProp(target, key, result);
25
+ return result;
26
+ };
27
+ var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
28
+
29
+ // src/index.ts
30
+ var src_exports = {};
31
+ __export(src_exports, {
32
+ EXGUARD_PERMISSIONS_KEY: () => EXGUARD_PERMISSIONS_KEY,
33
+ EXGUARD_ROLES_KEY: () => EXGUARD_ROLES_KEY,
34
+ ExGuardClient: () => ExGuardClient,
35
+ ExGuardModule: () => ExGuardModule,
36
+ ExGuardPermissionGuard: () => ExGuardPermissionGuard,
37
+ RequirePermissions: () => RequirePermissions,
38
+ RequireRoles: () => RequireRoles,
39
+ cache: () => cache,
40
+ createExGuardClient: () => createExGuardClient
41
+ });
42
+ module.exports = __toCommonJS(src_exports);
43
+
44
+ // src/client.ts
45
+ var ExGuardCache = class {
46
+ constructor() {
47
+ this.cache = /* @__PURE__ */ new Map();
48
+ this.ttl = 3e5;
49
+ }
50
+ get(key) {
51
+ const entry = this.cache.get(key);
52
+ if (!entry) return null;
53
+ if (Date.now() - entry.timestamp > entry.ttl) {
54
+ this.cache.delete(key);
55
+ return null;
56
+ }
57
+ return entry.data;
58
+ }
59
+ set(key, data, ttl) {
60
+ this.cache.set(key, {
61
+ data,
62
+ timestamp: Date.now(),
63
+ ttl: ttl || this.ttl
64
+ });
65
+ }
66
+ };
67
+ var cache = new ExGuardCache();
68
+ var ExGuardClient = class {
69
+ constructor(config) {
70
+ this.baseUrl = config.baseUrl;
71
+ this.apiKey = config.apiKey;
72
+ this.cache = cache;
73
+ }
74
+ async authenticate(context) {
75
+ const cacheKey = `auth:${context.token}`;
76
+ const cached = this.cache.get(cacheKey);
77
+ if (cached) return cached;
78
+ try {
79
+ const response = await fetch(`${this.baseUrl}/api/v1/auth/validate`, {
80
+ method: "POST",
81
+ headers: {
82
+ "Content-Type": "application/json",
83
+ "Authorization": `Bearer ${this.apiKey}`
84
+ },
85
+ body: JSON.stringify({ token: context.token })
86
+ });
87
+ if (!response.ok) {
88
+ return { allowed: false, error: "Invalid token" };
89
+ }
90
+ const data = await response.json();
91
+ const result = {
92
+ allowed: true,
93
+ user: data.user || data.data?.user
94
+ };
95
+ this.cache.set(cacheKey, result);
96
+ return result;
97
+ } catch (error) {
98
+ return { allowed: false, error: "Authentication failed" };
99
+ }
100
+ }
101
+ async hasPermission(token, permission) {
102
+ const result = await this.authenticate({ token });
103
+ if (!result.allowed || !result.user) return false;
104
+ const userPermissions = result.user.modules?.flatMap((m) => m.permissions) || [];
105
+ return userPermissions.includes(permission);
106
+ }
107
+ };
108
+ function createExGuardClient(config) {
109
+ return new ExGuardClient(config);
110
+ }
111
+
112
+ // src/module.ts
113
+ var import_common = require("@nestjs/common");
114
+ var ExGuardModule = class {
115
+ static forRoot(options) {
116
+ const client = new ExGuardClient({
117
+ baseUrl: options.baseUrl,
118
+ apiKey: options.apiKey,
119
+ cache: options.cache
120
+ });
121
+ return {
122
+ module: ExGuardModule,
123
+ providers: [
124
+ {
125
+ provide: "EXGUARD_CLIENT",
126
+ useValue: client
127
+ }
128
+ ],
129
+ exports: ["EXGUARD_CLIENT"]
130
+ };
131
+ }
132
+ };
133
+ ExGuardModule = __decorateClass([
134
+ (0, import_common.Global)(),
135
+ (0, import_common.Module)({})
136
+ ], ExGuardModule);
137
+
138
+ // src/guard.ts
139
+ var import_common2 = require("@nestjs/common");
140
+ var EXGUARD_PERMISSIONS_KEY = "exguard_permissions";
141
+ var EXGUARD_ROLES_KEY = "exguard_roles";
142
+ var ExGuardPermissionGuard = class {
143
+ constructor(client, reflector) {
144
+ this.client = client;
145
+ this.reflector = reflector;
146
+ }
147
+ async canActivate(context) {
148
+ const request = context.switchToHttp().getRequest();
149
+ const token = this.extractToken(request);
150
+ if (!token) {
151
+ throw new import_common2.UnauthorizedException("No token provided");
152
+ }
153
+ if (!this.client) {
154
+ return true;
155
+ }
156
+ const authResult = await this.client.authenticate({ token, request });
157
+ if (!authResult.allowed) {
158
+ throw new import_common2.ForbiddenException(authResult.error || "Access denied");
159
+ }
160
+ if (!authResult.user) {
161
+ throw new import_common2.ForbiddenException("User not found");
162
+ }
163
+ const handler = context.getHandler();
164
+ const permMeta = this.reflector.get(
165
+ EXGUARD_PERMISSIONS_KEY,
166
+ handler
167
+ );
168
+ if (permMeta) {
169
+ const { permissions, requireAll } = permMeta;
170
+ const userPermissions = authResult.user.modules?.flatMap((m) => m.permissions) || [];
171
+ if (requireAll) {
172
+ if (!permissions.every((p) => userPermissions.includes(p))) {
173
+ throw new import_common2.ForbiddenException("Insufficient permissions");
174
+ }
175
+ } else {
176
+ if (!permissions.some((p) => userPermissions.includes(p))) {
177
+ throw new import_common2.ForbiddenException("Insufficient permissions");
178
+ }
179
+ }
180
+ }
181
+ const roleMeta = this.reflector.get(
182
+ EXGUARD_ROLES_KEY,
183
+ handler
184
+ );
185
+ if (roleMeta) {
186
+ const { roles, requireAll } = roleMeta;
187
+ const userRoles = authResult.user.roles || [];
188
+ if (requireAll) {
189
+ if (!roles.every((r) => userRoles.includes(r))) {
190
+ throw new import_common2.ForbiddenException("Insufficient roles");
191
+ }
192
+ } else {
193
+ if (!roles.some((r) => userRoles.includes(r))) {
194
+ throw new import_common2.ForbiddenException("Insufficient roles");
195
+ }
196
+ }
197
+ }
198
+ request.user = authResult.user;
199
+ return true;
200
+ }
201
+ extractToken(request) {
202
+ const auth = request.headers?.authorization;
203
+ if (auth?.startsWith("Bearer ")) {
204
+ return auth.substring(7);
205
+ }
206
+ return request.headers?.["x-access-token"] || null;
207
+ }
208
+ };
209
+ ExGuardPermissionGuard = __decorateClass([
210
+ (0, import_common2.Injectable)(),
211
+ __decorateParam(0, (0, import_common2.Optional)()),
212
+ __decorateParam(0, (0, import_common2.Inject)("EXGUARD_CLIENT"))
213
+ ], ExGuardPermissionGuard);
214
+ function RequirePermissions(permissions, requireAll = false) {
215
+ return function(target, propertyKey, descriptor) {
216
+ Reflect.defineMetadata(EXGUARD_PERMISSIONS_KEY, { permissions, requireAll }, descriptor.value);
217
+ return descriptor;
218
+ };
219
+ }
220
+ function RequireRoles(roles, requireAll = false) {
221
+ return function(target, propertyKey, descriptor) {
222
+ Reflect.defineMetadata(EXGUARD_ROLES_KEY, { roles, requireAll }, descriptor.value);
223
+ return descriptor;
224
+ };
225
+ }
226
+ // Annotate the CommonJS export names for ESM import in node:
227
+ 0 && (module.exports = {
228
+ EXGUARD_PERMISSIONS_KEY,
229
+ EXGUARD_ROLES_KEY,
230
+ ExGuardClient,
231
+ ExGuardModule,
232
+ ExGuardPermissionGuard,
233
+ RequirePermissions,
234
+ RequireRoles,
235
+ cache,
236
+ createExGuardClient
237
+ });
238
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/module.ts","../src/guard.ts"],"sourcesContent":["export { ExGuardClient, createExGuardClient, cache } from './client.js';\nexport type { ExGuardConfig, User, ModulePermission, UserAccessResponse, GuardContext, GuardResult } from './client.js';\nexport { ExGuardModule } from './module.js';\nexport type { ExGuardModuleOptions } from './module.js';\nexport { ExGuardPermissionGuard, RequirePermissions, RequireRoles, EXGUARD_PERMISSIONS_KEY, EXGUARD_ROLES_KEY } from './guard.js';\n","export interface ExGuardConfig {\n baseUrl: string;\n apiKey: string;\n cache?: {\n enabled?: boolean;\n ttl?: number;\n };\n}\n\nexport interface User {\n id: string;\n username: string;\n email: string;\n}\n\nexport interface ModulePermission {\n key: string;\n name: string;\n permissions: string[];\n}\n\nexport interface UserAccessResponse {\n user: User;\n roles: string[];\n modules: ModulePermission[];\n}\n\nexport interface GuardContext {\n token: string;\n request?: any;\n}\n\nexport interface GuardResult {\n allowed: boolean;\n user?: UserAccessResponse;\n error?: string;\n}\n\nclass ExGuardCache {\n private cache = new Map<string, { data: any; timestamp: number; ttl: number }>();\n private ttl = 300000;\n\n get(key: string): any {\n const entry = this.cache.get(key);\n if (!entry) return null;\n if (Date.now() - entry.timestamp > entry.ttl) {\n this.cache.delete(key);\n return null;\n }\n return entry.data;\n }\n\n set(key: string, data: any, ttl?: number): void {\n this.cache.set(key, {\n data,\n timestamp: Date.now(),\n ttl: ttl || this.ttl,\n });\n }\n}\n\nconst cache = new ExGuardCache();\n\nexport class ExGuardClient {\n private baseUrl: string;\n private apiKey: string;\n private cache: ExGuardCache;\n\n constructor(config: ExGuardConfig) {\n this.baseUrl = config.baseUrl;\n this.apiKey = config.apiKey;\n this.cache = cache;\n }\n\n async authenticate(context: GuardContext): Promise<GuardResult> {\n const cacheKey = `auth:${context.token}`;\n const cached = this.cache.get(cacheKey);\n if (cached) return cached;\n\n try {\n const response = await fetch(`${this.baseUrl}/api/v1/auth/validate`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({ token: context.token }),\n });\n\n if (!response.ok) {\n return { allowed: false, error: 'Invalid token' };\n }\n\n const data = await response.json();\n const result: GuardResult = {\n allowed: true,\n user: data.user || data.data?.user,\n };\n\n this.cache.set(cacheKey, result);\n return result;\n } catch (error) {\n return { allowed: false, error: 'Authentication failed' };\n }\n }\n\n async hasPermission(token: string, permission: string): Promise<boolean> {\n const result = await this.authenticate({ token });\n if (!result.allowed || !result.user) return false;\n\n const userPermissions = result.user.modules?.flatMap(m => m.permissions) || [];\n return userPermissions.includes(permission);\n }\n}\n\nexport function createExGuardClient(config: ExGuardConfig): ExGuardClient {\n return new ExGuardClient(config);\n}\n\nexport { cache };\n","import { Module, Global, DynamicModule } from '@nestjs/common';\nimport { ExGuardClient } from './client.js';\n\nexport interface ExGuardModuleOptions {\n baseUrl: string;\n apiKey: string;\n cache?: {\n enabled?: boolean;\n ttl?: number;\n };\n}\n\n@Global()\n@Module({})\nexport class ExGuardModule {\n static forRoot(options: ExGuardModuleOptions): DynamicModule {\n const client = new ExGuardClient({\n baseUrl: options.baseUrl,\n apiKey: options.apiKey,\n cache: options.cache,\n });\n\n return {\n module: ExGuardModule,\n providers: [\n {\n provide: 'EXGUARD_CLIENT',\n useValue: client,\n },\n ],\n exports: ['EXGUARD_CLIENT'],\n };\n }\n}\n","import { Injectable, CanActivate, ExecutionContext, UnauthorizedException, ForbiddenException, Inject, Optional } from '@nestjs/common';\nimport { Reflector } from '@nestjs/core';\nimport { ExGuardClient } from './client.js';\n\nexport const EXGUARD_PERMISSIONS_KEY = 'exguard_permissions';\nexport const EXGUARD_ROLES_KEY = 'exguard_roles';\n\n@Injectable()\nexport class ExGuardPermissionGuard implements CanActivate {\n constructor(\n @Optional() @Inject('EXGUARD_CLIENT') private client: ExGuardClient,\n private reflector: Reflector,\n ) {}\n\n async canActivate(context: ExecutionContext): Promise<boolean> {\n const request = context.switchToHttp().getRequest();\n const token = this.extractToken(request);\n\n if (!token) {\n throw new UnauthorizedException('No token provided');\n }\n\n if (!this.client) {\n return true;\n }\n\n const authResult = await this.client.authenticate({ token, request });\n\n if (!authResult.allowed) {\n throw new ForbiddenException(authResult.error || 'Access denied');\n }\n\n if (!authResult.user) {\n throw new ForbiddenException('User not found');\n }\n\n const handler = context.getHandler();\n const permMeta = this.reflector.get<{ permissions: string[]; requireAll?: boolean }>(\n EXGUARD_PERMISSIONS_KEY,\n handler,\n );\n\n if (permMeta) {\n const { permissions, requireAll } = permMeta;\n const userPermissions = authResult.user.modules?.flatMap(m => m.permissions) || [];\n\n if (requireAll) {\n if (!permissions.every(p => userPermissions.includes(p))) {\n throw new ForbiddenException('Insufficient permissions');\n }\n } else {\n if (!permissions.some(p => userPermissions.includes(p))) {\n throw new ForbiddenException('Insufficient permissions');\n }\n }\n }\n\n const roleMeta = this.reflector.get<{ roles: string[]; requireAll?: boolean }>(\n EXGUARD_ROLES_KEY,\n handler,\n );\n\n if (roleMeta) {\n const { roles, requireAll } = roleMeta;\n const userRoles = authResult.user.roles || [];\n\n if (requireAll) {\n if (!roles.every(r => userRoles.includes(r))) {\n throw new ForbiddenException('Insufficient roles');\n }\n } else {\n if (!roles.some(r => userRoles.includes(r))) {\n throw new ForbiddenException('Insufficient roles');\n }\n }\n }\n\n request.user = authResult.user;\n return true;\n }\n\n private extractToken(request: any): string | null {\n const auth = request.headers?.authorization;\n if (auth?.startsWith('Bearer ')) {\n return auth.substring(7);\n }\n return request.headers?.['x-access-token'] || null;\n }\n}\n\nexport function RequirePermissions(permissions: string[], requireAll = false) {\n return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n Reflect.defineMetadata(EXGUARD_PERMISSIONS_KEY, { permissions, requireAll }, descriptor.value);\n return descriptor;\n };\n}\n\nexport function RequireRoles(roles: string[], requireAll = false) {\n return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n Reflect.defineMetadata(EXGUARD_ROLES_KEY, { roles, requireAll }, descriptor.value);\n return descriptor;\n };\n}\n"],"mappings":"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","names":["import_common"]}
@@ -0,0 +1,77 @@
1
+ import { DynamicModule, CanActivate, ExecutionContext } from '@nestjs/common';
2
+ import { Reflector } from '@nestjs/core';
3
+
4
+ interface ExGuardConfig {
5
+ baseUrl: string;
6
+ apiKey: string;
7
+ cache?: {
8
+ enabled?: boolean;
9
+ ttl?: number;
10
+ };
11
+ }
12
+ interface User {
13
+ id: string;
14
+ username: string;
15
+ email: string;
16
+ }
17
+ interface ModulePermission {
18
+ key: string;
19
+ name: string;
20
+ permissions: string[];
21
+ }
22
+ interface UserAccessResponse {
23
+ user: User;
24
+ roles: string[];
25
+ modules: ModulePermission[];
26
+ }
27
+ interface GuardContext {
28
+ token: string;
29
+ request?: any;
30
+ }
31
+ interface GuardResult {
32
+ allowed: boolean;
33
+ user?: UserAccessResponse;
34
+ error?: string;
35
+ }
36
+ declare class ExGuardCache {
37
+ private cache;
38
+ private ttl;
39
+ get(key: string): any;
40
+ set(key: string, data: any, ttl?: number): void;
41
+ }
42
+ declare const cache: ExGuardCache;
43
+ declare class ExGuardClient {
44
+ private baseUrl;
45
+ private apiKey;
46
+ private cache;
47
+ constructor(config: ExGuardConfig);
48
+ authenticate(context: GuardContext): Promise<GuardResult>;
49
+ hasPermission(token: string, permission: string): Promise<boolean>;
50
+ }
51
+ declare function createExGuardClient(config: ExGuardConfig): ExGuardClient;
52
+
53
+ interface ExGuardModuleOptions {
54
+ baseUrl: string;
55
+ apiKey: string;
56
+ cache?: {
57
+ enabled?: boolean;
58
+ ttl?: number;
59
+ };
60
+ }
61
+ declare class ExGuardModule {
62
+ static forRoot(options: ExGuardModuleOptions): DynamicModule;
63
+ }
64
+
65
+ declare const EXGUARD_PERMISSIONS_KEY = "exguard_permissions";
66
+ declare const EXGUARD_ROLES_KEY = "exguard_roles";
67
+ declare class ExGuardPermissionGuard implements CanActivate {
68
+ private client;
69
+ private reflector;
70
+ constructor(client: ExGuardClient, reflector: Reflector);
71
+ canActivate(context: ExecutionContext): Promise<boolean>;
72
+ private extractToken;
73
+ }
74
+ declare function RequirePermissions(permissions: string[], requireAll?: boolean): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
75
+ declare function RequireRoles(roles: string[], requireAll?: boolean): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
76
+
77
+ export { EXGUARD_PERMISSIONS_KEY, EXGUARD_ROLES_KEY, ExGuardClient, type ExGuardConfig, ExGuardModule, type ExGuardModuleOptions, ExGuardPermissionGuard, type GuardContext, type GuardResult, type ModulePermission, RequirePermissions, RequireRoles, type User, type UserAccessResponse, cache, createExGuardClient };
@@ -0,0 +1,77 @@
1
+ import { DynamicModule, CanActivate, ExecutionContext } from '@nestjs/common';
2
+ import { Reflector } from '@nestjs/core';
3
+
4
+ interface ExGuardConfig {
5
+ baseUrl: string;
6
+ apiKey: string;
7
+ cache?: {
8
+ enabled?: boolean;
9
+ ttl?: number;
10
+ };
11
+ }
12
+ interface User {
13
+ id: string;
14
+ username: string;
15
+ email: string;
16
+ }
17
+ interface ModulePermission {
18
+ key: string;
19
+ name: string;
20
+ permissions: string[];
21
+ }
22
+ interface UserAccessResponse {
23
+ user: User;
24
+ roles: string[];
25
+ modules: ModulePermission[];
26
+ }
27
+ interface GuardContext {
28
+ token: string;
29
+ request?: any;
30
+ }
31
+ interface GuardResult {
32
+ allowed: boolean;
33
+ user?: UserAccessResponse;
34
+ error?: string;
35
+ }
36
+ declare class ExGuardCache {
37
+ private cache;
38
+ private ttl;
39
+ get(key: string): any;
40
+ set(key: string, data: any, ttl?: number): void;
41
+ }
42
+ declare const cache: ExGuardCache;
43
+ declare class ExGuardClient {
44
+ private baseUrl;
45
+ private apiKey;
46
+ private cache;
47
+ constructor(config: ExGuardConfig);
48
+ authenticate(context: GuardContext): Promise<GuardResult>;
49
+ hasPermission(token: string, permission: string): Promise<boolean>;
50
+ }
51
+ declare function createExGuardClient(config: ExGuardConfig): ExGuardClient;
52
+
53
+ interface ExGuardModuleOptions {
54
+ baseUrl: string;
55
+ apiKey: string;
56
+ cache?: {
57
+ enabled?: boolean;
58
+ ttl?: number;
59
+ };
60
+ }
61
+ declare class ExGuardModule {
62
+ static forRoot(options: ExGuardModuleOptions): DynamicModule;
63
+ }
64
+
65
+ declare const EXGUARD_PERMISSIONS_KEY = "exguard_permissions";
66
+ declare const EXGUARD_ROLES_KEY = "exguard_roles";
67
+ declare class ExGuardPermissionGuard implements CanActivate {
68
+ private client;
69
+ private reflector;
70
+ constructor(client: ExGuardClient, reflector: Reflector);
71
+ canActivate(context: ExecutionContext): Promise<boolean>;
72
+ private extractToken;
73
+ }
74
+ declare function RequirePermissions(permissions: string[], requireAll?: boolean): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
75
+ declare function RequireRoles(roles: string[], requireAll?: boolean): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
76
+
77
+ export { EXGUARD_PERMISSIONS_KEY, EXGUARD_ROLES_KEY, ExGuardClient, type ExGuardConfig, ExGuardModule, type ExGuardModuleOptions, ExGuardPermissionGuard, type GuardContext, type GuardResult, type ModulePermission, RequirePermissions, RequireRoles, type User, type UserAccessResponse, cache, createExGuardClient };
package/dist/index.js ADDED
@@ -0,0 +1,206 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __decorateClass = (decorators, target, key, kind) => {
4
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
5
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
6
+ if (decorator = decorators[i])
7
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
8
+ if (kind && result) __defProp(target, key, result);
9
+ return result;
10
+ };
11
+ var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
12
+
13
+ // src/client.ts
14
+ var ExGuardCache = class {
15
+ constructor() {
16
+ this.cache = /* @__PURE__ */ new Map();
17
+ this.ttl = 3e5;
18
+ }
19
+ get(key) {
20
+ const entry = this.cache.get(key);
21
+ if (!entry) return null;
22
+ if (Date.now() - entry.timestamp > entry.ttl) {
23
+ this.cache.delete(key);
24
+ return null;
25
+ }
26
+ return entry.data;
27
+ }
28
+ set(key, data, ttl) {
29
+ this.cache.set(key, {
30
+ data,
31
+ timestamp: Date.now(),
32
+ ttl: ttl || this.ttl
33
+ });
34
+ }
35
+ };
36
+ var cache = new ExGuardCache();
37
+ var ExGuardClient = class {
38
+ constructor(config) {
39
+ this.baseUrl = config.baseUrl;
40
+ this.apiKey = config.apiKey;
41
+ this.cache = cache;
42
+ }
43
+ async authenticate(context) {
44
+ const cacheKey = `auth:${context.token}`;
45
+ const cached = this.cache.get(cacheKey);
46
+ if (cached) return cached;
47
+ try {
48
+ const response = await fetch(`${this.baseUrl}/api/v1/auth/validate`, {
49
+ method: "POST",
50
+ headers: {
51
+ "Content-Type": "application/json",
52
+ "Authorization": `Bearer ${this.apiKey}`
53
+ },
54
+ body: JSON.stringify({ token: context.token })
55
+ });
56
+ if (!response.ok) {
57
+ return { allowed: false, error: "Invalid token" };
58
+ }
59
+ const data = await response.json();
60
+ const result = {
61
+ allowed: true,
62
+ user: data.user || data.data?.user
63
+ };
64
+ this.cache.set(cacheKey, result);
65
+ return result;
66
+ } catch (error) {
67
+ return { allowed: false, error: "Authentication failed" };
68
+ }
69
+ }
70
+ async hasPermission(token, permission) {
71
+ const result = await this.authenticate({ token });
72
+ if (!result.allowed || !result.user) return false;
73
+ const userPermissions = result.user.modules?.flatMap((m) => m.permissions) || [];
74
+ return userPermissions.includes(permission);
75
+ }
76
+ };
77
+ function createExGuardClient(config) {
78
+ return new ExGuardClient(config);
79
+ }
80
+
81
+ // src/module.ts
82
+ import { Module, Global } from "@nestjs/common";
83
+ var ExGuardModule = class {
84
+ static forRoot(options) {
85
+ const client = new ExGuardClient({
86
+ baseUrl: options.baseUrl,
87
+ apiKey: options.apiKey,
88
+ cache: options.cache
89
+ });
90
+ return {
91
+ module: ExGuardModule,
92
+ providers: [
93
+ {
94
+ provide: "EXGUARD_CLIENT",
95
+ useValue: client
96
+ }
97
+ ],
98
+ exports: ["EXGUARD_CLIENT"]
99
+ };
100
+ }
101
+ };
102
+ ExGuardModule = __decorateClass([
103
+ Global(),
104
+ Module({})
105
+ ], ExGuardModule);
106
+
107
+ // src/guard.ts
108
+ import { Injectable, UnauthorizedException, ForbiddenException, Inject, Optional } from "@nestjs/common";
109
+ var EXGUARD_PERMISSIONS_KEY = "exguard_permissions";
110
+ var EXGUARD_ROLES_KEY = "exguard_roles";
111
+ var ExGuardPermissionGuard = class {
112
+ constructor(client, reflector) {
113
+ this.client = client;
114
+ this.reflector = reflector;
115
+ }
116
+ async canActivate(context) {
117
+ const request = context.switchToHttp().getRequest();
118
+ const token = this.extractToken(request);
119
+ if (!token) {
120
+ throw new UnauthorizedException("No token provided");
121
+ }
122
+ if (!this.client) {
123
+ return true;
124
+ }
125
+ const authResult = await this.client.authenticate({ token, request });
126
+ if (!authResult.allowed) {
127
+ throw new ForbiddenException(authResult.error || "Access denied");
128
+ }
129
+ if (!authResult.user) {
130
+ throw new ForbiddenException("User not found");
131
+ }
132
+ const handler = context.getHandler();
133
+ const permMeta = this.reflector.get(
134
+ EXGUARD_PERMISSIONS_KEY,
135
+ handler
136
+ );
137
+ if (permMeta) {
138
+ const { permissions, requireAll } = permMeta;
139
+ const userPermissions = authResult.user.modules?.flatMap((m) => m.permissions) || [];
140
+ if (requireAll) {
141
+ if (!permissions.every((p) => userPermissions.includes(p))) {
142
+ throw new ForbiddenException("Insufficient permissions");
143
+ }
144
+ } else {
145
+ if (!permissions.some((p) => userPermissions.includes(p))) {
146
+ throw new ForbiddenException("Insufficient permissions");
147
+ }
148
+ }
149
+ }
150
+ const roleMeta = this.reflector.get(
151
+ EXGUARD_ROLES_KEY,
152
+ handler
153
+ );
154
+ if (roleMeta) {
155
+ const { roles, requireAll } = roleMeta;
156
+ const userRoles = authResult.user.roles || [];
157
+ if (requireAll) {
158
+ if (!roles.every((r) => userRoles.includes(r))) {
159
+ throw new ForbiddenException("Insufficient roles");
160
+ }
161
+ } else {
162
+ if (!roles.some((r) => userRoles.includes(r))) {
163
+ throw new ForbiddenException("Insufficient roles");
164
+ }
165
+ }
166
+ }
167
+ request.user = authResult.user;
168
+ return true;
169
+ }
170
+ extractToken(request) {
171
+ const auth = request.headers?.authorization;
172
+ if (auth?.startsWith("Bearer ")) {
173
+ return auth.substring(7);
174
+ }
175
+ return request.headers?.["x-access-token"] || null;
176
+ }
177
+ };
178
+ ExGuardPermissionGuard = __decorateClass([
179
+ Injectable(),
180
+ __decorateParam(0, Optional()),
181
+ __decorateParam(0, Inject("EXGUARD_CLIENT"))
182
+ ], ExGuardPermissionGuard);
183
+ function RequirePermissions(permissions, requireAll = false) {
184
+ return function(target, propertyKey, descriptor) {
185
+ Reflect.defineMetadata(EXGUARD_PERMISSIONS_KEY, { permissions, requireAll }, descriptor.value);
186
+ return descriptor;
187
+ };
188
+ }
189
+ function RequireRoles(roles, requireAll = false) {
190
+ return function(target, propertyKey, descriptor) {
191
+ Reflect.defineMetadata(EXGUARD_ROLES_KEY, { roles, requireAll }, descriptor.value);
192
+ return descriptor;
193
+ };
194
+ }
195
+ export {
196
+ EXGUARD_PERMISSIONS_KEY,
197
+ EXGUARD_ROLES_KEY,
198
+ ExGuardClient,
199
+ ExGuardModule,
200
+ ExGuardPermissionGuard,
201
+ RequirePermissions,
202
+ RequireRoles,
203
+ cache,
204
+ createExGuardClient
205
+ };
206
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client.ts","../src/module.ts","../src/guard.ts"],"sourcesContent":["export interface ExGuardConfig {\n baseUrl: string;\n apiKey: string;\n cache?: {\n enabled?: boolean;\n ttl?: number;\n };\n}\n\nexport interface User {\n id: string;\n username: string;\n email: string;\n}\n\nexport interface ModulePermission {\n key: string;\n name: string;\n permissions: string[];\n}\n\nexport interface UserAccessResponse {\n user: User;\n roles: string[];\n modules: ModulePermission[];\n}\n\nexport interface GuardContext {\n token: string;\n request?: any;\n}\n\nexport interface GuardResult {\n allowed: boolean;\n user?: UserAccessResponse;\n error?: string;\n}\n\nclass ExGuardCache {\n private cache = new Map<string, { data: any; timestamp: number; ttl: number }>();\n private ttl = 300000;\n\n get(key: string): any {\n const entry = this.cache.get(key);\n if (!entry) return null;\n if (Date.now() - entry.timestamp > entry.ttl) {\n this.cache.delete(key);\n return null;\n }\n return entry.data;\n }\n\n set(key: string, data: any, ttl?: number): void {\n this.cache.set(key, {\n data,\n timestamp: Date.now(),\n ttl: ttl || this.ttl,\n });\n }\n}\n\nconst cache = new ExGuardCache();\n\nexport class ExGuardClient {\n private baseUrl: string;\n private apiKey: string;\n private cache: ExGuardCache;\n\n constructor(config: ExGuardConfig) {\n this.baseUrl = config.baseUrl;\n this.apiKey = config.apiKey;\n this.cache = cache;\n }\n\n async authenticate(context: GuardContext): Promise<GuardResult> {\n const cacheKey = `auth:${context.token}`;\n const cached = this.cache.get(cacheKey);\n if (cached) return cached;\n\n try {\n const response = await fetch(`${this.baseUrl}/api/v1/auth/validate`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({ token: context.token }),\n });\n\n if (!response.ok) {\n return { allowed: false, error: 'Invalid token' };\n }\n\n const data = await response.json();\n const result: GuardResult = {\n allowed: true,\n user: data.user || data.data?.user,\n };\n\n this.cache.set(cacheKey, result);\n return result;\n } catch (error) {\n return { allowed: false, error: 'Authentication failed' };\n }\n }\n\n async hasPermission(token: string, permission: string): Promise<boolean> {\n const result = await this.authenticate({ token });\n if (!result.allowed || !result.user) return false;\n\n const userPermissions = result.user.modules?.flatMap(m => m.permissions) || [];\n return userPermissions.includes(permission);\n }\n}\n\nexport function createExGuardClient(config: ExGuardConfig): ExGuardClient {\n return new ExGuardClient(config);\n}\n\nexport { cache };\n","import { Module, Global, DynamicModule } from '@nestjs/common';\nimport { ExGuardClient } from './client.js';\n\nexport interface ExGuardModuleOptions {\n baseUrl: string;\n apiKey: string;\n cache?: {\n enabled?: boolean;\n ttl?: number;\n };\n}\n\n@Global()\n@Module({})\nexport class ExGuardModule {\n static forRoot(options: ExGuardModuleOptions): DynamicModule {\n const client = new ExGuardClient({\n baseUrl: options.baseUrl,\n apiKey: options.apiKey,\n cache: options.cache,\n });\n\n return {\n module: ExGuardModule,\n providers: [\n {\n provide: 'EXGUARD_CLIENT',\n useValue: client,\n },\n ],\n exports: ['EXGUARD_CLIENT'],\n };\n }\n}\n","import { Injectable, CanActivate, ExecutionContext, UnauthorizedException, ForbiddenException, Inject, Optional } from '@nestjs/common';\nimport { Reflector } from '@nestjs/core';\nimport { ExGuardClient } from './client.js';\n\nexport const EXGUARD_PERMISSIONS_KEY = 'exguard_permissions';\nexport const EXGUARD_ROLES_KEY = 'exguard_roles';\n\n@Injectable()\nexport class ExGuardPermissionGuard implements CanActivate {\n constructor(\n @Optional() @Inject('EXGUARD_CLIENT') private client: ExGuardClient,\n private reflector: Reflector,\n ) {}\n\n async canActivate(context: ExecutionContext): Promise<boolean> {\n const request = context.switchToHttp().getRequest();\n const token = this.extractToken(request);\n\n if (!token) {\n throw new UnauthorizedException('No token provided');\n }\n\n if (!this.client) {\n return true;\n }\n\n const authResult = await this.client.authenticate({ token, request });\n\n if (!authResult.allowed) {\n throw new ForbiddenException(authResult.error || 'Access denied');\n }\n\n if (!authResult.user) {\n throw new ForbiddenException('User not found');\n }\n\n const handler = context.getHandler();\n const permMeta = this.reflector.get<{ permissions: string[]; requireAll?: boolean }>(\n EXGUARD_PERMISSIONS_KEY,\n handler,\n );\n\n if (permMeta) {\n const { permissions, requireAll } = permMeta;\n const userPermissions = authResult.user.modules?.flatMap(m => m.permissions) || [];\n\n if (requireAll) {\n if (!permissions.every(p => userPermissions.includes(p))) {\n throw new ForbiddenException('Insufficient permissions');\n }\n } else {\n if (!permissions.some(p => userPermissions.includes(p))) {\n throw new ForbiddenException('Insufficient permissions');\n }\n }\n }\n\n const roleMeta = this.reflector.get<{ roles: string[]; requireAll?: boolean }>(\n EXGUARD_ROLES_KEY,\n handler,\n );\n\n if (roleMeta) {\n const { roles, requireAll } = roleMeta;\n const userRoles = authResult.user.roles || [];\n\n if (requireAll) {\n if (!roles.every(r => userRoles.includes(r))) {\n throw new ForbiddenException('Insufficient roles');\n }\n } else {\n if (!roles.some(r => userRoles.includes(r))) {\n throw new ForbiddenException('Insufficient roles');\n }\n }\n }\n\n request.user = authResult.user;\n return true;\n }\n\n private extractToken(request: any): string | null {\n const auth = request.headers?.authorization;\n if (auth?.startsWith('Bearer ')) {\n return auth.substring(7);\n }\n return request.headers?.['x-access-token'] || null;\n }\n}\n\nexport function RequirePermissions(permissions: string[], requireAll = false) {\n return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n Reflect.defineMetadata(EXGUARD_PERMISSIONS_KEY, { permissions, requireAll }, descriptor.value);\n return descriptor;\n };\n}\n\nexport function RequireRoles(roles: string[], requireAll = false) {\n return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n Reflect.defineMetadata(EXGUARD_ROLES_KEY, { roles, requireAll }, descriptor.value);\n return descriptor;\n };\n}\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "exguard-endpoint",
3
+ "version": "1.0.1",
4
+ "private": false,
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "type": "module",
9
+ "description": "Simple RBAC permission guard for NestJS",
10
+ "main": "./dist/index.cjs",
11
+ "module": "./dist/index.js",
12
+ "types": "./dist/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js",
17
+ "require": "./dist/index.cjs"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "scripts": {
24
+ "build": "tsup",
25
+ "clean": "node -e \"fs.rmSync('dist', { recursive: true, force: true })\"",
26
+ "prebuild": "npm run clean"
27
+ },
28
+ "keywords": [
29
+ "exguard",
30
+ "rbac",
31
+ "nestjs",
32
+ "permissions",
33
+ "guards"
34
+ ],
35
+ "author": "EmpowerX",
36
+ "license": "MIT",
37
+ "dependencies": {
38
+ "axios": "^1.0.0"
39
+ },
40
+ "devDependencies": {
41
+ "@nestjs/common": "^10.0.0",
42
+ "@nestjs/core": "^10.0.0",
43
+ "@types/node": "^22.10.5",
44
+ "tsup": "^8.3.5",
45
+ "typescript": "^5.7.3"
46
+ },
47
+ "peerDependencies": {
48
+ "@nestjs/common": "^10.0.0",
49
+ "@nestjs/core": "^10.0.0"
50
+ }
51
+ }