Sudo auto fill password #441
@@ -1,8 +1,8 @@
|
||||
cask "termix" do
|
||||
version "VERSION_PLACEHOLDER"
|
||||
sha256 "CHECKSUM_PLACEHOLDER"
|
||||
version "1.9.0"
|
||||
sha256 "8fedd242b3cae1ebfd0c391a36f1c246a26ecac258b02478ee8dea2f33cd6d96"
|
||||
|
||||
url "https://github.com/Termix-SSH/Termix/releases/download/release-#{version}-tag/termix_macos_universal_#{version}_dmg.dmg"
|
||||
url "https://github.com/Termix-SSH/Termix/releases/download/release-#{version}-tag/termix_macos_universal_dmg.dmg"
|
||||
name "Termix"
|
||||
desc "Web-based server management platform with SSH terminal, tunneling, and file editing"
|
||||
homepage "https://github.com/Termix-SSH/Termix"
|
||||
@@ -80,16 +80,16 @@ Supported Devices:
|
||||
- Windows (x64/ia32)
|
||||
- Portable
|
||||
- MSI Installer
|
||||
- Chocolatey Package Manager (coming soon)
|
||||
- Chocolatey Package Manager
|
||||
- Linux (x64/ia32)
|
||||
- Portable
|
||||
- AppImage
|
||||
- Deb
|
||||
- Flatpak (coming soon)
|
||||
- Flatpak
|
||||
- macOS (x64/ia32 on v12.0+)
|
||||
- Apple App Store (coming soon)
|
||||
- Apple App Store
|
||||
- DMG
|
||||
- Homebrew (coming soon)
|
||||
- Homebrew
|
||||
- iOS/iPadOS (v15.1+)
|
||||
- Apple App Store
|
||||
- ISO
|
||||
|
||||
@@ -705,6 +705,7 @@ export const DEFAULT_TERMINAL_CONFIG = {
|
||||
startupSnippetId: null as number | null,
|
||||
autoMosh: false,
|
||||
moshCommand: "mosh-server new -s -l LANG=en_US.UTF-8",
|
||||
sudoPasswordAutoFill: false,
|
||||
};
|
||||
|
||||
export type TerminalConfigType = typeof DEFAULT_TERMINAL_CONFIG;
|
||||
|
||||
@@ -799,7 +799,9 @@
|
||||
"searchServers": "Server durchsuchen...",
|
||||
"noServerFound": "Kein Server gefunden",
|
||||
"jumpHostsOrder": "Verbindungen werden in dieser Reihenfolge hergestellt: Jump-Host 1 → Jump-Host 2 → ... → Ziel-Server",
|
||||
"advancedAuthSettings": "Erweiterte Authentifizierungseinstellungen"
|
||||
"advancedAuthSettings": "Erweiterte Authentifizierungseinstellungen",
|
||||
"sudoPasswordAutoFill": "Sudo-Passwort automatisch ausfüllen",
|
||||
"sudoPasswordAutoFillDesc": "Popup anzeigen, um das Passwort bei sudo-Befehlen automatisch einzufügen"
|
||||
},
|
||||
"terminal": {
|
||||
"title": "Terminal",
|
||||
@@ -833,7 +835,11 @@
|
||||
"connectionTimeout": "Zeitüberschreitung der Verbindung",
|
||||
"terminalTitle": "Terminal - {{host}}",
|
||||
"terminalWithPath": "Terminal - {{host}} : {{path}}",
|
||||
"runTitle": "Ausführen von {{command}} – {{host}}"
|
||||
"runTitle": "Ausführen von {{command}} – {{host}}",
|
||||
"sudoPasswordPopupTitle": "Passwort einfügen?",
|
||||
"sudoPasswordPopupHint": "Drücken Sie Enter zum Einfügen, Esc zum Abbrechen",
|
||||
"sudoPasswordPopupConfirm": "Einfügen",
|
||||
"sudoPasswordPopupDismiss": "Abbrechen"
|
||||
},
|
||||
"fileManager": {
|
||||
"title": "Dateimanager",
|
||||
@@ -1635,4 +1641,4 @@
|
||||
"close": "Schließen",
|
||||
"hostManager": "Host-Manager"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -908,7 +908,9 @@
|
||||
"quickActionName": "Action name",
|
||||
"noSnippetFound": "No snippet found",
|
||||
"quickActionsOrder": "Quick action buttons will appear in the order listed above on the Server Stats page",
|
||||
"advancedAuthSettings": "Advanced Authentication Settings"
|
||||
"advancedAuthSettings": "Advanced Authentication Settings",
|
||||
"sudoPasswordAutoFill": "Sudo Password Auto-Fill",
|
||||
"sudoPasswordAutoFillDesc": "Automatically offer to insert SSH password when sudo prompts for password"
|
||||
},
|
||||
"terminal": {
|
||||
"title": "Terminal",
|
||||
@@ -946,7 +948,11 @@
|
||||
"totpRequired": "Two-Factor Authentication Required",
|
||||
"totpCodeLabel": "Verification Code",
|
||||
"totpPlaceholder": "000000",
|
||||
"totpVerify": "Verify"
|
||||
"totpVerify": "Verify",
|
||||
"sudoPasswordPopupTitle": "Insert Password?",
|
||||
"sudoPasswordPopupHint": "Press Enter to insert, Esc to dismiss",
|
||||
"sudoPasswordPopupConfirm": "Insert",
|
||||
"sudoPasswordPopupDismiss": "Dismiss"
|
||||
},
|
||||
"fileManager": {
|
||||
"title": "File Manager",
|
||||
@@ -1825,4 +1831,4 @@
|
||||
"close": "Close",
|
||||
"hostManager": "Host Manager"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -790,7 +790,9 @@
|
||||
"searchServers": "Rechercher des serveurs...",
|
||||
"noServerFound": "Aucun serveur trouvé",
|
||||
"jumpHostsOrder": "Les connexions seront établies dans l'ordre : Serveur de rebond 1 → Serveur de rebond 2 → ... → Serveur cible",
|
||||
"advancedAuthSettings": "Paramètres d'authentification avancés"
|
||||
"advancedAuthSettings": "Paramètres d'authentification avancés",
|
||||
"sudoPasswordAutoFill": "Remplissage automatique du mot de passe sudo",
|
||||
"sudoPasswordAutoFillDesc": "Proposer automatiquement d’insérer le mot de passe SSH lorsque sudo demande un mot de passe"
|
||||
},
|
||||
"terminal": {
|
||||
"title": "Terminal",
|
||||
@@ -828,7 +830,11 @@
|
||||
"totpRequired": "Authentification à deux facteurs requise",
|
||||
"totpCodeLabel": "Code de vérification",
|
||||
"totpPlaceholder": "000000",
|
||||
"totpVerify": "Vérifier"
|
||||
"totpVerify": "Vérifier",
|
||||
"sudoPasswordPopupTitle": "Insérer le mot de passe ?",
|
||||
"sudoPasswordPopupHint": "Appuyez sur Entrée pour insérer, Échap pour annuler",
|
||||
"sudoPasswordPopupConfirm": "Insérer",
|
||||
"sudoPasswordPopupDismiss": "Annuler"
|
||||
},
|
||||
"fileManager": {
|
||||
"title": "Gestionnaire de fichiers",
|
||||
@@ -1606,4 +1612,4 @@
|
||||
"ram": "Mémoire (RAM)",
|
||||
"notAvailable": "N/D"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -745,7 +745,9 @@
|
||||
"searchServers": "Pesquisar servidores...",
|
||||
"noServerFound": "Nenhum servidor encontrado",
|
||||
"jumpHostsOrder": "As conexões serão feitas na ordem: Host de Salto 1 → Host de Salto 2 → ... → Servidor de Destino",
|
||||
"advancedAuthSettings": "Configurações Avançadas de Autenticação"
|
||||
"advancedAuthSettings": "Configurações Avançadas de Autenticação",
|
||||
"sudoPasswordAutoFill": "Preenchimento automático da senha do sudo",
|
||||
"sudoPasswordAutoFillDesc": "Oferecer automaticamente inserir a senha SSH quando o sudo solicitar uma senha"
|
||||
},
|
||||
"terminal": {
|
||||
"title": "Terminal",
|
||||
@@ -779,7 +781,11 @@
|
||||
"connectionTimeout": "Tempo limite de conexão esgotado",
|
||||
"terminalTitle": "Terminal - {{host}}",
|
||||
"terminalWithPath": "Terminal - {{host}}:{{path}}",
|
||||
"runTitle": "Executando {{command}} - {{host}}"
|
||||
"runTitle": "Executando {{command}} - {{host}}",
|
||||
"sudoPasswordPopupTitle": "Inserir Senha?",
|
||||
"sudoPasswordPopupHint": "Pressione Enter para inserir, Esc para cancelar",
|
||||
"sudoPasswordPopupConfirm": "Inserir",
|
||||
"sudoPasswordPopupDismiss": "Cancelar"
|
||||
},
|
||||
"fileManager": {
|
||||
"title": "Gerenciador de Arquivos",
|
||||
@@ -1034,7 +1040,6 @@
|
||||
"fileSavedSuccessfully": "Arquivo salvo com sucesso",
|
||||
"autoSaveFailed": "Falha no salvamento automático",
|
||||
"fileAutoSaved": "Arquivo salvo automaticamente",
|
||||
|
||||
"moveFileFailed": "Falha ao mover {{name}}",
|
||||
"moveOperationFailed": "Falha na operação de mover",
|
||||
"canOnlyCompareFiles": "Só é possível comparar dois arquivos",
|
||||
@@ -1528,4 +1533,4 @@
|
||||
"viewMobileAppDocs": "Instalar Aplicativo Móvel",
|
||||
"mobileAppDocumentation": "Documentação do Aplicativo Móvel"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -858,7 +858,9 @@
|
||||
"searchServers": "Поиск серверов...",
|
||||
"noServerFound": "Сервер не найден",
|
||||
"jumpHostsOrder": "Подключения будут выполнены в порядке: Промежуточный хост 1 → Промежуточный хост 2 → ... → Целевой сервер",
|
||||
"advancedAuthSettings": "Расширенные настройки аутентификации"
|
||||
"advancedAuthSettings": "Расширенные настройки аутентификации",
|
||||
"sudoPasswordAutoFill": "Автозаполнение пароля sudo",
|
||||
"sudoPasswordAutoFillDesc": "Показывать всплывающее окно для автоматического ввода пароля при выполнении команд sudo"
|
||||
},
|
||||
"terminal": {
|
||||
"title": "Терминал",
|
||||
@@ -896,7 +898,11 @@
|
||||
"totpRequired": "Требуется двухфакторная аутентификация",
|
||||
"totpCodeLabel": "Код проверки",
|
||||
"totpPlaceholder": "000000",
|
||||
"totpVerify": "Проверить"
|
||||
"totpVerify": "Проверить",
|
||||
"sudoPasswordPopupTitle": "Вставить пароль?",
|
||||
"sudoPasswordPopupHint": "Нажмите Enter для вставки, Esc для отмены",
|
||||
"sudoPasswordPopupConfirm": "Вставить",
|
||||
"sudoPasswordPopupDismiss": "Отмена"
|
||||
},
|
||||
"fileManager": {
|
||||
"title": "Файловый менеджер",
|
||||
@@ -1722,4 +1728,4 @@
|
||||
"close": "Закрыть",
|
||||
"hostManager": "Менеджер хостов"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -893,7 +893,9 @@
|
||||
"searchServers": "搜索服务器...",
|
||||
"noServerFound": "未找到服务器",
|
||||
"jumpHostsOrder": "连接将按顺序进行:跳板主机 1 → 跳板主机 2 → ... → 目标服务器",
|
||||
"advancedAuthSettings": "高级身份验证设置"
|
||||
"advancedAuthSettings": "高级身份验证设置",
|
||||
"sudoPasswordAutoFill": "Sudo 密码自动填充",
|
||||
"sudoPasswordAutoFillDesc": "在 sudo 命令时显示弹窗以自动输入密码"
|
||||
},
|
||||
"terminal": {
|
||||
"title": "终端",
|
||||
@@ -931,7 +933,11 @@
|
||||
"reconnecting": "重新连接中... ({{attempt}}/{{max}})",
|
||||
"reconnected": "重新连接成功",
|
||||
"maxReconnectAttemptsReached": "已达到最大重连尝试次数",
|
||||
"connectionTimeout": "连接超时"
|
||||
"connectionTimeout": "连接超时",
|
||||
"sudoPasswordPopupTitle": "插入密码?",
|
||||
"sudoPasswordPopupHint": "按 Enter 插入,Esc 取消",
|
||||
"sudoPasswordPopupConfirm": "插入",
|
||||
"sudoPasswordPopupDismiss": "取消"
|
||||
},
|
||||
"fileManager": {
|
||||
"title": "文件管理器",
|
||||
@@ -1686,4 +1692,4 @@
|
||||
"close": "关闭",
|
||||
"hostManager": "主机管理器"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -307,6 +307,7 @@ export interface TerminalConfig {
|
||||
startupSnippetId: number | null;
|
||||
autoMosh: boolean;
|
||||
moshCommand: string;
|
||||
sudoPasswordAutoFill: boolean;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
@@ -316,13 +317,13 @@ export interface TerminalConfig {
|
||||
export interface TabContextTab {
|
||||
id: number;
|
||||
type:
|
||||
| "home"
|
||||
| "terminal"
|
||||
| "ssh_manager"
|
||||
| "server"
|
||||
| "admin"
|
||||
| "file_manager"
|
||||
| "user_profile";
|
||||
| "home"
|
||||
| "terminal"
|
||||
| "ssh_manager"
|
||||
| "server"
|
||||
| "admin"
|
||||
| "file_manager"
|
||||
| "user_profile";
|
||||
title: string;
|
||||
hostConfig?: SSHHost;
|
||||
terminalRef?: any;
|
||||
|
||||
@@ -547,6 +547,7 @@ export function HostManagerEditor({
|
||||
startupSnippetId: z.number().nullable(),
|
||||
autoMosh: z.boolean(),
|
||||
moshCommand: z.string(),
|
||||
sudoPasswordAutoFill: z.boolean(),
|
||||
})
|
||||
.optional(),
|
||||
forceKeyboardInteractive: z.boolean().optional(),
|
||||
@@ -631,7 +632,7 @@ export function HostManagerEditor({
|
||||
type FormData = z.infer<typeof formSchema>;
|
||||
|
||||
const form = useForm<FormData>({
|
||||
resolver: zodResolver(formSchema),
|
||||
resolver: zodResolver(formSchema) as any,
|
||||
defaultValues: {
|
||||
name: "",
|
||||
ip: "",
|
||||
@@ -2443,6 +2444,29 @@ export function HostManagerEditor({
|
||||
/>
|
||||
)}
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="terminalConfig.sudoPasswordAutoFill"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex flex-row items-center justify-between rounded-lg border p-3">
|
||||
<div className="space-y-0.5">
|
||||
<FormLabel>
|
||||
{t("hosts.sudoPasswordAutoFill")}
|
||||
</FormLabel>
|
||||
<FormDescription>
|
||||
{t("hosts.sudoPasswordAutoFillDesc")}
|
||||
</FormDescription>
|
||||
</div>
|
||||
<FormControl>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium">
|
||||
Environment Variables
|
||||
|
||||
82
src/ui/desktop/apps/terminal/SudoPasswordPopup.tsx
Normal file
82
src/ui/desktop/apps/terminal/SudoPasswordPopup.tsx
Normal file
@@ -0,0 +1,82 @@
|
||||
import { useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { KeyRound } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button.tsx";
|
||||
|
||||
interface SudoPasswordPopupProps {
|
||||
isOpen: boolean;
|
||||
hostPassword: string;
|
||||
backgroundColor: string;
|
||||
onConfirm: (password: string) => void;
|
||||
onDismiss: () => void;
|
||||
}
|
||||
|
||||
export function SudoPasswordPopup({
|
||||
isOpen,
|
||||
hostPassword,
|
||||
backgroundColor,
|
||||
onConfirm,
|
||||
onDismiss
|
||||
}: SudoPasswordPopupProps) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
if (!isOpen) return;
|
||||
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
if (e.key === "Enter") {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
e.stopImmediatePropagation();
|
||||
onConfirm(hostPassword);
|
||||
} else if (e.key === "Escape") {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
e.stopImmediatePropagation();
|
||||
onDismiss();
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("keydown", handleKeyDown, true);
|
||||
return () => window.removeEventListener("keydown", handleKeyDown, true);
|
||||
}, [isOpen, onConfirm, onDismiss, hostPassword]);
|
||||
|
||||
if (!isOpen) return null;
|
||||
|
||||
return (
|
||||
<div
|
||||
className="absolute bottom-4 right-4 z-50 backdrop-blur-sm border border-border rounded-lg shadow-lg p-4 min-w-[280px]"
|
||||
style={{ backgroundColor: backgroundColor }}
|
||||
>
|
||||
<div className="flex items-center gap-3 mb-3">
|
||||
<div className="p-2 bg-primary/10 rounded-full">
|
||||
<KeyRound className="h-5 w-5 text-primary" />
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-medium text-sm">
|
||||
{t("terminal.sudoPasswordPopupTitle", "Insert password?")}
|
||||
</h4>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{t("terminal.sudoPasswordPopupHint", "Press Enter to insert, Esc to dismiss")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-2 justify-end">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={onDismiss}
|
||||
>
|
||||
{t("terminal.sudoPasswordPopupDismiss", "Dismiss")}
|
||||
</Button>
|
||||
<Button
|
||||
variant="default"
|
||||
size="sm"
|
||||
onClick={() => onConfirm(hostPassword)}
|
||||
>
|
||||
{t("terminal.sudoPasswordPopupConfirm", "Insert")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user