@igxjs/node-components 1.0.9 → 1.0.11

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/index.d.ts CHANGED
@@ -5,14 +5,26 @@ import { EncryptJWT, JWTDecryptResult, JWTPayload } from 'jose';
5
5
  import { RedisClientType } from '@redis/client';
6
6
  import { Application, RequestHandler, Request, Response, NextFunction, Router } from 'express';
7
7
 
8
- // Session Configuration
8
+ export { JWTPayload } from 'jose';
9
+
10
+ // Session Mode constants
11
+ export const SessionMode: {
12
+ SESSION: string;
13
+ TOKEN: string;
14
+ };
15
+
16
+ // Session Configuration - uses strict UPPERCASE naming convention for all property names
9
17
  export interface SessionConfig {
18
+ /** Identity Provider */
10
19
  SSO_ENDPOINT_URL?: string;
11
20
  SSO_CLIENT_ID?: string;
12
21
  SSO_CLIENT_SECRET?: string;
13
22
  SSO_SUCCESS_URL?: string;
14
23
  SSO_FAILURE_URL?: string;
15
24
 
25
+ /** Authentication mode: 'session' or 'token' (default: 'session') */
26
+ SESSION_MODE?: string;
27
+
16
28
  SESSION_AGE?: number;
17
29
  SESSION_COOKIE_PATH?: string;
18
30
  SESSION_SECRET?: string;
@@ -20,6 +32,15 @@ export interface SessionConfig {
20
32
 
21
33
  REDIS_URL?: string;
22
34
  REDIS_CERT_PATH?: string;
35
+
36
+ JWT_ALGORITHM?: string;
37
+ JWT_ENCRYPTION?: string;
38
+ JWT_EXPIRATION_TIME?: string;
39
+ JWT_CLOCK_TOLERANCE?: number;
40
+ JWT_SECRET_HASH_ALGORITHM?: string;
41
+ JWT_ISSUER?: string;
42
+ JWT_AUDIENCE?: string;
43
+ JWT_SUBJECT?: string;
23
44
  }
24
45
 
25
46
  export interface SessionUserAttributes {
@@ -58,7 +79,7 @@ export interface SessionUser {
58
79
  export class SessionManager {
59
80
  /**
60
81
  * Constructor
61
- * @param config - Session configuration
82
+ * @param config - Session configuration (uses strict UPPERCASE property names)
62
83
  */
63
84
  constructor(config: SessionConfig);
64
85
 
@@ -97,15 +118,35 @@ export class SessionManager {
97
118
  ): Promise<void>;
98
119
 
99
120
  /**
100
- * Resource protection middleware
121
+ * Resource protection middleware based on configured SESSION_MODE
122
+ * Uses verifySession() for SESSION mode and verifyToken() for TOKEN mode
101
123
  * @param isDebugging Debugging flag (default: false)
102
124
  * @param redirectUrl Redirect URL (default: '')
103
125
  * @returns Returns express Request Handler
104
126
  */
105
127
  authenticate(isDebugging?: boolean, redirectUrl?: string): RequestHandler;
106
128
 
129
+ /**
130
+ * Resource protection by token (explicit token verification)
131
+ * Requires Authorization: Bearer {token} header
132
+ * @param isDebugging Debugging flag (default: false)
133
+ * @param redirectUrl Redirect URL (default: '')
134
+ * @returns Returns express Request Handler
135
+ */
136
+ verifyToken(isDebugging?: boolean, redirectUrl?: string): RequestHandler;
137
+
138
+ /**
139
+ * Resource protection by session (explicit session verification)
140
+ * @param isDebugging Debugging flag (default: false)
141
+ * @param redirectUrl Redirect URL (default: '')
142
+ * @returns Returns express Request Handler
143
+ */
144
+ verifySession(isDebugging?: boolean, redirectUrl?: string): RequestHandler;
145
+
107
146
  /**
108
147
  * SSO callback for successful login
148
+ * SESSION mode: Saves session and redirects
149
+ * TOKEN mode: Generates JWT token, returns HTML page with localStorage script
109
150
  * @param initUser Initialize user object function
110
151
  * @returns Returns express Request Handler
111
152
  */
@@ -118,17 +159,22 @@ export class SessionManager {
118
159
  identityProviders(): RequestHandler;
119
160
 
120
161
  /**
121
- * Application logout (NOT SSO)
162
+ * Refresh user authentication based on configured SESSION_MODE
163
+ * SESSION mode: Refreshes session data
164
+ * TOKEN mode: Generates new token, invalidates old token
165
+ * @param initUser Initialize user object function
122
166
  * @returns Returns express Request Handler
123
167
  */
124
- logout(): RequestHandler;
168
+ refresh(initUser: (user: SessionUser) => SessionUser): RequestHandler;
125
169
 
126
170
  /**
127
- * Refresh user session
128
- * @param initUser Initialize user object function
171
+ * Application logout based on configured SESSION_MODE (NOT SSO)
172
+ * SESSION mode: Destroys session and clears cookie
173
+ * TOKEN mode: Invalidates current token or all tokens (with ?all=true query param)
174
+ * Query params: redirect=true (redirect to success/failure URL), all=true (logout all tokens - TOKEN mode only)
129
175
  * @returns Returns express Request Handler
130
176
  */
131
- refresh(initUser: (user: SessionUser) => SessionUser): RequestHandler;
177
+ logout(): RequestHandler;
132
178
  }
133
179
 
134
180
  // Custom Error class
@@ -187,7 +233,7 @@ export class RedisManager {
187
233
 
188
234
  /**
189
235
  * Determine if the Redis server is connected
190
- * @returns Returns true if Redis server is connected
236
+ * @returns Returns true if the Redis server is connected
191
237
  */
192
238
  isConnected(): Promise<boolean>;
193
239
 
@@ -198,57 +244,81 @@ export class RedisManager {
198
244
  disConnect(): Promise<void>;
199
245
  }
200
246
 
201
- // JWT Manager Configuration
247
+ // JWT Manager Configuration - uses strict UPPERCASE naming convention with JWT_ prefix for all property names
202
248
  export interface JwtManagerOptions {
203
- /** @type {string} JWE algorithm (default: 'dir') */
204
- algorithm?: string;
205
- /** @type {string} JWE encryption method (default: 'A256GCM') */
206
- encryption?: string;
207
- /** @type {string} Token expiration time (default: '10m') */
208
- expirationTime?: string;
209
- /** @type {number} Clock tolerance in seconds for token validation (default: 30) */
210
- clockTolerance?: number;
211
- /** @type {string} Hash algorithm for secret derivation (default: 'SHA-256') */
212
- secretHashAlgorithm?: string;
213
- /** @type {string} Optional JWT issuer claim */
214
- issuer?: string;
215
- /** @type {string} Optional JWT audience claim */
216
- audience?: string;
217
- /** @type {string} Optional JWT subject claim */
218
- subject?: string;
249
+ /** JWE algorithm (default: 'dir') */
250
+ JWT_ALGORITHM?: string;
251
+
252
+ /** JWE encryption method (default: 'A256GCM') */
253
+ JWT_ENCRYPTION?: string;
254
+
255
+ /** Token expiration time (default: '10m') */
256
+ JWT_EXPIRATION_TIME?: string;
257
+
258
+ /** Clock tolerance in seconds for token validation (default: 30) */
259
+ JWT_CLOCK_TOLERANCE?: number;
260
+
261
+ /** Hash algorithm for secret derivation (default: 'SHA-256') */
262
+ JWT_SECRET_HASH_ALGORITHM?: string;
263
+
264
+ /** Optional JWT issuer claim */
265
+ JWT_ISSUER?: string;
266
+
267
+ /** Optional JWT audience claim */
268
+ JWT_AUDIENCE?: string;
269
+
270
+ /** Optional JWT subject claim */
271
+ JWT_SUBJECT?: string;
219
272
  }
220
273
 
274
+ /**
275
+ * Options for encrypt() method - uses camelCase naming convention
276
+ */
221
277
  export interface JwtEncryptOptions {
222
- /** @type {string} Override default algorithm */
278
+ /** Override default algorithm */
223
279
  algorithm?: string;
224
- /** @type {string} Override default encryption method */
280
+
281
+ /** Override default encryption method */
225
282
  encryption?: string;
226
- /** @type {string} Override default expiration time */
283
+
284
+ /** Override default expiration time */
227
285
  expirationTime?: string;
228
- /** @type {string} Override default hash algorithm */
286
+
287
+ /** Override default hash algorithm */
229
288
  secretHashAlgorithm?: string;
230
- /** @type {string} Override default issuer claim */
289
+
290
+ /** Override default issuer claim */
231
291
  issuer?: string;
232
- /** @type {string} Override default audience claim */
292
+
293
+ /** Override default audience claim */
233
294
  audience?: string;
234
- /** @type {string} Override default subject claim */
295
+
296
+ /** Override default subject claim */
235
297
  subject?: string;
236
298
  }
237
299
 
300
+ /**
301
+ * Options for decrypt() method - uses camelCase naming convention
302
+ */
238
303
  export interface JwtDecryptOptions {
239
- /** @type {number} Override default clock tolerance */
304
+ /** Override default clock tolerance */
240
305
  clockTolerance?: number;
241
- /** @type {string} Override default hash algorithm */
306
+
307
+ /** Override default hash algorithm */
242
308
  secretHashAlgorithm?: string;
243
- /** @type {string} Expected issuer claim for validation */
309
+
310
+ /** Expected issuer claim for validation */
244
311
  issuer?: string;
245
- /** @type {string} Expected audience claim for validation */
312
+
313
+ /** Expected audience claim for validation */
246
314
  audience?: string;
247
- /** @type {string} Expected subject claim for validation */
315
+
316
+ /** Expected subject claim for validation */
248
317
  subject?: string;
249
318
  }
250
319
 
251
- export type DecryptedJWT = JWTDecryptResult<EncryptJWT>;
320
+ export type JwtDecryptResult = JWTDecryptResult<EncryptJWT>;
321
+
252
322
  // JwtManager class for JWT encryption and decryption
253
323
  export class JwtManager {
254
324
  algorithm: string;
@@ -262,7 +332,7 @@ export class JwtManager {
262
332
 
263
333
  /**
264
334
  * Create a new JwtManager instance with configurable defaults
265
- * @param options Configuration options
335
+ * @param options Configuration options (uses strict UPPERCASE with JWT_ prefix property names)
266
336
  */
267
337
  constructor(options?: JwtManagerOptions);
268
338
 
@@ -270,7 +340,7 @@ export class JwtManager {
270
340
  * Generate JWT token for user session
271
341
  * @param data User data payload
272
342
  * @param input Secret key or password for encryption
273
- * @param options Per-call configuration overrides
343
+ * @param options Per-call configuration overrides (uses strict UPPERCASE with JWT_ prefix property names)
274
344
  * @returns Returns encrypted JWT token
275
345
  */
276
346
  encrypt(data: JWTPayload, input: string, options?: JwtEncryptOptions): Promise<string>;
@@ -279,10 +349,10 @@ export class JwtManager {
279
349
  * Decrypt JWT token for user session
280
350
  * @param token JWT token to decrypt
281
351
  * @param input Secret key or password for decryption
282
- * @param options Per-call configuration overrides
352
+ * @param options Per-call configuration overrides (uses strict UPPERCASE with JWT_ prefix property names)
283
353
  * @returns Returns decrypted JWT token
284
354
  */
285
- decrypt(token: string, input: string, options?: JwtDecryptOptions): Promise<DecryptedJWT>;
355
+ decrypt(token: string, input: string, options?: JwtDecryptOptions): Promise<JwtDecryptResult>;
286
356
  }
287
357
 
288
358
  // HTTP status code keys (exposed for type safety)
@@ -400,4 +470,4 @@ declare module 'express-session' {
400
470
  [key: string]: any;
401
471
  user?: SessionUser;
402
472
  }
403
- }
473
+ }
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { SessionConfig, SessionManager } from './components/session.js';
1
+ export { SessionConfig, SessionManager, SessionMode } from './components/session.js';
2
2
  export { httpCodes, httpMessages, httpErrorHandler, httpNotFoundHandler, CustomError, httpHelper, httpError } from './components/http-handlers.js';
3
3
  export { RedisManager } from './components/redis.js';
4
4
  export { FlexRouter } from './components/router.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@igxjs/node-components",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "Node components for igxjs",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -26,16 +26,23 @@
26
26
  "axios": "^1.13.6",
27
27
  "connect-redis": "^9.0.0",
28
28
  "express-session": "^1.19.0",
29
- "jose": "^6.1.3",
29
+ "jose": "^6.2.0",
30
30
  "memorystore": "^1.6.7"
31
31
  },
32
32
  "devDependencies": {
33
33
  "chai": "^6.2.2",
34
34
  "express": "^5.2.1",
35
- "mocha": "^11.0.1",
35
+ "mocha": "^12.0.0-beta-10",
36
36
  "sinon": "^21.0.2",
37
37
  "supertest": "^7.0.0"
38
38
  },
39
+ "files": [
40
+ "index.js",
41
+ "index.d.ts",
42
+ "components/",
43
+ "LICENSE",
44
+ "README.md"
45
+ ],
39
46
  "publishConfig": {
40
47
  "access": "public"
41
48
  },
@@ -1,31 +0,0 @@
1
- # This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
2
- # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs
3
-
4
- name: Node.js CI
5
-
6
- on:
7
- push:
8
- branches: [ "main" ]
9
- pull_request:
10
- branches: [ "main" ]
11
-
12
- jobs:
13
- build:
14
-
15
- runs-on: ubuntu-latest
16
-
17
- strategy:
18
- matrix:
19
- node-version: [18.x, 20.x, 22.x]
20
- # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
21
-
22
- steps:
23
- - uses: actions/checkout@v4
24
- - name: Use Node.js ${{ matrix.node-version }}
25
- uses: actions/setup-node@v4
26
- with:
27
- node-version: ${{ matrix.node-version }}
28
- cache: 'npm'
29
- - run: npm ci
30
- - run: npm run build --if-present
31
- - run: npm test
@@ -1,33 +0,0 @@
1
- # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2
- # For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
3
-
4
- name: Node.js Package
5
-
6
- on:
7
- release:
8
- types: [created]
9
-
10
- jobs:
11
- build:
12
- runs-on: ubuntu-latest
13
- steps:
14
- - uses: actions/checkout@v4
15
- - uses: actions/setup-node@v4
16
- with:
17
- node-version: 20
18
- - run: npm ci
19
- - run: npm test
20
-
21
- publish-npm:
22
- needs: build
23
- runs-on: ubuntu-latest
24
- steps:
25
- - uses: actions/checkout@v4
26
- - uses: actions/setup-node@v4
27
- with:
28
- node-version: 20
29
- registry-url: https://registry.npmjs.org/
30
- - run: npm ci
31
- - run: npm publish
32
- env:
33
- NODE_AUTH_TOKEN: ${{secrets.npm_token}}
package/docs/README.md DELETED
@@ -1,54 +0,0 @@
1
- # Node Components Documentation
2
-
3
- Detailed documentation for `@igxjs/node-components` - shared components for Express.js applications.
4
-
5
- ## 📚 Component Documentation
6
-
7
- ### Core Modules
8
-
9
- - **[SessionManager](./session-manager.md)** - SSO session management with Redis and memory storage
10
- - Configuration options and singleton pattern
11
- - Complete setup and usage examples
12
- - API reference for all methods
13
-
14
- - **[FlexRouter](./flex-router.md)** - Flexible routing utility for Express.js
15
- - Context path and middleware management
16
- - API versioning and route organization
17
- - Advanced usage patterns
18
-
19
- - **[RedisManager](./redis-manager.md)** - Redis connection management
20
- - TLS/SSL support
21
- - Connection monitoring and error handling
22
- - Direct Redis operations
23
-
24
- - **[JWT Manager](./jwt-manager.md)** - JWT encryption and decryption
25
- - Secure token-based authentication
26
- - Express.js integration patterns
27
- - Refresh token implementation
28
-
29
- - **[HTTP Handlers](./http-handlers.md)** - Standardized error handling
30
- - Custom error classes and middleware
31
- - HTTP status codes and messages
32
- - Axios error handling and validation helpers
33
-
34
- ## 🚀 Quick Links
35
-
36
- - [Main README](../README.md) - Package overview and installation
37
- - [GitHub Repository](https://github.com/igxjs/node-components)
38
-
39
- ## 💡 Getting Help
40
-
41
- If you need help:
42
- 1. Check the relevant component documentation above
43
- 2. Review the examples in each guide
44
- 3. Look at the type definitions in `index.d.ts`
45
- 4. Open an issue on GitHub
46
-
47
- ## 📖 Documentation Structure
48
-
49
- Each component documentation includes:
50
- - Overview of features
51
- - Configuration options
52
- - Basic and advanced usage examples
53
- - Complete API reference
54
- - Related documentation links
@@ -1,167 +0,0 @@
1
- # FlexRouter
2
-
3
- A flexible routing utility for Express.js that allows mounting routers with custom context paths and middleware handlers.
4
-
5
- ## Overview
6
-
7
- FlexRouter provides a convenient way to organize and mount Express routers with predefined context paths and optional middleware. This is particularly useful for:
8
- - API versioning (e.g., `/api/v1`, `/api/v2`)
9
- - Separating public and protected routes
10
- - Applying middleware to specific route groups
11
- - Managing complex routing hierarchies
12
-
13
- ## Usage Example
14
-
15
- ```javascript
16
- import { Router } from 'express';
17
- import { FlexRouter } from '@igxjs/node-components';
18
- // Assuming you have an authenticate middleware
19
- // import { authenticate } from './middlewares/auth.js';
20
-
21
- // Create routers
22
- const publicRouter = Router();
23
- const privateRouter = Router();
24
-
25
- publicRouter.get('/health', (req, res) => {
26
- res.send('OK');
27
- });
28
-
29
- privateRouter.get('/users', (req, res) => {
30
- res.json({ users: [] });
31
- });
32
-
33
- // Define flex routers with context paths and optional middleware
34
- export const routers = [
35
- new FlexRouter('/api/v1/public', publicRouter),
36
- new FlexRouter('/api/v1/protected', privateRouter, [authenticate]), // with middleware
37
- ];
38
-
39
- // Mount all routers to your Express app
40
- const app = express();
41
- const basePath = '';
42
-
43
- routers.forEach(router => {
44
- router.mount(app, basePath);
45
- });
46
-
47
- // Routes will be available at:
48
- // - /api/v1/public/health
49
- // - /api/v1/protected/users (with authenticate middleware)
50
- ```
51
-
52
- ## Advanced Usage
53
-
54
- ### Multiple Middleware
55
-
56
- You can apply multiple middleware functions to a FlexRouter:
57
-
58
- ```javascript
59
- import { rateLimiter } from './middlewares/rate-limiter.js';
60
- import { logger } from './middlewares/logger.js';
61
- import { authenticate } from './middlewares/auth.js';
62
-
63
- const apiRouter = Router();
64
-
65
- apiRouter.get('/data', (req, res) => {
66
- res.json({ [] });
67
- });
68
-
69
- // Apply multiple middleware in order
70
- const protectedApi = new FlexRouter(
71
- '/api/v1',
72
- apiRouter,
73
- [logger, rateLimiter, authenticate] // Applied in this order
74
- );
75
-
76
- protectedApi.mount(app, '');
77
- ```
78
-
79
- ### Using Base Paths
80
-
81
- You can add a base path when mounting routers, useful for multi-tenant applications:
82
-
83
- ```javascript
84
- const tenantRouter = Router();
85
-
86
- tenantRouter.get('/dashboard', (req, res) => {
87
- res.json({ tenant: req.params.tenantId });
88
- });
89
-
90
- const flexRouter = new FlexRouter('/api', tenantRouter);
91
-
92
- // Mount with tenant-specific base path
93
- flexRouter.mount(app, '/tenant/:tenantId');
94
-
95
- // Route will be available at: /tenant/:tenantId/api/dashboard
96
- ```
97
-
98
- ### Organizing Routes by Feature
99
-
100
- ```javascript
101
- // features/users/routes.js
102
- const usersRouter = Router();
103
- usersRouter.get('/', getAllUsers);
104
- usersRouter.post('/', createUser);
105
- export const usersFlexRouter = new FlexRouter('/users', usersRouter);
106
-
107
- // features/products/routes.js
108
- const productsRouter = Router();
109
- productsRouter.get('/', getAllProducts);
110
- export const productsFlexRouter = new FlexRouter('/products', productsRouter);
111
-
112
- // app.js
113
- import { usersFlexRouter } from './features/users/routes.js';
114
- import { productsFlexRouter } from './features/products/routes.js';
115
-
116
- const apiRouters = [usersFlexRouter, productsFlexRouter];
117
-
118
- apiRouters.forEach(router => router.mount(app, '/api/v1'));
119
-
120
- // Routes available:
121
- // - /api/v1/users
122
- // - /api/v1/products
123
- ```
124
-
125
- ## API
126
-
127
- ### Constructor
128
-
129
- **`new FlexRouter(context, router, handlers?)`**
130
-
131
- Creates a new FlexRouter instance.
132
-
133
- **Parameters:**
134
- - `context` (string) - The context path for the router (e.g., `/api/v1`)
135
- - `router` (Router) - Express Router instance containing your route definitions
136
- - `handlers` (Array, optional) - Array of middleware handler functions to apply to all routes in this router
137
-
138
- **Returns:** FlexRouter instance
139
-
140
- ### Methods
141
-
142
- **`mount(app, basePath)`**
143
-
144
- Mounts the router to an Express application with the specified base path.
145
-
146
- **Parameters:**
147
- - `app` (Express) - Express application instance
148
- - `basePath` (string) - Base path to prepend to the context path
149
-
150
- **Example:**
151
- ```javascript
152
- const flexRouter = new FlexRouter('/api', router);
153
- flexRouter.mount(app, '/v1'); // Mounts at /v1/api
154
- ```
155
-
156
- ## Best Practices
157
-
158
- 1. **Group Related Routes**: Use FlexRouter to group related routes together
159
- 2. **Apply Middleware Strategically**: Apply middleware at the FlexRouter level for route groups that share the same requirements
160
- 3. **Consistent Naming**: Use consistent naming conventions for context paths (e.g., all lowercase, kebab-case)
161
- 4. **Version Your APIs**: Use FlexRouter to manage different API versions easily
162
- 5. **Keep Routers Focused**: Each router should handle a specific feature or resource type
163
-
164
- ## Related Documentation
165
-
166
- - [SessionManager](./session-manager.md) - For authentication middleware usage
167
- - [Back to main documentation](../README.md)