Add better password manager implementation

This commit is contained in:
crschnick 2024-09-18 12:55:22 +00:00
parent 13edc5cac6
commit ef64e39fda
17 changed files with 239 additions and 79 deletions

View file

@ -76,6 +76,7 @@ public class AppPrefs {
mapVaultSpecific(new SimpleBooleanProperty(false), "dontCachePasswords", Boolean.class);
public final BooleanProperty denyTempScriptCreation =
mapVaultSpecific(new SimpleBooleanProperty(false), "denyTempScriptCreation", Boolean.class);
final Property<ExternalPasswordManager> passwordManager = mapVaultSpecific(new SimpleObjectProperty<>(), "passwordManager", ExternalPasswordManager.class);
final StringProperty passwordManagerCommand =
map(new SimpleStringProperty(""), "passwordManagerCommand", String.class);
final ObjectProperty<StartupBehaviour> startupBehaviour =
@ -256,6 +257,10 @@ public class AppPrefs {
developerMode());
}
public ObservableValue<ExternalPasswordManager> externalPasswordManager() {
return passwordManager;
}
public ObservableValue<SupportedLocale> language() {
return language;
}

View file

@ -1,6 +1,9 @@
package io.xpipe.app.prefs;
import io.xpipe.app.ext.LocalStore;
import io.xpipe.app.ext.PrefsChoiceValue;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.util.LocalShell;
import io.xpipe.core.process.OsType;
import java.util.List;
@ -8,74 +11,114 @@ import java.util.stream.Stream;
public interface ExternalPasswordManager extends PrefsChoiceValue {
String getTemplate();
String retrievePassword(String key);
ExternalPasswordManager COMMAND = new ExternalPasswordManager() {
ExternalPasswordManager BITWARDEN = new ExternalPasswordManager() {
@Override
public String getTemplate() {
return "bw get password $KEY --nointeraction --raw";
public String retrievePassword(String key) {
var cmd = AppPrefs.get().passwordManagerString(key);
if (cmd == null) {
return null;
}
try (var cc = new LocalStore().control().command(cmd).start()) {
return cc.readStdoutOrThrow();
} catch (Exception ex) {
ErrorEvent.fromThrowable("Unable to retrieve password with command " + cmd, ex)
.expected()
.handle();
return null;
}
}
@Override
public String getId() {
return "bitwarden";
return "command";
}
};
ExternalPasswordManager ONEPASSWORD = new ExternalPasswordManager() {
ExternalPasswordManager WINDOWS_CREDENTIAL_MANAGER = new ExternalPasswordManager() {
private boolean loaded = false;
@Override
public String getTemplate() {
return "op read $KEY --force";
public synchronized String retrievePassword(String key) {
try {
if (!loaded) {
loaded = true;
var cmd = """
$code = @"
using System.Text;
using System;
using System.Runtime.InteropServices;
namespace CredManager {
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct CredentialMem
{
public int flags;
public int type;
public string targetName;
public string comment;
public System.Runtime.InteropServices.ComTypes.FILETIME lastWritten;
public int credentialBlobSize;
public IntPtr credentialBlob;
public int persist;
public int attributeCount;
public IntPtr credAttribute;
public string targetAlias;
public string userName;
}
public class Credential {
[DllImport("advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool CredRead(string target, int type, int reservedFlag, out IntPtr credentialPtr);
public static string GetUserPassword(string target)
{
CredentialMem credMem;
IntPtr credPtr;
if (CredRead(target, 1, 0, out credPtr))
{
credMem = Marshal.PtrToStructure<CredentialMem>(credPtr);
byte[] passwordBytes = new byte[credMem.credentialBlobSize];
Marshal.Copy(credMem.credentialBlob, passwordBytes, 0, credMem.credentialBlobSize);
return Encoding.Unicode.GetString(passwordBytes);
} else {
throw new Exception("Failed to retrieve credentials for target: " + target);
}
}
}
}
"@
Add-Type -TypeDefinition $code -Language CSharp
""";
LocalShell.getLocalPowershell().command(cmd).execute();
}
return LocalShell.getLocalPowershell().command("[CredManager.Credential]::GetUserPassword(\"" + key.replaceAll("\"", "`\"") + "\")").readStdoutOrThrow();
} catch (Exception ex) {
ErrorEvent.fromThrowable(ex)
.expected()
.handle();
return null;
}
}
@Override
public String getId() {
return "1password";
}
};
ExternalPasswordManager DASHLANE = new ExternalPasswordManager() {
@Override
public String getTemplate() {
return "dcli password --output console $KEY";
}
@Override
public String getId() {
return "dashlane";
}
};
ExternalPasswordManager LASTPASS = new ExternalPasswordManager() {
@Override
public String getTemplate() {
return "lpass show --password $KEY";
}
@Override
public String getId() {
return "lastpass";
}
};
ExternalPasswordManager MACOS_KEYCHAIN = new ExternalPasswordManager() {
@Override
public String getTemplate() {
return "security find-generic-password -w -l $KEY";
}
@Override
public String getId() {
return "macosKeychain";
return "windowsCredentialManager";
}
@Override
public boolean isSelectable() {
return OsType.getLocal() == OsType.MACOS;
return OsType.getLocal() == OsType.WINDOWS;
}
};
List<ExternalPasswordManager> ALL = Stream.of(ONEPASSWORD, BITWARDEN, DASHLANE, LASTPASS, MACOS_KEYCHAIN)
List<ExternalPasswordManager> ALL = Stream.of(COMMAND, WINDOWS_CREDENTIAL_MANAGER)
.filter(externalPasswordManager -> externalPasswordManager.isSelectable())
.toList();
}

View file

@ -0,0 +1,81 @@
package io.xpipe.app.prefs;
import io.xpipe.app.ext.PrefsChoiceValue;
import io.xpipe.core.process.OsType;
import java.util.List;
import java.util.stream.Stream;
public interface ExternalPasswordManagerTemplate extends PrefsChoiceValue {
String getTemplate();
ExternalPasswordManagerTemplate BITWARDEN = new ExternalPasswordManagerTemplate() {
@Override
public String getTemplate() {
return "bw get password $KEY --nointeraction --raw";
}
@Override
public String getId() {
return "bitwarden";
}
};
ExternalPasswordManagerTemplate ONEPASSWORD = new ExternalPasswordManagerTemplate() {
@Override
public String getTemplate() {
return "op read $KEY --force";
}
@Override
public String getId() {
return "1password";
}
};
ExternalPasswordManagerTemplate DASHLANE = new ExternalPasswordManagerTemplate() {
@Override
public String getTemplate() {
return "dcli password --output console $KEY";
}
@Override
public String getId() {
return "dashlane";
}
};
ExternalPasswordManagerTemplate LASTPASS = new ExternalPasswordManagerTemplate() {
@Override
public String getTemplate() {
return "lpass show --password $KEY";
}
@Override
public String getId() {
return "lastpass";
}
};
ExternalPasswordManagerTemplate MACOS_KEYCHAIN = new ExternalPasswordManagerTemplate() {
@Override
public String getTemplate() {
return "security find-generic-password -w -l $KEY";
}
@Override
public String getId() {
return "macosKeychain";
}
@Override
public boolean isSelectable() {
return OsType.getLocal() == OsType.MACOS;
}
};
List<ExternalPasswordManagerTemplate> ALL = Stream.of(ONEPASSWORD, BITWARDEN, DASHLANE, LASTPASS, MACOS_KEYCHAIN)
.filter(externalPasswordManager -> externalPasswordManager.isSelectable())
.toList();
}

View file

@ -1,33 +1,41 @@
package io.xpipe.app.prefs;
import atlantafx.base.theme.Styles;
import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.comp.base.IntegratedTextAreaComp;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.LocalStore;
import io.xpipe.app.ext.ProcessControlProvider;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.impl.HorizontalComp;
import io.xpipe.app.fxcomps.impl.TextFieldComp;
import io.xpipe.app.fxcomps.impl.VerticalComp;
import io.xpipe.app.fxcomps.util.BindingsHelper;
import io.xpipe.app.util.OptionsBuilder;
import io.xpipe.app.util.TerminalLauncher;
import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.process.CommandBuilder;
import io.xpipe.core.process.CommandControl;
import io.xpipe.app.ext.ProcessControlProvider;
import io.xpipe.app.ext.LocalStore;
import javafx.beans.property.SimpleStringProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.MenuButton;
import javafx.scene.control.MenuItem;
import atlantafx.base.theme.Styles;
import lombok.Value;
import org.kordamp.ikonli.javafx.FontIcon;
import java.util.ArrayList;
import java.util.List;
public class PasswordManagerCategory extends AppPrefsCategory {
@Value
private static class Choice {
String id;
String template;
ExternalPasswordManager passwordManager;
}
@Override
protected String getId() {
return "passwordManager";
@ -37,11 +45,11 @@ public class PasswordManagerCategory extends AppPrefsCategory {
return Comp.of(() -> {
var cb = new MenuButton();
cb.textProperty().bind(AppI18n.observable("templates"));
ExternalPasswordManager.ALL.forEach(externalPasswordManager -> {
ExternalPasswordManagerTemplate.ALL.forEach(e -> {
var m = new MenuItem(
externalPasswordManager.toTranslatedString().getValue());
e.toTranslatedString().getValue());
m.setOnAction(event -> {
AppPrefs.get().passwordManagerCommand.set(externalPasswordManager.getTemplate());
AppPrefs.get().passwordManagerCommand.set(e.getTemplate());
event.consume();
});
cb.getItems().add(m);
@ -52,6 +60,14 @@ public class PasswordManagerCategory extends AppPrefsCategory {
@Override
protected Comp<?> create() {
var choices = new ArrayList<Choice>();
ExternalPasswordManagerTemplate.ALL.forEach(externalPasswordManagerTemplate -> {
choices.add(new Choice(externalPasswordManagerTemplate.getId(), externalPasswordManagerTemplate.getTemplate(), null));
});
ExternalPasswordManager.ALL.stream().filter(externalPasswordManager -> externalPasswordManager != ExternalPasswordManager.COMMAND).forEach(externalPasswordManager -> {
choices.add(new Choice(externalPasswordManager.getId(), null, externalPasswordManager));
});
var prefs = AppPrefs.get();
var testPasswordManagerValue = new SimpleStringProperty();
Runnable test = () -> {
@ -72,20 +88,37 @@ public class PasswordManagerCategory extends AppPrefsCategory {
});
};
var c = new IntegratedTextAreaComp(
var command = new IntegratedTextAreaComp(
prefs.passwordManagerCommand,
true,
"pw",
false,
"command",
new SimpleStringProperty(ProcessControlProvider.get()
.getEffectiveLocalDialect()
.getScriptFileEnding()))
.apply(struc -> {
struc.getTextArea().setPromptText("mypassmgr get $KEY");
})
.disable(prefs.passwordManagerCommand.isNull())
.minWidth(350)
.minHeight(120);
var visit = createTemplateChoice();
var choice = new VerticalComp(List.of(c, visit)).apply(struc -> {
var templates = Comp.of(() -> {
var cb = new MenuButton();
cb.textProperty().bind(BindingsHelper.flatMap(prefs.passwordManager,externalPasswordManager -> {
return externalPasswordManager != null ? AppI18n.observable(externalPasswordManager.getId()) : AppI18n.observable("templates");
}));
choices.forEach(e -> {
var m = new MenuItem();
m.textProperty().bind(AppI18n.observable(e.getId()));
m.setOnAction(event -> {
AppPrefs.get().passwordManagerCommand.set(e.getTemplate());
AppPrefs.get().passwordManager.setValue(e.getPasswordManager());
event.consume();
});
cb.getItems().add(m);
});
return cb;
});
var choice = new VerticalComp(List.of(templates, command)).apply(struc -> {
struc.get().setAlignment(Pos.CENTER_LEFT);
struc.get().setSpacing(10);
});

View file

@ -124,17 +124,13 @@ public interface SecretRetrievalStrategy {
return new SecretQuery() {
@Override
public SecretQueryResult query(String prompt) {
var cmd = AppPrefs.get().passwordManagerString(key);
if (cmd == null) {
var pm = AppPrefs.get().externalPasswordManager().getValue();
if (pm == null) {
return new SecretQueryResult(null, SecretQueryState.RETRIEVAL_FAILURE);
}
String r;
try (var cc = new LocalStore().control().command(cmd).start()) {
r = cc.readStdoutOrThrow();
} catch (Exception ex) {
ErrorEvent.fromThrowable("Unable to retrieve password with command " + cmd, ex)
.handle();
var r = pm.retrievePassword(key);
if (r == null) {
return new SecretQueryResult(null, SecretQueryState.RETRIEVAL_FAILURE);
}

View file

@ -68,3 +68,4 @@ termius=Termius
devolutions=Devolutions
tryPtb=XPipe Public Test Build
zed=Zed
windowsCredentialManager=Windows credential manager

View file

@ -375,7 +375,7 @@ developerModeDescription=Når det er aktiveret, har du adgang til en række ekst
editor=Editor
custom=Brugerdefineret
passwordManagerCommand=Kommando til adgangskodehåndtering
passwordManagerCommandDescription=Den kommando, der skal udføres for at hente adgangskoder. Pladsholderstrengen $KEY vil blive erstattet af den citerede adgangskode, når den kaldes. Dette bør kalde din adgangskodeadministrator CLI for at udskrive adgangskoden til stdout, f.eks. mypassmgr get $KEY.\n\nDu kan derefter indstille nøglen til at blive hentet, hver gang du opretter en forbindelse, der kræver et kodeord.
passwordManagerCommandDescription=Implementeringen af adgangskodeadministratoren eller den brugerdefinerede kommando, der skal udføres for at hente adgangskoder. For brugerdefinerede kommandoer vil pladsholderstrengen $KEY blive erstattet af den citerede adgangskodenøgle, når den kaldes. Dette bør kalde din password manager CLI for at udskrive adgangskoden til stdout, f.eks. mypassmgr get $KEY.\n\nDu kan derefter indstille nøglen til at blive hentet, hver gang du opretter en forbindelse, der kræver en adgangskode.
passwordManagerCommandTest=Test password manager
passwordManagerCommandTestDescription=Her kan du teste, om outputtet ser korrekt ud, hvis du har opsat en password manager-kommando. Kommandoen skal kun sende selve adgangskoden til stdout, ingen anden formatering skal inkluderes i outputtet.
preferEditorTabs=Foretrækker at åbne nye faner

View file

@ -373,7 +373,8 @@ developerModeDescription=When enabled, you will have access to a variety of addi
editor=Editor
custom=Custom
passwordManagerCommand=Password manager command
passwordManagerCommandDescription=The command to execute to fetch passwords. The placeholder string $KEY will be replaced by the quoted password key when called. This should call your password manager CLI to print the password to stdout, e.g. mypassmgr get $KEY.\n\nYou can then set the key to be retrieved whenever you set up a connection which requires a password.
#force
passwordManagerCommandDescription=The password manager implementation or custom command to execute to fetch passwords. For custom commands, the placeholder string $KEY will be replaced by the quoted password key when called. This should call your password manager CLI to print the password to stdout, e.g. mypassmgr get $KEY.\n\nYou can then set the key to be retrieved whenever you set up a connection which requires a password.
passwordManagerCommandTest=Test password manager
passwordManagerCommandTestDescription=You can test here whether the output looks correct if you have set up a password manager command. The command should only output the password itself to stdout, no other formatting should be included in the output.
preferEditorTabs=Prefer to open new tabs

View file

@ -359,7 +359,7 @@ developerModeDescription=Cuando esté activado, tendrás acceso a una serie de o
editor=Editor
custom=Personalizado
passwordManagerCommand=Comando del gestor de contraseñas
passwordManagerCommandDescription=El comando a ejecutar para obtener las contraseñas. La cadena de texto $KEY se sustituirá por la clave de contraseña citada cuando se llame. Esto debería llamar a la CLI de tu gestor de contraseñas para que imprima la contraseña en stdout, por ejemplo, mypassmgr get $KEY.\n\nA continuación, puedes configurar la clave para que se recupere siempre que establezcas una conexión que requiera una contraseña.
passwordManagerCommandDescription=La implementación del gestor de contraseñas o el comando personalizado a ejecutar para obtener las contraseñas. En el caso de los comandos personalizados, la cadena $KEY se sustituirá por la clave de contraseña citada cuando se invoque. Esto debería llamar a la CLI de tu gestor de contraseñas para que imprima la contraseña en stdout, por ejemplo, mypassmgr get $KEY.\n\nA continuación, puedes configurar la clave para que se recupere siempre que establezcas una conexión que requiera una contraseña.
passwordManagerCommandTest=Gestor de contraseñas de prueba
passwordManagerCommandTestDescription=Aquí puedes comprobar si la salida parece correcta si has configurado un comando gestor de contraseñas. El comando sólo debe mostrar la contraseña en la salida estándar, no debe incluir ningún otro formato.
preferEditorTabs=Prefiere abrir nuevas pestañas

View file

@ -359,7 +359,7 @@ developerModeDescription=Lorsque cette option est activée, tu as accès à tout
editor=Éditeur
custom=Personnalisé
passwordManagerCommand=Commande du gestionnaire de mots de passe
passwordManagerCommandDescription=La commande à exécuter pour récupérer les mots de passe. La chaîne de caractères de remplacement $KEY sera remplacée par la clé de mot de passe citée lorsqu'elle sera appelée. Cette commande devrait appeler ton gestionnaire de mots de passe CLI pour imprimer le mot de passe sur stdout, par exemple mypassmgr get $KEY.\n\nTu peux ensuite configurer la clé pour qu'elle soit récupérée chaque fois que tu établis une connexion qui nécessite un mot de passe.
passwordManagerCommandDescription=L'implémentation du gestionnaire de mots de passe ou la commande personnalisée à exécuter pour récupérer les mots de passe. Pour les commandes personnalisées, la chaîne de caractères $KEY sera remplacée par la clé du mot de passe citée lors de l'appel. Ceci devrait appeler ton gestionnaire de mots de passe CLI pour imprimer le mot de passe sur stdout, par exemple mypassmgr get $KEY.\n\nTu peux ensuite configurer la clé pour qu'elle soit récupérée à chaque fois que tu établis une connexion nécessitant un mot de passe.
passwordManagerCommandTest=Test du gestionnaire de mot de passe
passwordManagerCommandTestDescription=Tu peux tester ici si la sortie semble correcte si tu as mis en place une commande de gestionnaire de mot de passe. La commande ne doit sortir que le mot de passe lui-même sur stdout, aucun autre formatage ne doit être inclus dans la sortie.
preferEditorTabs=Préfère ouvrir de nouveaux onglets

View file

@ -359,7 +359,7 @@ developerModeDescription=Se abilitato, avrai accesso a una serie di opzioni aggi
editor=Editore
custom=Personalizzato
passwordManagerCommand=Comando del gestore di password
passwordManagerCommandDescription=Il comando da eseguire per recuperare le password. La stringa segnaposto $KEY sarà sostituita dalla chiave della password citata quando verrà richiamata. Questo comando dovrebbe richiamare la CLI del tuo gestore di password per stampare la password su stdout, ad esempio mypassmgr get $KEY.\n\nPuoi quindi impostare la chiave da recuperare ogni volta che imposti una connessione che richiede una password.
passwordManagerCommandDescription=L'implementazione del gestore di password o il comando personalizzato da eseguire per recuperare le password. Per i comandi personalizzati, la stringa segnaposto $KEY sarà sostituita dalla chiave della password citata al momento della chiamata. Questo dovrebbe richiamare la CLI del tuo gestore di password per stampare la password su stdout, ad esempio mypassmgr get $KEY.\n\nPotrai quindi impostare la chiave in modo che venga recuperata ogni volta che imposti una connessione che richiede una password.
passwordManagerCommandTest=Test del gestore di password
passwordManagerCommandTestDescription=Puoi verificare se l'output è corretto se hai impostato un comando di gestione delle password. Il comando deve inviare a stdout solo la password stessa e non deve includere nessun'altra formattazione nell'output.
preferEditorTabs=Preferisce aprire nuove schede

View file

@ -359,7 +359,7 @@ developerModeDescription=有効にすると、開発に役立つさまざまな
editor=エディター
custom=カスタム
passwordManagerCommand=パスワードマネージャーコマンド
passwordManagerCommandDescription=パスワードを取得するために実行するコマンド。プレースホルダ文字列$KEYは、呼び出されたときに引用符で囲まれたパスワードキーに置き換えられる。これは、パスワードを標準出力に出力するために、パスワードマネージャCLIを呼び出す必要がある。\n\nパスワードを必要とする接続をセットアップするときはいつでも、このキーを取得するように設定できる。
passwordManagerCommandDescription=パスワードを取得するために実行するパスワードマネージャ実装またはカスタムコマンド。カスタムコマンドの場合、$KEYというプレースホルダー文字列は、呼び出されたときに引用符で囲まれたパスワードキーに置き換えられる。これは、パスワードを標準出力に出力するパスワードマネージャCLIを 呼び出す必要がある。\n\nパスワードを必要とする接続をセットアップするときはいつでも、このキーを取得するように設定できる。
passwordManagerCommandTest=テストパスワードマネージャー
passwordManagerCommandTestDescription=パスワード・マネージャー・コマンドをセットアップした場合、出力が正しく見えるかどうかをここでテストできる。コマンドはパスワードそのものを標準出力に出力するだけで、他の書式は出力に含まれないはずである。
preferEditorTabs=新しいタブを開きたい

View file

@ -359,7 +359,7 @@ developerModeDescription=Als deze optie is ingeschakeld, heb je toegang tot een
editor=Bewerker
custom=Aangepaste
passwordManagerCommand=Opdracht voor wachtwoordbeheer
passwordManagerCommandDescription=Het commando dat moet worden uitgevoerd om wachtwoorden op te halen. De tekenreeks $KEY wordt bij het aanroepen vervangen door de geciteerde wachtwoordsleutel. Dit moet je wachtwoordmanager CLI aanroepen om het wachtwoord naar stdout af te drukken, bijvoorbeeld mypassmgr get $KEY.\n\nJe kunt dan instellen dat de sleutel wordt opgehaald wanneer je een verbinding opzet waarvoor een wachtwoord nodig is.
passwordManagerCommandDescription=De implementatie van de wachtwoordmanager of het aangepaste commando dat moet worden uitgevoerd om wachtwoorden op te halen. Voor aangepaste commando's wordt de tekenreeks $KEY vervangen door de wachtwoordsleutel wanneer deze wordt aangeroepen. Dit moet je wachtwoordmanager CLI aanroepen om het wachtwoord naar stdout af te drukken, bijvoorbeeld mypassmgr get $KEY.\n\nJe kunt dan instellen dat de sleutel wordt opgehaald wanneer je een verbinding opzet waarvoor een wachtwoord nodig is.
passwordManagerCommandTest=Wachtwoordmanager testen
passwordManagerCommandTestDescription=Je kunt hier testen of de uitvoer er correct uitziet als je een wachtwoordmanager-commando hebt ingesteld. Het commando moet alleen het wachtwoord zelf uitvoeren naar stdout, er mag geen andere opmaak in de uitvoer worden opgenomen.
preferEditorTabs=Open liever nieuwe tabbladen

View file

@ -359,7 +359,7 @@ developerModeDescription=Quando ativado, terás acesso a uma variedade de opçõ
editor=Editor
custom=Personaliza
passwordManagerCommand=Comando do gestor de senhas
passwordManagerCommandDescription=O comando a executar para ir buscar as palavras-passe. A string de espaço reservado $KEY será substituída pela chave de senha citada quando chamada. Isto deve chamar o teu gestor de senhas CLI para imprimir a senha para stdout, por exemplo, mypassmgr get $KEY.\n\nPodes então definir a chave para ser recuperada sempre que configurares uma ligação que requeira uma palavra-passe.
passwordManagerCommandDescription=A implementação do gestor de palavras-passe ou o comando personalizado a executar para obter palavras-passe. Para comandos personalizados, a string de espaço reservado $KEY será substituída pela chave de senha citada quando chamada. Isto deve chamar o teu gestor de palavras-passe CLI para imprimir a palavra-passe no stdout, por exemplo, mypassmgr get $KEY.\n\nPodes então definir a chave para ser recuperada sempre que estabeleceres uma ligação que requeira uma palavra-passe.
passwordManagerCommandTest=Testa o gestor de palavras-passe
passwordManagerCommandTestDescription=Podes testar aqui se a saída parece correcta se tiveres configurado um comando de gestão de palavras-passe. O comando só deve enviar a própria palavra-passe para stdout, não devendo ser incluída qualquer outra formatação na saída.
preferEditorTabs=Prefere abrir novos separadores

View file

@ -359,7 +359,7 @@ developerModeDescription=Если включить эту функцию, то
editor=Редактор
custom=Пользовательский
passwordManagerCommand=Команда менеджера паролей
passwordManagerCommandDescription=Команда, которую нужно выполнить для получения паролей. Строка-заполнитель $KEY при вызове будет заменена на заключенный в кавычки ключ пароля. Это должно вызвать CLI твоего менеджера паролей для печати пароля в stdout, например, mypassmgr get $KEY.\n\nЗатем ты можешь задать, чтобы ключ извлекался всякий раз, когда ты устанавливаешь соединение, требующее ввода пароля.
passwordManagerCommandDescription=Реализация менеджера паролей или пользовательская команда, которую нужно выполнить для получения паролей. Для пользовательских команд строка-заполнитель $KEY при вызове будет заменена на ключ пароля, взятый в кавычки. Это должно вызвать CLI твоего менеджера паролей для печати пароля в stdout, например, mypassmgr get $KEY.\n\nЗатем ты можешь задать, чтобы ключ извлекался всякий раз, когда ты устанавливаешь соединение, требующее ввода пароля.
passwordManagerCommandTest=Тестовый менеджер паролей
passwordManagerCommandTestDescription=Здесь ты можешь проверить, правильно ли выглядит вывод, если ты настроил команду менеджера паролей. Команда должна выводить в stdout только сам пароль, никакое другое форматирование не должно присутствовать в выводе.
preferEditorTabs=Предпочитает открывать новые вкладки

View file

@ -360,7 +360,7 @@ developerModeDescription=Etkinleştirildiğinde, geliştirme için yararlı olan
editor=Editör
custom=Özel
passwordManagerCommand=Parola yöneticisi komutu
passwordManagerCommandDescription=Parolaları almak için çalıştırılacak komut. Yer tutucu dize $KEY, çağrıldığında alıntılanan parola anahtarıyla değiştirilecektir. Bu, parolayı stdout'a yazdırmak için parola yöneticinizin CLI'sini çağırmalıdır, örneğin mypassmgr get $KEY.\n\nDaha sonra anahtarı, parola gerektiren bir bağlantı kurduğunuzda alınacak şekilde ayarlayabilirsiniz.
passwordManagerCommandDescription=Parolaları almak için çalıştırılacak parola yöneticisi uygulaması veya özel komut. Özel komutlar için $KEY yer tutucu dizesi, çağrıldığında alıntılanan parola anahtarıyla değiştirilecektir. Bu, parolayı stdout'a yazdırmak için parola yöneticinizin CLI'sini çağırmalıdır, örneğin mypassmgr get $KEY.\n\nDaha sonra anahtarı, parola gerektiren bir bağlantı kurduğunuzda alınacak şekilde ayarlayabilirsiniz.
passwordManagerCommandTest=Parola yöneticisini test edin
passwordManagerCommandTestDescription=Bir parola yöneticisi komutu kurduysanız çıktının doğru görünüp görünmediğini burada test edebilirsiniz. Komut yalnızca parolanın kendisini stdout'a çıktılamalıdır, çıktıya başka hiçbir biçimlendirme dahil edilmemelidir.
preferEditorTabs=Yeni sekmeler açmayı tercih edin

View file

@ -359,7 +359,7 @@ developerModeDescription=启用后,您可以访问各种对开发有用的附
editor=编辑器
custom=自定义
passwordManagerCommand=密码管理器命令
passwordManagerCommandDescription=为获取密码而执行的命令。在调用时,占位符字符串 $KEY 将被带引号的密码密钥替换。该命令应调用密码管理器 CLI 将密码打印到 stdout例如mypassmgr get $KEY。\n\n然后您就可以设置在建立需要密码的连接时检索密钥。
passwordManagerCommandDescription=用于获取密码的密码管理器执行程序或自定义命令。对于自定义命令,在调用时,占位符字符串 $KEY 将被带引号的密码密钥替换。该命令应调用密码管理器 CLI 将密码打印到 stdout例如mypassmgr get $KEY。\n\n然后您就可以设置在建立需要密码的连接时检索密钥。
passwordManagerCommandTest=测试密码管理器
passwordManagerCommandTestDescription=如果您设置了密码管理器命令,可以在此测试输出是否正确。该命令只能将密码本身输出到 stdout输出中不应包含其他格式。
preferEditorTabs=首选打开新标签页