@carecard/jwt-read 2.0.1 → 3.0.2
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/index.js +1 -0
- package/lib/jwtLib.js +85 -38
- package/lib/jwtRoles.js +5 -5
- package/package.json +5 -5
- package/coverage/clover.xml +0 -206
- package/coverage/coverage-final.json +0 -4
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +0 -146
- package/coverage/lcov-report/index.ts.html +0 -94
- package/coverage/lcov-report/jwtLib.ts.html +0 -1363
- package/coverage/lcov-report/jwtRoles.ts.html +0 -151
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -210
- package/coverage/lcov-report/types.d.ts.html +0 -175
- package/coverage/lcov.info +0 -428
- package/dist/cjs/index.d.ts +0 -3
- package/dist/cjs/index.js +0 -19
- package/dist/cjs/jwtLib.d.ts +0 -38
- package/dist/cjs/jwtLib.js +0 -393
- package/dist/cjs/jwtRoles.d.ts +0 -2
- package/dist/cjs/jwtRoles.js +0 -19
- package/dist/cjs/types.d.ts +0 -25
- package/dist/cjs/types.js +0 -2
- package/dist/esm/index.d.ts +0 -3
- package/dist/esm/index.js +0 -3
- package/dist/esm/jwtLib.d.ts +0 -38
- package/dist/esm/jwtLib.js +0 -325
- package/dist/esm/jwtRoles.d.ts +0 -2
- package/dist/esm/jwtRoles.js +0 -15
- package/dist/esm/types.d.ts +0 -25
- package/dist/esm/types.js +0 -1
package/dist/esm/jwtLib.js
DELETED
|
@@ -1,325 +0,0 @@
|
|
|
1
|
-
import * as validate from '@carecard/validate';
|
|
2
|
-
import * as jwtUtilAuth from '@carecard/auth-util';
|
|
3
|
-
import { throwLoginRequiredError, throwNotAuthorizedError } from '@carecard/common-util';
|
|
4
|
-
export function jwtClientId(req) {
|
|
5
|
-
return req?.jwt?.payload?.client_id;
|
|
6
|
-
}
|
|
7
|
-
export function visitorClientId(req) {
|
|
8
|
-
return req?.visitor?.payload?.client_id;
|
|
9
|
-
}
|
|
10
|
-
export function doesJwtUserHasRole(req, userRole) {
|
|
11
|
-
if (userRole && typeof userRole === 'string') {
|
|
12
|
-
return req?.jwt?.payload?.roles?.includes(userRole);
|
|
13
|
-
}
|
|
14
|
-
else {
|
|
15
|
-
throwNotAuthorizedError();
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
export function throwError(customErrorFunction) {
|
|
19
|
-
typeof customErrorFunction === 'function' ? customErrorFunction() : throwLoginRequiredError();
|
|
20
|
-
}
|
|
21
|
-
export function isJwtExpired(req, jwtValiditySeconds) {
|
|
22
|
-
if (jwtValiditySeconds && typeof jwtValiditySeconds === 'number') {
|
|
23
|
-
return Math.abs(Math.round(jwtValiditySeconds)) * 1000 < jwtAgeInMilliseconds(req);
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
export function jwtAgeInMilliseconds(req) {
|
|
30
|
-
// Ensure req.jwt exists (create it if undefined)
|
|
31
|
-
req.jwt ?? (req.jwt = {
|
|
32
|
-
header: { alg: 'sha512', typ: 'JWT' }, // or a minimal placeholder
|
|
33
|
-
payload: { iat: 0, client_id: '', roles: [], email_not_confirmed: false },
|
|
34
|
-
age: Infinity,
|
|
35
|
-
});
|
|
36
|
-
const iat = req.jwt.payload?.iat;
|
|
37
|
-
const age = typeof iat === 'number' && iat > 0 ? Date.now() - iat : Infinity;
|
|
38
|
-
req.jwt.age = age;
|
|
39
|
-
return age;
|
|
40
|
-
}
|
|
41
|
-
export async function validateAndExtractJwtObject(req, publicKey, customErrorFunction) {
|
|
42
|
-
const jwtString = await _validateJwt(req, customErrorFunction);
|
|
43
|
-
const isJwtSignatureValid = await _isJwtSignatureValid(jwtString, publicKey, customErrorFunction);
|
|
44
|
-
if (jwtString && isJwtSignatureValid) {
|
|
45
|
-
await _extractJwtObject(req, jwtString, customErrorFunction);
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
req['jwt'] = null;
|
|
49
|
-
throwError(customErrorFunction);
|
|
50
|
-
}
|
|
51
|
-
return req;
|
|
52
|
-
}
|
|
53
|
-
export async function validateAndExtractWebToken(req, publicKey, headerName, customErrorFunction) {
|
|
54
|
-
const webTokenString = await _validateWebToken(req, headerName, customErrorFunction);
|
|
55
|
-
const isJwtSignatureValid = await _isJwtSignatureValid(webTokenString, publicKey, customErrorFunction);
|
|
56
|
-
if (webTokenString && isJwtSignatureValid) {
|
|
57
|
-
await _extractJwtObject(req, webTokenString, customErrorFunction);
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
req['jwt'] = null;
|
|
61
|
-
throwError(customErrorFunction);
|
|
62
|
-
}
|
|
63
|
-
return req;
|
|
64
|
-
}
|
|
65
|
-
export async function validateAndExtractJwtObjectNoThrow(req, publicKey) {
|
|
66
|
-
try {
|
|
67
|
-
const jwtString = await _validateJwtNoThrow(req);
|
|
68
|
-
const isJwtSignatureValid = await _isJwtSignatureValidNoThrow(jwtString, publicKey);
|
|
69
|
-
if (jwtString && isJwtSignatureValid) {
|
|
70
|
-
await _extractJwtObjectNoThrow(req, jwtString);
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
req['jwt'] = null;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
catch (err) {
|
|
77
|
-
req['jwt'] = null;
|
|
78
|
-
}
|
|
79
|
-
return req;
|
|
80
|
-
}
|
|
81
|
-
export async function validateAndExtractWebTokenObjectNoThrow(req, publicKey, headerName) {
|
|
82
|
-
try {
|
|
83
|
-
const jwtString = _validateWebTokenNoThrow(req, headerName);
|
|
84
|
-
const isJwtSignatureValid = await _isJwtSignatureValidNoThrow(jwtString, publicKey);
|
|
85
|
-
if (jwtString && isJwtSignatureValid) {
|
|
86
|
-
await _extractJwtObjectNoThrow(req, jwtString);
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
req['jwt'] = null;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
catch (err) {
|
|
93
|
-
req['jwt'] = null;
|
|
94
|
-
}
|
|
95
|
-
return req;
|
|
96
|
-
}
|
|
97
|
-
export async function validateAndExtractVisitorObjectNoThrow(req, publicKey) {
|
|
98
|
-
try {
|
|
99
|
-
const jwtString = await _validateVisitorNoThrow(req);
|
|
100
|
-
const isJwtSignatureValid = await _isJwtSignatureValidNoThrow(jwtString, publicKey);
|
|
101
|
-
if (jwtString && isJwtSignatureValid) {
|
|
102
|
-
await _extractVisitorObjectNoThrow(req, jwtString);
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
req['visitor'] = null;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
catch (err) {
|
|
109
|
-
req['visitor'] = null;
|
|
110
|
-
}
|
|
111
|
-
return req;
|
|
112
|
-
}
|
|
113
|
-
export function verifyJwtAndRole(role, publicKey, customErrorFunction) {
|
|
114
|
-
return async function (req, res, next) {
|
|
115
|
-
await validateAndExtractJwtObject(req, publicKey, customErrorFunction)
|
|
116
|
-
.then(req => doesJwtUserHasRole(req, role))
|
|
117
|
-
.then(isRoleExist => _isLoginRequired(isRoleExist, customErrorFunction))
|
|
118
|
-
.then(next)
|
|
119
|
-
.catch(next);
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
export function verifyJwt(publicKey, customErrorFunction) {
|
|
123
|
-
return async function (req, res, next) {
|
|
124
|
-
await validateAndExtractJwtObject(req, publicKey, customErrorFunction)
|
|
125
|
-
.then(() => process.nextTick(next))
|
|
126
|
-
.catch(next);
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
export function verifyWebToken(publicKey, headerName, customErrorFunction) {
|
|
130
|
-
return async function (req, res, next) {
|
|
131
|
-
await validateAndExtractWebToken(req, publicKey, headerName, customErrorFunction)
|
|
132
|
-
.then(() => process.nextTick(next))
|
|
133
|
-
.catch(next);
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
export function verifyJwtNoThrow(publicKey) {
|
|
137
|
-
return async function (req, res, next) {
|
|
138
|
-
await validateAndExtractJwtObjectNoThrow(req, publicKey)
|
|
139
|
-
.then(() => process.nextTick(next))
|
|
140
|
-
.catch(next);
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
export function verifyWebTokenNoThrow(publicKey, headerName) {
|
|
144
|
-
return async function (req, res, next) {
|
|
145
|
-
await validateAndExtractWebTokenObjectNoThrow(req, publicKey, headerName)
|
|
146
|
-
.then(() => process.nextTick(next))
|
|
147
|
-
.catch(next);
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
export function verifyVisitorNoThrow(publicKey) {
|
|
151
|
-
return async function (req, res, next) {
|
|
152
|
-
await validateAndExtractVisitorObjectNoThrow(req, publicKey)
|
|
153
|
-
.then(() => process.nextTick(next))
|
|
154
|
-
.catch(next);
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
export function throwUsedTokenError() {
|
|
158
|
-
throw new Error('Used_Token');
|
|
159
|
-
}
|
|
160
|
-
/*********************
|
|
161
|
-
* Private functions *
|
|
162
|
-
*********************/
|
|
163
|
-
export function _isLoginRequired(hasRequiredRole, customErrorFunction) {
|
|
164
|
-
if (!hasRequiredRole) {
|
|
165
|
-
throwError(customErrorFunction);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
export async function _extractJwtObject(req, jwt, customErrorFunction) {
|
|
169
|
-
if (jwt && typeof jwt === 'string') {
|
|
170
|
-
req['jwt'] = jwtUtilAuth.getHeaderPayloadFromJwt(jwt);
|
|
171
|
-
}
|
|
172
|
-
else {
|
|
173
|
-
throwError(customErrorFunction);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
export async function _extractJwtObjectNoThrow(req, jwt) {
|
|
177
|
-
if (jwt && typeof jwt === 'string') {
|
|
178
|
-
req['jwt'] = jwtUtilAuth.getHeaderPayloadFromJwt(jwt);
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
req['jwt'] = null;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
export async function _extractVisitorObjectNoThrow(req, jwt) {
|
|
185
|
-
if (jwt && typeof jwt === 'string') {
|
|
186
|
-
req['visitor'] = jwtUtilAuth.getHeaderPayloadFromJwt(jwt);
|
|
187
|
-
}
|
|
188
|
-
else {
|
|
189
|
-
req['visitor'] = null;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
export async function _isJwtSignatureValid(jwt, publicKey, customErrorFunction) {
|
|
193
|
-
if (jwt && typeof jwt === 'string') {
|
|
194
|
-
return jwtUtilAuth.verifyJwtSignature(jwt, publicKey);
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
197
|
-
throwError(customErrorFunction);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
export async function _isJwtSignatureValidNoThrow(jwt, publicKey) {
|
|
201
|
-
if (jwt && typeof jwt === 'string') {
|
|
202
|
-
return jwtUtilAuth.verifyJwtSignature(jwt, publicKey);
|
|
203
|
-
}
|
|
204
|
-
else {
|
|
205
|
-
return false;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
export async function _validateJwt(req, customErrorFunction) {
|
|
209
|
-
// Get from http header.
|
|
210
|
-
let jwtRaw = req.get('Authorization');
|
|
211
|
-
// Extract jwt from bearer schema.
|
|
212
|
-
let jwt = _extractJwt(jwtRaw, customErrorFunction);
|
|
213
|
-
// Validate characters string of jwt.
|
|
214
|
-
if (validate.isJwtString(jwt || '')) {
|
|
215
|
-
return jwt;
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
throwError(customErrorFunction);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
export async function _validateWebToken(req, headerName, customErrorFunction) {
|
|
222
|
-
// Get from http header.
|
|
223
|
-
let jwtRaw = req.get(headerName);
|
|
224
|
-
// Extract jwt from bearer schema.
|
|
225
|
-
let webToken = _extractWebToken(jwtRaw, customErrorFunction);
|
|
226
|
-
// Validate characters string of jwt.
|
|
227
|
-
if (validate.isJwtString(webToken || '')) {
|
|
228
|
-
return webToken;
|
|
229
|
-
}
|
|
230
|
-
else {
|
|
231
|
-
throwError(customErrorFunction);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
export function _validateJwtNoThrow(req) {
|
|
235
|
-
// Get from http header.
|
|
236
|
-
let jwtRaw = req.get('Authorization');
|
|
237
|
-
if (!jwtRaw) {
|
|
238
|
-
return null;
|
|
239
|
-
}
|
|
240
|
-
// Extract jwt from bearer schema.
|
|
241
|
-
let jwt = _extractJwtNoThrow(jwtRaw);
|
|
242
|
-
// Validate characters string of jwt.
|
|
243
|
-
if (validate.isJwtString(jwt || '')) {
|
|
244
|
-
return jwt;
|
|
245
|
-
}
|
|
246
|
-
return null;
|
|
247
|
-
}
|
|
248
|
-
export function _validateWebTokenNoThrow(req, headerName) {
|
|
249
|
-
// Get from http header.
|
|
250
|
-
let jwtRaw = req.get(headerName);
|
|
251
|
-
if (!jwtRaw) {
|
|
252
|
-
return null;
|
|
253
|
-
}
|
|
254
|
-
// Extract jwt from bearer schema.
|
|
255
|
-
let webToken = _extractWebTokenNoThrow(jwtRaw);
|
|
256
|
-
// Validate characters string of jwt.
|
|
257
|
-
if (validate.isJwtString(webToken || '')) {
|
|
258
|
-
return webToken;
|
|
259
|
-
}
|
|
260
|
-
return null;
|
|
261
|
-
}
|
|
262
|
-
export function _validateVisitorNoThrow(req) {
|
|
263
|
-
// Get from http header.
|
|
264
|
-
let jwtRaw = req.get('Visitor');
|
|
265
|
-
if (!jwtRaw) {
|
|
266
|
-
return null;
|
|
267
|
-
}
|
|
268
|
-
// Extract jwt from bearer schema.
|
|
269
|
-
let jwt = _extractJwtNoThrow(jwtRaw);
|
|
270
|
-
// Validate characters string of jwt.
|
|
271
|
-
if (validate.isJwtString(jwt || '')) {
|
|
272
|
-
return jwt;
|
|
273
|
-
}
|
|
274
|
-
return null;
|
|
275
|
-
}
|
|
276
|
-
export function _extractJwt(jwtRaw, customErrorFunction) {
|
|
277
|
-
let jwtSplit = null;
|
|
278
|
-
if (jwtRaw && typeof jwtRaw === 'string') {
|
|
279
|
-
jwtSplit = jwtRaw.split(' ');
|
|
280
|
-
}
|
|
281
|
-
else {
|
|
282
|
-
throwError(customErrorFunction);
|
|
283
|
-
return null;
|
|
284
|
-
}
|
|
285
|
-
// Guard before indexing
|
|
286
|
-
if (!jwtSplit || jwtSplit.length < 2) {
|
|
287
|
-
throwError(customErrorFunction);
|
|
288
|
-
return null;
|
|
289
|
-
}
|
|
290
|
-
if (jwtSplit[0].toLowerCase() === 'bearer') {
|
|
291
|
-
return jwtSplit[1] ?? null;
|
|
292
|
-
}
|
|
293
|
-
else {
|
|
294
|
-
throwError(customErrorFunction);
|
|
295
|
-
return null;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
export function _extractWebToken(jwtRaw, customErrorFunction) {
|
|
299
|
-
if (jwtRaw && typeof jwtRaw === 'string') {
|
|
300
|
-
return jwtRaw;
|
|
301
|
-
}
|
|
302
|
-
else {
|
|
303
|
-
throwError(customErrorFunction);
|
|
304
|
-
}
|
|
305
|
-
return null;
|
|
306
|
-
}
|
|
307
|
-
export function _extractJwtNoThrow(jwtRaw) {
|
|
308
|
-
let jwtSplit = null;
|
|
309
|
-
if (jwtRaw && typeof jwtRaw === 'string') {
|
|
310
|
-
jwtSplit = jwtRaw.split(' ');
|
|
311
|
-
}
|
|
312
|
-
else {
|
|
313
|
-
return null;
|
|
314
|
-
}
|
|
315
|
-
if (jwtSplit[0]?.toLowerCase() === 'bearer') {
|
|
316
|
-
return jwtSplit[1];
|
|
317
|
-
}
|
|
318
|
-
return null;
|
|
319
|
-
}
|
|
320
|
-
export function _extractWebTokenNoThrow(jwtRaw) {
|
|
321
|
-
if (jwtRaw && typeof jwtRaw === 'string') {
|
|
322
|
-
return jwtRaw;
|
|
323
|
-
}
|
|
324
|
-
return null;
|
|
325
|
-
}
|
package/dist/esm/jwtRoles.d.ts
DELETED
package/dist/esm/jwtRoles.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
const codesToCategory = {
|
|
2
|
-
ad: 'admin',
|
|
3
|
-
su: 'super_admin',
|
|
4
|
-
};
|
|
5
|
-
export function getNameOfRoleFromCode(roleCode) {
|
|
6
|
-
// Cast only at index, use nullish coalescing for fallback
|
|
7
|
-
return codesToCategory[roleCode] ?? '';
|
|
8
|
-
}
|
|
9
|
-
const namesToCode = {
|
|
10
|
-
admin: 'ad',
|
|
11
|
-
super_admin: 'su',
|
|
12
|
-
};
|
|
13
|
-
export function getCodeFromNameOfRole(roleName) {
|
|
14
|
-
return namesToCode[roleName] ?? '';
|
|
15
|
-
}
|
package/dist/esm/types.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { Request } from 'express';
|
|
2
|
-
export interface JwtHeader {
|
|
3
|
-
alg: string;
|
|
4
|
-
typ: string;
|
|
5
|
-
}
|
|
6
|
-
export type Role = string;
|
|
7
|
-
export type Roles = Role[];
|
|
8
|
-
export interface JwtPayload {
|
|
9
|
-
/** Issued-at timestamp */
|
|
10
|
-
iat: number;
|
|
11
|
-
/** Client identifier (UUID as string) */
|
|
12
|
-
client_id: string;
|
|
13
|
-
roles: Roles;
|
|
14
|
-
email_not_confirmed: boolean;
|
|
15
|
-
}
|
|
16
|
-
export interface JWToken {
|
|
17
|
-
header: JwtHeader;
|
|
18
|
-
payload: JwtPayload;
|
|
19
|
-
/** Age in milliseconds (number) */
|
|
20
|
-
age: number;
|
|
21
|
-
}
|
|
22
|
-
export interface RequestWithJWToken extends Request {
|
|
23
|
-
jwt?: JWToken | null | undefined;
|
|
24
|
-
visitor?: JWToken | null | undefined;
|
|
25
|
-
}
|
package/dist/esm/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|