@igxjs/node-components 1.0.7 → 1.0.8

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # Node Components
2
2
 
3
- Shared components for Express.js applications providing session management, routing utilities, error handling, and Redis integration.
3
+ Shared components for Express.js applications providing session management, routing utilities, error handling, JWT authentication, and Redis integration.
4
4
 
5
5
  ## Installation
6
6
 
@@ -8,559 +8,112 @@ Shared components for Express.js applications providing session management, rout
8
8
  npm install @igxjs/node-components
9
9
  ```
10
10
 
11
- ## Modules
11
+ ## Components
12
12
 
13
- ### 1. Session Manager
13
+ | Component | Description | Documentation |
14
+ |-----------|-------------|---------------|
15
+ | **SessionManager** | SSO session management with Redis/memory storage | [View docs](./docs/session-manager.md) |
16
+ | **FlexRouter** | Flexible routing with context paths and middleware | [View docs](./docs/flex-router.md) |
17
+ | **RedisManager** | Redis connection management with TLS support | [View docs](./docs/redis-manager.md) |
18
+ | **JWT Manager** | Secure JWT encryption/decryption with JWE | [View docs](./docs/jwt-manager.md) |
19
+ | **HTTP Handlers** | Standardized error handling and status codes | [View docs](./docs/http-handlers.md) |
14
20
 
15
- Provides SSO (Single Sign-On) session management with support for Redis and memory-based session stores.
21
+ ## Quick Start Examples
16
22
 
17
- #### Configuration Options
23
+ ### SessionManager
18
24
 
19
25
  ```javascript
20
- // Example configuration object
21
- // All fields are strings except SESSION_AGE which is a number
22
-
23
- const config = {
24
- // SSO Configuration
25
- SSO_ENDPOINT_URL: 'https://sso.example.com',
26
- SSO_CLIENT_ID: 'your-client-id',
27
- SSO_CLIENT_SECRET: 'your-client-secret',
28
- SSO_SUCCESS_URL: '/dashboard',
29
- SSO_FAILURE_URL: '/login',
30
-
31
- // Session Configuration
32
- SESSION_AGE: 64800000, // 18 hours in milliseconds
33
- SESSION_COOKIE_PATH: '/',
34
- SESSION_SECRET: 'your-session-secret',
35
- SESSION_PREFIX: 'ibmid:', // Default value when not provided
36
-
37
- // Redis Configuration (optional - uses memory store if not provided)
38
- REDIS_URL: 'redis://localhost:6379',
39
- REDIS_CERT_PATH: '/path/to/cert.pem' // For TLS connections
40
- };
41
- ```
42
-
43
- #### Usage Example
44
-
45
- ```javascript
46
- import express from 'express';
47
26
  import { SessionManager } from '@igxjs/node-components';
48
27
 
