feat(auth): auto-upgrade every legacy password format to bcrypt on login
checkLogin now verifies and migrates all known password formats without configuration: bcrypt, argon2id/argon2i/argon2d, unsalted md5/sha1/sha256/ sha512, double-md5 (UberCMS/Butterfly), salted md5 with embedded salt (hash:salt, salt:hash, hash$salt), and a guarded plaintext fallback. Every successful legacy login rewrites the stored hash to bcrypt, so the CONVERT_PASSWORDS flag is no longer required (kept for deploy compatibility).
This commit is contained in:
1 parent
905573e627
commit
e153300da0
5 files changed
+326
-47
No files matched your search
@@ -1,5 +1,4 @@
|
||||
import { sql } from "drizzle-orm";
|
||||
import { env } from "@/env";
|
||||
import { checkLogin } from "@/lib/auth/password";
|
||||
import { cachedQuery, invalidateKey } from "@/lib/cached-db";
|
||||
import { db } from "@/lib/db";
|
||||
@@ -98,7 +97,7 @@ export async function invalidateLoginCache(username: string): Promise<void> {
|
||||
|
||||
/** Runs a dummy hash check so missing-user responses stay timing-constant. */
|
||||
export async function runDummyHashCheck(password: string): Promise<void> {
|
||||
await checkLogin(password, DUMMY_BCRYPT_HASH, { convertPasswords: false });
|
||||
await checkLogin(password, DUMMY_BCRYPT_HASH);
|
||||
}
|
||||
|
||||
/** Verifies the password against the stored hash and reports a possible upgrade. */
|
||||
@@ -107,9 +106,7 @@ export async function verifyLoginPassword(
|
||||
password: string,
|
||||
): Promise<{ valid: boolean; upgradedHash?: string }> {
|
||||
if (!user.password) return { valid: false };
|
||||
return checkLogin(password, user.password, {
|
||||
convertPasswords: env.CONVERT_PASSWORDS,
|
||||
});
|
||||
return checkLogin(password, user.password);
|
||||
}
|
||||
|
||||
/** True when email verification is required but this account hasn't verified yet. */
|
||||
|
||||
Reference in new issue
Block a user