Fix SSH password authentication logic by removing requirePassword field

This commit eliminates the confusing requirePassword field that was causing
authentication issues where users couldn't disable password requirements.

Changes:
- Remove requirePassword field from database schema and migrations
- Simplify SSH authentication logic by removing special case branches
- Update frontend to remove requirePassword UI controls
- Clean up translation files to remove unused strings
- Support standard SSH empty password authentication

The new design follows the principle of "good taste" - password field itself
now expresses the requirement: null/empty = no password auth, value = use password.

Fixes the issue where setting requirePassword=false didn't work as expected.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
ZacharyZcR
2025-09-19 01:21:00 +08:00
parent 8afd84d96d
commit 540cfaa0f6
7 changed files with 1 additions and 63 deletions

View File

@@ -365,11 +365,6 @@ const migrateSchema = () => {
"INTEGER REFERENCES ssh_credentials(id)",
);
addColumnIfNotExists(
"ssh_data",
"require_password",
"INTEGER NOT NULL DEFAULT 1",
);
// SSH credentials table migrations for encryption support
addColumnIfNotExists("ssh_credentials", "private_key", "TEXT");

View File

@@ -45,9 +45,6 @@ export const sshData = sqliteTable("ssh_data", {
authType: text("auth_type").notNull(),
password: text("password"),
requirePassword: integer("require_password", { mode: "boolean" })
.notNull()
.default(true),
key: text("key", { length: 8192 }),
keyPassword: text("key_password"),
keyType: text("key_type"),

View File

@@ -77,7 +77,6 @@ router.get("/db/host/internal", async (req: Request, res: Response) => {
: []
: [],
pin: !!row.pin,
requirePassword: !!row.requirePassword,
enableTerminal: !!row.enableTerminal,
enableTunnel: !!row.enableTunnel,
tunnelConnections: row.tunnelConnections
@@ -138,7 +137,6 @@ router.post(
port,
username,
password,
requirePassword,
authMethod,
authType,
credentialId,
@@ -190,7 +188,6 @@ router.post(
if (effectiveAuthType === "password") {
sshDataObj.password = password || null;
sshDataObj.requirePassword = requirePassword !== false ? 1 : 0;
sshDataObj.key = null;
sshDataObj.keyPassword = null;
sshDataObj.keyType = null;
@@ -199,14 +196,12 @@ router.post(
sshDataObj.keyPassword = keyPassword || null;
sshDataObj.keyType = keyType;
sshDataObj.password = null;
sshDataObj.requirePassword = 1; // Default to true for non-password auth
} else {
// For credential auth
sshDataObj.password = null;
sshDataObj.key = null;
sshDataObj.keyPassword = null;
sshDataObj.keyType = null;
sshDataObj.requirePassword = 1; // Default to true for non-password auth
}
try {
@@ -237,7 +232,6 @@ router.post(
: []
: [],
pin: !!createdHost.pin,
requirePassword: !!createdHost.requirePassword,
enableTerminal: !!createdHost.enableTerminal,
enableTunnel: !!createdHost.enableTunnel,
tunnelConnections: createdHost.tunnelConnections
@@ -324,7 +318,6 @@ router.put(
port,
username,
password,
requirePassword,
authMethod,
authType,
credentialId,
@@ -379,7 +372,6 @@ router.put(
if (password) {
sshDataObj.password = password;
}
sshDataObj.requirePassword = requirePassword !== false ? 1 : 0;
sshDataObj.key = null;
sshDataObj.keyPassword = null;
sshDataObj.keyType = null;
@@ -394,14 +386,12 @@ router.put(
sshDataObj.keyType = keyType;
}
sshDataObj.password = null;
sshDataObj.requirePassword = 1; // Default to true for non-password auth
} else {
// For credential auth
sshDataObj.password = null;
sshDataObj.key = null;
sshDataObj.keyPassword = null;
sshDataObj.keyType = null;
sshDataObj.requirePassword = 1; // Default to true for non-password auth
}
try {
@@ -441,7 +431,6 @@ router.put(
: []
: [],
pin: !!updatedHost.pin,
requirePassword: !!updatedHost.requirePassword,
enableTerminal: !!updatedHost.enableTerminal,
enableTunnel: !!updatedHost.enableTunnel,
tunnelConnections: updatedHost.tunnelConnections
@@ -509,7 +498,6 @@ router.get("/db/host", authenticateJWT, async (req: Request, res: Response) => {
: []
: [],
pin: !!row.pin,
requirePassword: !!row.requirePassword,
enableTerminal: !!row.enableTerminal,
enableTunnel: !!row.enableTunnel,
tunnelConnections: row.tunnelConnections

View File

@@ -126,7 +126,6 @@ class DatabaseSQLiteExport {
pin INTEGER NOT NULL DEFAULT 0,
auth_type TEXT NOT NULL,
password TEXT,
require_password INTEGER NOT NULL DEFAULT 1,
key TEXT,
key_password TEXT,
key_type TEXT,
@@ -225,7 +224,6 @@ class DatabaseSQLiteExport {
const fieldMappings: Record<string, string> = {
userId: "user_id",
authType: "auth_type",
requirePassword: "require_password",
keyPassword: "key_password",
keyType: "key_type",
credentialId: "credential_id",
@@ -464,7 +462,6 @@ class DatabaseSQLiteExport {
const columnToFieldMappings: Record<string, string> = {
user_id: "userId",
auth_type: "authType",
require_password: "requirePassword",
key_password: "keyPassword",
key_type: "keyType",
credential_id: "credentialId",