diff --git a/src/lib/auth/password.test.ts b/src/lib/auth/password.test.ts index 9a50b138..2c07543d 100644 --- a/src/lib/auth/password.test.ts +++ b/src/lib/auth/password.test.ts @@ -169,36 +169,36 @@ describe("isCombinedDigestOf", () => { describe("isSaltedDigestOf", () => { it("verifies md5(salt+password) with hash:salt layout", async () => { const salt = "pepper123"; - const stored = `${await md5Hex(salt + "oldpass")}:${salt}`; + const stored = `${await md5Hex(`${salt}oldpass`)}:${salt}`; expect(await isSaltedDigestOf("oldpass", stored)).toBe(true); expect(await isSaltedDigestOf("wrong", stored)).toBe(false); }); it("verifies md5(password+salt) with hash:salt layout", async () => { const salt = "pepper123"; - const stored = `${await md5Hex("oldpass" + salt)}:${salt}`; + const stored = `${await md5Hex(`oldpass${salt}`)}:${salt}`; expect(await isSaltedDigestOf("oldpass", stored)).toBe(true); }); it("verifies the salt:hash layout", async () => { const salt = "abc123"; - const stored = `${salt}:${await md5Hex(salt + "oldpass")}`; + const stored = `${salt}:${await md5Hex(`${salt}oldpass`)}`; expect(await isSaltedDigestOf("oldpass", stored)).toBe(true); expect(await isSaltedDigestOf("wrong", stored)).toBe(false); }); it("verifies the hash$salt layout", async () => { const salt = "s0lt_9"; - const stored = `${await md5Hex("oldpass" + salt)}$s0lt_9`; + const stored = `${await md5Hex(`oldpass${salt}`)}$s0lt_9`; expect(await isSaltedDigestOf("oldpass", stored)).toBe(true); }); it("verifies salted sha1 and sha256 digests", async () => { const salt = "pepper123"; - const sha1Stored = `${await sha1Hex(salt + "oldpass")}:${salt}`; + const sha1Stored = `${await sha1Hex(`${salt}oldpass`)}:${salt}`; expect(await isSaltedDigestOf("oldpass", sha1Stored)).toBe(true); - const sha256Stored = `${await sha256Hex("oldpass" + salt)}:${salt}`; + const sha256Stored = `${await sha256Hex(`oldpass${salt}`)}:${salt}`; expect(await isSaltedDigestOf("oldpass", sha256Stored)).toBe(true); }); @@ -268,7 +268,7 @@ describe("checkLogin", () => { it("migrates a salted md5 hash to bcrypt (md5(salt+password))", async () => { const salt = "pepper123"; - const stored = `${await md5Hex(salt + "oldpass")}:${salt}`; + const stored = `${await md5Hex(`${salt}oldpass`)}:${salt}`; const res = await checkLogin("oldpass", stored); expect(res.valid).toBe(true); expect(res.upgradedHash).toMatch(/^\$2[aby]\$/); @@ -279,7 +279,7 @@ describe("checkLogin", () => { it("migrates a salted sha256 hash to bcrypt (sha256(salt+password))", async () => { const salt = "abc123"; - const stored = `${salt}:${await sha256Hex(salt + "oldpass")}`; + const stored = `${salt}:${await sha256Hex(`${salt}oldpass`)}`; const res = await checkLogin("oldpass", stored); expect(res.valid).toBe(true); expect(res.upgradedHash).toMatch(/^\$2[aby]\$/); diff --git a/src/lib/auth/password.ts b/src/lib/auth/password.ts index 05165b97..fe5bf6e2 100644 --- a/src/lib/auth/password.ts +++ b/src/lib/auth/password.ts @@ -130,7 +130,7 @@ export async function isCombinedDigestOf( * sha256, sha512) is tried, and both md5(salt+password) and md5(password+salt) * orderings are verified to cover both conventions. */ -const SALTED_HASH_DELIMITER_RE = /[:\$@_]/; +const SALTED_HASH_DELIMITER_RE = /[:$@_]/; export async function isSaltedDigestOf( password: string, @@ -140,10 +140,10 @@ export async function isSaltedDigestOf( for (const { length, hash: hashFn } of DIGEST_SCHEMES) { const hashFirst = stored.match( - new RegExp(`^([a-f0-9]{${length}})[:\$@_](.{1,64})$`, "i"), + new RegExp(`^([a-f0-9]{${length}})[:$@_](.{1,64})$`, "i"), ); const saltFirst = stored.match( - new RegExp(`^(.{1,64})[:\$@_]([a-f0-9]{${length}})$`, "i"), + new RegExp(`^(.{1,64})[:$@_]([a-f0-9]{${length}})$`, "i"), ); const hashHex = hashFirst?.[1] ?? saltFirst?.[2]; const salt = hashFirst?.[2] ?? saltFirst?.[1];