-
Notifications
You must be signed in to change notification settings - Fork 14
/
lib.w
112 lines (100 loc) · 2.83 KB
/
lib.w
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
pub struct VerifyJwtOptions {
algorithms: Array<str>?;
audience: str?;
issuer: str?;
ignoreExpiration: bool?;
ignoreNotBefore: bool?;
jwtid: str?;
nonce: str?;
subject: str?;
maxAge: str?;
}
pub struct VerifyOptions {
secret: str?;
jwksUri: str?;
options: VerifyJwtOptions?;
}
pub struct DecodeOptions {
complete: bool?;
}
pub struct SignOptions {
algorithm: str?;
keyid: str?;
expiresIn: duration?;
notBefore: duration?;
audience: Array<str>?;
subject: str?;
issuer: str?;
jwtid: str?;
encoding: str?;
}
struct JwtHeader {
alg: str?;
typ: str?;
cty: str?;
crit: Array<str>?;
kid: str?;
jku: str?;
x5u: str?;
x5t: str?;
x5c: str?;
}
struct IJwksClientOptions {
jwksUri: str;
}
inflight interface IJwksSigningKey {
inflight getPublicKey(): str;
}
inflight interface IJwksClient {
inflight getSigningKey(kid: str?): IJwksSigningKey;
}
inflight interface IJwt {
inflight jwksClient(options: IJwksClientOptions): IJwksClient;
inflight sign(data: Json, secret: str, options: Json?): str;
inflight verify(token: str, secret: inflight (JwtHeader, inflight (str, str): void): void, options: VerifyJwtOptions?): Json;
inflight decode(token: str, options: DecodeOptions?): Json;
}
class JwtUtil {
extern "./utils.js" pub static inflight _jwt(): IJwt;
}
pub class Util {
pub inflight static sign(data: Json, secret: str, options: SignOptions?): str {
let var opts: MutJson? = nil;
if let options = options {
opts = MutJson Json.parse(Json.stringify(options));
if let expiresIn = options.expiresIn {
opts?.set("expiresIn", expiresIn.seconds);
}
if let notBefore = options.notBefore {
opts?.set("notBefore", notBefore.seconds);
}
}
return JwtUtil._jwt().sign(data, secret, opts);
}
pub inflight static verify(token: str, options: VerifyOptions): Json {
if let secret = options.secret {
let getKey = inflight (header: JwtHeader, callback: inflight (str, str): void) => {
callback(unsafeCast(nil), secret);
};
let decoded = JwtUtil._jwt().verify(token, getKey, options.options);
return decoded;
} else if let jwksUri = options.jwksUri {
let client = JwtUtil._jwt().jwksClient(jwksUri: jwksUri);
let getKey = inflight (header: JwtHeader, callback: inflight (str, str): void) => {
try {
let secret = client.getSigningKey(header.kid).getPublicKey();
callback(unsafeCast(nil), secret);
} catch error {
callback(error, unsafeCast(nil));
}
};
let decoded = JwtUtil._jwt().verify(token, getKey, options.options);
return decoded;
} else {
throw "Either secret or jwksUri must be provided";
}
}
pub inflight static decode(token: str, options: DecodeOptions?): Json {
return JwtUtil._jwt().decode(token, options);
}
}