mirror of
https://github.com/louislam/uptime-kuma.git
synced 2026-10-13 17:02:17 -05:00
fix: skip HIBP check when migrating a v2 user (#7947)
This commit is contained in:
1 parent
0d9728993d
commit
4e7c4ae382
3 files changed
+41
-3
No files matched your search
@@ -120,6 +120,8 @@ npm run dev # Frontend on port 3000, backend on port 3001
|
||||
|
||||
- 4 spaces indentation, double quotes, Unix line endings (LF), semicolons required
|
||||
- Prettier enforces `printWidth: 120`; run `npm run fmt` to format (also run automatically in CI)
|
||||
- **Comments**: keep them short (one concise line explaining what/why); no multi-line essays or restating the code
|
||||
- **Commits**: one short sentence describing the change; no long body
|
||||
- **Naming**: JavaScript/TypeScript (camelCase), SQLite (snake_case), CSS/SCSS (kebab-case)
|
||||
- JSDoc is required on every function declaration and method (`jsdoc/require-jsdoc`); `*.ts` relaxes some JSDoc and `any` rules
|
||||
- Notable ESLint rules: `no-var`, `one-var: never`, `max-statements-per-line: 1`, `jsdoc/require-throws`
|
||||
|
||||
+28
-1
@@ -14,11 +14,28 @@ import { createAuthMiddleware } from "better-auth/api";
|
||||
import * as oldAuth from "./auth.js";
|
||||
import { hasUser } from "./routers/better-auth-router";
|
||||
import { symmetricEncrypt } from "better-auth/crypto";
|
||||
// @ts-ignore
|
||||
import config from "./config.js";
|
||||
|
||||
export type BetterAuthUser = ReturnType<typeof createAuthInstance>["$Infer"]["Session"]["user"];
|
||||
|
||||
let authInstance: ReturnType<typeof createAuthInstance>;
|
||||
|
||||
/**
|
||||
* Whether the HIBP password check is enabled (`UPTIME_KUMA_DISABLE_LEAK_PWD_CHECK` / `--disable-leak-pwd-check`).
|
||||
* @returns True to run the check
|
||||
*/
|
||||
function isHaveIBeenPwnedEnabled() {
|
||||
const disableHibp = process.env.UPTIME_KUMA_DISABLE_LEAK_PWD_CHECK;
|
||||
const disabledByEnv = !!disableHibp && disableHibp !== "false" && disableHibp !== "0";
|
||||
return !disabledByEnv && !config.args["disable-leak-pwd-check"];
|
||||
}
|
||||
|
||||
// Shared haveIBeenPwned plugin options; `enabled` is turned off during legacy user migration (#7946).
|
||||
const haveIBeenPwnedOptions = {
|
||||
enabled: true,
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the singleton instance of better-auth
|
||||
* Mainly used for http and socket.io authentication
|
||||
@@ -56,6 +73,12 @@ function createAuthInstance() {
|
||||
);
|
||||
}
|
||||
|
||||
// Apply the UPTIME_KUMA_DISABLE_LEAK_PWD_CHECK / --disable-leak-pwd-check setting
|
||||
haveIBeenPwnedOptions.enabled = isHaveIBeenPwnedEnabled();
|
||||
if (!haveIBeenPwnedOptions.enabled) {
|
||||
log.warn("auth", "haveIBeenPwned password check is disabled (UPTIME_KUMA_DISABLE_LEAK_PWD_CHECK).");
|
||||
}
|
||||
|
||||
const authDatabase = Database.createAuthDatabase(Database.dbConfig);
|
||||
|
||||
return betterAuth({
|
||||
@@ -108,7 +131,7 @@ function createAuthInstance() {
|
||||
admin(),
|
||||
|
||||
// Check if the password has been pwned in data breaches
|
||||
haveIBeenPwned(),
|
||||
haveIBeenPwned(haveIBeenPwnedOptions),
|
||||
|
||||
twoFactor({
|
||||
schema: {
|
||||
@@ -299,6 +322,8 @@ export async function doubleCheckPassword(cookie: string, currentPassword: strin
|
||||
export async function migrateUser(username: string, password: string) {
|
||||
const legacyUser = await oldAuth.login(username, password);
|
||||
if (legacyUser) {
|
||||
// Skip the HIBP check: the legacy user's existing password must not be rejected (#7946)
|
||||
haveIBeenPwnedOptions.enabled = false;
|
||||
try {
|
||||
// Create BetterAuth user with the same username and password
|
||||
const newUser = await auth().api.createUser({
|
||||
@@ -338,6 +363,8 @@ export async function migrateUser(username: string, password: string) {
|
||||
log.info("auth", `Migrated legacy user: ${username}`);
|
||||
} catch (e) {
|
||||
log.error("auth", `Failed to migrate legacy user ${username}:`, e);
|
||||
} finally {
|
||||
haveIBeenPwnedOptions.enabled = isHaveIBeenPwnedEnabled();
|
||||
}
|
||||
} else {
|
||||
log.info("auth", `No legacy user found for username: ${username}, do not migrate.`);
|
||||
|
||||
@@ -7,6 +7,8 @@ import zlib from "node:zlib";
|
||||
import { spawn } from "node:child_process";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { io } from "socket.io-client";
|
||||
import BetterSqlite3 from "better-sqlite3";
|
||||
import bcrypt from "bcryptjs";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
@@ -14,7 +16,9 @@ const fixturePath = path.join(__dirname, "../fixtures/v2-kuma.db.gz");
|
||||
const dataDir = path.join(__dirname, "../../data/test-migration-v2-upgrade");
|
||||
|
||||
const username = "admin";
|
||||
const password = "Kuma-V2-Test-Password";
|
||||
|
||||
// A password that Have I Been Pwned reports as breached, to cover the migration path from #7946.
|
||||
const password = "Admin123!x";
|
||||
|
||||
/**
|
||||
* Get a free TCP port from the OS.
|
||||
@@ -76,7 +80,7 @@ async function callOk(socket, event, ...args) {
|
||||
return result;
|
||||
}
|
||||
|
||||
test("A v2.5.3 database still works after upgrading to v3 (#7944)", { timeout: 180000 }, async () => {
|
||||
test("A v2.5.3 database still works after upgrading to v3 (#7944, #7946)", { timeout: 180000 }, async () => {
|
||||
assert.ok(fs.existsSync(fixturePath), `v2 fixture not found: ${fixturePath}`);
|
||||
|
||||
// Start from a real 2.5.3 database (see extra/prepare-v2-test-db.mjs) and let the server
|
||||
@@ -85,6 +89,11 @@ test("A v2.5.3 database still works after upgrading to v3 (#7944)", { timeout: 1
|
||||
fs.mkdirSync(dataDir, { recursive: true });
|
||||
fs.writeFileSync(path.join(dataDir, "kuma.db"), zlib.gunzipSync(fs.readFileSync(fixturePath)));
|
||||
|
||||
// Seed the admin with a breached password, so migrating it must skip the leak check (#7946).
|
||||
const seedDb = new BetterSqlite3(path.join(dataDir, "kuma.db"));
|
||||
seedDb.prepare("UPDATE user SET password = ? WHERE username = ?").run(await bcrypt.hash(password, 10), username);
|
||||
seedDb.close();
|
||||
|
||||
let child;
|
||||
let socket;
|
||||
|
||||
|
||||
Reference in new issue
Block a user