-
Notifications
You must be signed in to change notification settings - Fork 0
/
jwt.ts
48 lines (42 loc) · 1.33 KB
/
jwt.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import * as base64url from 'https://deno.land/[email protected]/encoding/base64url.ts';
import * as base64 from 'https://deno.land/[email protected]/encoding/base64.ts';
export type Header = {
alg: 'RS256';
[key: string]: unknown;
};
export type Payload = {
iss: string;
aud: string;
exp: number;
iat: number;
scope: string;
};
const encoder = new TextEncoder();
export default async function (
header: Header,
payload: Payload,
secret: string,
): Promise<string> {
const encodedHeader = base64url.encode(JSON.stringify(header));
const encodedPayload = base64url.encode(JSON.stringify(payload));
const data = encoder.encode(`${encodedHeader}.${encodedPayload}`);
const cleanedKey = secret.replace(
/^\n?-----BEGIN PRIVATE KEY-----\n?|\n?-----END PRIVATE KEY-----\n?$/g,
'',
);
const decodedKey = base64.decode(cleanedKey).buffer;
const key = await crypto.subtle.importKey(
'pkcs8',
decodedKey,
{ name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' },
true,
['sign'],
);
const signature = await crypto.subtle.sign(
{ hash: { name: 'SHA-256' }, name: 'RSASSA-PKCS1-v1_5' },
key,
data,
);
const encodedSignature = base64url.encode(signature);
return `${encodedHeader}.${encodedPayload}.${encodedSignature}`;
}