mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-07-15 04:43:36 +00:00
feat: improve sentinel system
This commit is contained in:
@@ -431,18 +431,11 @@ router.get(
|
|||||||
if (credential.password) {
|
if (credential.password) {
|
||||||
output.password = credential.password;
|
output.password = credential.password;
|
||||||
}
|
}
|
||||||
if (credential.key) {
|
output.hasKey = !!credential.key;
|
||||||
output.key = credential.key;
|
output.hasKeyPassword = !!credential.keyPassword;
|
||||||
}
|
|
||||||
if (credential.privateKey) {
|
|
||||||
output.privateKey = credential.privateKey;
|
|
||||||
}
|
|
||||||
if (credential.publicKey) {
|
if (credential.publicKey) {
|
||||||
output.publicKey = credential.publicKey;
|
output.publicKey = credential.publicKey;
|
||||||
}
|
}
|
||||||
if (credential.keyPassword) {
|
|
||||||
output.keyPassword = credential.keyPassword;
|
|
||||||
}
|
|
||||||
|
|
||||||
res.json(output);
|
res.json(output);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -246,29 +246,18 @@ function normalizeImportedHost(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const SENSITIVE_FIELDS = [
|
const SENSITIVE_FIELDS = [
|
||||||
"password",
|
|
||||||
"key",
|
"key",
|
||||||
"keyPassword",
|
"keyPassword",
|
||||||
"sudoPassword",
|
|
||||||
"autostartPassword",
|
|
||||||
"autostartKey",
|
"autostartKey",
|
||||||
"autostartKeyPassword",
|
"autostartKeyPassword",
|
||||||
"socks5Password",
|
|
||||||
"rdpPassword",
|
|
||||||
"vncPassword",
|
|
||||||
"telnetPassword",
|
|
||||||
];
|
];
|
||||||
|
|
||||||
function stripSensitiveFields(
|
function stripSensitiveFields(
|
||||||
host: Record<string, unknown>,
|
host: Record<string, unknown>,
|
||||||
): Record<string, unknown> {
|
): Record<string, unknown> {
|
||||||
const result = { ...host };
|
const result = { ...host };
|
||||||
result.hasPassword = !!host.password;
|
|
||||||
result.hasKey = !!host.key;
|
result.hasKey = !!host.key;
|
||||||
result.hasSudoPassword = !!host.sudoPassword;
|
result.hasKeyPassword = !!host.keyPassword;
|
||||||
result.hasRdpPassword = !!host.rdpPassword;
|
|
||||||
result.hasVncPassword = !!host.vncPassword;
|
|
||||||
result.hasTelnetPassword = !!host.telnetPassword;
|
|
||||||
for (const field of SENSITIVE_FIELDS) {
|
for (const field of SENSITIVE_FIELDS) {
|
||||||
delete result[field];
|
delete result[field];
|
||||||
}
|
}
|
||||||
@@ -323,9 +312,6 @@ function transformHostResponse(
|
|||||||
rdpIgnoreCert: !!host.rdpIgnoreCert,
|
rdpIgnoreCert: !!host.rdpIgnoreCert,
|
||||||
vncUser: host.vncUser || undefined,
|
vncUser: host.vncUser || undefined,
|
||||||
telnetUser: host.telnetUser || undefined,
|
telnetUser: host.telnetUser || undefined,
|
||||||
hasRdpPassword: !!host.rdpPassword,
|
|
||||||
hasVncPassword: !!host.vncPassword,
|
|
||||||
hasTelnetPassword: !!host.telnetPassword,
|
|
||||||
tunnelConnections: host.tunnelConnections
|
tunnelConnections: host.tunnelConnections
|
||||||
? JSON.parse(host.tunnelConnections as string)
|
? JSON.parse(host.tunnelConnections as string)
|
||||||
: [],
|
: [],
|
||||||
|
|||||||
+1
-6
@@ -105,16 +105,11 @@ export interface Host {
|
|||||||
vncUser?: string;
|
vncUser?: string;
|
||||||
telnetUser?: string;
|
telnetUser?: string;
|
||||||
telnetPassword?: string;
|
telnetPassword?: string;
|
||||||
hasRdpPassword?: boolean;
|
|
||||||
hasVncPassword?: boolean;
|
|
||||||
hasTelnetPassword?: boolean;
|
|
||||||
|
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
|
|
||||||
hasPassword?: boolean;
|
|
||||||
hasKey?: boolean;
|
hasKey?: boolean;
|
||||||
hasSudoPassword?: boolean;
|
hasKeyPassword?: boolean;
|
||||||
|
|
||||||
isShared?: boolean;
|
isShared?: boolean;
|
||||||
permissionLevel?: "view";
|
permissionLevel?: "view";
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ export type Host = {
|
|||||||
credentialId?: string;
|
credentialId?: string;
|
||||||
overrideCredentialUsername?: boolean;
|
overrideCredentialUsername?: boolean;
|
||||||
password?: string;
|
password?: string;
|
||||||
hasPassword?: boolean;
|
|
||||||
hasKey?: boolean;
|
hasKey?: boolean;
|
||||||
|
hasKeyPassword?: boolean;
|
||||||
key?: string;
|
key?: string;
|
||||||
keyPassword?: string;
|
keyPassword?: string;
|
||||||
keyType?: string;
|
keyType?: string;
|
||||||
|
|||||||
@@ -176,7 +176,6 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"authentication": "Authentication",
|
"authentication": "Authentication",
|
||||||
"password": "Password",
|
"password": "Password",
|
||||||
"passwordSaved": "Password saved, type to change",
|
|
||||||
"key": "Key",
|
"key": "Key",
|
||||||
"credential": "Credential",
|
"credential": "Credential",
|
||||||
"none": "None",
|
"none": "None",
|
||||||
@@ -297,6 +296,7 @@
|
|||||||
"clearKey": "Clear key",
|
"clearKey": "Clear key",
|
||||||
"keySaved": "SSH key saved",
|
"keySaved": "SSH key saved",
|
||||||
"keyReplaceNotice": "paste a new key below to replace it",
|
"keyReplaceNotice": "paste a new key below to replace it",
|
||||||
|
"keyPassphraseSaved": "Passphrase saved, type to change",
|
||||||
"replaceKey": "Replace key",
|
"replaceKey": "Replace key",
|
||||||
"forceKeyboardInteractiveLabel": "Force Keyboard Interactive",
|
"forceKeyboardInteractiveLabel": "Force Keyboard Interactive",
|
||||||
"forceKeyboardInteractiveShortDesc": "Force manual password entry even if keys are present",
|
"forceKeyboardInteractiveShortDesc": "Force manual password entry even if keys are present",
|
||||||
|
|||||||
+92
-111
@@ -132,8 +132,8 @@ function sshHostToHost(h: SSHHostWithStatus): Host {
|
|||||||
tags: h.tags ?? [],
|
tags: h.tags ?? [],
|
||||||
authType: h.authType,
|
authType: h.authType,
|
||||||
password: h.password,
|
password: h.password,
|
||||||
hasPassword: !!(h as any).hasPassword || !!h.password,
|
|
||||||
hasKey: !!(h as any).hasKey || !!(typeof h.key === "string" && h.key),
|
hasKey: !!(h as any).hasKey || !!(typeof h.key === "string" && h.key),
|
||||||
|
hasKeyPassword: !!(h as any).hasKeyPassword || !!h.keyPassword,
|
||||||
key: typeof h.key === "string" ? h.key : undefined,
|
key: typeof h.key === "string" ? h.key : undefined,
|
||||||
keyPassword: h.keyPassword,
|
keyPassword: h.keyPassword,
|
||||||
keyType: h.keyType,
|
keyType: h.keyType,
|
||||||
@@ -159,20 +159,14 @@ function sshHostToHost(h: SSHHostWithStatus): Host {
|
|||||||
vncPort: h.vncPort ?? (h.connectionType === "vnc" ? h.port : 5900),
|
vncPort: h.vncPort ?? (h.connectionType === "vnc" ? h.port : 5900),
|
||||||
telnetPort: h.telnetPort ?? (h.connectionType === "telnet" ? h.port : 23),
|
telnetPort: h.telnetPort ?? (h.connectionType === "telnet" ? h.port : 23),
|
||||||
rdpUser: h.rdpUser,
|
rdpUser: h.rdpUser,
|
||||||
rdpPassword: (h as any).hasRdpPassword
|
rdpPassword: h.rdpPassword ?? "",
|
||||||
? "existing_password"
|
|
||||||
: (h.rdpPassword ?? ""),
|
|
||||||
domain: h.rdpDomain,
|
domain: h.rdpDomain,
|
||||||
security: h.rdpSecurity,
|
security: h.rdpSecurity,
|
||||||
ignoreCert: h.rdpIgnoreCert ?? false,
|
ignoreCert: h.rdpIgnoreCert ?? false,
|
||||||
vncPassword: (h as any).hasVncPassword
|
vncPassword: h.vncPassword ?? "",
|
||||||
? "existing_password"
|
|
||||||
: (h.vncPassword ?? ""),
|
|
||||||
vncUser: h.vncUser,
|
vncUser: h.vncUser,
|
||||||
telnetUser: h.telnetUser,
|
telnetUser: h.telnetUser,
|
||||||
telnetPassword: (h as any).hasTelnetPassword
|
telnetPassword: h.telnetPassword ?? "",
|
||||||
? "existing_password"
|
|
||||||
: (h.telnetPassword ?? ""),
|
|
||||||
quickActions: (h.quickActions ?? []).map((a: any) => ({
|
quickActions: (h.quickActions ?? []).map((a: any) => ({
|
||||||
name: a.name,
|
name: a.name,
|
||||||
snippetId: String(a.snippetId),
|
snippetId: String(a.snippetId),
|
||||||
@@ -870,10 +864,11 @@ function HostEditor({
|
|||||||
vncPort: host?.vncPort ?? 5900,
|
vncPort: host?.vncPort ?? 5900,
|
||||||
telnetPort: host?.telnetPort ?? 23,
|
telnetPort: host?.telnetPort ?? 23,
|
||||||
authType: host?.authType ?? "password",
|
authType: host?.authType ?? "password",
|
||||||
password:
|
password: host?.password ?? "",
|
||||||
host?.password ?? (host?.hasPassword ? "existing_password" : ""),
|
|
||||||
key: host?.key ?? (host?.hasKey ? "existing_key" : ""),
|
key: host?.key ?? (host?.hasKey ? "existing_key" : ""),
|
||||||
keyPassword: host?.keyPassword ?? "",
|
keyPassword: host?.hasKeyPassword
|
||||||
|
? "existing_key_password"
|
||||||
|
: (host?.keyPassword ?? ""),
|
||||||
keyType: host?.keyType ?? "auto",
|
keyType: host?.keyType ?? "auto",
|
||||||
keySubTab: "paste" as "paste" | "upload",
|
keySubTab: "paste" as "paste" | "upload",
|
||||||
credentialId: host?.credentialId ?? "",
|
credentialId: host?.credentialId ?? "",
|
||||||
@@ -951,20 +946,14 @@ function HostEditor({
|
|||||||
quickActions:
|
quickActions:
|
||||||
host?.quickActions ?? ([] as { name: string; snippetId: string }[]),
|
host?.quickActions ?? ([] as { name: string; snippetId: string }[]),
|
||||||
rdpUser: host?.rdpUser ?? "",
|
rdpUser: host?.rdpUser ?? "",
|
||||||
rdpPassword: (host as any)?.hasRdpPassword
|
rdpPassword: host?.rdpPassword ?? "",
|
||||||
? "existing_password"
|
|
||||||
: (host?.rdpPassword ?? ""),
|
|
||||||
domain: host?.domain ?? "",
|
domain: host?.domain ?? "",
|
||||||
security: host?.security ?? "",
|
security: host?.security ?? "",
|
||||||
ignoreCert: host?.ignoreCert ?? false,
|
ignoreCert: host?.ignoreCert ?? false,
|
||||||
vncPassword: (host as any)?.hasVncPassword
|
vncPassword: host?.vncPassword ?? "",
|
||||||
? "existing_password"
|
|
||||||
: (host?.vncPassword ?? ""),
|
|
||||||
vncUser: host?.vncUser ?? "",
|
vncUser: host?.vncUser ?? "",
|
||||||
telnetUser: host?.telnetUser ?? "",
|
telnetUser: host?.telnetUser ?? "",
|
||||||
telnetPassword: (host as any)?.hasTelnetPassword
|
telnetPassword: host?.telnetPassword ?? "",
|
||||||
? "existing_password"
|
|
||||||
: (host?.telnetPassword ?? ""),
|
|
||||||
guacamoleConfig: host?.guacamoleConfig ?? ({} as Record<string, any>),
|
guacamoleConfig: host?.guacamoleConfig ?? ({} as Record<string, any>),
|
||||||
statsConfig: host?.statsConfig ?? {
|
statsConfig: host?.statsConfig ?? {
|
||||||
statusCheckEnabled: true,
|
statusCheckEnabled: true,
|
||||||
@@ -1092,12 +1081,12 @@ function HostEditor({
|
|||||||
tags,
|
tags,
|
||||||
pin: form.pin,
|
pin: form.pin,
|
||||||
authType: form.authType,
|
authType: form.authType,
|
||||||
password:
|
password: form.password || null,
|
||||||
form.password === "existing_password"
|
|
||||||
? undefined
|
|
||||||
: form.password || null,
|
|
||||||
key: form.key === "existing_key" ? undefined : form.key || null,
|
key: form.key === "existing_key" ? undefined : form.key || null,
|
||||||
keyPassword: form.keyPassword || null,
|
keyPassword:
|
||||||
|
form.keyPassword === "existing_key_password"
|
||||||
|
? undefined
|
||||||
|
: form.keyPassword || null,
|
||||||
keyType: form.keyType !== "auto" ? form.keyType : null,
|
keyType: form.keyType !== "auto" ? form.keyType : null,
|
||||||
credentialId: form.credentialId ? Number(form.credentialId) : null,
|
credentialId: form.credentialId ? Number(form.credentialId) : null,
|
||||||
overrideCredentialUsername: form.overrideCredentialUsername,
|
overrideCredentialUsername: form.overrideCredentialUsername,
|
||||||
@@ -1133,23 +1122,14 @@ function HostEditor({
|
|||||||
telnetPort: Number(form.telnetPort),
|
telnetPort: Number(form.telnetPort),
|
||||||
forceKeyboardInteractive: form.forceKeyboardInteractive,
|
forceKeyboardInteractive: form.forceKeyboardInteractive,
|
||||||
rdpUser: form.rdpUser || null,
|
rdpUser: form.rdpUser || null,
|
||||||
rdpPassword:
|
rdpPassword: form.rdpPassword || null,
|
||||||
form.rdpPassword === "existing_password"
|
|
||||||
? undefined
|
|
||||||
: form.rdpPassword || null,
|
|
||||||
rdpDomain: form.domain || null,
|
rdpDomain: form.domain || null,
|
||||||
rdpSecurity: form.security || null,
|
rdpSecurity: form.security || null,
|
||||||
rdpIgnoreCert: form.ignoreCert,
|
rdpIgnoreCert: form.ignoreCert,
|
||||||
vncPassword:
|
vncPassword: form.vncPassword || null,
|
||||||
form.vncPassword === "existing_password"
|
|
||||||
? undefined
|
|
||||||
: form.vncPassword || null,
|
|
||||||
vncUser: form.vncUser || null,
|
vncUser: form.vncUser || null,
|
||||||
telnetUser: form.telnetUser || null,
|
telnetUser: form.telnetUser || null,
|
||||||
telnetPassword:
|
telnetPassword: form.telnetPassword || null,
|
||||||
form.telnetPassword === "existing_password"
|
|
||||||
? undefined
|
|
||||||
: form.telnetPassword || null,
|
|
||||||
jumpHosts: form.jumpHosts,
|
jumpHosts: form.jumpHosts,
|
||||||
portKnockSequence: form.portKnockSequence,
|
portKnockSequence: form.portKnockSequence,
|
||||||
tunnelConnections: form.serverTunnels,
|
tunnelConnections: form.serverTunnels,
|
||||||
@@ -1973,20 +1953,8 @@ function HostEditor({
|
|||||||
</label>
|
</label>
|
||||||
<PasswordInput
|
<PasswordInput
|
||||||
className="h-8 text-xs pr-8"
|
className="h-8 text-xs pr-8"
|
||||||
placeholder={
|
placeholder="••••••••"
|
||||||
form.password === "existing_password"
|
value={form.password}
|
||||||
? t("hosts.passwordSaved")
|
|
||||||
: "••••••••"
|
|
||||||
}
|
|
||||||
value={
|
|
||||||
form.password === "existing_password"
|
|
||||||
? ""
|
|
||||||
: form.password
|
|
||||||
}
|
|
||||||
onFocus={() => {
|
|
||||||
if (form.password === "existing_password")
|
|
||||||
setField("password", "");
|
|
||||||
}}
|
|
||||||
onChange={(e) => setField("password", e.target.value)}
|
onChange={(e) => setField("password", e.target.value)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -2077,8 +2045,20 @@ function HostEditor({
|
|||||||
</label>
|
</label>
|
||||||
<PasswordInput
|
<PasswordInput
|
||||||
className="h-8 text-xs pr-8"
|
className="h-8 text-xs pr-8"
|
||||||
placeholder={t("hosts.optional")}
|
placeholder={
|
||||||
value={form.keyPassword}
|
form.keyPassword === "existing_key_password"
|
||||||
|
? t("hosts.keyPassphraseSaved")
|
||||||
|
: t("hosts.optional")
|
||||||
|
}
|
||||||
|
value={
|
||||||
|
form.keyPassword === "existing_key_password"
|
||||||
|
? ""
|
||||||
|
: form.keyPassword
|
||||||
|
}
|
||||||
|
onFocus={() => {
|
||||||
|
if (form.keyPassword === "existing_key_password")
|
||||||
|
setField("keyPassword", "");
|
||||||
|
}}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
setField("keyPassword", e.target.value)
|
setField("keyPassword", e.target.value)
|
||||||
}
|
}
|
||||||
@@ -3330,20 +3310,8 @@ function HostEditor({
|
|||||||
</label>
|
</label>
|
||||||
<PasswordInput
|
<PasswordInput
|
||||||
className="h-8 text-xs pr-8"
|
className="h-8 text-xs pr-8"
|
||||||
placeholder={
|
placeholder="••••••••"
|
||||||
form.rdpPassword === "existing_password"
|
value={form.rdpPassword}
|
||||||
? t("hosts.passwordSaved")
|
|
||||||
: "••••••••"
|
|
||||||
}
|
|
||||||
value={
|
|
||||||
form.rdpPassword === "existing_password"
|
|
||||||
? ""
|
|
||||||
: form.rdpPassword
|
|
||||||
}
|
|
||||||
onFocus={() => {
|
|
||||||
if (form.rdpPassword === "existing_password")
|
|
||||||
setField("rdpPassword", "");
|
|
||||||
}}
|
|
||||||
onChange={(e) => setField("rdpPassword", e.target.value)}
|
onChange={(e) => setField("rdpPassword", e.target.value)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -4118,20 +4086,8 @@ function HostEditor({
|
|||||||
</label>
|
</label>
|
||||||
<PasswordInput
|
<PasswordInput
|
||||||
className="h-8 text-xs pr-8"
|
className="h-8 text-xs pr-8"
|
||||||
placeholder={
|
placeholder="••••••••"
|
||||||
form.vncPassword === "existing_password"
|
value={form.vncPassword}
|
||||||
? t("hosts.passwordSaved")
|
|
||||||
: "••••••••"
|
|
||||||
}
|
|
||||||
value={
|
|
||||||
form.vncPassword === "existing_password"
|
|
||||||
? ""
|
|
||||||
: form.vncPassword
|
|
||||||
}
|
|
||||||
onFocus={() => {
|
|
||||||
if (form.vncPassword === "existing_password")
|
|
||||||
setField("vncPassword", "");
|
|
||||||
}}
|
|
||||||
onChange={(e) => setField("vncPassword", e.target.value)}
|
onChange={(e) => setField("vncPassword", e.target.value)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -4514,20 +4470,8 @@ function HostEditor({
|
|||||||
</label>
|
</label>
|
||||||
<PasswordInput
|
<PasswordInput
|
||||||
className="h-8 text-xs pr-8"
|
className="h-8 text-xs pr-8"
|
||||||
placeholder={
|
placeholder="••••••••"
|
||||||
form.telnetPassword === "existing_password"
|
value={form.telnetPassword}
|
||||||
? t("hosts.passwordSaved")
|
|
||||||
: "••••••••"
|
|
||||||
}
|
|
||||||
value={
|
|
||||||
form.telnetPassword === "existing_password"
|
|
||||||
? ""
|
|
||||||
: form.telnetPassword
|
|
||||||
}
|
|
||||||
onFocus={() => {
|
|
||||||
if (form.telnetPassword === "existing_password")
|
|
||||||
setField("telnetPassword", "");
|
|
||||||
}}
|
|
||||||
onChange={(e) => setField("telnetPassword", e.target.value)}
|
onChange={(e) => setField("telnetPassword", e.target.value)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -5010,9 +4954,19 @@ function CredentialEditorView({
|
|||||||
tags: credForm.tags,
|
tags: credForm.tags,
|
||||||
authType: credForm.type,
|
authType: credForm.type,
|
||||||
password: credForm.type === "password" ? credForm.value : null,
|
password: credForm.type === "password" ? credForm.value : null,
|
||||||
key: credForm.type === "key" ? credForm.value : null,
|
key:
|
||||||
|
credForm.type === "key"
|
||||||
|
? credForm.value === "existing_key"
|
||||||
|
? undefined
|
||||||
|
: credForm.value || null
|
||||||
|
: null,
|
||||||
publicKey: credForm.type === "key" ? credForm.publicKey : null,
|
publicKey: credForm.type === "key" ? credForm.publicKey : null,
|
||||||
keyPassword: credForm.type === "key" ? credForm.passphrase : null,
|
keyPassword:
|
||||||
|
credForm.type === "key"
|
||||||
|
? credForm.passphrase === "existing_key_password"
|
||||||
|
? undefined
|
||||||
|
: credForm.passphrase || null
|
||||||
|
: null,
|
||||||
};
|
};
|
||||||
const saved = credential
|
const saved = credential
|
||||||
? await updateCredential(Number(credential.id), data)
|
? await updateCredential(Number(credential.id), data)
|
||||||
@@ -5218,7 +5172,9 @@ function CredentialEditorView({
|
|||||||
| "ssh-rsa"
|
| "ssh-rsa"
|
||||||
| "ecdsa-sha2-nistp256",
|
| "ecdsa-sha2-nistp256",
|
||||||
bits,
|
bits,
|
||||||
credForm.passphrase || undefined,
|
credForm.passphrase === "existing_key_password"
|
||||||
|
? undefined
|
||||||
|
: credForm.passphrase || undefined,
|
||||||
);
|
);
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
setCredField("value", result.privateKey);
|
setCredField("value", result.privateKey);
|
||||||
@@ -5272,10 +5228,17 @@ function CredentialEditorView({
|
|||||||
e.target.value = "";
|
e.target.value = "";
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
{credForm.value === "existing_key" && (
|
||||||
|
<div className="px-3 py-2 text-[10px] border border-accent-brand/30 bg-accent-brand/5 text-accent-brand">
|
||||||
|
{t("hosts.keySaved")} — {t("hosts.keyReplaceNotice")}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<textarea
|
<textarea
|
||||||
placeholder="-----BEGIN OPENSSH PRIVATE KEY-----"
|
placeholder="-----BEGIN OPENSSH PRIVATE KEY-----"
|
||||||
rows={8}
|
rows={8}
|
||||||
value={credForm.value}
|
value={
|
||||||
|
credForm.value === "existing_key" ? "" : credForm.value
|
||||||
|
}
|
||||||
onChange={(e) => setCredField("value", e.target.value)}
|
onChange={(e) => setCredField("value", e.target.value)}
|
||||||
className="w-full px-3 py-2 text-[10px] bg-background border border-border text-foreground placeholder:text-muted-foreground resize-none outline-none focus:ring-1 focus:ring-ring font-mono"
|
className="w-full px-3 py-2 text-[10px] bg-background border border-border text-foreground placeholder:text-muted-foreground resize-none outline-none focus:ring-1 focus:ring-ring font-mono"
|
||||||
/>
|
/>
|
||||||
@@ -5286,8 +5249,20 @@ function CredentialEditorView({
|
|||||||
</label>
|
</label>
|
||||||
<PasswordInput
|
<PasswordInput
|
||||||
className="h-8 text-xs pr-8"
|
className="h-8 text-xs pr-8"
|
||||||
placeholder="••••••••"
|
placeholder={
|
||||||
value={credForm.passphrase}
|
credForm.passphrase === "existing_key_password"
|
||||||
|
? t("hosts.keyPassphraseSaved")
|
||||||
|
: "••••••••"
|
||||||
|
}
|
||||||
|
value={
|
||||||
|
credForm.passphrase === "existing_key_password"
|
||||||
|
? ""
|
||||||
|
: credForm.passphrase
|
||||||
|
}
|
||||||
|
onFocus={() => {
|
||||||
|
if (credForm.passphrase === "existing_key_password")
|
||||||
|
setCredField("passphrase", "");
|
||||||
|
}}
|
||||||
onChange={(e) => setCredField("passphrase", e.target.value)}
|
onChange={(e) => setCredField("passphrase", e.target.value)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -5301,13 +5276,19 @@ function CredentialEditorView({
|
|||||||
variant="outline"
|
variant="outline"
|
||||||
size="sm"
|
size="sm"
|
||||||
className="h-6 text-[10px] px-2 border-accent-brand/40 text-accent-brand"
|
className="h-6 text-[10px] px-2 border-accent-brand/40 text-accent-brand"
|
||||||
disabled={!credForm.value || generatingPublicKey}
|
disabled={
|
||||||
|
!credForm.value ||
|
||||||
|
credForm.value === "existing_key" ||
|
||||||
|
generatingPublicKey
|
||||||
|
}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
setGeneratingPublicKey(true);
|
setGeneratingPublicKey(true);
|
||||||
try {
|
try {
|
||||||
const result = await generatePublicKeyFromPrivate(
|
const result = await generatePublicKeyFromPrivate(
|
||||||
credForm.value,
|
credForm.value,
|
||||||
credForm.passphrase || undefined,
|
credForm.passphrase === "existing_key_password"
|
||||||
|
? undefined
|
||||||
|
: credForm.passphrase || undefined,
|
||||||
);
|
);
|
||||||
if (result?.publicKey) {
|
if (result?.publicKey) {
|
||||||
setCredField("publicKey", result.publicKey);
|
setCredField("publicKey", result.publicKey);
|
||||||
@@ -6935,12 +6916,12 @@ export function HostManager({
|
|||||||
);
|
);
|
||||||
setEditingCredential({
|
setEditingCredential({
|
||||||
...cred,
|
...cred,
|
||||||
value:
|
value: (full as any).hasKey
|
||||||
(full as any).password ??
|
? "existing_key"
|
||||||
(full as any).key ??
|
: ((full as any).password ?? ""),
|
||||||
"",
|
passphrase: (full as any).hasKeyPassword
|
||||||
passphrase:
|
? "existing_key_password"
|
||||||
(full as any).keyPassword ?? "",
|
: "",
|
||||||
});
|
});
|
||||||
} catch {
|
} catch {
|
||||||
setEditingCredential(cred);
|
setEditingCredential(cred);
|
||||||
|
|||||||
Reference in New Issue
Block a user