@nitrotool/jwt 0.0.4
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/dist/h3.mjs +15 -0
- package/dist/index.mjs +5 -0
- package/dist/jwt.mjs +53 -0
- package/package.json +24 -0
- package/src/h3.ts +24 -0
- package/src/index.ts +4 -0
- package/src/jwt.ts +79 -0
- package/tsconfig.json +8 -0
package/dist/h3.mjs
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { getRequestHeader, getQuery } from 'h3';
|
|
2
|
+
import { UnauthenticatedError } from '@nitrotool/errors';
|
|
3
|
+
|
|
4
|
+
const extractBearerToken = (event) => getRequestHeader(event, "Authorization")?.replace("Bearer ", "") || void 0;
|
|
5
|
+
const extractQueryToken = (event) => getQuery(event)?.token || void 0;
|
|
6
|
+
const extractApiToken = (event) => extractBearerToken(event) || extractQueryToken(event);
|
|
7
|
+
const requireApiToken = (event) => {
|
|
8
|
+
const token = extractApiToken(event);
|
|
9
|
+
if (!token) {
|
|
10
|
+
throw UnauthenticatedError();
|
|
11
|
+
}
|
|
12
|
+
return token;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export { extractApiToken, extractBearerToken, extractQueryToken, requireApiToken };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { extractApiToken, extractBearerToken, extractQueryToken, requireApiToken } from './h3.mjs';
|
|
2
|
+
export { decodeJwt, decodeJwtRaw, encodeJwt, encodeJwtRaw, verifyJwt, verifyJwtRaw } from './jwt.mjs';
|
|
3
|
+
import 'h3';
|
|
4
|
+
import '@nitrotool/errors';
|
|
5
|
+
import '@tsndr/cloudflare-worker-jwt';
|
package/dist/jwt.mjs
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import jwt from '@tsndr/cloudflare-worker-jwt';
|
|
2
|
+
import { createError } from 'h3';
|
|
3
|
+
|
|
4
|
+
const encodeJwtRaw = async (payload = {}, secret, ttl = 60) => {
|
|
5
|
+
return await jwt.sign(
|
|
6
|
+
{
|
|
7
|
+
exp: Date.now() / 1e3 + ttl,
|
|
8
|
+
...payload
|
|
9
|
+
},
|
|
10
|
+
secret
|
|
11
|
+
);
|
|
12
|
+
};
|
|
13
|
+
const encodeJwt = async (payload = {}) => {
|
|
14
|
+
const secret = (
|
|
15
|
+
//@ts-expect-error Expected.
|
|
16
|
+
typeof useRuntimeConfig === "function" ? useRuntimeConfig()?.jwtSecret : ""
|
|
17
|
+
);
|
|
18
|
+
return encodeJwtRaw(payload, secret);
|
|
19
|
+
};
|
|
20
|
+
const verifyJwtRaw = async (token, secret) => {
|
|
21
|
+
return new Promise(async (resolve) => {
|
|
22
|
+
if (await jwt.verify(token, secret, { throwError: false })) {
|
|
23
|
+
return resolve(true);
|
|
24
|
+
}
|
|
25
|
+
return resolve(false);
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
const verifyJwt = async (token) => {
|
|
29
|
+
const secret = (
|
|
30
|
+
//@ts-expect-error Expected.
|
|
31
|
+
typeof useRuntimeConfig === "function" ? useRuntimeConfig()?.jwtSecret : ""
|
|
32
|
+
);
|
|
33
|
+
return verifyJwtRaw(token, secret);
|
|
34
|
+
};
|
|
35
|
+
const decodeJwtRaw = async (token, secret, { verify } = { verify: true }) => {
|
|
36
|
+
if (!secret && verify) {
|
|
37
|
+
throw new Error("Cannot check signature without secret.");
|
|
38
|
+
}
|
|
39
|
+
if (secret && verify && !await verifyJwtRaw(token, secret)) {
|
|
40
|
+
throw createError(`Invalid JWT token.`);
|
|
41
|
+
}
|
|
42
|
+
const { payload } = jwt.decode(token);
|
|
43
|
+
return payload;
|
|
44
|
+
};
|
|
45
|
+
const decodeJwt = async (token, { verify } = { verify: true }) => {
|
|
46
|
+
if (verify && !await verifyJwt(token)) {
|
|
47
|
+
throw createError(`Invalid JWT token.`);
|
|
48
|
+
}
|
|
49
|
+
const { payload } = jwt.decode(token);
|
|
50
|
+
return payload;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export { decodeJwt, decodeJwtRaw, encodeJwt, encodeJwtRaw, verifyJwt, verifyJwtRaw };
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nitrotool/jwt",
|
|
3
|
+
"version": "0.0.4",
|
|
4
|
+
"main": "dist/index.mjs",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./dist/index.mjs",
|
|
8
|
+
"./jwt": "./dist/jwt.mjs",
|
|
9
|
+
"./h3": "./dist/h3.mjs"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@tsndr/cloudflare-worker-jwt": "^3.2.0",
|
|
13
|
+
"@nitrotool/errors": "0.0.4"
|
|
14
|
+
},
|
|
15
|
+
"peerDependencies": {
|
|
16
|
+
"h3": "^1.15.3"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"unbuild": "^3.5.0"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "unbuild ."
|
|
23
|
+
}
|
|
24
|
+
}
|
package/src/h3.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type H3Event,
|
|
3
|
+
getRequestHeader,
|
|
4
|
+
getQuery,
|
|
5
|
+
} from 'h3';
|
|
6
|
+
import {UnauthenticatedError} from "@nitrotool/errors";
|
|
7
|
+
|
|
8
|
+
export const extractBearerToken = (event: H3Event) =>
|
|
9
|
+
getRequestHeader(event, 'Authorization')?.replace('Bearer ', '') || undefined;
|
|
10
|
+
|
|
11
|
+
export const extractQueryToken = (event: H3Event): string | undefined =>
|
|
12
|
+
getQuery<{ token: string }>(event)?.token || undefined;
|
|
13
|
+
|
|
14
|
+
export const extractApiToken = (event: H3Event): string | undefined =>
|
|
15
|
+
extractBearerToken(event) || extractQueryToken(event);
|
|
16
|
+
|
|
17
|
+
export const requireApiToken = (event: H3Event) => {
|
|
18
|
+
const token = extractApiToken(event);
|
|
19
|
+
if (!token) {
|
|
20
|
+
throw UnauthenticatedError();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return token;
|
|
24
|
+
}
|
package/src/index.ts
ADDED
package/src/jwt.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import jwt from '@tsndr/cloudflare-worker-jwt';
|
|
2
|
+
import { createError } from 'h3';
|
|
3
|
+
|
|
4
|
+
export const encodeJwtRaw = async <
|
|
5
|
+
T extends Record<string, any> = Record<string, any>,
|
|
6
|
+
>(
|
|
7
|
+
payload: T = {} as T,
|
|
8
|
+
secret: string,
|
|
9
|
+
ttl = 60,
|
|
10
|
+
): Promise<string> => {
|
|
11
|
+
return await jwt.sign(
|
|
12
|
+
{
|
|
13
|
+
exp: Date.now() / 1000 + ttl,
|
|
14
|
+
...payload,
|
|
15
|
+
},
|
|
16
|
+
secret,
|
|
17
|
+
);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const encodeJwt = async <
|
|
21
|
+
T extends Record<string, any> = Record<string, any>,
|
|
22
|
+
>(
|
|
23
|
+
payload: T = {} as T,
|
|
24
|
+
): Promise<string> => {
|
|
25
|
+
const secret =
|
|
26
|
+
//@ts-expect-error Expected.
|
|
27
|
+
typeof useRuntimeConfig === 'function' ? useRuntimeConfig()?.jwtSecret : '';
|
|
28
|
+
return encodeJwtRaw(payload, secret);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const verifyJwtRaw = async (
|
|
32
|
+
token: string,
|
|
33
|
+
secret: string,
|
|
34
|
+
): Promise<boolean> => {
|
|
35
|
+
return new Promise(async (resolve) => {
|
|
36
|
+
if (await jwt.verify(token, secret, { throwError: false })) {
|
|
37
|
+
return resolve(true);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return resolve(false);
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const verifyJwt = async (token: string): Promise<boolean> => {
|
|
45
|
+
const secret =
|
|
46
|
+
//@ts-expect-error Expected.
|
|
47
|
+
typeof useRuntimeConfig === 'function' ? useRuntimeConfig()?.jwtSecret : '';
|
|
48
|
+
return verifyJwtRaw(token, secret);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const decodeJwtRaw = async <
|
|
52
|
+
T extends Record<string, any> = Record<string, any>,
|
|
53
|
+
>(
|
|
54
|
+
token: string,
|
|
55
|
+
secret: string,
|
|
56
|
+
{ verify }: { verify?: boolean } = { verify: true },
|
|
57
|
+
) => {
|
|
58
|
+
if (!secret && verify) {
|
|
59
|
+
throw new Error('Cannot check signature without secret.');
|
|
60
|
+
}
|
|
61
|
+
if (secret && verify && !(await verifyJwtRaw(token, secret))) {
|
|
62
|
+
throw createError(`Invalid JWT token.`);
|
|
63
|
+
}
|
|
64
|
+
const { payload } = jwt.decode<T>(token);
|
|
65
|
+
return payload;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const decodeJwt = async <
|
|
69
|
+
T extends Record<string, any> = Record<string, any>,
|
|
70
|
+
>(
|
|
71
|
+
token: string,
|
|
72
|
+
{ verify }: { verify?: boolean } = { verify: true },
|
|
73
|
+
) => {
|
|
74
|
+
if (verify && !(await verifyJwt(token))) {
|
|
75
|
+
throw createError(`Invalid JWT token.`);
|
|
76
|
+
}
|
|
77
|
+
const { payload } = jwt.decode<T>(token);
|
|
78
|
+
return payload;
|
|
79
|
+
};
|