exguard-backend 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,201 @@
1
+ # ExGuard Backend SDK
2
+
3
+ A simple and lightweight backend SDK for integrating with EmpowerX Guard API to validate user roles and permissions.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install exguard-backend
9
+ # or
10
+ yarn add exguard-backend
11
+ # or
12
+ pnpm add exguard-backend
13
+ ```
14
+
15
+ ## Quick Start
16
+
17
+ ```typescript
18
+ import { ExGuardBackend } from 'exguard-backend';
19
+
20
+ // Initialize the SDK
21
+ const exGuard = new ExGuardBackend({
22
+ apiUrl: 'https://your-guard-api-url.com'
23
+ });
24
+
25
+ // Get user access information
26
+ async function checkUserAccess(token: string) {
27
+ try {
28
+ const userAccess = await exGuard.getUserAccess(token);
29
+ console.log('User roles:', userAccess.roles);
30
+ console.log('User permissions:', userAccess.modules);
31
+ } catch (error) {
32
+ console.error('Error:', error.message);
33
+ }
34
+ }
35
+ ```
36
+
37
+ ## API Reference
38
+
39
+ ### Constructor
40
+
41
+ ```typescript
42
+ new ExGuardBackend(config: ExGuardConfig)
43
+ ```
44
+
45
+ **Config:**
46
+ - `apiUrl` (string): Base URL of your Guard API
47
+ - `timeout` (number, optional): Request timeout in milliseconds (default: 10000)
48
+
49
+ ### Methods
50
+
51
+ #### `getUserAccess(token: string): Promise<UserAccessResponse>`
52
+
53
+ Get complete user access information including roles, permissions, and field offices.
54
+
55
+ **Returns:**
56
+ ```typescript
57
+ {
58
+ user: User,
59
+ groups: string[],
60
+ roles: string[],
61
+ module: string[],
62
+ modules: ModulePermission[],
63
+ fieldOffices: string[]
64
+ }
65
+ ```
66
+
67
+ #### `hasPermission(token: string, permission: string): Promise<boolean>`
68
+
69
+ Check if user has a specific permission.
70
+
71
+ **Example:**
72
+ ```typescript
73
+ const canCreateEvent = await exGuard.hasPermission(token, 'events:create');
74
+ ```
75
+
76
+ #### `hasRole(token: string, role: string): Promise<boolean>`
77
+
78
+ Check if user has a specific role.
79
+
80
+ **Example:**
81
+ ```typescript
82
+ const isEventManager = await exGuard.hasRole(token, 'Event Manager');
83
+ ```
84
+
85
+ #### `getModulePermissions(token: string, moduleKey: string): Promise<string[]>`
86
+
87
+ Get all permissions for a specific module.
88
+
89
+ **Example:**
90
+ ```typescript
91
+ const eventPermissions = await exGuard.getModulePermissions(token, 'events');
92
+ // Returns: ['events:create', 'events:read', 'events:update', 'events:delete']
93
+ ```
94
+
95
+ #### `getUserRoles(token: string): Promise<string[]>`
96
+
97
+ Get all user roles.
98
+
99
+ **Example:**
100
+ ```typescript
101
+ const roles = await exGuard.getUserRoles(token);
102
+ // Returns: ['Event Manager', 'Viewer']
103
+ ```
104
+
105
+ #### `getUserFieldOffices(token: string): Promise<string[]>`
106
+
107
+ Get all user field offices.
108
+
109
+ **Example:**
110
+ ```typescript
111
+ const fieldOffices = await exGuard.getUserFieldOffices(token);
112
+ // Returns: ['FO-MIMAROPA', 'FO-NCR']
113
+ ```
114
+
115
+ ## Usage Examples
116
+
117
+ ### Express.js Middleware
118
+
119
+ ```typescript
120
+ import express from 'express';
121
+ import { ExGuardBackend } from 'exguard-backend';
122
+
123
+ const app = express();
124
+ const exGuard = new ExGuardBackend({
125
+ apiUrl: process.env.GUARD_API_URL || 'http://localhost:3001'
126
+ });
127
+
128
+ // Middleware to check permissions
129
+ const requirePermission = (permission: string) => {
130
+ return async (req: express.Request, res: express.Response, next: express.NextFunction) => {
131
+ const token = req.headers.authorization?.replace('Bearer ', '');
132
+
133
+ if (!token) {
134
+ return res.status(401).json({ error: 'No token provided' });
135
+ }
136
+
137
+ try {
138
+ const hasPermission = await exGuard.hasPermission(token, permission);
139
+ if (!hasPermission) {
140
+ return res.status(403).json({ error: 'Insufficient permissions' });
141
+ }
142
+ next();
143
+ } catch (error) {
144
+ return res.status(401).json({ error: 'Invalid token' });
145
+ }
146
+ };
147
+ };
148
+
149
+ // Use in routes
150
+ app.post('/events', requirePermission('events:create'), (req, res) => {
151
+ // Your route logic here
152
+ });
153
+ ```
154
+
155
+ ### NestJS Guard
156
+
157
+ ```typescript
158
+ import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
159
+ import { ExGuardBackend } from 'exguard-backend';
160
+
161
+ @Injectable()
162
+ export class PermissionGuard implements CanActivate {
163
+ private exGuard = new ExGuardBackend({
164
+ apiUrl: process.env.GUARD_API_URL
165
+ });
166
+
167
+ constructor(private requiredPermission: string) {}
168
+
169
+ async canActivate(context: ExecutionContext): Promise<boolean> {
170
+ const request = context.switchToHttp().getRequest();
171
+ const token = request.headers.authorization?.replace('Bearer ', '');
172
+
173
+ if (!token) {
174
+ return false;
175
+ }
176
+
177
+ return await this.exGuard.hasPermission(token, this.requiredPermission);
178
+ }
179
+ }
180
+
181
+ // Usage in controller
182
+ @Get('events')
183
+ @UseGuards(new PermissionGuard('events:read'))
184
+ async getEvents() {
185
+ // Your logic here
186
+ }
187
+ ```
188
+
189
+ ## Error Handling
190
+
191
+ The SDK throws specific errors for different scenarios:
192
+
193
+ - **Unauthorized**: Invalid or expired token (401)
194
+ - **API Error**: General API errors with detailed messages
195
+ - **Network Error**: Connection issues
196
+
197
+ Always wrap SDK calls in try-catch blocks for proper error handling.
198
+
199
+ ## License
200
+
201
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ ExGuardBackend: () => ExGuardBackend
34
+ });
35
+ module.exports = __toCommonJS(index_exports);
36
+
37
+ // src/exguard-backend.ts
38
+ var import_axios = __toESM(require("axios"), 1);
39
+ var ExGuardBackend = class {
40
+ constructor(config) {
41
+ this.config = {
42
+ timeout: 1e4,
43
+ ...config
44
+ };
45
+ this.client = import_axios.default.create({
46
+ baseURL: this.config.apiUrl,
47
+ timeout: this.config.timeout,
48
+ headers: {
49
+ "Content-Type": "application/json"
50
+ }
51
+ });
52
+ }
53
+ /**
54
+ * Get user roles and permissions from the /guard/me endpoint
55
+ * @param token - JWT access token
56
+ * @returns Promise<UserAccessResponse>
57
+ */
58
+ async getUserAccess(token) {
59
+ try {
60
+ const response = await this.client.get("/guard/me", {
61
+ headers: {
62
+ "Authorization": `Bearer ${token}`
63
+ }
64
+ });
65
+ if (!response.data.success) {
66
+ throw new Error("Failed to fetch user access information");
67
+ }
68
+ return response.data.data;
69
+ } catch (error) {
70
+ if (import_axios.default.isAxiosError(error)) {
71
+ if (error.response?.status === 401) {
72
+ throw new Error("Unauthorized: Invalid or expired token");
73
+ }
74
+ throw new Error(`API Error: ${error.response?.data?.message || error.message}`);
75
+ }
76
+ throw error;
77
+ }
78
+ }
79
+ /**
80
+ * Check if user has specific permission
81
+ * @param token - JWT access token
82
+ * @param permission - Permission to check (e.g., 'events:create')
83
+ * @returns Promise<boolean>
84
+ */
85
+ async hasPermission(token, permission) {
86
+ try {
87
+ const userAccess = await this.getUserAccess(token);
88
+ return userAccess.modules.some(
89
+ (module2) => module2.permissions.includes(permission)
90
+ );
91
+ } catch (error) {
92
+ return false;
93
+ }
94
+ }
95
+ /**
96
+ * Check if user has specific role
97
+ * @param token - JWT access token
98
+ * @param role - Role to check (e.g., 'Event Manager')
99
+ * @returns Promise<boolean>
100
+ */
101
+ async hasRole(token, role) {
102
+ try {
103
+ const userAccess = await this.getUserAccess(token);
104
+ return userAccess.roles.includes(role);
105
+ } catch (error) {
106
+ return false;
107
+ }
108
+ }
109
+ /**
110
+ * Get all permissions for a specific module
111
+ * @param token - JWT access token
112
+ * @param moduleKey - Module key (e.g., 'events')
113
+ * @returns Promise<string[]>
114
+ */
115
+ async getModulePermissions(token, moduleKey) {
116
+ try {
117
+ const userAccess = await this.getUserAccess(token);
118
+ const module2 = userAccess.modules.find((m) => m.key === moduleKey);
119
+ return module2?.permissions || [];
120
+ } catch (error) {
121
+ return [];
122
+ }
123
+ }
124
+ /**
125
+ * Get user roles
126
+ * @param token - JWT access token
127
+ * @returns Promise<string[]>
128
+ */
129
+ async getUserRoles(token) {
130
+ try {
131
+ const userAccess = await this.getUserAccess(token);
132
+ return userAccess.roles;
133
+ } catch (error) {
134
+ return [];
135
+ }
136
+ }
137
+ /**
138
+ * Get user field offices
139
+ * @param token - JWT access token
140
+ * @returns Promise<string[]>
141
+ */
142
+ async getUserFieldOffices(token) {
143
+ try {
144
+ const userAccess = await this.getUserAccess(token);
145
+ return userAccess.fieldOffices;
146
+ } catch (error) {
147
+ return [];
148
+ }
149
+ }
150
+ };
151
+ // Annotate the CommonJS export names for ESM import in node:
152
+ 0 && (module.exports = {
153
+ ExGuardBackend
154
+ });
@@ -0,0 +1,87 @@
1
+ interface User {
2
+ id: string;
3
+ cognitoSubId: string;
4
+ username: string;
5
+ email: string;
6
+ emailVerified: boolean;
7
+ givenName: string;
8
+ familyName: string;
9
+ employeeNumber: string;
10
+ regionId: string;
11
+ createdAt: string;
12
+ updatedAt: string;
13
+ lastLoginAt: string;
14
+ fieldOffice: {
15
+ id: string;
16
+ code: string;
17
+ name: string;
18
+ };
19
+ }
20
+ interface ModulePermission {
21
+ key: string;
22
+ name: string;
23
+ permissions: string[];
24
+ }
25
+ interface UserAccessResponse {
26
+ user: User;
27
+ groups: string[];
28
+ roles: string[];
29
+ module: string[];
30
+ modules: ModulePermission[];
31
+ fieldOffices: string[];
32
+ }
33
+ interface ApiResponse<T> {
34
+ success: boolean;
35
+ data: T;
36
+ }
37
+ interface ExGuardConfig {
38
+ apiUrl: string;
39
+ timeout?: number;
40
+ }
41
+
42
+ declare class ExGuardBackend {
43
+ private client;
44
+ private config;
45
+ constructor(config: ExGuardConfig);
46
+ /**
47
+ * Get user roles and permissions from the /guard/me endpoint
48
+ * @param token - JWT access token
49
+ * @returns Promise<UserAccessResponse>
50
+ */
51
+ getUserAccess(token: string): Promise<UserAccessResponse>;
52
+ /**
53
+ * Check if user has specific permission
54
+ * @param token - JWT access token
55
+ * @param permission - Permission to check (e.g., 'events:create')
56
+ * @returns Promise<boolean>
57
+ */
58
+ hasPermission(token: string, permission: string): Promise<boolean>;
59
+ /**
60
+ * Check if user has specific role
61
+ * @param token - JWT access token
62
+ * @param role - Role to check (e.g., 'Event Manager')
63
+ * @returns Promise<boolean>
64
+ */
65
+ hasRole(token: string, role: string): Promise<boolean>;
66
+ /**
67
+ * Get all permissions for a specific module
68
+ * @param token - JWT access token
69
+ * @param moduleKey - Module key (e.g., 'events')
70
+ * @returns Promise<string[]>
71
+ */
72
+ getModulePermissions(token: string, moduleKey: string): Promise<string[]>;
73
+ /**
74
+ * Get user roles
75
+ * @param token - JWT access token
76
+ * @returns Promise<string[]>
77
+ */
78
+ getUserRoles(token: string): Promise<string[]>;
79
+ /**
80
+ * Get user field offices
81
+ * @param token - JWT access token
82
+ * @returns Promise<string[]>
83
+ */
84
+ getUserFieldOffices(token: string): Promise<string[]>;
85
+ }
86
+
87
+ export { type ApiResponse, ExGuardBackend, type ExGuardConfig, type ModulePermission, type User, type UserAccessResponse };
@@ -0,0 +1,87 @@
1
+ interface User {
2
+ id: string;
3
+ cognitoSubId: string;
4
+ username: string;
5
+ email: string;
6
+ emailVerified: boolean;
7
+ givenName: string;
8
+ familyName: string;
9
+ employeeNumber: string;
10
+ regionId: string;
11
+ createdAt: string;
12
+ updatedAt: string;
13
+ lastLoginAt: string;
14
+ fieldOffice: {
15
+ id: string;
16
+ code: string;
17
+ name: string;
18
+ };
19
+ }
20
+ interface ModulePermission {
21
+ key: string;
22
+ name: string;
23
+ permissions: string[];
24
+ }
25
+ interface UserAccessResponse {
26
+ user: User;
27
+ groups: string[];
28
+ roles: string[];
29
+ module: string[];
30
+ modules: ModulePermission[];
31
+ fieldOffices: string[];
32
+ }
33
+ interface ApiResponse<T> {
34
+ success: boolean;
35
+ data: T;
36
+ }
37
+ interface ExGuardConfig {
38
+ apiUrl: string;
39
+ timeout?: number;
40
+ }
41
+
42
+ declare class ExGuardBackend {
43
+ private client;
44
+ private config;
45
+ constructor(config: ExGuardConfig);
46
+ /**
47
+ * Get user roles and permissions from the /guard/me endpoint
48
+ * @param token - JWT access token
49
+ * @returns Promise<UserAccessResponse>
50
+ */
51
+ getUserAccess(token: string): Promise<UserAccessResponse>;
52
+ /**
53
+ * Check if user has specific permission
54
+ * @param token - JWT access token
55
+ * @param permission - Permission to check (e.g., 'events:create')
56
+ * @returns Promise<boolean>
57
+ */
58
+ hasPermission(token: string, permission: string): Promise<boolean>;
59
+ /**
60
+ * Check if user has specific role
61
+ * @param token - JWT access token
62
+ * @param role - Role to check (e.g., 'Event Manager')
63
+ * @returns Promise<boolean>
64
+ */
65
+ hasRole(token: string, role: string): Promise<boolean>;
66
+ /**
67
+ * Get all permissions for a specific module
68
+ * @param token - JWT access token
69
+ * @param moduleKey - Module key (e.g., 'events')
70
+ * @returns Promise<string[]>
71
+ */
72
+ getModulePermissions(token: string, moduleKey: string): Promise<string[]>;
73
+ /**
74
+ * Get user roles
75
+ * @param token - JWT access token
76
+ * @returns Promise<string[]>
77
+ */
78
+ getUserRoles(token: string): Promise<string[]>;
79
+ /**
80
+ * Get user field offices
81
+ * @param token - JWT access token
82
+ * @returns Promise<string[]>
83
+ */
84
+ getUserFieldOffices(token: string): Promise<string[]>;
85
+ }
86
+
87
+ export { type ApiResponse, ExGuardBackend, type ExGuardConfig, type ModulePermission, type User, type UserAccessResponse };
package/dist/index.js ADDED
@@ -0,0 +1,117 @@
1
+ // src/exguard-backend.ts
2
+ import axios from "axios";
3
+ var ExGuardBackend = class {
4
+ constructor(config) {
5
+ this.config = {
6
+ timeout: 1e4,
7
+ ...config
8
+ };
9
+ this.client = axios.create({
10
+ baseURL: this.config.apiUrl,
11
+ timeout: this.config.timeout,
12
+ headers: {
13
+ "Content-Type": "application/json"
14
+ }
15
+ });
16
+ }
17
+ /**
18
+ * Get user roles and permissions from the /guard/me endpoint
19
+ * @param token - JWT access token
20
+ * @returns Promise<UserAccessResponse>
21
+ */
22
+ async getUserAccess(token) {
23
+ try {
24
+ const response = await this.client.get("/guard/me", {
25
+ headers: {
26
+ "Authorization": `Bearer ${token}`
27
+ }
28
+ });
29
+ if (!response.data.success) {
30
+ throw new Error("Failed to fetch user access information");
31
+ }
32
+ return response.data.data;
33
+ } catch (error) {
34
+ if (axios.isAxiosError(error)) {
35
+ if (error.response?.status === 401) {
36
+ throw new Error("Unauthorized: Invalid or expired token");
37
+ }
38
+ throw new Error(`API Error: ${error.response?.data?.message || error.message}`);
39
+ }
40
+ throw error;
41
+ }
42
+ }
43
+ /**
44
+ * Check if user has specific permission
45
+ * @param token - JWT access token
46
+ * @param permission - Permission to check (e.g., 'events:create')
47
+ * @returns Promise<boolean>
48
+ */
49
+ async hasPermission(token, permission) {
50
+ try {
51
+ const userAccess = await this.getUserAccess(token);
52
+ return userAccess.modules.some(
53
+ (module) => module.permissions.includes(permission)
54
+ );
55
+ } catch (error) {
56
+ return false;
57
+ }
58
+ }
59
+ /**
60
+ * Check if user has specific role
61
+ * @param token - JWT access token
62
+ * @param role - Role to check (e.g., 'Event Manager')
63
+ * @returns Promise<boolean>
64
+ */
65
+ async hasRole(token, role) {
66
+ try {
67
+ const userAccess = await this.getUserAccess(token);
68
+ return userAccess.roles.includes(role);
69
+ } catch (error) {
70
+ return false;
71
+ }
72
+ }
73
+ /**
74
+ * Get all permissions for a specific module
75
+ * @param token - JWT access token
76
+ * @param moduleKey - Module key (e.g., 'events')
77
+ * @returns Promise<string[]>
78
+ */
79
+ async getModulePermissions(token, moduleKey) {
80
+ try {
81
+ const userAccess = await this.getUserAccess(token);
82
+ const module = userAccess.modules.find((m) => m.key === moduleKey);
83
+ return module?.permissions || [];
84
+ } catch (error) {
85
+ return [];
86
+ }
87
+ }
88
+ /**
89
+ * Get user roles
90
+ * @param token - JWT access token
91
+ * @returns Promise<string[]>
92
+ */
93
+ async getUserRoles(token) {
94
+ try {
95
+ const userAccess = await this.getUserAccess(token);
96
+ return userAccess.roles;
97
+ } catch (error) {
98
+ return [];
99
+ }
100
+ }
101
+ /**
102
+ * Get user field offices
103
+ * @param token - JWT access token
104
+ * @returns Promise<string[]>
105
+ */
106
+ async getUserFieldOffices(token) {
107
+ try {
108
+ const userAccess = await this.getUserAccess(token);
109
+ return userAccess.fieldOffices;
110
+ } catch (error) {
111
+ return [];
112
+ }
113
+ }
114
+ };
115
+ export {
116
+ ExGuardBackend
117
+ };
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "exguard-backend",
3
+ "version": "1.0.1",
4
+ "private": false,
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "type": "module",
9
+ "description": "ExGuard backend SDK for user role and permission validation",
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
+ "README.md"
23
+ ],
24
+ "scripts": {
25
+ "build": "tsup",
26
+ "dev": "tsup --watch",
27
+ "type-check": "tsc --noEmit",
28
+ "prepublishOnly": "pnpm build"
29
+ },
30
+ "keywords": [
31
+ "exguard",
32
+ "rbac",
33
+ "backend",
34
+ "typescript",
35
+ "permissions",
36
+ "roles"
37
+ ],
38
+ "author": "EmpowerX",
39
+ "license": "MIT",
40
+ "dependencies": {
41
+ "axios": "^1.0.0"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^22.10.5",
45
+ "tsup": "^8.3.5",
46
+ "typescript": "^5.7.3"
47
+ }
48
+ }