*/ if (php_sapi_name() !== 'cli') { exit(1); } require_once __DIR__ . '/../common.php'; require_once __DIR__ . '/../db_init.php'; $username = $argv[1] ?? ''; $password = $argv[2] ?? ''; if ($username === '' || $password === '') { fwrite(STDERR, "Usage: php cli/diagnose_login.php \n"); fwrite(STDERR, "Run as www-data to match php-fpm: sudo -u www-data php cli/diagnose_login.php ...\n"); exit(1); } echo 'User: ' . (function_exists('posix_getpwuid') ? (posix_getpwuid(posix_geteuid())['name'] ?? '?') : '?') . "\n"; echo 'QDB_MASTER_KEY env length: ' . strlen(getenv('QDB_MASTER_KEY') ?: '') . "\n"; echo 'Derived key sha256: ' . hash('sha256', get_master_key_bytes()) . "\n\n"; try { echo "1) qdb_open(read-only)... "; [$pdo, $tmpDb, $lockFp] = qdb_open(false); echo "OK\n"; echo "2) lookup user... "; $stmt = $pdo->prepare( "SELECT userID, passwordHash, role, entityID, mustChangePassword FROM users WHERE username = :u" ); $stmt->execute([':u' => $username]); $user = $stmt->fetch(PDO::FETCH_ASSOC); if (!$user) { qdb_discard($tmpDb, $lockFp); echo "FAIL — user not found\n"; exit(1); } echo "OK (role={$user['role']}, mustChange={$user['mustChangePassword']})\n"; echo "3) password_verify... "; if (!password_verify($password, $user['passwordHash'])) { qdb_discard($tmpDb, $lockFp); echo "FAIL — wrong password\n"; exit(1); } echo "OK\n"; qdb_discard($tmpDb, $lockFp); echo "4) token_add (writable save, same as login)... "; $token = bin2hex(random_bytes(32)); token_add($token, 120, [ 'role' => $user['role'], 'entityID' => $user['entityID'], 'userID' => $user['userID'], 'temp' => (int)$user['mustChangePassword'] === 1, ]); echo "OK\n"; echo "5) token_get_record... "; $rec = token_get_record($token); if (!$rec) { echo "FAIL — session not readable after save\n"; exit(1); } echo "OK\n"; token_revoke($token); echo "\nAll login steps succeeded. If the website still fails, check nginx routing (curl below).\n"; } catch (Throwable $e) { echo "FAIL\n " . $e->getMessage() . "\n"; echo " " . $e->getFile() . ':' . $e->getLine() . "\n"; exit(1); }