@igxjs/node-components 1.0.0 → 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 +3 -3
- package/components/http-handlers.js +24 -1
- package/components/session.js +28 -22
- package/index.d.ts +0 -6
- package/index.js +0 -4
- package/package.json +1 -1
- package/tests/session.test.js +1 -1
package/README.md
CHANGED
|
@@ -44,12 +44,13 @@ const config = {
|
|
|
44
44
|
|
|
45
45
|
```javascript
|
|
46
46
|
import express from 'express';
|
|
47
|
-
import {
|
|
47
|
+
import { SessionManager } from '@igxjs/node-components';
|
|
48
48
|
|
|
49
49
|
const app = express();
|
|
50
|
+
const session = new SessionManager(config);
|
|
50
51
|
|
|
51
52
|
// Initialize session
|
|
52
|
-
await session.setup(app,
|
|
53
|
+
await session.setup(app, (user) => {
|
|
53
54
|
// Process user object - compute permissions, avatar URL, etc.
|
|
54
55
|
return {
|
|
55
56
|
...user,
|
|
@@ -87,7 +88,6 @@ app.get('/auth/logout', session.logout());
|
|
|
87
88
|
#### API Methods
|
|
88
89
|
|
|
89
90
|
- **`setup(app, config, updateUser)`** - Initialize session configurations
|
|
90
|
-
- **`sessionHandler()`** - Session RequestHandler (returns Promise<RequestHandler>)
|
|
91
91
|
- **`authenticate(isDebugging?, redirectUrl?)`** - Resource protection middleware
|
|
92
92
|
- **`callback(initUser)`** - SSO callback handler for successful login
|
|
93
93
|
- **`identityProviders()`** - Get available identity providers
|
|
@@ -24,6 +24,7 @@ export const httpCodes = {
|
|
|
24
24
|
NOT_ACCEPTABLE: 406,
|
|
25
25
|
CONFLICT: 409,
|
|
26
26
|
SYSTEM_FAILURE: 500,
|
|
27
|
+
NOT_IMPLEMENTED: 501,
|
|
27
28
|
};
|
|
28
29
|
|
|
29
30
|
export class CustomError extends Error {
|
|
@@ -47,7 +48,7 @@ export class CustomError extends Error {
|
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
/**
|
|
50
|
-
* Custom
|
|
51
|
+
* Custom Error handler
|
|
51
52
|
*
|
|
52
53
|
* @param {CustomError} err Error
|
|
53
54
|
* @param {import('@types/express').Request} req Request
|
|
@@ -98,6 +99,16 @@ export const httpErrorHandler = (err, req, res, next) => {
|
|
|
98
99
|
console.error('### /ERROR ###');
|
|
99
100
|
};
|
|
100
101
|
|
|
102
|
+
/**
|
|
103
|
+
* HTTP not found error handler
|
|
104
|
+
* @param {Request} _req Request object
|
|
105
|
+
* @param {Response} _res Response object
|
|
106
|
+
* @param {NextFunction} next Next function
|
|
107
|
+
*/
|
|
108
|
+
export const httpNotFoundHandler = (_req, _res, next) => {
|
|
109
|
+
next(new CustomError(httpCodes.NOT_FOUND, httpMessages.NOT_FOUND));
|
|
110
|
+
};
|
|
111
|
+
|
|
101
112
|
/**
|
|
102
113
|
* Extract HTTP status code from error
|
|
103
114
|
* @param {Error} error Error object
|
|
@@ -165,3 +176,15 @@ export const httpHelper = {
|
|
|
165
176
|
return new CustomError(errorCode, errorMessage, error, errorData);
|
|
166
177
|
}
|
|
167
178
|
};
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* HTTP Error - alias of `new CustomError()`
|
|
182
|
+
* @param {Number} code Error code
|
|
183
|
+
* @param {string} message Error message
|
|
184
|
+
* @param {Error} error Original Error instance
|
|
185
|
+
* @param {any} data Error data
|
|
186
|
+
* @returns {CustomError} Returns a new instance of CustomError
|
|
187
|
+
*/
|
|
188
|
+
export const httpError = (code, message, error, data) => {
|
|
189
|
+
return new CustomError(code, message, error, data);
|
|
190
|
+
};
|
package/components/session.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
2
|
import session from 'express-session';
|
|
3
|
-
import { jwtDecrypt } from 'jose';
|
|
4
|
-
import { RedisStore } from 'connect-redis';
|
|
5
3
|
import memStore from 'memorystore';
|
|
4
|
+
import { RedisStore } from 'connect-redis';
|
|
5
|
+
import { jwtDecrypt } from 'jose';
|
|
6
6
|
|
|
7
7
|
import { CustomError, httpCodes, httpHelper, httpMessages } from './http-handlers.js';
|
|
8
8
|
import { RedisManager } from './redis.js';
|
|
@@ -46,6 +46,29 @@ export class SessionManager {
|
|
|
46
46
|
/** @type {import('axios').AxiosInstance} */
|
|
47
47
|
#idpRequest = null;
|
|
48
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Create a new session manager
|
|
51
|
+
* @param {SessionConfig} config Session configuration
|
|
52
|
+
*/
|
|
53
|
+
constructor(config) {
|
|
54
|
+
this.#config = {
|
|
55
|
+
// Session
|
|
56
|
+
SESSION_AGE: config.SESSION_AGE || 64800000,
|
|
57
|
+
SESSION_COOKIE_PATH: config.SESSION_COOKIE_PATH || '/',
|
|
58
|
+
SESSION_SECRET: config.SESSION_SECRET,
|
|
59
|
+
SESSION_PREFIX: config.SESSION_PREFIX || 'ibmid:',
|
|
60
|
+
// Identity Provider
|
|
61
|
+
SSO_ENDPOINT_URL: config.SSO_ENDPOINT_URL,
|
|
62
|
+
SSO_CLIENT_ID: config.SSO_CLIENT_ID,
|
|
63
|
+
SSO_CLIENT_SECRET: config.SSO_CLIENT_SECRET,
|
|
64
|
+
SSO_SUCCESS_URL: config.SSO_SUCCESS_URL,
|
|
65
|
+
SSO_FAILURE_URL: config.SSO_FAILURE_URL,
|
|
66
|
+
// Redis
|
|
67
|
+
REDIS_URL: config.REDIS_URL,
|
|
68
|
+
REDIS_CERT_PATH: config.REDIS_CERT_PATH,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
49
72
|
/**
|
|
50
73
|
* Check if the email has a session refresh lock
|
|
51
74
|
* @param {string} email Email address
|
|
@@ -99,34 +122,17 @@ export class SessionManager {
|
|
|
99
122
|
/**
|
|
100
123
|
* Setup the session/user handlers with configurations
|
|
101
124
|
* @param {import('@types/express').Application} app Express application
|
|
102
|
-
* @param {SessionConfig} config Redis configurations
|
|
103
125
|
* @param {(user: object) => object} updateUser Update user object if user should have proper attributes, e.g. permissions, avatar URL
|
|
104
126
|
*/
|
|
105
|
-
async setup(app,
|
|
127
|
+
async setup(app, updateUser) {
|
|
106
128
|
this.#redisManager = new RedisManager();
|
|
107
|
-
this.#config = {
|
|
108
|
-
// Session
|
|
109
|
-
SESSION_AGE: config.SESSION_AGE || 64800000,
|
|
110
|
-
SESSION_COOKIE_PATH: config.SESSION_COOKIE_PATH || '/',
|
|
111
|
-
SESSION_SECRET: config.SESSION_SECRET,
|
|
112
|
-
SESSION_PREFIX: config.SESSION_PREFIX || 'ibmid:',
|
|
113
|
-
// Identity Provider
|
|
114
|
-
SSO_ENDPOINT_URL: config.SSO_ENDPOINT_URL,
|
|
115
|
-
SSO_CLIENT_ID: config.SSO_CLIENT_ID,
|
|
116
|
-
SSO_CLIENT_SECRET: config.SSO_CLIENT_SECRET,
|
|
117
|
-
SSO_SUCCESS_URL: config.SSO_SUCCESS_URL,
|
|
118
|
-
SSO_FAILURE_URL: config.SSO_FAILURE_URL,
|
|
119
|
-
// Redis
|
|
120
|
-
REDIS_URL: config.REDIS_URL,
|
|
121
|
-
REDIS_CERT_PATH: config.REDIS_CERT_PATH,
|
|
122
|
-
};
|
|
123
129
|
// Identity Provider Request
|
|
124
130
|
this.#idpRequest = axios.create({
|
|
125
131
|
baseURL: this.#config.SSO_ENDPOINT_URL,
|
|
126
132
|
timeout: 30000,
|
|
127
133
|
});
|
|
128
134
|
app.set('trust proxy', 1);
|
|
129
|
-
app.use(await this
|
|
135
|
+
app.use(await this.#sessionHandler());
|
|
130
136
|
app.use(this.#userHandler(updateUser));
|
|
131
137
|
}
|
|
132
138
|
|
|
@@ -164,7 +170,7 @@ export class SessionManager {
|
|
|
164
170
|
* Get session RequestHandler
|
|
165
171
|
* @returns {Promise<import('@types/express').RequestHandler>} Returns RequestHandler instance of Express
|
|
166
172
|
*/
|
|
167
|
-
async sessionHandler() {
|
|
173
|
+
async #sessionHandler() {
|
|
168
174
|
if(this.#config.REDIS_URL?.length > 0) {
|
|
169
175
|
await this.#redisManager.connect(this.#config.REDIS_URL, this.#config.REDIS_CERT_PATH);
|
|
170
176
|
return this.#redisSession();
|
package/index.d.ts
CHANGED
|
@@ -91,12 +91,6 @@ export class SessionManager {
|
|
|
91
91
|
updateUser: (user: SessionUser | undefined) => any
|
|
92
92
|
): Promise<void>;
|
|
93
93
|
|
|
94
|
-
/**
|
|
95
|
-
* Get session RequestHandler
|
|
96
|
-
* @returns Returns RequestHandler instance of Express
|
|
97
|
-
*/
|
|
98
|
-
sessionHandler(): Promise<RequestHandler>;
|
|
99
|
-
|
|
100
94
|
/**
|
|
101
95
|
* Resource protection middleware
|
|
102
96
|
* @param isDebugging Debugging flag (default: false)
|
package/index.js
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import { SessionManager } from './components/session.js';
|
|
2
|
-
|
|
3
1
|
export { SessionConfig, SessionManager } from './components/session.js';
|
|
4
2
|
export { httpCodes, httpMessages, httpErrorHandler, CustomError, httpHelper } from './components/http-handlers.js';
|
|
5
3
|
export { RedisManager } from './components/redis.js';
|
|
6
4
|
export { FlexRouter } from './components/router.js';
|
|
7
|
-
|
|
8
|
-
export const session = new SessionManager();
|
package/package.json
CHANGED
package/tests/session.test.js
CHANGED
|
@@ -9,7 +9,6 @@ describe('SessionManager', () => {
|
|
|
9
9
|
let clock;
|
|
10
10
|
|
|
11
11
|
beforeEach(() => {
|
|
12
|
-
sessionManager = new SessionManager();
|
|
13
12
|
clock = sinon.useFakeTimers();
|
|
14
13
|
});
|
|
15
14
|
|
|
@@ -24,6 +23,7 @@ describe('SessionManager', () => {
|
|
|
24
23
|
expect(config).to.have.property('SSO_ENDPOINT_URL');
|
|
25
24
|
expect(config).to.have.property('SESSION_SECRET');
|
|
26
25
|
expect(config).to.have.property('REDIS_URL');
|
|
26
|
+
sessionManager = new SessionManager(config);
|
|
27
27
|
});
|
|
28
28
|
});
|
|
29
29
|
|