From 0499fa127c8e6c56f315d7bc8a5bccadb55b2d8a Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 23 Apr 2026 17:53:55 +0300 Subject: [PATCH] fix(migration): resolve v1.0.0 password column migration causing login failures (#1059) Fixes users unable to login after upgrading from v1.0.0 to v1.1.0-dev.16. The migration was using COALESCE(password_digest, password) which fails in SQLite when password_digest column doesn't exist in v1.0.0 databases. The v1.0.0 schema had a 'password' column, not 'password_digest'. Changes: - Dynamically detect which password column exists (password vs password_digest) - Use the correct column in the migration SELECT statement - Add enhanced trust proxy diagnostics to help debug configuration issues Tested: - Created v1.0.0 database with 'password' column - Verified user login works pre-migration - Ran migration with fix - Confirmed password hash preserved and login still works post-migration --- backend/app.js | 2 ++ .../20260420000004-make-password-optional.js | 22 ++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/backend/app.js b/backend/app.js index c6cca11..291d596 100644 --- a/backend/app.js +++ b/backend/app.js @@ -26,6 +26,8 @@ if (config.trustProxy !== false) { console.log(`[Trust Proxy] Disabled (value: false)`); } +console.log(`[Trust Proxy] Express setting confirmed:`, app.get('trust proxy')); + // Session store const sessionStore = new SequelizeStore({ db: sequelize, diff --git a/backend/migrations/20260420000004-make-password-optional.js b/backend/migrations/20260420000004-make-password-optional.js index 4713912..99d835a 100644 --- a/backend/migrations/20260420000004-make-password-optional.js +++ b/backend/migrations/20260420000004-make-password-optional.js @@ -48,6 +48,26 @@ module.exports = { ); `); + const [columns] = await queryInterface.sequelize.query( + 'PRAGMA table_info(users);' + ); + const hasPasswordDigest = columns.some( + (col) => col.name === 'password_digest' + ); + const hasPassword = columns.some((col) => col.name === 'password'); + + const passwordColumn = hasPasswordDigest + ? 'password_digest' + : hasPassword + ? 'password' + : null; + + if (!passwordColumn) { + throw new Error( + 'Neither password nor password_digest column found in users table' + ); + } + await queryInterface.sequelize.query(` INSERT INTO users_new ( id, uid, name, surname, email, password_digest, appearance, language, @@ -64,7 +84,7 @@ module.exports = { ) SELECT id, uid, name, surname, email, - COALESCE(password_digest, password) as password_digest, + ${passwordColumn} as password_digest, appearance, language, timezone, first_day_of_week, avatar_image, telegram_bot_token, telegram_chat_id, task_summary_enabled, task_summary_frequency,