diff --git a/src/node/util.ts b/src/node/util.ts index 93d82851..f575eb52 100644 --- a/src/node/util.ts +++ b/src/node/util.ts @@ -249,6 +249,31 @@ export async function handlePasswordValidation( return passwordValidation } +export type IsCookieValidArgs = { + passwordMethod: PasswordMethod + cookieKey: string + hashedPasswordFromArgs: string | undefined + passwordFromArgs: string | undefined +} + +/** Checks if a req.cookies.key is valid using the PasswordMethod */ +export async function isCookieValid(isCookieValidArgs: IsCookieValidArgs): Promise { + let isValid = false + const { passwordFromArgs = "", cookieKey, hashedPasswordFromArgs = "" } = isCookieValidArgs + switch (isCookieValidArgs.passwordMethod) { + case "PLAIN_TEXT": + isValid = await isHashMatch(passwordFromArgs, cookieKey) + break + case "ARGON2": + case "SHA256": + isValid = safeCompare(cookieKey, hashedPasswordFromArgs) + break + default: + break + } + return isValid +} + const mimeTypes: { [key: string]: string } = { ".aac": "audio/x-aac", ".avi": "video/x-msvideo", diff --git a/test/unit/node/util.test.ts b/test/unit/node/util.test.ts index 5927ca32..0397fbff 100644 --- a/test/unit/node/util.test.ts +++ b/test/unit/node/util.test.ts @@ -6,6 +6,7 @@ import { getPasswordMethod, hashLegacy, isHashLegacyMatch, + isCookieValid, } from "../../../src/node/util" describe("getEnvPaths", () => { @@ -234,7 +235,7 @@ describe("getPasswordMethod", () => { }) }) -describe.only("handlePasswordValidation", () => { +describe("handlePasswordValidation", () => { it("should return true with a hashedPassword for a PLAIN_TEXT password", async () => { const p = "password" const passwordValidation = await handlePasswordValidation({ @@ -322,3 +323,62 @@ describe.only("handlePasswordValidation", () => { expect(matchesHash).toBe(false) }) }) + +describe.only("isCookieValid", () => { + it("should be valid if hashed-password for SHA256 matches cookie.key", async () => { + const isValid = await isCookieValid({ + passwordMethod: "SHA256", + cookieKey: "936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af", + hashedPasswordFromArgs: "936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af", + passwordFromArgs: undefined, + }) + expect(isValid).toBe(true) + }) + it("should be invalid if hashed-password for SHA256 does not match cookie.key", async () => { + const isValid = await isCookieValid({ + passwordMethod: "SHA256", + cookieKey: "936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb9442bb6f8f8f07af", + hashedPasswordFromArgs: "936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af", + passwordFromArgs: undefined, + }) + expect(isValid).toBe(false) + }) + it("should be valid if hashed-password for ARGON2 matches cookie.key", async () => { + const isValid = await isCookieValid({ + passwordMethod: "ARGON2", + cookieKey: "$argon2i$v=19$m=4096,t=3,p=1$0qR/o+0t00hsbJFQCKSfdQ$oFcM4rL6o+B7oxpuA4qlXubypbBPsf+8L531U7P9HYY", + hashedPasswordFromArgs: + "$argon2i$v=19$m=4096,t=3,p=1$0qR/o+0t00hsbJFQCKSfdQ$oFcM4rL6o+B7oxpuA4qlXubypbBPsf+8L531U7P9HYY", + passwordFromArgs: undefined, + }) + expect(isValid).toBe(true) + }) + it("should be invalid if hashed-password for ARGON2 does not match cookie.key", async () => { + const isValid = await isCookieValid({ + passwordMethod: "ARGON2", + cookieKey: "$argon2i$v=19$m=4096,t=3,p=1$0qR/o+0t00hsbJFQCKSfdQ$oFcM4rL6o+B7oxpuA4qlXubypbBPsf+8L531U7P9H", + hashedPasswordFromArgs: + "$argon2i$v=19$m=4096,t=3,p=1$0qR/o+0t00hsbJFQCKSfdQ$oFcM4rL6o+B7oxpuA4qlXubypbBPsf+8L531U7P9HYY", + passwordFromArgs: undefined, + }) + expect(isValid).toBe(false) + }) + it("should be valid if password for PLAIN_TEXT matches cookie.key", async () => { + const isValid = await isCookieValid({ + passwordMethod: "PLAIN_TEXT", + cookieKey: "$argon2i$v=19$m=4096,t=3,p=1$0qR/o+0t00hsbJFQCKSfdQ$oFcM4rL6o+B7oxpuA4qlXubypbBPsf+8L531U7P9HYY", + passwordFromArgs: "password", + hashedPasswordFromArgs: undefined, + }) + expect(isValid).toBe(true) + }) + it("should be invalid if hashed-password for PLAIN_TEXT does not match cookie.key", async () => { + const isValid = await isCookieValid({ + passwordMethod: "PLAIN_TEXT", + cookieKey: "$argon2i$v=19$m=4096,t=3,p=1$0qR/o+0t00hsbJFQCKSfdQ$oFcM4rL6o+B7oxpuA4qlXubypbBPsf+8L531U7P9H", + passwordFromArgs: "password1234", + hashedPasswordFromArgs: undefined, + }) + expect(isValid).toBe(false) + }) +})