1
0
This commit is contained in:
2022-12-15 16:22:49 +01:00
committed by Toby
parent 10dcf2f01b
commit de658122b9

View File

@@ -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<string>} Returns token as a `string`.
*/
export async function sign(payload: JwtPayload, secret: string | JwkPayload, options: JwtSignOptions | JwtAlgorithm = { algorithm: 'HS256', header: { typ: 'JWT' } }): Promise<string> {
export async function sign(payload: JwtPayload, secret: string | JsonWebKey, options: JwtSignOptions | JwtAlgorithm = { algorithm: 'HS256', header: { typ: 'JWT' } }): Promise<string> {
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<boolean>} 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<boolean> {
export async function verify(token: string, secret: string | JsonWebKey, options: JwtVerifyOptions | JwtAlgorithm = { algorithm: 'HS256', throwError: false }): Promise<boolean> {
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]}`))
}