From 4ec42e7816362a4026be1d1dbe7809938422e809 Mon Sep 17 00:00:00 2001 From: Guoguo Date: Tue, 28 Apr 2026 19:14:13 -0700 Subject: [PATCH] fix: resolve password migration crash and schema constraints - Login bcrypt migration: write password_salt = '' instead of NULL, which violated the NOT NULL constraint and caused 500 errors - Schema: widen password_hash from CHAR(64) to VARCHAR(100) for bcrypt compatibility, add DEFAULT '' to password_salt - init-db: add ALTER TABLE migrations for existing databases - app.js: enrich error logging with method, path, SQL error details --- server/scripts/init-db.js | 2 ++ server/sql/schema.sql | 4 ++-- server/src/app.js | 2 +- server/src/routes/admin.js | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/server/scripts/init-db.js b/server/scripts/init-db.js index 338f0a0..78feb43 100644 --- a/server/scripts/init-db.js +++ b/server/scripts/init-db.js @@ -20,6 +20,8 @@ async function main() { await conn.query(schema) await conn.query("ALTER TABLE devices MODIFY product_id VARCHAR(64) NOT NULL DEFAULT 'HOX_LIGHT_MASK'").catch(() => {}) + await conn.query("ALTER TABLE admin_accounts MODIFY password_hash VARCHAR(100) NOT NULL").catch(() => {}) + await conn.query("ALTER TABLE admin_accounts MODIFY password_salt VARCHAR(32) NOT NULL DEFAULT ''").catch(() => {}) const [rows] = await conn.execute('SELECT admin_id FROM admin_accounts WHERE username = ?', [config.admin.username]) if (rows.length === 0) { diff --git a/server/sql/schema.sql b/server/sql/schema.sql index 3b97425..fa3a37c 100644 --- a/server/sql/schema.sql +++ b/server/sql/schema.sql @@ -128,8 +128,8 @@ CREATE TABLE IF NOT EXISTS operation_logs ( CREATE TABLE IF NOT EXISTS admin_accounts ( admin_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, username VARCHAR(64) NOT NULL, - password_hash CHAR(64) NOT NULL, - password_salt CHAR(32) NOT NULL, + password_hash VARCHAR(100) NOT NULL, + password_salt VARCHAR(32) NOT NULL DEFAULT '', real_name VARCHAR(100) NOT NULL DEFAULT '', role VARCHAR(32) NOT NULL DEFAULT 'admin', status TINYINT NOT NULL DEFAULT 1, diff --git a/server/src/app.js b/server/src/app.js index 4761e1d..59c1a31 100644 --- a/server/src/app.js +++ b/server/src/app.js @@ -26,7 +26,7 @@ async function handle(event) { const body = await match.handler(ctx) return http(200, body) } catch (err) { - console.error(err) + console.error('[ERROR]', ctx.method, ctx.path, err.code || '', err.sqlMessage || err.message, err.stack) return http(500, fail(3001, 'server_error')) } } diff --git a/server/src/routes/admin.js b/server/src/routes/admin.js index eae0099..5da2243 100644 --- a/server/src/routes/admin.js +++ b/server/src/routes/admin.js @@ -20,8 +20,8 @@ function register(router) { // Try legacy SHA-256 verification for migration if (admin.password_salt && hashPasswordLegacy(password, admin.password_salt) === admin.password_hash) { // Auto-migrate to bcrypt - const newHash = await hashPassword(password) - await query('UPDATE admin_accounts SET password_hash = :password_hash, password_salt = NULL WHERE admin_id = :admin_id', { password_hash: newHash, admin_id: admin.admin_id }) + const newHash = hashPassword(password) + await query('UPDATE admin_accounts SET password_hash = :password_hash, password_salt = :password_salt WHERE admin_id = :admin_id', { password_hash: newHash, password_salt: '', admin_id: admin.admin_id }) matched = true } }