@igxjs/node-components 1.0.15 → 1.0.16
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/components/assets/template.html +7 -2
- package/components/session.js +90 -70
- package/index.d.ts +9 -2
- package/package.json +3 -17
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<title>Sign in IBM Garage</title>
|
|
5
|
-
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no,viewport-fit=cover,minimum-scale=1,maximum-scale=
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no,viewport-fit=cover,minimum-scale=1,maximum-scale=2">
|
|
6
6
|
<meta name="robots" content="noindex, nofollow" />
|
|
7
7
|
<style>
|
|
8
8
|
:root {
|
|
@@ -94,9 +94,14 @@
|
|
|
94
94
|
localStorage.setItem('{{SESSION_EXPIRY_KEY}}', '{{SESSION_EXPIRY_VALUE}}');
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
/**
|
|
98
|
+
* Note: You can also request full user informlation by using ajax request or loading server side page.
|
|
99
|
+
*/
|
|
100
|
+
|
|
97
101
|
// Fall back to simple navigation
|
|
98
102
|
location.href = '{{SSO_SUCCESS_URL}}';
|
|
99
|
-
}
|
|
103
|
+
}
|
|
104
|
+
catch (e) {
|
|
100
105
|
console.error('Redirect failed:', e);
|
|
101
106
|
success = false;
|
|
102
107
|
}
|
package/components/session.js
CHANGED
|
@@ -272,7 +272,7 @@ export class SessionManager {
|
|
|
272
272
|
* @private
|
|
273
273
|
*/
|
|
274
274
|
#getTokenRedisKey(email, tid) {
|
|
275
|
-
return `${this.#config.SESSION_KEY}
|
|
275
|
+
return `${this.#config.SESSION_KEY}:${email}:${tid}`;
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
/**
|
|
@@ -282,7 +282,7 @@ export class SessionManager {
|
|
|
282
282
|
* @private
|
|
283
283
|
*/
|
|
284
284
|
#getTokenRedisPattern(email) {
|
|
285
|
-
return `${this.#config.SESSION_KEY}
|
|
285
|
+
return `${this.#config.SESSION_KEY}:${email}:*`;
|
|
286
286
|
}
|
|
287
287
|
|
|
288
288
|
/**
|
|
@@ -311,12 +311,12 @@ export class SessionManager {
|
|
|
311
311
|
});
|
|
312
312
|
app.set('trust proxy', 1);
|
|
313
313
|
const isOK = await this.#redisManager.connect(this.#config.REDIS_URL, this.#config.REDIS_CERT_PATH);
|
|
314
|
-
if (this
|
|
314
|
+
if (this.getSessionMode() === SessionMode.SESSION) {
|
|
315
315
|
app.use(this.#sessionHandler(isOK));
|
|
316
316
|
}
|
|
317
317
|
|
|
318
318
|
// Cache HTML template for TOKEN mode
|
|
319
|
-
if (this
|
|
319
|
+
if (this.getSessionMode() === SessionMode.TOKEN) {
|
|
320
320
|
const templatePath = this.#config.TOKEN_STORAGE_TEMPLATE_PATH ||
|
|
321
321
|
path.resolve(__dirname, 'assets', 'template.html');
|
|
322
322
|
this.#htmlTemplate = fs.readFileSync(templatePath, 'utf8');
|
|
@@ -324,27 +324,37 @@ export class SessionManager {
|
|
|
324
324
|
}
|
|
325
325
|
}
|
|
326
326
|
|
|
327
|
+
/**
|
|
328
|
+
* Generate lightweight JWT token
|
|
329
|
+
* @param {string} email User email
|
|
330
|
+
* @param {string} tokenId Token ID
|
|
331
|
+
* @param {number} expirationTime Expiration time in seconds
|
|
332
|
+
* @returns {Promise<string>} Returns the generated JWT token
|
|
333
|
+
* @private
|
|
334
|
+
*/
|
|
335
|
+
async #getLightweightToken(email, tokenId, expirationTime) {
|
|
336
|
+
return await this.#jwtManager.encrypt({ email, tid: tokenId }, this.#config.SSO_CLIENT_SECRET, { expirationTime });
|
|
337
|
+
}
|
|
338
|
+
|
|
327
339
|
/**
|
|
328
340
|
* Generate and store JWT token in Redis
|
|
329
341
|
* - JWT payload contains only { email, tid } for minimal size
|
|
330
342
|
* - Full user data is stored in Redis as single source of truth
|
|
331
|
-
* @param {
|
|
343
|
+
* @param {string} tid Token ID
|
|
344
|
+
* @param {Record<string, any> & { email: string, tid: string }} user User object with email and attributes
|
|
332
345
|
* @returns {Promise<string>} Returns the generated JWT token
|
|
333
346
|
* @throws {Error} If JWT encryption fails
|
|
334
347
|
* @throws {Error} If Redis storage fails
|
|
335
348
|
* @private
|
|
336
349
|
* @example
|
|
337
|
-
* const token = await this.#generateAndStoreToken({
|
|
350
|
+
* const token = await this.#generateAndStoreToken('tid', {
|
|
338
351
|
* email: 'user@example.com',
|
|
339
352
|
* attributes: { /* user data * / }
|
|
340
353
|
* });
|
|
341
354
|
*/
|
|
342
|
-
async #generateAndStoreToken(user) {
|
|
343
|
-
//
|
|
344
|
-
const
|
|
345
|
-
// Create JWT token with only email and tid (minimal payload)
|
|
346
|
-
const payload = { email: user.email, tid };
|
|
347
|
-
const token = await this.#jwtManager.encrypt(payload, this.#config.SESSION_SECRET, { expirationTime: this.#config.SESSION_AGE });
|
|
355
|
+
async #generateAndStoreToken(tid, user) {
|
|
356
|
+
// Create JWT token with only email, tid and idp (minimal payload)
|
|
357
|
+
const token = await this.#getLightweightToken(user.email, tid, this.#config.SESSION_AGE);
|
|
348
358
|
|
|
349
359
|
// Store user data in Redis with TTL
|
|
350
360
|
const redisKey = this.#getTokenRedisKey(user.email, tid);
|
|
@@ -357,28 +367,28 @@ export class SessionManager {
|
|
|
357
367
|
/**
|
|
358
368
|
* Extract and validate user data from Authorization header (TOKEN mode only)
|
|
359
369
|
* @param {string} authHeader Authorization header in format "Bearer {token}"
|
|
360
|
-
* @param {boolean} [
|
|
361
|
-
* - true: Returns { tid, user } with full user data
|
|
370
|
+
* @param {boolean} [includeUserData=true] Whether to include full user data in response
|
|
371
|
+
* - true: Returns { tid, user } with full user data (default)
|
|
362
372
|
* - false: Returns JWT payload only (lightweight validation)
|
|
363
|
-
* @returns {Promise<{ tid: string
|
|
364
|
-
* - When
|
|
365
|
-
* - When
|
|
373
|
+
* @returns {Promise<{ tid: string, user: { email: string, attributes: { expires_at: number, sub: string } } } & object>}
|
|
374
|
+
* - When includeUserData=true: { tid: string, user: object }
|
|
375
|
+
* - When includeUserData=false: JWT payload object
|
|
366
376
|
* @throws {CustomError} UNAUTHORIZED (401) if:
|
|
367
377
|
* - Authorization header is missing or invalid format
|
|
368
378
|
* - Token decryption fails
|
|
369
379
|
* - Token payload is invalid (missing email/tid)
|
|
370
|
-
* - Token not found in Redis (when
|
|
380
|
+
* - Token not found in Redis (when includeUserData=true)
|
|
371
381
|
* @private
|
|
372
382
|
*/
|
|
373
|
-
async #getUserFromToken(authHeader,
|
|
383
|
+
async #getUserFromToken(authHeader, includeUserData = true) {
|
|
374
384
|
if (!authHeader?.startsWith('Bearer ')) {
|
|
375
385
|
throw new CustomError(httpCodes.UNAUTHORIZED, 'Missing or invalid authorization header');
|
|
376
386
|
}
|
|
377
387
|
const token = authHeader.substring(7); // Remove 'Bearer ' prefix
|
|
378
|
-
|
|
379
|
-
const { payload } = await this.#jwtManager.decrypt(token, this.#config.
|
|
388
|
+
/** @type {{ payload: { email: string, tid: string } & import('jose').JWTPayload }} */
|
|
389
|
+
const { payload } = await this.#jwtManager.decrypt(token, this.#config.SSO_CLIENT_SECRET);
|
|
380
390
|
|
|
381
|
-
if (
|
|
391
|
+
if (includeUserData) {
|
|
382
392
|
/** @type {{ email: string, tid: string }} Extract email and token ID */
|
|
383
393
|
const { email, tid } = payload;
|
|
384
394
|
if (!email || !tid) {
|
|
@@ -392,14 +402,15 @@ export class SessionManager {
|
|
|
392
402
|
if (!userData) {
|
|
393
403
|
throw new CustomError(httpCodes.UNAUTHORIZED, 'Token not found or expired');
|
|
394
404
|
}
|
|
395
|
-
return { tid, user: JSON.parse(userData) };
|
|
405
|
+
return { tid, user: { ...JSON.parse(userData) } };
|
|
396
406
|
}
|
|
397
|
-
return payload;
|
|
407
|
+
return { tid: payload.tid, user: { email: payload.email, attributes: { sub: payload.sub, expires_at: payload.exp ? payload.exp * 1000 : 0 } } };
|
|
398
408
|
}
|
|
399
409
|
|
|
400
410
|
/**
|
|
401
411
|
* Get authenticated user data (works for both SESSION and TOKEN modes)
|
|
402
412
|
* @param {import('@types/express').Request} req Express request object
|
|
413
|
+
* @param {boolean} [includeUserData=false] Whether to include full user data in response
|
|
403
414
|
* @returns {Promise<object>} Full user data object
|
|
404
415
|
* @throws {CustomError} If user is not authenticated
|
|
405
416
|
* @public
|
|
@@ -415,9 +426,9 @@ export class SessionManager {
|
|
|
415
426
|
* }
|
|
416
427
|
* });
|
|
417
428
|
*/
|
|
418
|
-
async getUser(req) {
|
|
419
|
-
if (this
|
|
420
|
-
const { user } = await this.#getUserFromToken(req.headers.authorization,
|
|
429
|
+
async getUser(req, includeUserData = false) {
|
|
430
|
+
if (this.getSessionMode() === SessionMode.TOKEN) {
|
|
431
|
+
const { user } = await this.#getUserFromToken(req.headers.authorization, includeUserData);
|
|
421
432
|
return user;
|
|
422
433
|
}
|
|
423
434
|
// Session mode
|
|
@@ -484,17 +495,16 @@ export class SessionManager {
|
|
|
484
495
|
* @param {import('@types/express').Request} req Request with Authorization header
|
|
485
496
|
* @param {import('@types/express').Response} res Response object
|
|
486
497
|
* @param {import('@types/express').NextFunction} next Next middleware function
|
|
487
|
-
* @param {(user: object) => object} initUser Function to initialize/transform user object
|
|
498
|
+
* @param {(user: object) => object & { email: string }} initUser Function to initialize/transform user object
|
|
488
499
|
* @param {string} idpRefreshUrl Identity provider refresh endpoint URL
|
|
489
500
|
* @throws {CustomError} If refresh lock is active or SSO refresh fails
|
|
490
501
|
* @private
|
|
491
502
|
* @example
|
|
492
503
|
* // Response format:
|
|
493
|
-
* // { jwt: "new_jwt", user: {...}
|
|
504
|
+
* // { jwt: "new_jwt", user: {...} }
|
|
494
505
|
*/
|
|
495
506
|
async #refreshToken(req, res, next, initUser, idpRefreshUrl) {
|
|
496
507
|
try {
|
|
497
|
-
/** @type {{ tid: string, user: { email: string, attributes: { idp: string, refresh_token: string }? } }} */
|
|
498
508
|
const { tid, user } = await this.#getUserFromToken(req.headers.authorization, true);
|
|
499
509
|
|
|
500
510
|
// Check refresh lock
|
|
@@ -505,12 +515,11 @@ export class SessionManager {
|
|
|
505
515
|
|
|
506
516
|
// Call SSO refresh endpoint
|
|
507
517
|
const response = await this.#idpRequest.post(idpRefreshUrl, {
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
}
|
|
518
|
+
idp: user?.attributes?.idp,
|
|
519
|
+
refresh_token: user?.attributes?.refresh_token
|
|
520
|
+
}, {
|
|
521
|
+
headers: {
|
|
522
|
+
Authorization: req.headers.authorization
|
|
514
523
|
}
|
|
515
524
|
});
|
|
516
525
|
|
|
@@ -530,16 +539,12 @@ export class SessionManager {
|
|
|
530
539
|
const newUser = initUser(newPayload.user);
|
|
531
540
|
|
|
532
541
|
// Generate new token
|
|
533
|
-
const newToken = await this.#generateAndStoreToken(newUser);
|
|
534
|
-
|
|
535
|
-
// Remove old token from Redis
|
|
536
|
-
const oldRedisKey = this.#getTokenRedisKey(user.email, tid);
|
|
537
|
-
await this.#redisManager.getClient().del(oldRedisKey);
|
|
542
|
+
const newToken = await this.#generateAndStoreToken(tid, newUser);
|
|
538
543
|
|
|
539
544
|
this.#logger.debug('### TOKEN REFRESHED SUCCESSFULLY ###');
|
|
540
545
|
|
|
541
546
|
// Return new token
|
|
542
|
-
return res.json({ jwt: newToken, user: newUser
|
|
547
|
+
return res.json({ jwt: newToken, user: newUser });
|
|
543
548
|
} catch (error) {
|
|
544
549
|
return next(httpHelper.handleAxiosError(error));
|
|
545
550
|
}
|
|
@@ -557,23 +562,30 @@ export class SessionManager {
|
|
|
557
562
|
async #refreshSession(req, res, next, initUser, idpRefreshUrl) {
|
|
558
563
|
try {
|
|
559
564
|
const { email, attributes } = req.user || { email: '', attributes: {} };
|
|
565
|
+
// Check refresh lock
|
|
560
566
|
if (this.hasLock(email)) {
|
|
561
|
-
throw new CustomError(httpCodes.CONFLICT, '
|
|
567
|
+
throw new CustomError(httpCodes.CONFLICT, 'Session refresh is locked');
|
|
562
568
|
}
|
|
563
569
|
this.lock(email);
|
|
570
|
+
|
|
571
|
+
/** @type {string} */
|
|
572
|
+
const token = await this.#getLightweightToken(email, req.sessionID, req.user.attributes.expires_at);
|
|
573
|
+
|
|
574
|
+
// Call SSO refresh endpoint
|
|
564
575
|
const response = await this.#idpRequest.post(idpRefreshUrl, {
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
}
|
|
576
|
+
idp: attributes?.idp,
|
|
577
|
+
refresh_token: attributes?.refresh_token,
|
|
578
|
+
}, {
|
|
579
|
+
headers: {
|
|
580
|
+
Authorization: `Bearer ${token}`
|
|
571
581
|
}
|
|
572
582
|
});
|
|
573
583
|
if (response.status === httpCodes.OK) {
|
|
584
|
+
/** @type {{ jwt: string }} */
|
|
574
585
|
const { jwt } = response.data;
|
|
575
|
-
const payload = await this.#
|
|
576
|
-
|
|
586
|
+
const { payload } = await this.#jwtManager.decrypt(jwt, this.#config.SSO_CLIENT_SECRET);
|
|
587
|
+
const result = await this.#saveSession(req, payload, initUser);
|
|
588
|
+
return res.json(result);
|
|
577
589
|
}
|
|
578
590
|
throw new CustomError(response.status, response.statusText);
|
|
579
591
|
} catch (error) {
|
|
@@ -643,8 +655,8 @@ export class SessionManager {
|
|
|
643
655
|
|
|
644
656
|
try {
|
|
645
657
|
// Extract Token ID and email from current token
|
|
646
|
-
const
|
|
647
|
-
const { email
|
|
658
|
+
const { tid, user } = await this.#getUserFromToken(req.headers.authorization, false);
|
|
659
|
+
const { email } = user;
|
|
648
660
|
|
|
649
661
|
if (!email || !tid) {
|
|
650
662
|
throw new CustomError(httpCodes.BAD_REQUEST, 'Invalid token payload');
|
|
@@ -749,9 +761,9 @@ export class SessionManager {
|
|
|
749
761
|
* @returns {import('@types/express').RequestHandler} Returns express Request Handler
|
|
750
762
|
*/
|
|
751
763
|
requireUser = () => {
|
|
752
|
-
return async (req,
|
|
764
|
+
return async (req, _res, next) => {
|
|
753
765
|
try {
|
|
754
|
-
req.user = await this.getUser(req);
|
|
766
|
+
req.user = await this.getUser(req, true);
|
|
755
767
|
return next();
|
|
756
768
|
}
|
|
757
769
|
catch (error) {
|
|
@@ -786,7 +798,7 @@ export class SessionManager {
|
|
|
786
798
|
*/
|
|
787
799
|
authenticate(errorRedirectUrl = '') {
|
|
788
800
|
return async (req, res, next) => {
|
|
789
|
-
const mode = this
|
|
801
|
+
const mode = this.getSessionMode() || SessionMode.SESSION;
|
|
790
802
|
if (mode === SessionMode.TOKEN) {
|
|
791
803
|
return this.#verifyToken(req, res, next, errorRedirectUrl);
|
|
792
804
|
}
|
|
@@ -819,13 +831,11 @@ export class SessionManager {
|
|
|
819
831
|
/**
|
|
820
832
|
* Save session
|
|
821
833
|
* @param {import('@types/express').Request} request Request object
|
|
822
|
-
* @param {
|
|
834
|
+
* @param {import('jose').JWTPayload} payload JWT
|
|
823
835
|
* @param {(user: object) => object} initUser Redirect URL
|
|
824
836
|
* @returns {Promise<{ user: import('../models/types/user').UserModel, redirect_url: string }>} Promise
|
|
825
837
|
*/
|
|
826
|
-
#saveSession = async (request,
|
|
827
|
-
/** @type {{ payload: { user: import('../models/types/user').UserModel, redirect_url: string } }} */
|
|
828
|
-
const { payload } = await this.#jwtManager.decrypt(jwt, this.#config.SSO_CLIENT_SECRET);
|
|
838
|
+
#saveSession = async (request, payload, initUser) => {
|
|
829
839
|
if (payload?.user) {
|
|
830
840
|
this.#logger.debug('### CALLBACK USER ###');
|
|
831
841
|
request.session[this.#getSessionKey()] = initUser(payload.user);
|
|
@@ -876,26 +886,28 @@ export class SessionManager {
|
|
|
876
886
|
try {
|
|
877
887
|
// Decrypt JWT from Identity Adapter
|
|
878
888
|
const { payload } = await this.#jwtManager.decrypt(jwt, this.#config.SSO_CLIENT_SECRET);
|
|
879
|
-
|
|
889
|
+
|
|
880
890
|
if (!payload?.user) {
|
|
881
891
|
throw new CustomError(httpCodes.BAD_REQUEST, 'Invalid JWT payload');
|
|
882
892
|
}
|
|
883
893
|
|
|
884
|
-
/** @type {import('../index.js').SessionUser} */
|
|
885
|
-
const user = initUser(payload.user);
|
|
886
894
|
/** @type {string} */
|
|
887
895
|
const callbackRedirectUrl = payload.redirect_url || this.#config.SSO_SUCCESS_URL;
|
|
888
896
|
|
|
889
897
|
// Token mode: Generate token and return HTML page
|
|
890
|
-
if (this
|
|
891
|
-
|
|
898
|
+
if (this.getSessionMode() === SessionMode.TOKEN) {
|
|
899
|
+
/** @type {import('../index.js').SessionUser} */
|
|
900
|
+
const user = initUser(payload.user);
|
|
901
|
+
// Generate unique token ID for this device/session
|
|
902
|
+
const tid = crypto.randomUUID();
|
|
903
|
+
const token = await this.#generateAndStoreToken(tid, user);
|
|
892
904
|
this.#logger.debug('### CALLBACK TOKEN GENERATED ###');
|
|
893
905
|
const html = this.#renderTokenStorageHtml(token, user.attributes.expires_at, callbackRedirectUrl);
|
|
894
906
|
return res.send(html);
|
|
895
907
|
}
|
|
896
908
|
|
|
897
909
|
// Session mode: Save to session and redirect
|
|
898
|
-
await this.#saveSession(req,
|
|
910
|
+
await this.#saveSession(req, payload, initUser);
|
|
899
911
|
return res.redirect(callbackRedirectUrl);
|
|
900
912
|
}
|
|
901
913
|
catch (error) {
|
|
@@ -939,11 +951,12 @@ export class SessionManager {
|
|
|
939
951
|
refresh(initUser) {
|
|
940
952
|
const idpRefreshUrl = '/auth/refresh'.concat('?client_id=').concat(this.#config.SSO_CLIENT_ID);
|
|
941
953
|
return async (req, res, next) => {
|
|
942
|
-
const mode = this
|
|
954
|
+
const mode = this.getSessionMode() || SessionMode.SESSION;
|
|
943
955
|
|
|
944
956
|
if (mode === SessionMode.TOKEN) {
|
|
945
957
|
return this.#refreshToken(req, res, next, initUser, idpRefreshUrl);
|
|
946
|
-
}
|
|
958
|
+
}
|
|
959
|
+
else {
|
|
947
960
|
return this.#refreshSession(req, res, next, initUser, idpRefreshUrl);
|
|
948
961
|
}
|
|
949
962
|
};
|
|
@@ -958,8 +971,8 @@ export class SessionManager {
|
|
|
958
971
|
const { redirect = false, all = false } = req.query;
|
|
959
972
|
const isRedirect = (redirect === 'true' || redirect === true);
|
|
960
973
|
const logoutAll = (all === 'true' || all === true);
|
|
961
|
-
const mode = this
|
|
962
|
-
|
|
974
|
+
const mode = this.getSessionMode() || SessionMode.SESSION;
|
|
975
|
+
|
|
963
976
|
if (mode === SessionMode.TOKEN) {
|
|
964
977
|
return this.#logoutToken(req, res, isRedirect, logoutAll);
|
|
965
978
|
}
|
|
@@ -985,4 +998,11 @@ export class SessionManager {
|
|
|
985
998
|
};
|
|
986
999
|
}
|
|
987
1000
|
|
|
1001
|
+
/**
|
|
1002
|
+
* Get session mode
|
|
1003
|
+
* @returns {string} Session mode
|
|
1004
|
+
*/
|
|
1005
|
+
getSessionMode() {
|
|
1006
|
+
return this.#config.SESSION_MODE;
|
|
1007
|
+
}
|
|
988
1008
|
}
|
package/index.d.ts
CHANGED
|
@@ -316,6 +316,7 @@ export class SessionManager {
|
|
|
316
316
|
/**
|
|
317
317
|
* Get authenticated user data (works for both SESSION and TOKEN modes)
|
|
318
318
|
* @param req Express request object
|
|
319
|
+
* @param includeUserData Include user data in the response (default: false)
|
|
319
320
|
* @returns Promise resolving to full user data object
|
|
320
321
|
* @throws CustomError If user is not authenticated
|
|
321
322
|
* @example
|
|
@@ -323,7 +324,7 @@ export class SessionManager {
|
|
|
323
324
|
* // Use in custom middleware
|
|
324
325
|
* app.use(async (req, res, next) => {
|
|
325
326
|
* try {
|
|
326
|
-
* const user = await sessionManager.getUser(req);
|
|
327
|
+
* const user = await sessionManager.getUser(req, true);
|
|
327
328
|
* req.customUser = user;
|
|
328
329
|
* next();
|
|
329
330
|
* } catch (error) {
|
|
@@ -332,7 +333,7 @@ export class SessionManager {
|
|
|
332
333
|
* });
|
|
333
334
|
* ```
|
|
334
335
|
*/
|
|
335
|
-
getUser(req: Request): Promise<SessionUser>;
|
|
336
|
+
getUser(req: Request, includeUserData: boolean?): Promise<SessionUser>;
|
|
336
337
|
|
|
337
338
|
/**
|
|
338
339
|
* Initialize the session configurations and middleware
|
|
@@ -439,6 +440,12 @@ export class SessionManager {
|
|
|
439
440
|
* @returns Returns express Request Handler
|
|
440
441
|
*/
|
|
441
442
|
logout(): RequestHandler;
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* Get the current session mode
|
|
446
|
+
* @returns Returns 'session' or 'token' based on configuration
|
|
447
|
+
*/
|
|
448
|
+
getSessionMode(): string;
|
|
442
449
|
}
|
|
443
450
|
|
|
444
451
|
// Custom Error class
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@igxjs/node-components",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.16",
|
|
4
4
|
"description": "Node components for igxjs",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -12,21 +12,7 @@
|
|
|
12
12
|
"url": "git+https://github.com/igxjs/node-components.git"
|
|
13
13
|
},
|
|
14
14
|
"keywords": [
|
|
15
|
-
"igxjs"
|
|
16
|
-
"express",
|
|
17
|
-
"session-management",
|
|
18
|
-
"jwt",
|
|
19
|
-
"jwe",
|
|
20
|
-
"redis",
|
|
21
|
-
"authentication",
|
|
22
|
-
"sso",
|
|
23
|
-
"oauth",
|
|
24
|
-
"middleware",
|
|
25
|
-
"node-components",
|
|
26
|
-
"session",
|
|
27
|
-
"token-auth",
|
|
28
|
-
"bearer-token",
|
|
29
|
-
"express-middleware"
|
|
15
|
+
"igxjs"
|
|
30
16
|
],
|
|
31
17
|
"author": "Michael",
|
|
32
18
|
"license": "Apache-2.0",
|
|
@@ -43,7 +29,7 @@
|
|
|
43
29
|
"axios": "^1.13.6",
|
|
44
30
|
"connect-redis": "^9.0.0",
|
|
45
31
|
"express-session": "^1.19.0",
|
|
46
|
-
"jose": "^6.2.
|
|
32
|
+
"jose": "^6.2.2",
|
|
47
33
|
"memorystore": "^1.6.7"
|
|
48
34
|
},
|
|
49
35
|
"devDependencies": {
|