make verify return decoded token
This commit is contained in:
59
src/index.ts
59
src/index.ts
@@ -137,11 +137,11 @@ const algorithms: JwtAlgorithms = {
|
||||
/**
|
||||
* 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 | JsonWebKey | CryptoKey} 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`.
|
||||
* @param payload The payload object. To use `nbf` (Not Before) and/or `exp` (Expiration Time) add `nbf` and/or `exp` to the payload.
|
||||
* @param secret A string which is used to sign the payload.
|
||||
* @param [options={ algorithm: "HS256", header: { typ: "JWT" } }] The options object or the algorithm.
|
||||
* @throws If there"s a validation issue.
|
||||
* @returns Returns token as a `string`.
|
||||
*/
|
||||
export async function sign<Payload = {}, Header = {}>(payload: JwtPayload<Payload>, secret: string | JsonWebKey | CryptoKey, options: JwtSignOptions<Header> | JwtAlgorithm = "HS256"): Promise<string> {
|
||||
if (typeof options === "string")
|
||||
@@ -177,13 +177,13 @@ export async function sign<Payload = {}, Header = {}>(payload: JwtPayload<Payloa
|
||||
/**
|
||||
* Verifies the integrity of the token and returns a boolean value.
|
||||
*
|
||||
* @param {string} token The token string generated by `jwt.sign()`.
|
||||
* @param {string | JsonWebKey | CryptoKey} 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`.
|
||||
* @param token The token string generated by `sign()`.
|
||||
* @param secret The string which was used to sign the payload.
|
||||
* @param options The options object or the algorithm.
|
||||
* @throws Throws integration errors and if `options.throwError` is set to `true` also throws `NOT_YET_VALID`, `EXPIRED` or `INVALID_SIGNATURE`.
|
||||
* @returns Returns the decoded token or `undefined`.
|
||||
*/
|
||||
export async function verify(token: string, secret: string | JsonWebKey | CryptoKey, options: JwtVerifyOptions | JwtAlgorithm = "HS256"): Promise<boolean> {
|
||||
export async function verify<Payload = {}, Header = {}>(token: string, secret: string | JsonWebKey | CryptoKey, options: JwtVerifyOptions | JwtAlgorithm = "HS256"): Promise<JwtData<Payload, Header> | undefined> {
|
||||
if (typeof options === "string")
|
||||
options = { algorithm: options }
|
||||
options = { algorithm: "HS256", clockTolerance: 0, throwError: false, ...options }
|
||||
@@ -207,41 +207,40 @@ export async function verify(token: string, secret: string | JsonWebKey | Crypto
|
||||
if (!algorithm)
|
||||
throw new Error("algorithm not found")
|
||||
|
||||
const { header, payload } = decode(token)
|
||||
|
||||
if (header?.alg !== options.algorithm) {
|
||||
if (options.throwError)
|
||||
throw new Error("ALG_MISMATCH")
|
||||
return false
|
||||
}
|
||||
const decodedToken = decode<Payload, Header>(token)
|
||||
|
||||
try {
|
||||
if (!payload)
|
||||
throw new Error("PARSE_ERROR")
|
||||
if (decodedToken.header?.alg !== options.algorithm)
|
||||
throw new Error("INVALID_SIGNATURE")
|
||||
|
||||
const now = Math.floor(Date.now() / 1000)
|
||||
if (decodedToken.payload) {
|
||||
const now = Math.floor(Date.now() / 1000)
|
||||
|
||||
if (payload.nbf && payload.nbf > now && (payload.nbf - now) > (options.clockTolerance ?? 0))
|
||||
throw new Error("NOT_YET_VALID")
|
||||
if (decodedToken.payload.nbf && decodedToken.payload.nbf > now && (decodedToken.payload.nbf - now) > (options.clockTolerance ?? 0))
|
||||
throw new Error("NOT_YET_VALID")
|
||||
|
||||
if (payload.exp && payload.exp <= now && (now - payload.exp) > (options.clockTolerance ?? 0))
|
||||
throw new Error("EXPIRED")
|
||||
if (decodedToken.payload.exp && decodedToken.payload.exp <= now && (now - decodedToken.payload.exp) > (options.clockTolerance ?? 0))
|
||||
throw new Error("EXPIRED")
|
||||
}
|
||||
|
||||
const key = secret instanceof CryptoKey ? secret : await importKey(secret, algorithm, ["verify"])
|
||||
|
||||
return await crypto.subtle.verify(algorithm, key, base64UrlToArrayBuffer(tokenParts[2]), textToArrayBuffer(`${tokenParts[0]}.${tokenParts[1]}`))
|
||||
if (!await crypto.subtle.verify(algorithm, key, base64UrlToArrayBuffer(tokenParts[2]), textToArrayBuffer(`${tokenParts[0]}.${tokenParts[1]}`)))
|
||||
throw new Error("INVALID_SIGNATURE")
|
||||
|
||||
return decodedToken
|
||||
} catch(err) {
|
||||
if (options.throwError)
|
||||
throw err
|
||||
return false
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the payload **without** verifying the integrity of the token. Please use `jwt.verify()` first to keep your application secure!
|
||||
* Returns the payload **without** verifying the integrity of the token. Please use `verify()` first to keep your application secure!
|
||||
*
|
||||
* @param {string} token The token string generated by `jwt.sign()`.
|
||||
* @returns {JwtData} Returns an `object` containing `header` and `payload`.
|
||||
* @param token The token string generated by `sign()`.
|
||||
* @returns Returns an `object` containing `header` and `payload`.
|
||||
*/
|
||||
export function decode<Payload = {}, Header = {}>(token: string): JwtData<Payload, Header> {
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user