49
- const app = express();
50
- const session = new SessionManager(config);
51
-
52
- // Initialize session
53
- await session.setup(app, (user) => {
54
- // Process user object - compute permissions, avatar URL, etc.
55
- return {
56
- ...user,
57
- displayName: user.email?.split('@')[0],
58
- hasAdminAccess: user.authorized && user.email?.endsWith('@admin.com')
59
- };
28
+ // Create singleton instance
29
+ export const session = new SessionManager({
30
+ SSO_ENDPOINT_URL: process.env.SSO_ENDPOINT_URL,
31
+ SSO_CLIENT_ID: process.env.SSO_CLIENT_ID,
32
+ SSO_CLIENT_SECRET: process.env.SSO_CLIENT_SECRET,
33
+ SESSION_SECRET: process.env.SESSION_SECRET,
34
+ REDIS_URL: process.env.REDIS_URL
60
35
  });
61
36
 
62
- // Protect routes with authentication
37
+ // Setup in your app
38
+ await session.setup(app, (user) => ({ ...user, displayName: user.email }));
39
+
40
+ // Protect routes
63
41
  app.get('/protected', session.authenticate(), (req, res) => {
64
42
  res.json({ user: req.user });
65
43
  });
66
-
67
- // SSO callback endpoint
68
- app.get('/auth/callback', session.callback((user) => {
69
- // Initialize user object after successful login
70
- return {
71
- ...user,
72
- loginTime: new Date()
73
- };
74
- }));
75
-
76
- // Get available identity providers
77
- app.get('/auth/providers', session.identityProviders());
78
-
79
- // Refresh user session
80
- app.post('/auth/refresh', session.refresh((user) => {
81
- return { ...user, refreshedAt: new Date() };
82
- }));
83
-
84
- // Logout endpoint
85
- app.get('/auth/logout', session.logout());
86
44
  ```
87
45
 
88
- #### API Methods
89
-
90
- - **`setup(app, updateUser)`** - Initialize session configurations
91
- - **`authenticate(isDebugging?, redirectUrl?)`** - Resource protection middleware
92
- - **`callback(initUser)`** - SSO callback handler for successful login
93
- - **`identityProviders()`** - Get available identity providers
94
- - **`logout()`** - Application logout handler (not SSO logout)
95
- - **`refresh(initUser)`** - Refresh user session with new token
96
- - **`redisManager()`** - Get the RedisManager instance (returns RedisManager or null)
97
- - **`hasLock(email)`** - Check if email has a session refresh lock
98
- - **`lock(email)`** - Lock email for session refresh (prevents concurrent refreshes)
99
- - **`clearLocks()`** - Clear expired session refresh locks
46
+ [📖 Full SessionManager Documentation](./docs/session-manager.md)
100
47
 
101
- ---
102
-
103
- ### 2. FlexRouter
104
-
105
- A flexible routing utility for Express.js that allows mounting routers with custom context paths and middleware handlers.
106
-
107
- #### Usage Example
48
+ ### FlexRouter
108
49
 
109
50
  ```javascript
110
51
  import { Router } from 'express';
111
52
  import { FlexRouter } from '@igxjs/node-components';
112
- // Assuming you have an authenticate middleware
113
- // import { authenticate } from './middlewares/auth.js';
114
-
115
- // Create routers
116
- const publicRouter = Router();
117
- const privateRouter = Router();
118
-
119
- publicRouter.get('/health', (req, res) => {
120
- res.send('OK');
121
- });
122
-
123
- privateRouter.get('/users', (req, res) => {
124
- res.json({ users: [] });
125
- });
126
-
127
- // Define flex routers with context paths and optional middleware
128
- export const routers = [
129
- new FlexRouter('/api/v1/public', publicRouter),
130
- new FlexRouter('/api/v1/protected', privateRouter, [authenticate]), // with middleware
131
- ];
132
53
 
133
- // Mount all routers to your Express app
134
- const app = express();
135
- const basePath = '';
136
-
137
- routers.forEach(router => {
138
- router.mount(app, basePath);
139
- });
54
+ const apiRouter = Router();
55
+ apiRouter.get('/users', (req, res) => res.json({ users: [] }));
140
56
 
141
- // Routes will be available at:
142
- // - /api/v1/public/health
143
- // - /api/v1/protected/users (with authenticate middleware)
57
+ // Mount with context path and middleware
58
+ const flexRouter = new FlexRouter('/api/v1', apiRouter, [authenticate]);
59
+ flexRouter.mount(app, '');
144
60
  ```
145
61
 
146
- #### API
147
-
148
- - **`constructor(context, router, handlers?)`** - Create a new FlexRouter
149
- - `context` (string) - The context path for the router
150
- - `router` - Express Router instance
151
- - `handlers` - Optional array of middleware handlers
152
-
153
- - **`mount(app, basePath)`** - Mount the router to an Express application
154
- - `app` - Express application instance
155
- - `basePath` (string) - Base path to prepend to the context
156
-
157
- ---
158
-
159
- ### 3. RedisManager
62
+ [📖 Full FlexRouter Documentation](./docs/flex-router.md)
160
63
 
161
- Redis connection management with TLS support and automatic reconnection handling.
162
-
163
- * Note: the RedisManager is used internally by the `SessionManager`, so you don't need to use it directly.
164
-
165
- #### Usage Example
166
-
167
- ```javascript
168
- import { RedisManager } from '@igxjs/node-components';
169
-
170
- const redisManager = new RedisManager();
171
-
172
- // Connect to Redis (with optional TLS certificate)
173
- const connected = await redisManager.connect(
174
- 'rediss://localhost:6379',
175
- '/path/to/cert.pem'
176
- );
177
-
178
- if (connected) {
179
- // Get Redis client for direct operations
180
- const client = redisManager.getClient();
181
- await client.set('key', 'value');
182
-
183
- // Check connection status
184
- const isConnected = await redisManager.isConnected();
185
-
186
- // Disconnect when done
187
- await redisManager.disConnect();
188
- }
189
- ```
190
-
191
- #### API Methods
192
-
193
- - **`connect(redisUrl, certPath)`** - Connect to Redis server
194
- - Returns: `Promise<boolean>` - Returns true if connected successfully
195
- - Supports both `redis://` and `rediss://` (TLS) URLs
196
- - Automatically handles TLS certificate loading when using `rediss://`
197
-
198
- - **`getClient()`** - Get the Redis client instance
199
- - Returns: Redis client for direct operations
200
-
201
- - **`isConnected()`** - Check if Redis connection is active
202
- - Returns: `Promise<boolean>` - Returns true if connected and responsive
203
-
204
- - **`disConnect()`** - Disconnect from Redis server
205
- - Returns: `Promise<void>`
206
-
207
- ---
208
-
209
- ### 4. JWT Manager
210
-
211
- Provides JWT (JSON Web Token) encryption and decryption utilities using the `jose` library with JWE (JSON Web Encryption) for secure token management.
212
-
213
- #### Configuration Options
214
-
215
- ```javascript
216
- // Example configuration object
217
- const jwtOptions = {
218
- algorithm: 'dir', // JWE algorithm (default: 'dir')
219
- encryption: 'A256GCM', // JWE encryption method (default: 'A256GCM')
220
- expirationTime: '10m', // Token expiration (default: '10m')
221
- clockTolerance: 30, // Clock tolerance in seconds (default: 30)
222
- secretHashAlgorithm: 'SHA-256', // Hash algorithm for secret derivation (default: 'SHA-256')
223
- issuer: 'your-app', // Optional JWT issuer claim
224
- audience: 'your-users', // Optional JWT audience claim
225
- subject: 'user-session' // Optional JWT subject claim
226
- };
227
- ```
228
-
229
- #### Usage Example
64
+ ### JWT Manager
230
65
 
231
66
  ```javascript
232
67
  import { JwtManager } from '@igxjs/node-components';
233
68
 
234
- // Create instance with default configuration
235
- const jwtManager = new JwtManager({
236
- expirationTime: '1h',
237
- issuer: 'my-app',
238
- audience: 'my-users'
239
- });
240
-
241
- // Encrypt user data
242
- const userData = {
243
- userId: '12345',
244
- email: 'user@example.com',
245
- roles: ['admin', 'user']
246
- };
247
-
248
- const secret = 'your-secret-key';
249
- const token = await jwtManager.encrypt(userData, secret);
250
-
251
- console.log('Encrypted Token:', token);
252
-
253
- // Decrypt token
254
- try {
255
- const result = await jwtManager.decrypt(token, secret);
256
- console.log('Decrypted Payload:', result.payload);
257
- console.log('Protected Header:', result.protectedHeader);
258
- } catch (error) {
259
- console.error('Token validation failed:', error);
260
- }
261
-
262
- // Override options per-call
263
- const shortLivedToken = await jwtManager.encrypt(
264
- userData,
265
- secret,
266
- { expirationTime: '5m' } // Override default expiration
267
- );
268
-
269
- // Decrypt with custom validation
270
- const validatedResult = await jwtManager.decrypt(
271
- token,
272
- secret,
273
- {
274
- clockTolerance: 60, // Allow more clock skew
275
- issuer: 'my-app', // Validate issuer
276
- audience: 'my-users' // Validate audience
277
- }
278
- );
279
- ```
280
-
281
- #### Advanced Usage with Express
282
-
283
- ```javascript
284
- import express from 'express';
285
- import { JwtManager } from '@igxjs/node-components';
286
-
287
- const app = express();
288
- const jwt = new JwtManager({ expirationTime: '24h' });
69
+ const jwt = new JwtManager({ expirationTime: '1h' });
289
70
  const SECRET = process.env.JWT_SECRET;
290
71
 
291
- // Login endpoint - create token
292
- app.post('/api/login', async (req, res, next) => {
293
- try {
294
- const { username, password } = req.body;
295
-
296
- // Verify credentials (your logic here)
297
- const user = await verifyCredentials(username, password);
298
-
299
- // Create JWT token
300
- const token = await jwt.encrypt({
301
- sub: user.id,
302
- email: user.email,
303
- roles: user.roles
304
- }, SECRET);
305
-
306
- res.json({ token });
307
- } catch (error) {
308
- next(error);
309
- }
310
- });
72
+ // Create token
73
+ const token = await jwt.encrypt({ userId: '123', email: 'user@example.com' }, SECRET);
311
74
 
312
- // Protected endpoint - verify token
313
- app.get('/api/profile', async (req, res, next) => {
314
- try {
315
- const token = req.headers.authorization?.replace('Bearer ', '');
316
-
317
- if (!token) {
318
- return res.status(401).json({ error: 'No token provided' });
319
- }
320
-
321
- // Decrypt and validate token
322
- const { payload } = await jwt.decrypt(token, SECRET);
323
-
324
- res.json({ user: payload });
325
- } catch (error) {
326
- // Token expired or invalid
327
- res.status(401).json({ error: 'Invalid or expired token' });
328
- }
329
- });
75
+ // Verify token
76
+ const { payload } = await jwt.decrypt(token, SECRET);
330
77
  ```
331
78
 
332
- #### API Methods
333
-
334
- **Constructor:**
335
- - **`new JwtManager(options?)`** - Create a new JwtManager instance
336
- - `options` (JwtManagerOptions, optional) - Configuration options
337
- - All options are optional and have sensible defaults
338
-
339
- **Methods:**
340
- - **`encrypt(data, input, options?)`** - Generate encrypted JWT token
341
- - `data` (JWTPayload) - User data payload to encrypt
342
- - `input` (string) - Secret key or password for encryption
343
- - `options` (JwtEncryptOptions, optional) - Per-call configuration overrides
344
- - Returns: `Promise<string>` - Encrypted JWT token
345
-
346
- - **`decrypt(token, input, options?)`** - Decrypt and validate JWT token
347
- - `token` (string) - JWT token to decrypt
348
- - `input` (string) - Secret key or password for decryption
349
- - `options` (JwtDecryptOptions, optional) - Per-call configuration overrides
350
- - Returns: `Promise<JWTDecryptResult>` - Object containing `payload` and `protectedHeader`
351
-
352
- #### Configuration Details
353
-
354
- **Algorithms:**
355
- - `'dir'` (default) - Direct encryption with shared symmetric key
356
- - `'A128KW'`, `'A192KW'`, `'A256KW'` - AES Key Wrap algorithms
357
-
358
- **Encryption Methods:**
359
- - `'A256GCM'` (default) - AES-GCM with 256-bit key
360
- - `'A128GCM'`, `'A192GCM'` - AES-GCM with 128/192-bit keys
79
+ [📖 Full JWT Manager Documentation](./docs/jwt-manager.md)
361
80
 
362
- **Expiration Time Format:**
363
- - `'10m'` - 10 minutes
364
- - `'1h'` - 1 hour
365
- - `'7d'` - 7 days
366
- - `'30s'` - 30 seconds
367
-
368
- **JWT Claims:**
369
- - `issuer` (iss) - Token issuer identification
370
- - `audience` (aud) - Intended token recipient
371
- - `subject` (sub) - Token subject (usually user ID)
372
-
373
- ---
374
-
375
- ### 5. HTTP Handlers
376
-
377
- Custom error handling utilities with standardized HTTP status codes and error responses.
378
-
379
- #### Available Exports
81
+ ### HTTP Handlers
380
82
 
381
83
  ```javascript
382
- import {
383
- CustomError,
84
+ import {
85
+ httpCodes,
384
86
  httpError,
385
87
  httpErrorHandler,
386
- httpNotFoundHandler,
387
- httpCodes,
388
- httpMessages,
389
- httpHelper
88
+ httpNotFoundHandler
390
89
  } from '@igxjs/node-components';
391
- ```
392
-
393
- #### Usage Examples
394
90
 
395
- **Creating Custom Errors:**
396
-
397
- ```javascript
398
- // Using CustomError class
399
- throw new CustomError(httpCodes.BAD_REQUEST, 'Invalid input data');
400
-
401
- // Using httpError helper function (alias for new CustomError)
402
- throw httpError(httpCodes.BAD_REQUEST, 'Invalid input data');
403
-
404
- // With error details and additional data
405
- throw new CustomError(
406
- httpCodes.UNAUTHORIZED,
407
- 'Authentication failed',
408
- { originalError: err },
409
- { attemptedEmail: email }
410
- );
411
-
412
- // Using httpError with additional data
413
- throw httpError(
414
- httpCodes.UNAUTHORIZED,
415
- 'Authentication failed',
416
- { originalError: err },
417
- { attemptedEmail: email }
418
- );
419
- ```
420
-
421
- **Handling Axios/HTTP Errors:**
422
-
423
- ```javascript
424
- // Use httpHelper to handle Axios errors
425
- try {
426
- await axios.get('https://api.example.com/data');
427
- } catch (error) {
428
- // Convert Axios error to CustomError
429
- throw httpHelper.handleAxiosError(error, 'Failed to fetch data');
430
- }
431
-
432
- // Or use it in error handling
91
+ // Use in routes
433
92
  app.get('/api/data', async (req, res, next) => {
434
93
  try {
435
- const response = await axios.get('https://external-api.com/data');
436
- res.json(response.data);
94
+ const data = await fetchData();
95
+ res.json(data);
437
96
  } catch (error) {
438
- return next(httpHelper.handleAxiosError(error, 'Failed to fetch external data'));
97
+ next(httpError(httpCodes.SYSTEM_FAILURE, 'Failed to fetch data', error));
439
98
  }
440
99
  });
441
- ```
442
100
 
443
- **Error Handler Middleware:**
444
-
445
- ```javascript
446
- import express from 'express';
447
- import { httpErrorHandler, httpNotFoundHandler } from '@igxjs/node-components';
448
-
449
- const app = express();
450
-
451
- // Your routes here
452
- app.get('/api/data', async (req, res, next) => {
453
- try {
454
- // Your logic
455
- } catch (error) {
456
- next(error);
457
- }
458
- });
459
-
460
- // Add 404 handler before error handler
101
+ // Add middleware
461
102
  app.use(httpNotFoundHandler);
462
-
463
- // Add error handler as the last middleware
464
103
  app.use(httpErrorHandler);
465
104
  ```
466
105
 
467
- #### HTTP Codes & Messages
468
-
469
- **Available Status Codes:**
470
- - `httpCodes.OK` (200)
471
- - `httpCodes.CREATED` (201)
472
- - `httpCodes.NO_CONTENT` (204)
473
- - `httpCodes.BAD_REQUEST` (400)
474
- - `httpCodes.UNAUTHORIZED` (401)
475
- - `httpCodes.FORBIDDEN` (403)
476
- - `httpCodes.NOT_FOUND` (404)
477
- - `httpCodes.NOT_ACCEPTABLE` (406)
478
- - `httpCodes.CONFLICT` (409)
479
- - `httpCodes.LOCKED` (423)
480
- - `httpCodes.SYSTEM_FAILURE` (500)
481
- - `httpCodes.NOT_IMPLEMENTED` (501)
482
-
483
- **Available Status Messages:**
484
- - Corresponding `httpMessages` constants are available for each status code (e.g., `httpMessages.OK`, `httpMessages.BAD_REQUEST`, etc.)
485
-
486
- #### CustomError API
487
-
488
- **Constructor:**
489
- ```javascript
490
- // new CustomError(code, message, error, data)
491
- // - code: number - HTTP status code
492
- // - message: string - Error message
493
- // - error: object (optional) - Original error object
494
- // - object (optional) - Additional error data
495
- ```
496
-
497
- **Properties:**
498
- - **`code`** - HTTP status code (number)
499
- - **`message`** - Error message (string)
500
- - **`error`** - Original error object (if provided)
501
- - **`data`** - Additional error data (if provided)
502
-
503
- #### httpError API
504
-
505
- **Function:**
506
- - **`httpError(code, message, error?, data?)`** - Convenience function to create CustomError instances
507
- - `code` (number) - HTTP status code
508
- - `message` (string) - Error message
509
- - `error` (object, optional) - Original error object
510
- - `data` (object, optional) - Additional error data
511
- - Returns: `CustomError` instance
512
- - **Note:** This is an alias for `new CustomError()` - use whichever syntax you prefer
513
-
514
- #### httpErrorHandler API
515
-
516
- **Middleware Function:**
517
- - **`httpErrorHandler(err, req, res, next)`** - Express error handling middleware
518
- - Handles `CustomError` instances and other errors
519
- - Sets appropriate HTTP status codes and response format
520
- - Adds CORS headers automatically
521
- - Logs error details to console
522
- - **Usage:** Add as the last middleware in your Express app
523
-
524
- #### httpNotFoundHandler API
525
-
526
- **Middleware Function:**
527
- - **`httpNotFoundHandler(req, res, next)`** - Express 404 handler middleware
528
- - Catches all unmatched routes and returns 404 error
529
- - Creates a `CustomError` with NOT_FOUND status
530
- - **Usage:** Add before the error handler middleware
531
-
532
- #### httpHelper API
533
-
534
- The `httpHelper` object provides utility methods for error handling:
535
-
536
- **Methods:**
537
-
538
- - **`httpHelper.handleAxiosError(error, defaultMessage)`** - Analyze and convert Axios/HTTP errors to CustomError
539
- - `error` (Error | AxiosError) - The error object to analyze
540
- - `defaultMessage` (string, optional) - Default message if error message cannot be extracted (default: 'An error occurred')
541
- - Returns: `CustomError` instance with extracted status code, message, and data
542
-
543
- - **`httpHelper.format(str, ...args)`** - Format a string with placeholders
544
- - `str` (string) - String with `{0}`, `{1}`, etc. placeholders
545
- - `...args` - Values to replace placeholders
546
- - Returns: Formatted string
547
-
548
- - **`httpHelper.toZodMessage(error)`** - Generate friendly Zod validation error message
549
- - `error` (ZodError) - Zod validation error
550
- - Returns: Formatted error message string
551
-
552
- ---
106
+ [📖 Full HTTP Handlers Documentation](./docs/http-handlers.md)
553
107
 
554
108
  ## Features
555
109
 
556
- - ✅ **Session Management** - Full SSO integration with Redis or memory storage
557
- - ✅ **JWT Manager** - Secure JWT encryption/decryption with JWE using the jose library
558
- - ✅ **Flexible Routing** - Easy mounting of routers with context paths and middleware
559
- - ✅ **Redis Integration** - Robust Redis connection management with TLS support
560
- - ✅ **Error Handling** - Standardized error responses and HTTP status codes
561
- - ✅ **TypeScript Support** - Complete type definitions included
562
- - ✅ **Session Locking** - Prevents concurrent session refresh operations
563
- - ✅ **Automatic Reconnection** - Redis auto-reconnect with event handling
110
+ - ✅ **SSO Integration** - Full SSO support with Redis or memory storage
111
+ - ✅ **JWT Security** - Encrypted JWT tokens using JWE (jose library)
112
+ - ✅ **Flexible Routing** - Easy mounting with context paths and middleware
113
+ - ✅ **Redis Support** - TLS/SSL and automatic reconnection
114
+ - ✅ **Error Handling** - Standardized HTTP responses
115
+ - ✅ **TypeScript** - Complete type definitions included
116
+ - ✅ **Production Ready** - Session locking, auto-reconnection, error handling
564
117
 
565
118
  ## Requirements
566
119
 
@@ -568,26 +121,31 @@ The `httpHelper` object provides utility methods for error handling:
568
121
  - Express.js >= 4.x
569
122
  - Redis (optional, for session storage)
570
123
 
571
- ## TypeScript
124
+ ## TypeScript Support
572
125
 
573
- This package includes TypeScript definitions. You can import types in TypeScript projects:
126
+ This package includes TypeScript definitions:
574
127
 
575
128
  ```typescript
576
129
  import type {
577
- SessionConfig,
578
130
  SessionManager,
579
- SessionUser,
580
- SessionUserAttributes,
131
+ SessionConfig,
581
132
  JwtManager,
582
- JwtManagerOptions,
583
- JwtEncryptOptions,
584
- JwtDecryptOptions,
585
133
  FlexRouter,
586
134
  RedisManager,
587
135
  CustomError
588
136
  } from '@igxjs/node-components';
589
137
  ```
590
138
 
139
+ ## Documentation
140
+
141
+ 📚 **[Complete Documentation](./docs/README.md)** - Detailed guides for all components
142
+
143
+ - [SessionManager Documentation](./docs/session-manager.md) - Comprehensive SSO session management guide
144
+ - [FlexRouter Documentation](./docs/flex-router.md) - Advanced routing patterns
145
+ - [RedisManager Documentation](./docs/redis-manager.md) - Redis connection management
146
+ - [JWT Manager Documentation](./docs/jwt-manager.md) - Token authentication guide
147
+ - [HTTP Handlers Documentation](./docs/http-handlers.md) - Error handling utilities
148
+
591
149
  ## License
592
150
 
593
- [Apache 2.0](LICENSE.md)
151
+ [Apache 2.0](LICENSE)