@carecard/jwt-read 3.19.0 → 3.20.0
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/lib/jwtLib.js +36 -18
- package/package.json +4 -4
package/lib/jwtLib.js
CHANGED
|
@@ -97,6 +97,7 @@ function validateAndExtractJwtObject(req, publicKey, customErrorFunction, option
|
|
|
97
97
|
|
|
98
98
|
if (jwtString && isJwtSignatureValid) {
|
|
99
99
|
_extractJwtObject(req, jwtString, customErrorFunction);
|
|
100
|
+
requireActiveExtractedToken(req, 'jwt', customErrorFunction);
|
|
100
101
|
validateAndExtractOptionalUserAuthorizationObject(req, options, customErrorFunction);
|
|
101
102
|
} else {
|
|
102
103
|
req['jwt'] = null;
|
|
@@ -114,6 +115,7 @@ function validateAndExtractWebToken(req, publicKey, headerName, customErrorFunct
|
|
|
114
115
|
|
|
115
116
|
if (webTokenString && isJwtSignatureValid) {
|
|
116
117
|
_extractJwtObject(req, webTokenString, customErrorFunction);
|
|
118
|
+
requireActiveExtractedToken(req, 'jwt', customErrorFunction);
|
|
117
119
|
validateAndExtractOptionalUserAuthorizationObject(req, options, customErrorFunction);
|
|
118
120
|
} else {
|
|
119
121
|
req['jwt'] = null;
|
|
@@ -463,6 +465,7 @@ function _isLoginRequired(hasRequiredRole, customErrorFunction) {
|
|
|
463
465
|
}
|
|
464
466
|
}
|
|
465
467
|
|
|
468
|
+
// Pattern: Fail-Closed Probe - accepts a bearer JWT only when signature and lifetime are valid.
|
|
466
469
|
function tryValidateAndExtractJwtObject(req, publicKey) {
|
|
467
470
|
const jwtString = _validateJwtNoThrow(req);
|
|
468
471
|
if (!jwtString || !isJwtString(jwtString)) {
|
|
@@ -476,7 +479,11 @@ function tryValidateAndExtractJwtObject(req, publicKey) {
|
|
|
476
479
|
}
|
|
477
480
|
|
|
478
481
|
_extractJwtObjectNoThrow(req, jwtString);
|
|
479
|
-
|
|
482
|
+
if (!isJwtPayloadWithinLifetime(req?.jwt?.payload)) {
|
|
483
|
+
req.jwt = null;
|
|
484
|
+
return false;
|
|
485
|
+
}
|
|
486
|
+
return true;
|
|
480
487
|
}
|
|
481
488
|
|
|
482
489
|
function _validateServerAuthToken(req, customErrorFunction) {
|
|
@@ -564,6 +571,7 @@ function normalizeSeconds(value) {
|
|
|
564
571
|
return value > 1000000000000 ? Math.floor(value / 1000) : Math.floor(value);
|
|
565
572
|
}
|
|
566
573
|
|
|
574
|
+
// Pattern: Policy - validates service identity, audience, and registered token lifetime.
|
|
567
575
|
function _isServiceJwtFor(payload, expectedIssuer, expectedAudience) {
|
|
568
576
|
if (!payload) {
|
|
569
577
|
return false;
|
|
@@ -577,16 +585,7 @@ function _isServiceJwtFor(payload, expectedIssuer, expectedAudience) {
|
|
|
577
585
|
if (!payloadAudienceMatches(payload.aud, expectedAudience)) {
|
|
578
586
|
return false;
|
|
579
587
|
}
|
|
580
|
-
|
|
581
|
-
return false;
|
|
582
|
-
}
|
|
583
|
-
if (isJwtPayloadExpired(payload)) {
|
|
584
|
-
return false;
|
|
585
|
-
}
|
|
586
|
-
if (isJwtPayloadNotYetValid(payload)) {
|
|
587
|
-
return false;
|
|
588
|
-
}
|
|
589
|
-
return true;
|
|
588
|
+
return isJwtPayloadWithinLifetime(payload);
|
|
590
589
|
}
|
|
591
590
|
|
|
592
591
|
function payloadAudienceMatches(actualAudience, expectedAudience) {
|
|
@@ -629,6 +628,27 @@ function isJwtPayloadNotYetValid(payload) {
|
|
|
629
628
|
return Math.floor(Date.now() / 1000) < nbf;
|
|
630
629
|
}
|
|
631
630
|
|
|
631
|
+
// Pattern: Specification - centralizes the registered time-claim policy for signed tokens.
|
|
632
|
+
function isJwtPayloadWithinLifetime(payload) {
|
|
633
|
+
return (
|
|
634
|
+
Boolean(payload) &&
|
|
635
|
+
!isJwtPayloadIssuedInFuture(payload) &&
|
|
636
|
+
!isJwtPayloadExpired(payload) &&
|
|
637
|
+
!isJwtPayloadNotYetValid(payload)
|
|
638
|
+
);
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
// Pattern: Guard Clause - clears an extracted token before surfacing an authentication failure.
|
|
642
|
+
function requireActiveExtractedToken(req, propertyName, customErrorFunction) {
|
|
643
|
+
if (isJwtPayloadWithinLifetime(req?.[propertyName]?.payload)) {
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
if (req) {
|
|
647
|
+
req[propertyName] = null;
|
|
648
|
+
}
|
|
649
|
+
throwError(customErrorFunction);
|
|
650
|
+
}
|
|
651
|
+
|
|
632
652
|
// Pattern: Factory - normalizes direct user authorization options into one config shape.
|
|
633
653
|
function createUserAuthorizationConfig(publicKey, options) {
|
|
634
654
|
return normalizeUserAuthorizationConfig({
|
|
@@ -705,13 +725,7 @@ function isUserAuthorizationTokenAllowed(token, config) {
|
|
|
705
725
|
if (!payload) {
|
|
706
726
|
return false;
|
|
707
727
|
}
|
|
708
|
-
if (
|
|
709
|
-
return false;
|
|
710
|
-
}
|
|
711
|
-
if (isJwtPayloadExpired(payload)) {
|
|
712
|
-
return false;
|
|
713
|
-
}
|
|
714
|
-
if (isJwtPayloadNotYetValid(payload)) {
|
|
728
|
+
if (!isJwtPayloadWithinLifetime(payload)) {
|
|
715
729
|
return false;
|
|
716
730
|
}
|
|
717
731
|
if (config.expectedType && payload.typ !== config.expectedType) {
|
|
@@ -762,6 +776,7 @@ function _validateGeneric(req, headerName, extractor, customErrorFunction) {
|
|
|
762
776
|
return null;
|
|
763
777
|
}
|
|
764
778
|
|
|
779
|
+
// Pattern: Fail-Closed Extraction - optional tokens survive only valid signatures and lifetimes.
|
|
765
780
|
function _validateAndExtractGenericNoThrow(req, publicKey, validator, extractor, propertyName) {
|
|
766
781
|
try {
|
|
767
782
|
const jwtString = validator(req);
|
|
@@ -769,6 +784,9 @@ function _validateAndExtractGenericNoThrow(req, publicKey, validator, extractor,
|
|
|
769
784
|
|
|
770
785
|
if (jwtString && isJwtSignatureValid) {
|
|
771
786
|
extractor(req, jwtString);
|
|
787
|
+
if (!isJwtPayloadWithinLifetime(req?.[propertyName]?.payload)) {
|
|
788
|
+
req[propertyName] = null;
|
|
789
|
+
}
|
|
772
790
|
} else {
|
|
773
791
|
req[propertyName] = null;
|
|
774
792
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@carecard/jwt-read",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.20.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/CareCard-ca/pkg-jwt-read.git"
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
"typescript": "6.0.3"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@carecard/auth-util": "3.
|
|
51
|
-
"@carecard/common-util": "3.
|
|
52
|
-
"@carecard/validate": "3.
|
|
50
|
+
"@carecard/auth-util": "3.20.0",
|
|
51
|
+
"@carecard/common-util": "3.20.0",
|
|
52
|
+
"@carecard/validate": "3.20.0"
|
|
53
53
|
},
|
|
54
54
|
"overrides": {
|
|
55
55
|
"diff": "8.0.4",
|