From 701a10e118a36d0af8e54f8a4d5025f8f8b5269d Mon Sep 17 00:00:00 2001 From: nasriyasoftware Date: Wed, 2 Oct 2024 18:12:53 +0300 Subject: [PATCH] Update `exp` handling and added header validation --- package.json | 2 +- src/assets/jwt/jwt.ts | 32 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index 603cc0a..8f44f09 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nasriya/authcrypto", - "version": "1.1.2", + "version": "1.1.3", "description": "AuthCrypto is a versatile cryptographic toolkit for handling JSON Web Tokens (JWT), password hashing, and secure token generation and verification. It provides robust methods for creating and managing JWTs, hashing and verifying passwords with secure algorithms, and generating cryptographically strong random values for various use cases.", "main": "./dist/cjs/manager.js", "module": "./dist/esm/manager.js", diff --git a/src/assets/jwt/jwt.ts b/src/assets/jwt/jwt.ts index c27ff36..a7fd4f1 100644 --- a/src/assets/jwt/jwt.ts +++ b/src/assets/jwt/jwt.ts @@ -142,32 +142,32 @@ class JWTManager { const [headerEncoded, payloadEncoded, signature] = parts; + // Decode the header/payload + const header = JSON.parse(Buffer.from(headerEncoded, 'base64').toString()); + const payload = JSON.parse(Buffer.from(payloadEncoded, 'base64').toString()); + + // Verify the algorithm matches expected (e.g., HS512) + if (header.alg !== 'HS512') { + return { valid: false, message: `Unexpected algorithm: ${header.alg}` }; + } + // Verify the signature const expectedSignature = this.#_helpers.createSignature(`${headerEncoded}.${payloadEncoded}`); if (signature !== this.#_helpers.base64ToUrlEncoded(expectedSignature)) { return { valid: false, message: "Invalid token signature" }; } - // Decode the header/payload - const header = JSON.parse(Buffer.from(headerEncoded, 'base64').toString()); - const payload = JSON.parse(Buffer.from(payloadEncoded, 'base64').toString()); - if ('exp' in payload) { - if (typeof payload.exp === 'string' && payload.exp.endsWith('Z')) { - let expiryDate: Date; - - try { - expiryDate = new Date(payload.exp); - const now = new Date(); - if (expiryDate <= now) { - return { valid: false, message: "The token is expired" }; - } - } catch { - return { valid: false, message: "Invalid expiry date value" }; + if (typeof payload.exp === 'number') { + const now = Math.floor(Date.now() / 1000); // current time in seconds + if (payload.exp <= now) { + return { valid: false, message: "The token is expired" }; } + } else { + return { valid: false, message: "Invalid 'exp' claim type" }; } } else { - return { valid: false, message: "The token is missing the 'exp` property" }; + return { valid: false, message: "Missing 'exp' claim" }; } // Return the payload if the token is valid