diff --git a/src/node/util.ts b/src/node/util.ts index e3039d89c..551ed4b60 100644 --- a/src/node/util.ts +++ b/src/node/util.ts @@ -162,6 +162,33 @@ export const isHashLegacyMatch = (password: string, hashPassword: string) => { return safeCompare(hashedWithLegacy, hashPassword) } +const passwordMethods = ["SHA256", "ARGON2", "PLAIN_TEXT"] as const +export type PasswordMethod = typeof passwordMethods[number] + +/** + * Used to determine the password method. + * + * There are three options for the return value: + * 1. "SHA256" -> the legacy hashing algorithm + * 2. "ARGON2" -> the newest hashing algorithm + * 3. "PLAIN_TEXT" -> regular ol' password with no hashing + * + * @returns {PasswordMethod} "SHA256" | "ARGON2" | "PLAIN_TEXT" + */ +export function getPasswordMethod(hashedPassword: string | undefined): PasswordMethod { + if (!hashedPassword) { + return "PLAIN_TEXT" + } + + // This is the new hashing algorithm + if (hashedPassword.includes("$argon")) { + return "ARGON2" + } + + // This is the legacy hashing algorithm + return "SHA256" +} + 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 62d27ff25..11fb701a1 100644 --- a/test/unit/node/util.test.ts +++ b/test/unit/node/util.test.ts @@ -1,4 +1,11 @@ -import { hash, isHashMatch, hashLegacy, isHashLegacyMatch } from "../../../src/node/util" +import { + hash, + isHashMatch, + PasswordMethod, + getPasswordMethod, + hashLegacy, + isHashLegacyMatch, +} from "../../../src/node/util" describe("getEnvPaths", () => { describe("on darwin", () => { @@ -203,3 +210,25 @@ describe("isHashLegacyMatch", () => { expect(isHashLegacyMatch(password, _hash)).toBe(true) }) }) + +describe("getPasswordMethod", () => { + it("should return PLAIN_TEXT for no hashed password", () => { + const hashedPassword = undefined + const passwordMethod = getPasswordMethod(hashedPassword) + const expected: PasswordMethod = "PLAIN_TEXT" + expect(passwordMethod).toEqual(expected) + }) + it("should return ARGON2 for password with 'argon2'", () => { + const hashedPassword = + "$argon2i$v=19$m=4096,t=3,p=1$0qR/o+0t00hsbJFQCKSfdQ$oFcM4rL6o+B7oxpuA4qlXubypbBPsf+8L531U7P9HYY" + const passwordMethod = getPasswordMethod(hashedPassword) + const expected: PasswordMethod = "ARGON2" + expect(passwordMethod).toEqual(expected) + }) + it("should return SHA256 for password with legacy hash", () => { + const hashedPassword = "936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af" + const passwordMethod = getPasswordMethod(hashedPassword) + const expected: PasswordMethod = "SHA256" + expect(passwordMethod).toEqual(expected) + }) +})