From de658122b986d09bfd12375e42551739cf207a3f Mon Sep 17 00:00:00 2001 From: Tobias Schneider Date: Thu, 15 Dec 2022 16:22:49 +0100 Subject: [PATCH] clean up --- src/index.ts | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/index.ts b/src/index.ts index 948c0b8..5edb6be 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,18 +1,6 @@ if (typeof crypto === 'undefined' || !crypto.subtle) throw new Error('SubtleCrypto not supported!') -/** - * @typedef JwkPayload - */ -export interface JwkPayload extends Object { - "crv": string, - "d": string, - "ext": boolean, - "key_ops": string[], - "kty": string, - "x": string, - "y": string -}; /** * @typedef JwtAlgorithm * @type {'ES256'|'ES384'|'ES512'|'HS256'|'HS384'|'HS512'|'RS256'|'RS384'|'RS512'} @@ -183,12 +171,12 @@ function _decodePayload(raw: string): JwtHeader | JwtPayload | null { * Signs a payload and returns the token * * @param {JwtPayload} payload The payload object. To use `nbf` (Not Before) and/or `exp` (Expiration Time) add `nbf` and/or `exp` to the payload. - * @param {string} secret A string which is used to sign the payload. + * @param {string | JsonWebKey} secret A string which is used to sign the payload. * @param {JwtSignOptions | JwtAlgorithm | string} [options={ algorithm: 'HS256', header: { typ: 'JWT' } }] The options object or the algorithm. * @throws {Error} If there's a validation issue. * @returns {Promise} Returns token as a `string`. */ -export async function sign(payload: JwtPayload, secret: string | JwkPayload, options: JwtSignOptions | JwtAlgorithm = { algorithm: 'HS256', header: { typ: 'JWT' } }): Promise { +export async function sign(payload: JwtPayload, secret: string | JsonWebKey, options: JwtSignOptions | JwtAlgorithm = { algorithm: 'HS256', header: { typ: 'JWT' } }): Promise { if (typeof options === 'string') options = { algorithm: options, header: { typ: 'JWT' } } @@ -213,16 +201,19 @@ export async function sign(payload: JwtPayload, secret: string | JwkPayload, opt const payloadAsJSON = JSON.stringify(payload) const partialToken = `${base64UrlStringify(_utf8ToUint8Array(JSON.stringify({ ...options.header, alg: options.algorithm })))}.${base64UrlStringify(_utf8ToUint8Array(payloadAsJSON))}` + let keyFormat = 'raw' let keyData + if (typeof secret === 'object') { - keyFormat = 'jwk'; - keyData = secret; + keyFormat = 'jwk' + keyData = secret } else if (typeof secret === 'string' && secret.startsWith('-----BEGIN')) { keyFormat = 'pkcs8' keyData = _str2ab(secret.replace(/-----BEGIN.*?-----/g, '').replace(/-----END.*?-----/g, '').replace(/\s/g, '')) } else keyData = _utf8ToUint8Array(secret) + const key = await crypto.subtle.importKey(keyFormat, keyData, algorithm, false, ['sign']) const signature = await crypto.subtle.sign(algorithm, key, _utf8ToUint8Array(partialToken)) @@ -233,12 +224,12 @@ export async function sign(payload: JwtPayload, secret: string | JwkPayload, opt * Verifies the integrity of the token and returns a boolean value. * * @param {string} token The token string generated by `jwt.sign()`. - * @param {string} secret The string which was used to sign the payload. + * @param {string | JsonWebKey} secret The string which was used to sign the payload. * @param {JWTVerifyOptions | JWTAlgorithm} options The options object or the algorithm. * @throws {Error | string} Throws an error `string` if the token is invalid or an `Error-Object` if there's a validation issue. * @returns {Promise} Returns `true` if signature, `nbf` (if set) and `exp` (if set) are valid, otherwise returns `false`. */ -export async function verify(token: string, secret: string | JwkPayload, options: JwtVerifyOptions | JwtAlgorithm = { algorithm: 'HS256', throwError: false }): Promise { +export async function verify(token: string, secret: string | JsonWebKey, options: JwtVerifyOptions | JwtAlgorithm = { algorithm: 'HS256', throwError: false }): Promise { if (typeof options === 'string') options = { algorithm: options, throwError: false } @@ -287,6 +278,7 @@ export async function verify(token: string, secret: string | JwkPayload, options } let keyFormat = 'raw' let keyData + if (typeof secret === 'object') { keyFormat = 'jwk'; keyData = secret; @@ -295,7 +287,9 @@ export async function verify(token: string, secret: string | JwkPayload, options keyData = _str2ab(secret.replace(/-----BEGIN.*?-----/g, '').replace(/-----END.*?-----/g, '').replace(/\s/g, '')) } else keyData = _utf8ToUint8Array(secret) + const key = await crypto.subtle.importKey(keyFormat, keyData, algorithm, false, ['verify']) + return await crypto.subtle.verify(algorithm, key, base64UrlParse(tokenParts[2]), _utf8ToUint8Array(`${tokenParts[0]}.${tokenParts[1]}`)) }