@carecard/jwt-read 3.1.13 → 3.1.15
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/.agents/config.toml +2 -0
- package/.agents/skills/carecard-workspace-standards/SKILL.md +388 -0
- package/.agents/skills/carecard-workspace-standards/agents/openai.yaml +4 -0
- package/.agents/skills/github-pr-create-update/SKILL.md +188 -0
- package/.agents/skills/github-pr-create-update/agents/openai.yaml +5 -0
- package/.agents/skills/github-pr-merge-cleanup/SKILL.md +175 -0
- package/.agents/skills/github-pr-merge-cleanup/agents/openai.yaml +5 -0
- package/.agents/skills/pkg-jwt-read-jwt-middleware-library/SKILL.md +239 -0
- package/.agents/skills/pkg-jwt-read-jwt-middleware-library/agents/openai.yaml +4 -0
- package/.agents/skills/software-design-patterns-and-clean-code/SKILL.md +73 -0
- package/.codex/config.toml +2 -0
- package/.prettierrc.js +12 -0
- package/eslint.config.mjs +14 -0
- package/index.d.ts +91 -26
- package/index.js +48 -45
- package/lib/jwtLib.js +313 -256
- package/lib/jwtRoles.js +32 -13
- package/package.json +20 -12
- package/readme.md +35 -5
package/lib/jwtLib.js
CHANGED
|
@@ -1,411 +1,468 @@
|
|
|
1
|
-
const {isJwtString} = require('@carecard/validate')
|
|
2
|
-
const {jwtVerifySignedToken, jwtGetHeaderPayload} = require('@carecard/auth-util');
|
|
1
|
+
const { isJwtString } = require('@carecard/validate');
|
|
2
|
+
const { jwtVerifySignedToken, jwtGetHeaderPayload } = require('@carecard/auth-util');
|
|
3
3
|
|
|
4
|
-
const {
|
|
5
|
-
throwLoginRequiredError,
|
|
6
|
-
throwNotAuthorizedError
|
|
7
|
-
} = require("@carecard/common-util").error;
|
|
4
|
+
const { throwLoginRequiredError, throwNotAuthorizedError } = require('@carecard/common-util');
|
|
8
5
|
|
|
9
6
|
function jwtClientId(req) {
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
const jwtObj = req?.jwt || this;
|
|
8
|
+
return jwtObj?.payload?.sub;
|
|
12
9
|
}
|
|
13
10
|
|
|
14
11
|
function visitorClientId(req) {
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
const visitorObj = req?.visitor || this;
|
|
13
|
+
return visitorObj?.payload?.sub;
|
|
17
14
|
}
|
|
18
15
|
|
|
19
16
|
function doesJwtUserHasRole(req, userRole) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
// Check if called as req.jwt.doesJwtUserHasRole(userRole) or doesJwtUserHasRole(role)
|
|
18
|
+
if (arguments.length === 1 && typeof req === 'string') {
|
|
19
|
+
userRole = req;
|
|
20
|
+
req = undefined;
|
|
21
|
+
}
|
|
25
22
|
|
|
26
|
-
|
|
23
|
+
const jwtObj = req?.jwt || this;
|
|
27
24
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
if (!userRole || typeof userRole !== 'string' || !jwtObj?.payload?.roles || !Array.isArray(jwtObj.payload.roles)) {
|
|
26
|
+
throwNotAuthorizedError();
|
|
27
|
+
}
|
|
31
28
|
|
|
32
|
-
|
|
29
|
+
return jwtObj.payload.roles.includes(userRole);
|
|
33
30
|
}
|
|
34
31
|
|
|
35
32
|
function throwError(customErrorFunction) {
|
|
36
|
-
|
|
37
|
-
customErrorFunction() :
|
|
38
|
-
throwLoginRequiredError()
|
|
33
|
+
typeof customErrorFunction === 'function' ? customErrorFunction() : throwLoginRequiredError();
|
|
39
34
|
}
|
|
40
35
|
|
|
41
36
|
function isJwtExpired(req, jwtValiditySeconds) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
37
|
+
// Check if called as req.jwt.isJwtExpired(seconds) or isJwtExpired(seconds)
|
|
38
|
+
if (arguments.length === 1 && typeof req === 'number') {
|
|
39
|
+
jwtValiditySeconds = req;
|
|
40
|
+
req = undefined;
|
|
41
|
+
}
|
|
47
42
|
|
|
48
|
-
|
|
43
|
+
const jwtObj = req?.jwt || this;
|
|
49
44
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (jwtValiditySeconds && typeof jwtValiditySeconds === "number") {
|
|
55
|
-
return (parseInt(jwtValiditySeconds)) < jwtAgeInSeconds.call(this, req);
|
|
56
|
-
} else {
|
|
57
|
-
return true;
|
|
58
|
-
}
|
|
45
|
+
if (jwtObj?.payload?.exp) {
|
|
46
|
+
return Math.floor(Date.now() / 1000) >= jwtObj.payload.exp;
|
|
47
|
+
}
|
|
59
48
|
|
|
49
|
+
if (jwtValiditySeconds && typeof jwtValiditySeconds === 'number') {
|
|
50
|
+
return parseInt(jwtValiditySeconds) < jwtAgeInSeconds.call(this, req);
|
|
51
|
+
} else {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
60
54
|
}
|
|
61
55
|
|
|
62
56
|
function jwtAgeInSeconds(req) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if (jwtObj?.payload?.iat) {
|
|
66
|
-
|
|
67
|
-
let iat = jwtObj.payload.iat;
|
|
68
|
-
if (iat > 1000000000000) {
|
|
69
|
-
iat = Math.floor(iat / 1000);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
jwtObj["age"] = Math.floor(Date.now() / 1000) - iat;
|
|
73
|
-
return jwtObj.age;
|
|
74
|
-
|
|
75
|
-
} else {
|
|
76
|
-
|
|
77
|
-
jwtObj["age"] = Infinity
|
|
78
|
-
return jwtObj.age;
|
|
57
|
+
const jwtObj = req?.jwt || this;
|
|
79
58
|
|
|
59
|
+
if (jwtObj?.payload?.iat) {
|
|
60
|
+
let iat = jwtObj.payload.iat;
|
|
61
|
+
if (iat > 1000000000000) {
|
|
62
|
+
iat = Math.floor(iat / 1000);
|
|
80
63
|
}
|
|
64
|
+
|
|
65
|
+
jwtObj['age'] = Math.floor(Date.now() / 1000) - iat;
|
|
66
|
+
return jwtObj.age;
|
|
67
|
+
} else {
|
|
68
|
+
jwtObj['age'] = Infinity;
|
|
69
|
+
return jwtObj.age;
|
|
70
|
+
}
|
|
81
71
|
}
|
|
82
72
|
|
|
83
73
|
function validateAndExtractJwtObject(req, publicKey, customErrorFunction) {
|
|
74
|
+
const jwtString = _validateJwt(req, customErrorFunction);
|
|
84
75
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const isJwtSignatureValid = jwtVerifySignedToken(jwtString, publicKey);
|
|
76
|
+
const isJwtSignatureValid = jwtVerifySignedToken(jwtString, publicKey);
|
|
88
77
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
78
|
+
if (jwtString && isJwtSignatureValid) {
|
|
79
|
+
_extractJwtObject(req, jwtString, customErrorFunction);
|
|
80
|
+
} else {
|
|
81
|
+
req['jwt'] = null;
|
|
82
|
+
throwError(customErrorFunction);
|
|
83
|
+
}
|
|
95
84
|
|
|
96
|
-
|
|
85
|
+
return req;
|
|
97
86
|
}
|
|
98
87
|
|
|
99
88
|
function validateAndExtractWebToken(req, publicKey, headerName, customErrorFunction) {
|
|
89
|
+
const webTokenString = _validateWebToken(req, headerName, customErrorFunction);
|
|
100
90
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const isJwtSignatureValid = jwtVerifySignedToken(webTokenString, publicKey);
|
|
91
|
+
const isJwtSignatureValid = jwtVerifySignedToken(webTokenString, publicKey);
|
|
104
92
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
93
|
+
if (webTokenString && isJwtSignatureValid) {
|
|
94
|
+
_extractJwtObject(req, webTokenString, customErrorFunction);
|
|
95
|
+
} else {
|
|
96
|
+
req['jwt'] = null;
|
|
97
|
+
throwError(customErrorFunction);
|
|
98
|
+
}
|
|
111
99
|
|
|
112
|
-
|
|
100
|
+
return req;
|
|
113
101
|
}
|
|
114
102
|
|
|
115
103
|
function validateAndExtractJwtObjectNoThrow(req, publicKey) {
|
|
116
|
-
|
|
104
|
+
return _validateAndExtractGenericNoThrow(req, publicKey, _validateJwtNoThrow, _extractJwtObjectNoThrow, 'jwt');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function validateAndExtractServiceJwtObject(req, publicKey, expectedIssuer, expectedAudience, customErrorFunction) {
|
|
108
|
+
const jwtString = _validateJwt(req, customErrorFunction);
|
|
109
|
+
const isJwtSignatureValid = jwtVerifySignedToken(jwtString, publicKey);
|
|
110
|
+
|
|
111
|
+
if (jwtString && isJwtSignatureValid) {
|
|
112
|
+
_extractJwtObject(req, jwtString, customErrorFunction);
|
|
113
|
+
} else if (req) {
|
|
114
|
+
req.jwt = null;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (!req?.jwt || !_isServiceJwtFor(req.jwt.payload, expectedIssuer, expectedAudience)) {
|
|
118
|
+
if (req) req.jwt = null;
|
|
119
|
+
throwError(customErrorFunction);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return req;
|
|
117
123
|
}
|
|
118
124
|
|
|
119
125
|
function validateAndExtractWebTokenObjectNoThrow(req, publicKey, headerName) {
|
|
120
|
-
|
|
126
|
+
return _validateAndExtractGenericNoThrow(req, publicKey, r => _validateWebTokenNoThrow(r, headerName), _extractJwtObjectNoThrow, 'jwt');
|
|
121
127
|
}
|
|
122
128
|
|
|
123
129
|
function validateAndExtractVisitorObjectNoThrow(req, publicKey) {
|
|
124
|
-
|
|
130
|
+
return _validateAndExtractGenericNoThrow(req, publicKey, _validateVisitorNoThrow, _extractVisitorObjectNoThrow, 'visitor');
|
|
125
131
|
}
|
|
126
132
|
|
|
127
133
|
function verifyJwtAndRole(role, publicKey, customErrorFunction) {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
134
|
+
return function (req, res, next) {
|
|
135
|
+
try {
|
|
136
|
+
validateAndExtractJwtObject(req, publicKey, customErrorFunction);
|
|
137
|
+
const isRoleExist = doesJwtUserHasRole(req, role);
|
|
138
|
+
_isLoginRequired(isRoleExist, customErrorFunction);
|
|
139
|
+
next();
|
|
140
|
+
} catch (err) {
|
|
141
|
+
next(err);
|
|
137
142
|
}
|
|
143
|
+
};
|
|
138
144
|
}
|
|
139
145
|
|
|
140
146
|
function verifyJwt(publicKey, customErrorFunction) {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
147
|
+
return function (req, res, next) {
|
|
148
|
+
try {
|
|
149
|
+
validateAndExtractJwtObject(req, publicKey, customErrorFunction);
|
|
150
|
+
next();
|
|
151
|
+
} catch (err) {
|
|
152
|
+
next(err);
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function verifyServiceJwt(publicKey, expectedIssuer, expectedAudience, customErrorFunction) {
|
|
158
|
+
return function (req, res, next) {
|
|
159
|
+
try {
|
|
160
|
+
validateAndExtractServiceJwtObject(req, publicKey, expectedIssuer, expectedAudience, customErrorFunction);
|
|
161
|
+
next();
|
|
162
|
+
} catch (err) {
|
|
163
|
+
next(err);
|
|
148
164
|
}
|
|
165
|
+
};
|
|
149
166
|
}
|
|
150
167
|
|
|
151
168
|
function verifyWebToken(publicKey, headerName, customErrorFunction) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
169
|
+
return function (req, res, next) {
|
|
170
|
+
try {
|
|
171
|
+
validateAndExtractWebToken(req, publicKey, headerName, customErrorFunction);
|
|
172
|
+
next();
|
|
173
|
+
} catch (err) {
|
|
174
|
+
next(err);
|
|
159
175
|
}
|
|
176
|
+
};
|
|
160
177
|
}
|
|
161
178
|
|
|
162
179
|
function verifyJwtNoThrow(publicKey) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
180
|
+
return function (req, res, next) {
|
|
181
|
+
try {
|
|
182
|
+
validateAndExtractJwtObjectNoThrow(req, publicKey);
|
|
183
|
+
next();
|
|
184
|
+
} catch (err) {
|
|
185
|
+
next(err);
|
|
170
186
|
}
|
|
187
|
+
};
|
|
171
188
|
}
|
|
172
189
|
|
|
173
190
|
function verifyWebTokenNoThrow(publicKey, headerName) {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
191
|
+
return function (req, res, next) {
|
|
192
|
+
try {
|
|
193
|
+
validateAndExtractWebTokenObjectNoThrow(req, publicKey, headerName);
|
|
194
|
+
next();
|
|
195
|
+
} catch (err) {
|
|
196
|
+
next(err);
|
|
181
197
|
}
|
|
198
|
+
};
|
|
182
199
|
}
|
|
183
200
|
|
|
184
201
|
function verifyVisitorNoThrow(publicKey) {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
202
|
+
return function (req, res, next) {
|
|
203
|
+
try {
|
|
204
|
+
validateAndExtractVisitorObjectNoThrow(req, publicKey);
|
|
205
|
+
next();
|
|
206
|
+
} catch (err) {
|
|
207
|
+
next(err);
|
|
192
208
|
}
|
|
209
|
+
};
|
|
193
210
|
}
|
|
194
211
|
|
|
195
212
|
function throwUsedTokenError() {
|
|
196
|
-
|
|
213
|
+
throw new Error('Used_Token');
|
|
197
214
|
}
|
|
198
215
|
|
|
199
216
|
/*********************
|
|
200
217
|
* Private functions *
|
|
201
218
|
*********************/
|
|
202
219
|
function _isLoginRequired(hasRequiredRole, customErrorFunction) {
|
|
220
|
+
if (!hasRequiredRole) {
|
|
221
|
+
throwError(customErrorFunction);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
203
224
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
225
|
+
function normalizeSeconds(value) {
|
|
226
|
+
if (!Number.isFinite(value)) return null;
|
|
227
|
+
return value > 1000000000000 ? Math.floor(value / 1000) : Math.floor(value);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function _isServiceJwtFor(payload, expectedIssuer, expectedAudience) {
|
|
231
|
+
if (!payload) return false;
|
|
232
|
+
if (payload.iss !== expectedIssuer) return false;
|
|
233
|
+
if (payload.sub !== expectedIssuer) return false;
|
|
234
|
+
if (!payloadAudienceMatches(payload.aud, expectedAudience)) return false;
|
|
235
|
+
if (isJwtPayloadIssuedInFuture(payload)) return false;
|
|
236
|
+
if (isJwtPayloadExpired(payload)) return false;
|
|
237
|
+
if (isJwtPayloadNotYetValid(payload)) return false;
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function payloadAudienceMatches(actualAudience, expectedAudience) {
|
|
242
|
+
if (Array.isArray(actualAudience)) return actualAudience.includes(expectedAudience);
|
|
243
|
+
return actualAudience === expectedAudience;
|
|
244
|
+
}
|
|
207
245
|
|
|
246
|
+
function isJwtPayloadExpired(payload) {
|
|
247
|
+
if (!payload.exp) return true;
|
|
248
|
+
const exp = normalizeSeconds(payload.exp);
|
|
249
|
+
if (!Number.isInteger(exp)) return true;
|
|
250
|
+
return Math.floor(Date.now() / 1000) >= exp;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function isJwtPayloadIssuedInFuture(payload) {
|
|
254
|
+
if (!payload.iat) return true;
|
|
255
|
+
const iat = normalizeSeconds(payload.iat);
|
|
256
|
+
if (!Number.isInteger(iat)) return true;
|
|
257
|
+
return Math.floor(Date.now() / 1000) < iat;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function isJwtPayloadNotYetValid(payload) {
|
|
261
|
+
if (!payload.nbf) return false;
|
|
262
|
+
const nbf = normalizeSeconds(payload.nbf);
|
|
263
|
+
if (!Number.isInteger(nbf)) return true;
|
|
264
|
+
return Math.floor(Date.now() / 1000) < nbf;
|
|
208
265
|
}
|
|
209
266
|
|
|
210
267
|
function _validateGenericNoThrow(req, headerName, extractor) {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
268
|
+
let jwtRaw = req.get(headerName);
|
|
269
|
+
if (!jwtRaw) return null;
|
|
270
|
+
let jwt = extractor(jwtRaw);
|
|
271
|
+
return isJwtString(jwt) ? jwt : null;
|
|
215
272
|
}
|
|
216
273
|
|
|
217
274
|
function _validateGeneric(req, headerName, extractor, customErrorFunction) {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
275
|
+
let jwtRaw = req.get(headerName);
|
|
276
|
+
let jwt = extractor(jwtRaw, customErrorFunction);
|
|
277
|
+
if (isJwtString(jwt)) return jwt;
|
|
278
|
+
throwError(customErrorFunction);
|
|
279
|
+
return null;
|
|
223
280
|
}
|
|
224
281
|
|
|
225
282
|
function _validateAndExtractGenericNoThrow(req, publicKey, validator, extractor, propertyName) {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
}
|
|
235
|
-
} catch (err) {
|
|
236
|
-
if (req) req[propertyName] = null;
|
|
237
|
-
throw err;
|
|
283
|
+
try {
|
|
284
|
+
const jwtString = validator(req);
|
|
285
|
+
const isJwtSignatureValid = jwtVerifySignedToken(jwtString, publicKey);
|
|
286
|
+
|
|
287
|
+
if (jwtString && isJwtSignatureValid) {
|
|
288
|
+
extractor(req, jwtString);
|
|
289
|
+
} else {
|
|
290
|
+
req[propertyName] = null;
|
|
238
291
|
}
|
|
239
|
-
|
|
292
|
+
} catch (err) {
|
|
293
|
+
if (req) req[propertyName] = null;
|
|
294
|
+
throw err;
|
|
295
|
+
}
|
|
296
|
+
return req;
|
|
240
297
|
}
|
|
241
298
|
|
|
242
299
|
function _extractGenericObjectNoThrow(req, jwt, attacher, propertyName) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
300
|
+
if (jwt && typeof jwt === 'string') {
|
|
301
|
+
const obj = jwtGetHeaderPayload(jwt);
|
|
302
|
+
attacher(obj);
|
|
303
|
+
req[propertyName] = obj;
|
|
304
|
+
} else {
|
|
305
|
+
if (req) req[propertyName] = null;
|
|
306
|
+
}
|
|
250
307
|
}
|
|
251
308
|
|
|
252
309
|
function _extractJwtObject(req, jwt, customErrorFunction) {
|
|
253
|
-
|
|
310
|
+
_extractJwtObjectNoThrow(req, jwt);
|
|
254
311
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
312
|
+
if (!req['jwt']) {
|
|
313
|
+
throwError(customErrorFunction);
|
|
314
|
+
}
|
|
258
315
|
}
|
|
259
316
|
|
|
260
317
|
function _extractJwtObjectNoThrow(req, jwt) {
|
|
261
|
-
|
|
318
|
+
_extractGenericObjectNoThrow(req, jwt, _attachJwtMethods, 'jwt');
|
|
262
319
|
}
|
|
263
320
|
|
|
264
321
|
function _extractVisitorObjectNoThrow(req, jwt) {
|
|
265
|
-
|
|
322
|
+
_extractGenericObjectNoThrow(req, jwt, _attachVisitorMethods, 'visitor');
|
|
266
323
|
}
|
|
267
324
|
|
|
268
325
|
function _attachJwtMethods(jwtObj) {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
326
|
+
if (jwtObj) {
|
|
327
|
+
Object.defineProperties(jwtObj, {
|
|
328
|
+
jwtClientId: { value: jwtClientId, enumerable: false },
|
|
329
|
+
doesJwtUserHasRole: { value: doesJwtUserHasRole, enumerable: false },
|
|
330
|
+
isJwtExpired: { value: isJwtExpired, enumerable: false },
|
|
331
|
+
jwtAgeInSeconds: { value: jwtAgeInSeconds, enumerable: false },
|
|
332
|
+
});
|
|
333
|
+
}
|
|
277
334
|
}
|
|
278
335
|
|
|
279
336
|
function _attachVisitorMethods(visitorObj) {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
337
|
+
if (visitorObj) {
|
|
338
|
+
Object.defineProperties(visitorObj, {
|
|
339
|
+
visitorClientId: { value: visitorClientId, enumerable: false },
|
|
340
|
+
});
|
|
341
|
+
}
|
|
285
342
|
}
|
|
286
343
|
|
|
287
344
|
async function _isJwtSignatureValid(jwt, publicKey, customErrorFunction) {
|
|
345
|
+
const isValid = await _isJwtSignatureValidNoThrow(jwt, publicKey);
|
|
288
346
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
throwError(customErrorFunction);
|
|
295
|
-
}
|
|
347
|
+
if (isValid) {
|
|
348
|
+
return isValid;
|
|
349
|
+
} else {
|
|
350
|
+
throwError(customErrorFunction);
|
|
351
|
+
}
|
|
296
352
|
}
|
|
297
353
|
|
|
298
354
|
async function _isJwtSignatureValidNoThrow(jwt, publicKey) {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
}
|
|
355
|
+
if (jwt && typeof jwt === 'string') {
|
|
356
|
+
return jwtVerifySignedToken(jwt, publicKey);
|
|
357
|
+
} else {
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
305
360
|
}
|
|
306
361
|
|
|
307
362
|
function _validateJwt(req, customErrorFunction) {
|
|
308
|
-
|
|
363
|
+
return _validateGeneric(req, 'Authorization', _extractJwt, customErrorFunction);
|
|
309
364
|
}
|
|
310
365
|
|
|
311
366
|
function _validateWebToken(req, headerName, customErrorFunction) {
|
|
312
|
-
|
|
367
|
+
return _validateGeneric(req, headerName, _extractWebToken, customErrorFunction);
|
|
313
368
|
}
|
|
314
369
|
|
|
315
370
|
function _validateJwtNoThrow(req) {
|
|
316
|
-
|
|
371
|
+
return _validateGenericNoThrow(req, 'Authorization', _extractJwtNoThrow);
|
|
317
372
|
}
|
|
318
373
|
|
|
319
374
|
function _validateWebTokenNoThrow(req, headerName) {
|
|
320
|
-
|
|
375
|
+
return _validateGenericNoThrow(req, headerName, _extractWebTokenNoThrow);
|
|
321
376
|
}
|
|
322
377
|
|
|
323
378
|
function _validateVisitorNoThrow(req) {
|
|
324
|
-
|
|
379
|
+
return _validateGenericNoThrow(req, 'Visitor', _extractJwtNoThrow);
|
|
325
380
|
}
|
|
326
381
|
|
|
327
382
|
function _extractJwt(jwtRaw, customErrorFunction) {
|
|
328
|
-
|
|
383
|
+
const jwt = _extractJwtNoThrow(jwtRaw);
|
|
329
384
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
385
|
+
if (jwt !== null) {
|
|
386
|
+
return jwt;
|
|
387
|
+
} else {
|
|
388
|
+
throwError(customErrorFunction);
|
|
389
|
+
}
|
|
335
390
|
|
|
336
|
-
|
|
391
|
+
return null;
|
|
337
392
|
}
|
|
338
393
|
|
|
339
394
|
function _extractWebToken(jwtRaw, customErrorFunction) {
|
|
340
|
-
|
|
395
|
+
const webToken = _extractWebTokenNoThrow(jwtRaw);
|
|
341
396
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
397
|
+
if (webToken !== null) {
|
|
398
|
+
return webToken;
|
|
399
|
+
} else {
|
|
400
|
+
throwError(customErrorFunction);
|
|
401
|
+
}
|
|
347
402
|
|
|
348
|
-
|
|
403
|
+
return null;
|
|
349
404
|
}
|
|
350
405
|
|
|
351
406
|
function _extractJwtNoThrow(jwtRaw) {
|
|
352
|
-
|
|
407
|
+
let jwtSplit = null;
|
|
353
408
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
409
|
+
if (jwtRaw && typeof jwtRaw === 'string') {
|
|
410
|
+
jwtSplit = jwtRaw.split(' ');
|
|
411
|
+
} else {
|
|
412
|
+
return null;
|
|
413
|
+
}
|
|
359
414
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
415
|
+
if (jwtSplit[0]?.toLowerCase() === 'bearer') {
|
|
416
|
+
return jwtSplit[1];
|
|
417
|
+
}
|
|
363
418
|
|
|
364
|
-
|
|
419
|
+
return null;
|
|
365
420
|
}
|
|
366
421
|
|
|
367
422
|
function _extractWebTokenNoThrow(jwtRaw) {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
return null;
|
|
423
|
+
if (jwtRaw && typeof jwtRaw === 'string') {
|
|
424
|
+
return jwtRaw;
|
|
425
|
+
}
|
|
426
|
+
return null;
|
|
373
427
|
}
|
|
374
428
|
|
|
375
429
|
module.exports = {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
430
|
+
_validateJwt,
|
|
431
|
+
_validateJwtNoThrow,
|
|
432
|
+
_isJwtSignatureValid,
|
|
433
|
+
_isJwtSignatureValidNoThrow,
|
|
434
|
+
_extractJwtObject,
|
|
435
|
+
validateAndExtractJwtObject,
|
|
436
|
+
validateAndExtractServiceJwtObject,
|
|
437
|
+
validateAndExtractWebToken,
|
|
438
|
+
jwtAgeInSeconds,
|
|
439
|
+
isJwtExpired,
|
|
440
|
+
doesJwtUserHasRole,
|
|
441
|
+
jwtClientId,
|
|
442
|
+
visitorClientId,
|
|
443
|
+
verifyJwtAndRole,
|
|
444
|
+
verifyServiceJwt,
|
|
445
|
+
verifyJwt,
|
|
446
|
+
verifyWebTokenNoThrow,
|
|
447
|
+
verifyWebToken,
|
|
448
|
+
verifyJwtNoThrow,
|
|
449
|
+
throwUsedTokenError,
|
|
450
|
+
throwError,
|
|
451
|
+
verifyVisitorNoThrow,
|
|
452
|
+
validateAndExtractVisitorObjectNoThrow,
|
|
453
|
+
validateAndExtractJwtObjectNoThrow,
|
|
454
|
+
validateAndExtractWebTokenObjectNoThrow,
|
|
455
|
+
_extractJwtNoThrow,
|
|
456
|
+
_extractWebTokenNoThrow,
|
|
457
|
+
_extractJwt,
|
|
458
|
+
_validateWebTokenNoThrow,
|
|
459
|
+
_validateVisitorNoThrow,
|
|
460
|
+
_extractJwtObjectNoThrow,
|
|
461
|
+
_extractVisitorObjectNoThrow,
|
|
462
|
+
_extractWebToken,
|
|
463
|
+
_isLoginRequired,
|
|
464
|
+
_isServiceJwtFor,
|
|
465
|
+
_attachJwtMethods,
|
|
466
|
+
_attachVisitorMethods,
|
|
467
|
+
_validateWebToken,
|
|
468
|
+
};
|