Skip to content

Commit f1ea0df

Browse files
committed
feat: support asymmetric algorithm
1 parent afb8cb1 commit f1ea0df

File tree

1 file changed

+36
-5
lines changed

1 file changed

+36
-5
lines changed

src/index.ts

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,19 @@ export interface JWTOption<
5252
name?: Name
5353
/**
5454
* JWT Secret
55+
* Only `secret` or both `privateKey`, `publicKey` must be set
5556
*/
56-
secret: string | Uint8Array | KeyLike
57+
secret?: string | Uint8Array | KeyLike
58+
/**
59+
* JWT Private Key
60+
* Only `secret` or both `privateKey`, `publicKey` must be set
61+
*/
62+
privateKey?: Uint8Array | KeyLike
63+
/**
64+
* JWT Public Key
65+
* Only `secret` or both `privateKey`, `publicKey` must be set
66+
*/
67+
publicKey?: Uint8Array | KeyLike
5768
/**
5869
* Type strict validation for JWT payload
5970
*/
@@ -80,6 +91,8 @@ export const jwt = <
8091
>({
8192
name = 'jwt' as Name,
8293
secret,
94+
publicKey,
95+
privateKey,
8396
// Start JWT Header
8497
alg = 'HS256',
8598
crit,
@@ -91,11 +104,29 @@ export const jwt = <
91104
...payload
92105
}: // End JWT Payload
93106
JWTOption<Name, Schema>) => {
94-
if (!secret) throw new Error("Secret can't be empty")
95-
96107
const key =
97108
typeof secret === 'string' ? new TextEncoder().encode(secret) : secret
98109

110+
let asymmetric = false
111+
112+
if (secret && (privateKey || publicKey)) {
113+
throw new Error("When using asymmetric algorithm, only `privateKey` and `publicKey` is accepted")
114+
}
115+
116+
if (privateKey && !publicKey) {
117+
throw new Error("When using asymmetric algorithm, both `privateKey` and `publicKey` must be set. Public key is missing")
118+
}
119+
120+
if (publicKey && !privateKey) {
121+
throw new Error("When using asymmetric algorithm, both `privateKey` and `publicKey` must be set. Private key is missing")
122+
}
123+
124+
if (privateKey && privateKey) {
125+
asymmetric = true
126+
} else if (!secret) {
127+
throw new Error("Secret can't be empty")
128+
}
129+
99130
const validator = schema
100131
? getSchemaValidator(
101132
t.Intersect([
@@ -146,7 +177,7 @@ JWTOption<Name, Schema>) => {
146177
if (nbf) jwt = jwt.setNotBefore(nbf)
147178
if (exp) jwt = jwt.setExpirationTime(exp)
148179

149-
return jwt.sign(key)
180+
return jwt.sign(asymmetric ? privateKey! : key!)
150181
},
151182
verify: async (
152183
jwt?: string
@@ -158,7 +189,7 @@ JWTOption<Name, Schema>) => {
158189
if (!jwt) return false
159190

160191
try {
161-
const data: any = (await jwtVerify(jwt, key)).payload
192+
const data: any = (await jwtVerify(jwt, asymmetric ? publicKey! : key!)).payload
162193

163194
if (validator && !validator!.Check(data))
164195
throw new ValidationError('JWT', validator, data)

0 commit comments

Comments
 (0)