├── .cargo └── audit.toml ├── .github ├── FUNDING.yml └── workflows │ └── rust.yml ├── .gitignore ├── .rustfmt.toml ├── BUILD_INSTRUCTIONS.md ├── Cargo.lock ├── Cargo.toml ├── LICENCE ├── README.md ├── TRANSLATIONS.md ├── benches └── library_benchmark.rs ├── cursive ├── .gitignore ├── Cargo.toml ├── README.md ├── build.rs ├── doc │ └── ripasso-cursive-animated.gif ├── res │ ├── de.po │ ├── es.po │ ├── fr.po │ ├── it.po │ ├── nb.po │ ├── nn.po │ ├── ripasso-cursive.pot │ ├── ru.po │ ├── style.toml │ └── sv.po └── src │ ├── helpers.rs │ ├── main.rs │ ├── tests │ ├── helpers.rs │ └── main.rs │ └── wizard.rs ├── doc ├── ripasso-cursive-0.4.0.png ├── ripasso-cursive.png └── ripasso-gtk.png ├── generate_pot.sh ├── gtk ├── Cargo.toml ├── build.rs └── src │ ├── collection_object │ ├── imp.rs │ └── mod.rs │ ├── com.github.cortex.ripasso-gtk.gschema.xml │ ├── main.rs │ ├── password_object │ ├── imp.rs │ └── mod.rs │ ├── resources │ ├── logo.svg │ ├── resources.gresource.xml │ ├── shortcuts.ui │ └── window.ui │ ├── utils.rs │ └── window │ ├── imp.rs │ └── mod.rs ├── src ├── crypto.rs ├── error.rs ├── git.rs ├── lib.rs ├── pass.rs ├── signature.rs ├── tests │ ├── crypto.rs │ ├── git.rs │ ├── pass.rs │ ├── signature.rs │ ├── test_helpers.rs │ └── words.rs └── words.rs └── testres ├── get_history_with_repo.tar.gz ├── password_store_with_files_in_initial_commit.tar.gz ├── password_store_with_relative_path.tar.gz ├── password_store_with_shallow_checkout.tar.gz ├── password_store_with_sparse_checkout.tar.gz ├── password_store_with_symlink.tar.gz ├── populate_password_list_directory_without_git.tar.gz ├── populate_password_list_large_repo.tar.gz ├── populate_password_list_repo_with_deleted_files.tar.gz ├── populate_password_list_small_repo.tar.gz ├── rename_file.tar.gz ├── rename_file_absolute_path.tar.gz ├── rename_file_git_index_clean.tar.gz ├── test_add_and_commit_internal.tar.gz ├── test_move_and_commit_signed.tar.gz ├── test_remove_and_commit.tar.gz ├── test_should_sign_false.tar.gz ├── test_should_sign_true.tar.gz └── test_verify_git_signature.tar.gz /.cargo/audit.toml: -------------------------------------------------------------------------------- 1 | [advisories] 2 | ### motivations: 3 | ### RUSTSEC-2022-0040: We don't use the reexported OwningHandle type in cursive 4 | ### see https://github.com/gyscos/cursive/issues/678 5 | ignore = ["RUSTSEC-2022-0040"] -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: alexanderkjall 2 | -------------------------------------------------------------------------------- /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - master 5 | - release/* 6 | pull_request: 7 | 8 | name: Continuous integration 9 | 10 | jobs: 11 | check: 12 | name: Check 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v3 16 | - uses: actions-rs/toolchain@v1 17 | with: 18 | profile: minimal 19 | toolchain: stable 20 | override: true 21 | - name: Dependencies 22 | run: sudo apt update -y && sudo apt install libgpgme11-dev libgpg-error-dev nettle-dev -y 23 | - uses: actions-rs/cargo@v1 24 | with: 25 | command: check 26 | 27 | ubuntutest: 28 | name: Test Suite on Ubuntu 29 | runs-on: ubuntu-latest 30 | steps: 31 | - uses: actions/checkout@v3 32 | - uses: actions-rs/toolchain@v1 33 | with: 34 | profile: minimal 35 | toolchain: stable 36 | override: true 37 | - name: Dependencies 38 | run: sudo apt update -y && sudo apt install libssl-dev libclang-dev libadwaita-1-dev libgpgme11-dev libgpg-error-dev libgtk-4-dev libxcb-shape0-dev libxcb-xfixes0-dev nettle-dev -y 39 | - uses: actions-rs/cargo@v1 40 | with: 41 | command: test 42 | args: --all 43 | 44 | macostest: 45 | name: Test Suite on MacOS 46 | runs-on: macos-latest 47 | steps: 48 | - uses: actions/checkout@v3 49 | - uses: actions-rs/toolchain@v1 50 | with: 51 | profile: minimal 52 | toolchain: stable 53 | override: true 54 | - name: Install dependencies 55 | run: | 56 | brew update || true 57 | brew install gpgme nettle || true 58 | - uses: actions-rs/cargo@v1 59 | with: 60 | command: test 61 | args: -p ripasso-cursive 62 | 63 | fmt: 64 | name: Rustfmt 65 | runs-on: ubuntu-latest 66 | steps: 67 | - uses: actions/checkout@v3 68 | - uses: actions-rs/toolchain@v1 69 | with: 70 | profile: minimal 71 | toolchain: stable 72 | override: true 73 | - run: rustup component add rustfmt 74 | - name: Dependencies 75 | run: sudo apt update -y && sudo apt install libgpgme11-dev libgpg-error-dev nettle-dev -y 76 | - uses: actions-rs/cargo@v1 77 | with: 78 | command: fmt 79 | args: --all -- --check 80 | 81 | clippy: 82 | name: Clippy 83 | runs-on: ubuntu-latest 84 | steps: 85 | - uses: actions/checkout@v3 86 | - uses: actions-rs/toolchain@v1 87 | with: 88 | profile: minimal 89 | toolchain: stable 90 | override: true 91 | - run: rustup component add clippy 92 | - name: Dependencies 93 | run: sudo apt update -y && sudo apt install libgpgme11-dev libgpg-error-dev nettle-dev -y 94 | - uses: actions-rs/cargo@v1 95 | with: 96 | command: clippy 97 | args: -- -D warnings 98 | 99 | audit: 100 | name: Audit 101 | runs-on: ubuntu-latest 102 | permissions: 103 | issues: write 104 | steps: 105 | - uses: actions/checkout@v3 106 | - uses: actions-rust-lang/audit@v1 107 | name: Audit Rust Dependencies 108 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | *.qmlc 3 | **/*~ 4 | **/*.bk 5 | .idea/ 6 | *.iml 7 | *.kdev4 8 | 9 | #Generated binary translation files 10 | *.mo -------------------------------------------------------------------------------- /.rustfmt.toml: -------------------------------------------------------------------------------- 1 | imports_granularity = "Crate" 2 | group_imports = "StdExternalCrate" 3 | -------------------------------------------------------------------------------- /BUILD_INSTRUCTIONS.md: -------------------------------------------------------------------------------- 1 | # Build instructions 2 | 3 | ## Build dependencies 4 | 5 | Ripasso depends on a number of local libraries through it's dependencies: 6 | 7 | * openssl - for git operations 8 | * libgit2 - for git operations 9 | * libgpgerror - for the gpgme encryption backend 10 | * gpgme - for the gpgme encryption backend 11 | * xorg - for the clippboard 12 | * nettle-dev - for the sequoia encryption backend 13 | 14 | They are named different things on different platforms 15 | 16 | ### Mac OS X 17 | 18 | ``` 19 | $ brew update 20 | $ brew install automake cmake gettext gtk+4 gpgme 21 | $ git clone https://github.com/cortex/ripasso.git 22 | $ cd ripasso 23 | $ cargo run 24 | ``` 25 | 26 | ### Ubuntu 27 | ``` 28 | $ apt install cargo libssl-dev libclang-dev libadwaita-1-dev libgpgme11-dev libgpg-error-dev libgtk-4-dev libxcb-shape0-dev libxcb-xfixes0-dev nettle-dev 29 | $ cargo build --all 30 | ``` 31 | 32 | ### Fedora 33 | #### All 34 | ``` 35 | $ dnf install cargo gpgme-devel openssl-devel libxcb libxcb-devel nettle-devel 36 | ``` 37 | #### GTK 38 | ``` 39 | $ dnf install rust-gdk-devel 40 | ``` 41 | ## Building 42 | 43 | Perform the build with: 44 | ``` 45 | cargo build --all --frozen --release 46 | ``` 47 | The argument `--frozen` ensures that the content of the `Cargo.lock` file is respected so that the build is repeatable, 48 | this is mostly of interest for package maintainers in distributions. 49 | 50 | ### Build artifacts 51 | 52 | The build produces a number of artifacts: 53 | * `./target/release/ripasso-cursive` - the main application binary, with the curses TUI 54 | * `./target/release/ripasso-gtk` - the GTK application, still in an experimental phase 55 | * `./target/man-page/cursive/ripasso-cursive.1` - The manual page for ripasso-cursive 56 | * `./target/translations/cursive/de.mo` - german translation 57 | * `./target/translations/cursive/fr.mo` - french translation 58 | * `./target/translations/cursive/it.mo` - italian translation 59 | * `./target/translations/cursive/nb.mo` - norwegian bokmål translation 60 | * `./target/translations/cursive/nn.mo` - norwegian nynorsk translation 61 | * `./target/translations/cursive/sv.mo` - swedish translation 62 | 63 | The translation files are in gettext binary format, and should be installed in 64 | `/usr/share/locale/{}/LC_MESSAGES/ripasso-cursive.mo` where `{}` should be replaced 65 | with the locale. If that location doesn't conform to your distribution's guidelines, 66 | then you can supply the environmental variable `TRANSLATION_INPUT_PATH` when building 67 | to specify another. 68 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ripasso" 3 | description = "A password manager that uses the file format of the standard unix password manager 'pass'" 4 | repository = "https://github.com/cortex/ripasso/" 5 | keywords = ["password-manager", "pass"] 6 | version = "0.8.0" 7 | authors = ["Joakim Lundborg ", "Alexander Kjäll "] 8 | license = "GPL-3.0-only" 9 | edition = '2024' 10 | 11 | [dependencies] 12 | arboard = "3" 13 | glob = "0.3" 14 | gpgme = "0.11" 15 | chrono = { version = "0.4", default-features = false, features = ["clock"] } 16 | git2 = "0.20" 17 | rand = "0.8" 18 | whoami = "1" 19 | toml = "0.8" 20 | reqwest = { version = "0.12", features = ["blocking"] } 21 | hex = "0.4" 22 | totp-rs = { version = "5", features = ["otpauth"] } 23 | sequoia-openpgp = "2" 24 | anyhow = "1" 25 | sequoia-gpg-agent = "0.6" 26 | zeroize = { version = "1", features = ["zeroize_derive", "alloc"] } 27 | 28 | [dependencies.config] 29 | version = "0.15" 30 | default-features = false 31 | features = ["toml"] 32 | 33 | [dev-dependencies] 34 | tempfile = "3" 35 | flate2 = "1" 36 | tar = "0.4" 37 | criterion = "0.5" 38 | 39 | [workspace] 40 | 41 | members = [ 42 | "gtk", "cursive" 43 | ] 44 | 45 | [[bench]] 46 | name = "library_benchmark" 47 | harness = false 48 | 49 | [profile.release] 50 | lto = true 51 | codegen-units = 1 52 | strip = true 53 | debug = false 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ripasso 2 | [![Build Status](https://github.com/cortex/ripasso/actions/workflows/rust.yml/badge.svg)](https://github.com/cortex/ripasso/actions/workflows/rust.yml) 3 | [![Crates Version](https://img.shields.io/crates/v/ripasso.svg)](https://crates.io/crates/ripasso) 4 | [![Documentation Status](https://docs.rs/ripasso/badge.svg)](https://docs.rs/ripasso/) 5 | [![Packaging Status](https://repology.org/badge/tiny-repos/ripasso-cursive.svg)](https://repology.org/project/ripasso-cursive/versions) 6 | 7 | A simple password manager written in Rust. 8 | 9 | The root crate `ripasso` is a library for accessing and decrypting passwords 10 | stored in [pass](https://www.passwordstore.org/) format, that means 11 | PGP-encrypted files optionally stored in a git repository. 12 | 13 | Multiple UI's in different stages of development are available in subcrates. 14 | 15 | To build all UI's: 16 | ``` 17 | cargo build --all 18 | ``` 19 | 20 | PR's are very welcome! 21 | 22 | ## History 23 | This is a reimplementation of https://github.com/cortex/gopass in Rust. I started it mainly because https://github.com/go-qml/qml 24 | is unmaintained. Also, using a safe language for your passwords seems like a good idea. 25 | 26 | ## UI's 27 | 28 | ### Cursive - Terminal interface 29 | ![Screenshot of ripasso-cursive](doc/ripasso-cursive-0.4.0.png) 30 | 31 | TUI interface based on [cursive](https://github.com/gyscos/Cursive) 32 | Supports password age display and password editing. 33 | I use this as my daily password-manager. 34 | 35 | #### Build 36 | ``` 37 | cargo build -p ripasso-cursive 38 | ``` 39 | 40 | ### GTK GUI - (WIP) 41 | ![Screenshot of ripasso-gtk](doc/ripasso-gtk.png) 42 | 43 | Not at feature-parity with the cursive code base yet, but basic operations work. 44 | 45 | #### Build 46 | 47 | ``` 48 | cargo build -p ripasso-gtk 49 | ``` 50 | 51 | ## Install instructions 52 | 53 | ### Arch 54 | 55 | TUI version 56 | ``` 57 | pacman -S ripasso 58 | ``` 59 | 60 | ### Fedora 61 | 62 | Available in [Copr](https://copr.fedorainfracloud.org/coprs/atim/ripasso/) 63 | ``` 64 | sudo dnf copr enable atim/ripasso -y 65 | ``` 66 | 67 | TUI version 68 | ``` 69 | sudo dnf install ripasso 70 | ``` 71 | 72 | GTK version (unstable) 73 | ``` 74 | sudo dnf install ripasso-gtk 75 | ``` 76 | 77 | ### Nix 78 | 79 | TUI version 80 | ``` 81 | nix-env -iA nixpkgs.ripasso-cursive 82 | ``` 83 | 84 | ### Mac OS X 85 | 86 | The best way to install ripasso on mac right now is the nix package system, first [install that](https://nixos.org/download/) and then 87 | 88 | ``` 89 | nix-env -iA nixpkgs.ripasso-cursive 90 | ``` 91 | 92 | ### Alpine 93 | 94 | Ripasso-cursive is currently in the testing repository for apk, so the testing repository needs to be added to the apk repositories file. 95 | 96 | TUI version 97 | ``` 98 | apk add ripasso-cursive 99 | ``` 100 | 101 | ## Build instructions 102 | 103 | [See here](https://github.com/cortex/ripasso/blob/master/BUILD_INSTRUCTIONS.md) 104 | 105 | ## Translations 106 | 107 | Do you want to have ripasso in your native language? Help out with a translation: 108 | 109 | [See here](https://github.com/cortex/ripasso/blob/master/TRANSLATIONS.md) 110 | -------------------------------------------------------------------------------- /TRANSLATIONS.md: -------------------------------------------------------------------------------- 1 | ## Updating an existing translation 2 | 3 | If you spot a typo or something else that needs to be improved, these are the steps: 4 | 5 | ``` 6 | git clone git@github.com:cortex/ripasso.git 7 | cd ripasso 8 | poedit cursive/res/fr.po 9 | ``` 10 | 11 | [poedit](https://poedit.net/) is a stand-alone program to edit translation files. There is other 12 | alternatives, but poedit is quite easy to use. 13 | 14 | After that you just need to submit a [pull request on github](https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request) 15 | with your changes in them. 16 | 17 | ## Adding a new translation 18 | 19 | If you want to translate ripasso to your language here is how: 20 | 21 | 1. Check out the source code `git clone git@github.com:cortex/ripasso.git` 22 | 2. Edit `generate_pot.sh` and add a line at the bottom for the new language 23 | 3. Execute `./generate_pot.sh` 24 | 4. Translate the strings `poedit cursive/res/fr.po` 25 | 26 | After that you just need to submit a [pull request on github](https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request) 27 | with your changes. Poedit will generate a `.mo` file in addition to the 28 | `.po` file, that is only a binary representation of the information in the `.po` file 29 | and should not be included in the pull request. 30 | -------------------------------------------------------------------------------- /benches/library_benchmark.rs: -------------------------------------------------------------------------------- 1 | use std::{fs::File, path::PathBuf}; 2 | 3 | use criterion::{Criterion, criterion_group, criterion_main}; 4 | use flate2::read::GzDecoder; 5 | use ripasso::{crypto::CryptoImpl, pass}; 6 | use tar::Archive; 7 | 8 | fn unpack_tar_gz(mut base_path: PathBuf, tar_gz_name: &str) -> Result<(), std::io::Error> { 9 | let target = format!("{}", base_path.as_path().display()); 10 | base_path.push(tar_gz_name); 11 | 12 | let path = format!("{}", base_path.as_path().display()); 13 | 14 | let tar_gz = File::open(path)?; 15 | let tar = GzDecoder::new(tar_gz); 16 | let mut archive = Archive::new(tar); 17 | archive.unpack(target)?; 18 | 19 | Ok(()) 20 | } 21 | 22 | fn cleanup(mut base_path: PathBuf, path_name: &str) -> Result<(), std::io::Error> { 23 | base_path.push(path_name); 24 | 25 | std::fs::remove_dir_all(base_path)?; 26 | 27 | Ok(()) 28 | } 29 | 30 | fn pop_list(password_dir: PathBuf) -> pass::Result<()> { 31 | let store = pass::PasswordStore::new( 32 | "", 33 | &Some(password_dir), 34 | &None, 35 | &None, 36 | &None, 37 | &CryptoImpl::GpgMe, 38 | &None, 39 | )?; 40 | let results = store.all_passwords().unwrap(); 41 | 42 | assert_eq!(results.len(), 4); 43 | Ok(()) 44 | } 45 | 46 | fn criterion_benchmark_load_4_passwords(c: &mut Criterion) { 47 | let mut base_path: PathBuf = std::env::current_exe().unwrap(); 48 | base_path.pop(); 49 | base_path.pop(); 50 | base_path.pop(); 51 | base_path.pop(); 52 | base_path.push("testres"); 53 | 54 | let mut password_dir: PathBuf = base_path.clone(); 55 | password_dir.push("populate_password_list_large_repo"); 56 | 57 | unpack_tar_gz( 58 | base_path.clone(), 59 | "populate_password_list_large_repo.tar.gz", 60 | ) 61 | .unwrap(); 62 | 63 | c.bench_function("populate_password_list 4 passwords", |b| { 64 | b.iter(|| pop_list(password_dir.clone())) 65 | }); 66 | 67 | cleanup(base_path, "populate_password_list_large_repo").unwrap(); 68 | } 69 | 70 | criterion_group!(benches, criterion_benchmark_load_4_passwords); 71 | criterion_main!(benches); 72 | -------------------------------------------------------------------------------- /cursive/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | Cargo.lock 3 | *.qmlc 4 | **/*~ 5 | **/*.bk 6 | .idea/ 7 | *.iml 8 | -------------------------------------------------------------------------------- /cursive/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ripasso-cursive" 3 | description = "A password manager that uses the file format of the standard unix password manager 'pass', this is the ncurses frontend application" 4 | repository = "https://github.com/cortex/ripasso/" 5 | keywords = ["password-manager", "pass"] 6 | categories = ["command-line-utilities"] 7 | version = "0.8.0" 8 | authors = ["Joakim Lundborg ", "Alexander Kjäll "] 9 | license = "GPL-3.0-only" 10 | edition = '2024' 11 | build = "build.rs" 12 | 13 | [dependencies] 14 | cursive = { version = "0.21", default-features = false, features = ["toml", "crossterm-backend"]} 15 | arboard = { version = "3", features = ["wayland-data-control"]} 16 | ripasso = { path = "../", version = "0.8.0" } 17 | locale_config = "0.3" 18 | unic-langid = "0.9" 19 | gettext = "0.4" 20 | lazy_static = "1" 21 | terminal_size = "0.4" 22 | hex = "0.4" 23 | zeroize = { version = "1", features = ["zeroize_derive", "alloc"] } 24 | 25 | [dependencies.config] 26 | version = "0.15" 27 | default-features = false 28 | features = ["toml"] 29 | 30 | [dev-dependencies] 31 | tempfile = "3.10.1" 32 | chrono = { version = "0.4", default-features = false, features = ["clock"] } 33 | 34 | [build-dependencies] 35 | glob = "0.3" 36 | man = "0.3" 37 | -------------------------------------------------------------------------------- /cursive/README.md: -------------------------------------------------------------------------------- 1 | # ripasso 2 | [![Build Status](https://github.com/cortex/ripasso/actions/workflows/rust.yml/badge.svg)](https://github.com/cortex/ripasso/actions/workflows/rust.yml) 3 | [![Crates Version](https://img.shields.io/crates/v/ripasso-cursive.svg)](https://crates.io/crates/ripasso) 4 | [![Documentation Status](https://docs.rs/ripasso/badge.svg)](https://docs.rs/ripasso/) 5 | [![Packaging Status](https://repology.org/badge/tiny-repos/ripasso-cursive.svg)](https://repology.org/project/ripasso-cursive/versions) 6 | 7 | A curses password manager written in Rust. 8 | 9 | ### Cursive - Terminal interface 10 | ![Screenshot of ripasso-cursive](doc/ripasso-cursive-animated.gif) 11 | 12 | TUI interface based on [cursive](https://github.com/gyscos/Cursive) 13 | 14 | #### Install 15 | ``` 16 | cargo install ripasso-cursive 17 | ``` 18 | 19 | Or get it from your package system if it's availible. 20 | 21 | ## Translations 22 | 23 | Do you want to have ripasso in your native language? Help out with a translation: 24 | 25 | [See here](https://github.com/cortex/ripasso/blob/master/TRANSLATIONS.md) 26 | -------------------------------------------------------------------------------- /cursive/build.rs: -------------------------------------------------------------------------------- 1 | use std::{io::prelude::*, process::Command}; 2 | 3 | fn generate_man_page() -> String { 4 | man::prelude::Manual::new("ripasso-cursive") 5 | .about("A password manager that uses the file format of the standard unix password manager 'pass', implemented in rust.") 6 | .author(man::prelude::Author::new("Joakim Lundborg").email("joakim.lundborg@gmail.com")) 7 | .author(man::prelude::Author::new("Alexander Kjäll").email("alexander.kjall@gmail.com")) 8 | .flag(man::prelude::Flag::new() 9 | .short("-h") 10 | .long("--help") 11 | .help("Print a help text"), 12 | ) 13 | .description("ripasso-cursive is an curses application that lets you manage your or your teams passwords.\ 14 | The passwords are encrypted with pgp and optionally stored in an git repository. The list of team members are stored \ 15 | in the file .gpg-id, one pgp key id per line.") 16 | 17 | .custom(man::prelude::Section::new("Keyboard shortcuts") 18 | .paragraph("Enter : Copy the current selected password to the copy buffer for 40 seconds") 19 | .paragraph("Delete : Delete the marked password") 20 | .paragraph("Insert : Create a new password entry") 21 | .paragraph("Control + y : same as Enter") 22 | .paragraph("Control + b : if the password have an otpauth:// url in it, generate a code and store it in the copy buffer") 23 | .paragraph("Control + n : move marker down") 24 | .paragraph("Control + p : move marker up") 25 | .paragraph("Control + r : rename the password without changing it's content") 26 | .paragraph("Control + u : copy the filename of the password") 27 | .paragraph("Control + h : show the git history of the password") 28 | .paragraph("Control + v : view the list of team members") 29 | .paragraph("Control + o : open a password edit dialog") 30 | .paragraph("Control + f : pull from the git repository") 31 | .paragraph("Control + g : push to the git repository") 32 | .paragraph("Escape : quit ")) 33 | .custom(man::prelude::Section::new("usage note") 34 | .paragraph("ripasso-cursive reads $HOME/.password-store/ by default, override this by setting 35 | the PASSWORD_STORE_DIR environmental variable.") 36 | .paragraph("If you specify the PASSWORD_STORE_SIGNING_KEY environmental variable, then 37 | ripasso will verify that the .gpg-id file is correctly signed. Valid values are one or more 40 character pgp fingerprints, 38 | separated by commas.")) 39 | .custom(man::prelude::Section::new("config file") 40 | .paragraph("ripasso reads configuration from $XDG_CONFIG_HOME/ripasso/settings.toml") 41 | .paragraph("Example config file") 42 | .paragraph("[stores]") 43 | .paragraph(" [stores.default]") 44 | .paragraph(" path = \"/home/user/.password-store/\"") 45 | .paragraph(" valid_signing_keys = \"AF77DAC5B3882EAD316B7312D5B659E1D2FDF0C3\"") 46 | .paragraph(" [stores.work]") 47 | .paragraph(" path = \"/home/user/.work_pass/\"") 48 | .paragraph(" style_path = \"/home/user/.config/ripasso/work-style.toml\"") 49 | .paragraph("") 50 | .paragraph("Valid settings for a store are:") 51 | .paragraph("path : This is the root path to the password store directory") 52 | .paragraph("valid_signing_keys : this setting corresponds to the PASSWORD_STORE_SIGNING_KEY environmental variable") 53 | .paragraph("style_path : color and style information for the store, different stores can have different styles and they will 54 | change when you switch store. Documentation on the format can be found here https://docs.rs/cursive_core/0.1.1/cursive_core/theme/index.html") 55 | .paragraph("pgp : the pgp implementation to use for the store, valid values are gpg or sequoia") 56 | .paragraph("own_fingerprint : if the pgp option is set to sequoia, ripasso needs to know the fingerprint of your own key in order to communicate with gpg-agent") 57 | ) 58 | .render() 59 | } 60 | 61 | fn generate_man_page_file() { 62 | let mut dest_path = std::env::current_exe().unwrap(); 63 | dest_path.pop(); 64 | dest_path.pop(); 65 | dest_path.pop(); 66 | dest_path.pop(); 67 | dest_path.push("man-page"); 68 | print!("creating directory: {:?} ", &dest_path); 69 | let res = std::fs::create_dir(&dest_path); 70 | if res.is_ok() { 71 | println!("success"); 72 | } else { 73 | println!("error: {:?}", res.err().unwrap()); 74 | } 75 | dest_path.push("cursive"); 76 | print!("creating directory: {:?} ", &dest_path); 77 | let res = std::fs::create_dir(&dest_path); 78 | if res.is_ok() { 79 | println!("success"); 80 | } else { 81 | println!("error: {:?}", res.err().unwrap()); 82 | } 83 | 84 | dest_path.push("ripasso-cursive.1"); 85 | 86 | let mut file = std::fs::File::create(dest_path).unwrap(); 87 | file.write_all(generate_man_page().as_bytes()).unwrap(); 88 | } 89 | 90 | fn generate_translation_files() { 91 | let mut dest_path = std::env::current_exe().unwrap(); 92 | dest_path.pop(); 93 | dest_path.pop(); 94 | dest_path.pop(); 95 | dest_path.pop(); 96 | dest_path.push("translations"); 97 | print!("creating directory: {:?} ", &dest_path); 98 | let res = std::fs::create_dir(&dest_path); 99 | if res.is_ok() { 100 | println!("success"); 101 | } else { 102 | println!("error: {:?}", res.err().unwrap()); 103 | } 104 | dest_path.push("cursive"); 105 | print!("creating directory: {:?} ", &dest_path); 106 | let res = std::fs::create_dir(&dest_path); 107 | if res.is_ok() { 108 | println!("success"); 109 | } else { 110 | println!("error: {:?}", res.err().unwrap()); 111 | } 112 | 113 | let mut dir = std::env::current_exe().unwrap(); 114 | dir.pop(); 115 | dir.pop(); 116 | dir.pop(); 117 | dir.pop(); 118 | dir.pop(); 119 | dir.push("cursive"); 120 | dir.push("res"); 121 | 122 | let translation_path_glob = dir.join("**/*.po"); 123 | let existing_iter = glob::glob(&translation_path_glob.to_string_lossy()).unwrap(); 124 | 125 | for existing_file in existing_iter { 126 | let file = existing_file.unwrap(); 127 | let mut filename = file.file_name().unwrap().to_str().unwrap().to_string(); 128 | filename.replace_range(3..4, "m"); 129 | 130 | print!( 131 | "generating .mo file for {:?} to {}/{} ", 132 | &file, 133 | dest_path.display(), 134 | &filename 135 | ); 136 | let res = Command::new("msgfmt") 137 | .arg(format!( 138 | "--output-file={}/{}", 139 | dest_path.display(), 140 | &filename 141 | )) 142 | .arg(format!("{}", &file.display())) 143 | .output(); 144 | 145 | if res.is_ok() { 146 | println!("success"); 147 | } else { 148 | println!("error: {:?}", res.err().unwrap()); 149 | } 150 | } 151 | } 152 | 153 | fn main() { 154 | generate_translation_files(); 155 | generate_man_page_file(); 156 | } 157 | -------------------------------------------------------------------------------- /cursive/doc/ripasso-cursive-animated.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cortex/ripasso/eb4ceffcb6e1f237e8ed0e24cb97b593b34b196e/cursive/doc/ripasso-cursive-animated.gif -------------------------------------------------------------------------------- /cursive/res/es.po: -------------------------------------------------------------------------------- 1 | # Header entry was created by Lokalize. 2 | # 3 | #: cursive/src/main.rs:1166 4 | # SPDX-FileCopyrightText: 2024 victorhck 5 | msgid "" 6 | msgstr "" 7 | "Content-Type: text/plain; charset=UTF-8\n" 8 | "Content-Transfer-Encoding: 8bit\n" 9 | "Last-Translator: victorhck \n" 10 | "PO-Revision-Date: 2024-09-19 15:47+0200\n" 11 | "Project-Id-Version: \n" 12 | "Language-Team: Spanish \n" 13 | "Language: es_ES\n" 14 | "MIME-Version: 1.0\n" 15 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 16 | "X-Generator: Lokalize 24.08.1\n" 17 | 18 | #: cursive/src/main.rs:1166 19 | msgid "" 20 | "A password manager that uses the file format of the standard unix password " 21 | "manager 'pass', implemented in Rust. Ripasso reads $HOME/.password-store/ by " 22 | "default, override this by setting the PASSWORD_STORE_DIR environmental " 23 | "variable." 24 | msgstr "" 25 | "Un administrador de contraseñas que utiliza el formato de archivo de contraseñ" 26 | "as estándar del gestor " 27 | "de contraseñas de Unix 'pass', implementado en Rust. Ripasso lee $HOME/.passwo" 28 | "rd-store/ de manera " 29 | "predeterminada, anule esto ajustando la variable de entorno PASSWORD_STORE_DIR" 30 | " " 31 | 32 | #: cursive/src/main.rs:694 33 | msgid "Add new password" 34 | msgstr "Añadir una nueva contraseña" 35 | 36 | #: cursive/src/main.rs:810 37 | msgid "Added team member to password store" 38 | msgstr "Miembro del equipo añadido al almacén de contraseñas" 39 | 40 | #: cursive/src/wizard.rs:75 41 | msgid "Also create a git repository for the encrypted files?" 42 | msgstr "¿Crear también un repositorio git para los archivos cifrados?" 43 | 44 | #: cursive/src/main.rs:272 45 | msgid "Are you sure you want to delete the password?" 46 | msgstr "¿Está seguro de que desea eliminar la contraseña?" 47 | 48 | #: cursive/src/main.rs:748 49 | msgid "Are you sure you want to remove this person?" 50 | msgstr "¿Está seguro de que desea eliminar esta persona?" 51 | 52 | #: cursive/src/main.rs:773 53 | msgid "" 54 | "Can't import team member due to that the GPG trust relationship level isn't " 55 | "Ultimate" 56 | msgstr "" 57 | "No se puede importar un miembro del equipo debido a que el nivel de relación d" 58 | "e confianza de GPG no es " 59 | "Último" 60 | 61 | #: cursive/src/main.rs:280 cursive/src/main.rs:550 cursive/src/main.rs:704 62 | #: cursive/src/main.rs:758 cursive/src/main.rs:862 cursive/src/main.rs:1253 63 | #: cursive/src/main.rs:1291 cursive/src/main.rs:1777 cursive/src/main.rs:1923 64 | #: cursive/src/wizard.rs:145 65 | msgid "Cancel" 66 | msgstr "Cancelar" 67 | 68 | #: cursive/src/main.rs:431 cursive/src/main.rs:450 cursive/src/main.rs:643 69 | msgid "Close" 70 | msgstr "Cerrar" 71 | 72 | #: cursive/src/main.rs:212 73 | msgid "Copied MFA code to copy buffer" 74 | msgstr "Código MFA copiado en el búfer de copiado" 75 | 76 | #: cursive/src/main.rs:237 77 | msgid "Copied file name to copy buffer" 78 | msgstr "Nombre del archivo copiado en el búfer de copiado" 79 | 80 | #: cursive/src/main.rs:187 81 | msgid "Copied first line of password to copy buffer for 40 seconds" 82 | msgstr "" 83 | "Copiada la primera línea de la contraseña en el búfer copiado durante 40 segun" 84 | "dos" 85 | 86 | #: cursive/src/main.rs:158 87 | msgid "Copied password to copy buffer for 40 seconds" 88 | msgstr "Contraseña copiada en el búfer de copiado durante 40 segundos" 89 | 90 | #: cursive/src/main.rs:2283 91 | msgid "Copy (ctrl-y)" 92 | msgstr "Copiar (ctrl-y)" 93 | 94 | #: cursive/src/main.rs:2290 95 | msgid "Copy MFA Code (ctrl-b)" 96 | msgstr "Copiar el código MFA (ctrl-b)" 97 | 98 | #: cursive/src/main.rs:2289 99 | msgid "Copy Name (ctrl-u)" 100 | msgstr "Copiar nombre (ctrl-u)" 101 | 102 | #: cursive/src/wizard.rs:77 cursive/src/wizard.rs:98 cursive/src/wizard.rs:142 103 | msgid "Create" 104 | msgstr "Crear" 105 | 106 | #: cursive/src/main.rs:2308 107 | msgid "Create (ins) " 108 | msgstr "Crear (ins) " 109 | 110 | #: cursive/src/main.rs:606 111 | msgid "Created new password" 112 | msgstr "Nueva contraseña creada" 113 | 114 | #: cursive/src/main.rs:2314 115 | msgid "Delete (del)" 116 | msgstr "Eliminar (del)" 117 | 118 | #: cursive/src/main.rs:737 119 | msgid "Deleted team member from password store" 120 | msgstr "Miembro del equipo eliminado del almacén de contraseñas" 121 | 122 | #: cursive/src/main.rs:840 cursive/src/main.rs:1690 cursive/src/main.rs:1853 123 | msgid "Directory: " 124 | msgstr "Carpeta: " 125 | 126 | #: cursive/src/main.rs:1292 127 | msgid "Download" 128 | msgstr "Descargar" 129 | 130 | #: cursive/src/main.rs:1289 131 | msgid "" 132 | "Download pgp data from keys.openpgp.org and import them into your key ring?" 133 | msgstr "" 134 | "¿Descargar los datos pgp desde keys.openpgp.org e importarlos en su anillo de " 135 | "claves?" 136 | 137 | #: cursive/src/main.rs:1979 138 | msgid "Edit password stores" 139 | msgstr "Editar almacenes de contraseñas" 140 | 141 | #: cursive/src/main.rs:1772 142 | msgid "Edit store config" 143 | msgstr "Editar configuración del almacén" 144 | 145 | #: cursive/src/main.rs:1701 cursive/src/main.rs:1863 146 | msgid "Enforce signing of .gpg-id file: " 147 | msgstr "Aplicar la firma del archivo .gpg-id: " 148 | 149 | #: cursive/src/helpers.rs:45 150 | msgid "Error" 151 | msgstr "Error" 152 | 153 | #: cursive/src/main.rs:2274 cursive/src/wizard.rs:134 154 | msgid "F1: Menu | " 155 | msgstr "F1: Menú | " 156 | 157 | #: cursive/src/main.rs:333 158 | msgid "File History" 159 | msgstr "Historial de archivos" 160 | 161 | #: cursive/src/main.rs:2302 162 | msgid "File History (ctrl-h)" 163 | msgstr "Historial de archivos (ctrl-h)" 164 | 165 | #: cursive/src/main.rs:884 166 | msgid "Full" 167 | msgstr "Completo" 168 | 169 | #: cursive/src/main.rs:1298 170 | msgid "GPG Download" 171 | msgstr "Descargar GPG" 172 | 173 | #: cursive/src/main.rs:829 174 | msgid "GPG Key ID: " 175 | msgstr "ID de clave GPG: " 176 | 177 | #: cursive/src/main.rs:443 cursive/src/main.rs:695 178 | msgid "Generate" 179 | msgstr "Generar" 180 | 181 | #: cursive/src/wizard.rs:83 182 | msgid "Git Init" 183 | msgstr "Git Init" 184 | 185 | #: cursive/src/main.rs:2334 186 | msgid "Git Pull (ctrl-f)" 187 | msgstr "Git Pull (ctrl-f)" 188 | 189 | #: cursive/src/main.rs:2340 190 | msgid "Git Push (ctrl-g)" 191 | msgstr "Git Push (ctrl-g)" 192 | 193 | #: cursive/src/main.rs:1254 194 | msgid "Import" 195 | msgstr "Importar" 196 | 197 | #: cursive/src/main.rs:2354 198 | msgid "Import PGP Certificate from text" 199 | msgstr "Importar certificado GPG de texto" 200 | 201 | #: cursive/src/main.rs:1234 cursive/src/main.rs:1275 202 | msgid "Import Results" 203 | msgstr "Importar resultados" 204 | 205 | #: cursive/src/wizard.rs:149 206 | msgid "Init" 207 | msgstr "Init" 208 | 209 | #: cursive/src/wizard.rs:35 210 | msgid "Initialized password repo with Ripasso" 211 | msgstr "Inicializado el repositorio de contraseñas con Ripasso" 212 | 213 | #: cursive/src/main.rs:423 cursive/src/main.rs:639 214 | msgid "" 215 | "It seems like you are trying to save a TOTP code to the password store. This " 216 | "will reduce your 2FA solution to just 1FA, do you want to proceed?" 217 | msgstr "" 218 | "Parece que está intentando guardar un código TOTP en el almacén de contraseñas" 219 | ". Esto " 220 | "reducirá su solución 2FA a solo 1FA, ¿desea continuar?" 221 | 222 | #: cursive/src/main.rs:2396 223 | msgid "Manage" 224 | msgstr "Gestionar" 225 | 226 | #: cursive/src/main.rs:1252 227 | msgid "Manual GPG Import" 228 | msgstr "Importar manualmente GPG" 229 | 230 | #: cursive/src/main.rs:885 231 | msgid "Marginal" 232 | msgstr "Marginal" 233 | 234 | #: cursive/src/main.rs:1679 cursive/src/main.rs:1843 235 | msgid "Name: " 236 | msgstr "Nombre: " 237 | 238 | #: cursive/src/main.rs:886 239 | msgid "Never" 240 | msgstr "Nunca" 241 | 242 | #: cursive/src/main.rs:529 243 | msgid "New file name: " 244 | msgstr "Nuevo nombre de archivo: " 245 | 246 | #: cursive/src/main.rs:1908 247 | msgid "New store config" 248 | msgstr "Nueva configuración de almacenamiento" 249 | 250 | #: cursive/src/wizard.rs:80 251 | msgid "No" 252 | msgstr "No" 253 | 254 | #: cursive/src/main.rs:2069 255 | msgid "No home directory set" 256 | msgstr "No se ha establecido ningún directorio de inicio" 257 | 258 | #: cursive/src/main.rs:898 259 | msgid "Not Usable" 260 | msgstr "No utilizable" 261 | 262 | #: cursive/src/main.rs:682 263 | msgid "Note: " 264 | msgstr "Nota: " 265 | 266 | #: cursive/src/helpers.rs:44 cursive/src/main.rs:334 cursive/src/main.rs:1001 267 | #: cursive/src/main.rs:1076 cursive/src/main.rs:1233 cursive/src/main.rs:1274 268 | #: cursive/src/main.rs:1980 269 | msgid "Ok" 270 | msgstr "Ok" 271 | 272 | #: cursive/src/main.rs:519 273 | msgid "Old file name: " 274 | msgstr "Antiguo nombre de archivo: " 275 | 276 | #: cursive/src/main.rs:2296 277 | msgid "Open (ctrl-o)" 278 | msgstr "Abrir (ctrl-o)" 279 | 280 | #: cursive/src/main.rs:2281 281 | msgid "Operations" 282 | msgstr "Operaciones" 283 | 284 | #: cursive/src/main.rs:1726 285 | msgid "Own key fingerprint: " 286 | msgstr "Clave de huella digital propia: " 287 | 288 | #: cursive/src/main.rs:1712 cursive/src/main.rs:1870 289 | msgid "PGP Implementation: " 290 | msgstr "Implementaciones PGP: " 291 | 292 | #: cursive/src/main.rs:277 293 | msgid "Password deleted" 294 | msgstr "Contraseña eliminada" 295 | 296 | #: cursive/src/main.rs:671 297 | msgid "Password: " 298 | msgstr "Contraseña: " 299 | 300 | #: cursive/src/main.rs:661 301 | msgid "Path: " 302 | msgstr "Ruta: " 303 | 304 | #: cursive/src/main.rs:2347 305 | msgid "Pull PGP Certificates" 306 | msgstr "Importar certificados PGP" 307 | 308 | #: cursive/src/main.rs:1218 309 | msgid "Pulled from remote git repository" 310 | msgstr "Importado desde un repositorio git remoto" 311 | 312 | #: cursive/src/main.rs:1182 313 | msgid "Pushed to remote git repository" 314 | msgstr "Enviado a un repositorio git remoto" 315 | 316 | #: cursive/src/main.rs:2361 317 | msgid "Quit (esc)" 318 | msgstr "Salir (esc)" 319 | 320 | #: cursive/src/main.rs:545 321 | msgid "Rename" 322 | msgstr "Renombrar" 323 | 324 | #: cursive/src/main.rs:544 325 | msgid "Rename File" 326 | msgstr "Renombrar archivo" 327 | 328 | #: cursive/src/main.rs:2320 329 | msgid "Rename file (ctrl-r)" 330 | msgstr "Renombrar archivo (ctrl-r)" 331 | 332 | #: cursive/src/wizard.rs:95 333 | msgid "" 334 | "Ripasso uses GPG in order to encrypt the stored passwords.\n" 335 | "Please enter your GPG key ID" 336 | msgstr "" 337 | "Ripasso utiliza GPG para cifrar las contraseñas almacenadas.\n" 338 | "Por favor ingrese su ID de clave GPG" 339 | 340 | #: cursive/src/main.rs:416 cursive/src/main.rs:424 cursive/src/main.rs:640 341 | #: cursive/src/main.rs:701 cursive/src/main.rs:1773 cursive/src/main.rs:1909 342 | msgid "Save" 343 | msgstr "Guardar" 344 | 345 | #: cursive/src/main.rs:1746 cursive/src/main.rs:1888 346 | msgid "Store Members: " 347 | msgstr "Almacenar miembros: " 348 | 349 | #: cursive/src/main.rs:2399 350 | msgid "Stores" 351 | msgstr "Almacenes" 352 | 353 | #: cursive/src/main.rs:1000 cursive/src/main.rs:1075 354 | msgid "Team Members" 355 | msgstr "Miembros del equipo" 356 | 357 | #: cursive/src/main.rs:2326 358 | msgid "Team Members (ctrl-v)" 359 | msgstr "Miembros del equipo (ctrl-v)" 360 | 361 | #: cursive/src/helpers.rs:37 362 | msgid "Team member with key id {} isn't in your GPG keyring, fetch it first" 363 | msgstr "" 364 | "El miembro del equipo con ID de clave {} no está en su conjunto de claves GPG," 365 | " búsquelo primero" 366 | 367 | #: cursive/src/main.rs:2150 368 | msgid "" 369 | "The password store is backed by a git repository, but there is passwords " 370 | "there that's not in git. Please add them, otherwise they might get lost." 371 | msgstr "" 372 | "El almacén de contraseñas está respaldado en un repositorio git, pero hay cont" 373 | "raseñas " 374 | "ahí que no están en git. Por favor añádalas, de lo contrario podrían perderse." 375 | 376 | #: cursive/src/main.rs:883 377 | msgid "Ultimate" 378 | msgstr "Último" 379 | 380 | #: cursive/src/wizard.rs:69 381 | msgid "Unable to write file" 382 | msgstr "No se puede escribir el archivo" 383 | 384 | #: cursive/src/main.rs:887 385 | msgid "Undefined" 386 | msgstr "Indefinido" 387 | 388 | #: cursive/src/main.rs:888 389 | msgid "Unknown" 390 | msgstr "Desconocido" 391 | 392 | #: cursive/src/main.rs:2047 cursive/src/main.rs:2055 393 | msgid "Unknown argument, usage: ripasso-cursive [-h|--help]" 394 | msgstr "Argumento desconocido, utilice: ripasso-cursive [-h|--help]" 395 | 396 | #: cursive/src/main.rs:1589 cursive/src/main.rs:1634 cursive/src/main.rs:1823 397 | msgid "Updated config file" 398 | msgstr "Archivo de configuración actualizado" 399 | 400 | #: cursive/src/main.rs:382 401 | msgid "Updated password entry" 402 | msgstr "Entrada de contraseña actualizada" 403 | 404 | #: cursive/src/main.rs:900 405 | msgid "Usable" 406 | msgstr "Utilizable" 407 | 408 | #: cursive/src/wizard.rs:141 409 | msgid "" 410 | "Welcome to Ripasso, it seems like you don't have a password store directory " 411 | "yet would you like to create it?\n" 412 | "It's created in $HOME/.password-store or where the PASSWORD_STORE_DIR " 413 | "environmental variable points." 414 | msgstr "" 415 | "Bienvenido a Ripasso, parece que aún no tiene un directorio de almacenamiento " 416 | "de contraseñas " 417 | "¿Le gustaría crearlo?\n" 418 | "Se crea en $HOME/.password-store o donde apunte la variable de entorno " 419 | "PASSWORD_STORE_DIR." 420 | 421 | #: cursive/src/main.rs:274 cursive/src/main.rs:750 cursive/src/main.rs:856 422 | msgid "Yes" 423 | msgstr "Sí" 424 | 425 | #: cursive/src/main.rs:2144 426 | msgid "" 427 | "You haven't configured you name and email in git, doing so will make " 428 | "cooperation with your team easier, you can do it like this:\n" 429 | "git config --global user.name \"John Doe\"\n" 430 | "git config --global user.email \"email@example.com\"\n" 431 | "\n" 432 | "Also consider configuring git to sign your commits with GPG:\n" 433 | "git config --global user.signingkey 3AA5C34371567BD2\n" 434 | "git config --global commit.gpgsign true" 435 | msgstr "" 436 | "No ha configurado su nombre y correo electrónico en git, hacerlo hará que " 437 | "la cooperación con su equipo sea más fácil, puede hacerlo así:\n" 438 | "git config --global user.name \"John Doe\"\n" 439 | "git config --global user.email \"email@ejemplo.com\"\n" 440 | "\n" 441 | "También considere configurar git para firmar sus confirmaciones con GPG::\n" 442 | "git config --global user.signingkey 3AA5C34371567BD2\n" 443 | "git config --global commit.gpgsign true" 444 | 445 | #: cursive/src/main.rs:1984 446 | msgid "ctrl-e: Edit | " 447 | msgstr "ctrl-e: Editar | " 448 | 449 | #: cursive/src/main.rs:1006 cursive/src/main.rs:1081 cursive/src/main.rs:1986 450 | msgid "del: Remove" 451 | msgstr "del: Eliminar" 452 | 453 | #: cursive/src/main.rs:1005 cursive/src/main.rs:1080 cursive/src/main.rs:1985 454 | msgid "ins: Add | " 455 | msgstr "ins: Añadir | " 456 | 457 | #: cursive/src/main.rs:1113 cursive/src/main.rs:1135 458 | msgid "n/a" 459 | msgstr "n/a" 460 | -------------------------------------------------------------------------------- /cursive/res/fr.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: \n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2024-09-19 15:10+0200\n" 11 | "PO-Revision-Date: 2020-10-06 13:58-0400\n" 12 | "Last-Translator: \n" 13 | "Language-Team: \n" 14 | "Language: fr_FR\n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "X-Generator: Poedit 2.4.1\n" 19 | "Plural-Forms: nplurals=2; plural=(n > 1);\n" 20 | 21 | #: cursive/src/main.rs:1166 22 | msgid "" 23 | "A password manager that uses the file format of the standard unix password " 24 | "manager 'pass', implemented in Rust. Ripasso reads $HOME/.password-store/ by " 25 | "default, override this by setting the PASSWORD_STORE_DIR environmental " 26 | "variable." 27 | msgstr "" 28 | "Un gestionnaire de mots de passe qui utilise le format de fichier de 'pass', " 29 | "le gestionnaire de mots de passe standard de Unix, implémenté en Rust. " 30 | "RIpasso lit $HOME/.password-store/ par défaut, remplacez cela en définissant " 31 | "la variable d'environnement PASSWORD_STORE_DIR." 32 | 33 | #: cursive/src/main.rs:694 34 | msgid "Add new password" 35 | msgstr "Ajouter un nouveau mot de passe" 36 | 37 | #: cursive/src/main.rs:810 38 | msgid "Added team member to password store" 39 | msgstr "Membre de l'équipe ajouté au stockage des mots de passe" 40 | 41 | #: cursive/src/wizard.rs:75 42 | msgid "Also create a git repository for the encrypted files?" 43 | msgstr "Créer également un dépôt distant git pour les fichiers chiffrés?" 44 | 45 | #: cursive/src/main.rs:272 46 | msgid "Are you sure you want to delete the password?" 47 | msgstr "Êtes-vous sûr de vouloir supprimer le mot de passe ?" 48 | 49 | #: cursive/src/main.rs:748 50 | msgid "Are you sure you want to remove this person?" 51 | msgstr "Êtes-vous sûr de vouloir retirer cette personne ?" 52 | 53 | #: cursive/src/main.rs:773 54 | msgid "" 55 | "Can't import team member due to that the GPG trust relationship level isn't " 56 | "Ultimate" 57 | msgstr "" 58 | "Impossible d'importe le membre d'équipe car la relation de confiance GPG " 59 | "n'est pas au niveau Ultime" 60 | 61 | #: cursive/src/main.rs:280 cursive/src/main.rs:550 cursive/src/main.rs:704 62 | #: cursive/src/main.rs:758 cursive/src/main.rs:862 cursive/src/main.rs:1253 63 | #: cursive/src/main.rs:1291 cursive/src/main.rs:1777 cursive/src/main.rs:1923 64 | #: cursive/src/wizard.rs:145 65 | msgid "Cancel" 66 | msgstr "Annuler" 67 | 68 | #: cursive/src/main.rs:431 cursive/src/main.rs:450 cursive/src/main.rs:643 69 | msgid "Close" 70 | msgstr "Fermer" 71 | 72 | #: cursive/src/main.rs:212 73 | #, fuzzy 74 | msgid "Copied MFA code to copy buffer" 75 | msgstr "Mot de passe copié dans le tampon " 76 | 77 | #: cursive/src/main.rs:237 78 | msgid "Copied file name to copy buffer" 79 | msgstr "Mot de passe copié dans le tampon " 80 | 81 | #: cursive/src/main.rs:187 82 | #, fuzzy 83 | msgid "Copied first line of password to copy buffer for 40 seconds" 84 | msgstr "Mot de passe copié dans le tampon pendant 40 secondes" 85 | 86 | #: cursive/src/main.rs:158 87 | msgid "Copied password to copy buffer for 40 seconds" 88 | msgstr "Mot de passe copié dans le tampon pendant 40 secondes" 89 | 90 | #: cursive/src/main.rs:2283 91 | msgid "Copy (ctrl-y)" 92 | msgstr "Copier (ctrl-y)" 93 | 94 | #: cursive/src/main.rs:2290 95 | #, fuzzy 96 | msgid "Copy MFA Code (ctrl-b)" 97 | msgstr "Copier le nom (ctrl-y)" 98 | 99 | #: cursive/src/main.rs:2289 100 | msgid "Copy Name (ctrl-u)" 101 | msgstr "Copier le nom (ctrl-y)" 102 | 103 | #: cursive/src/wizard.rs:77 cursive/src/wizard.rs:98 cursive/src/wizard.rs:142 104 | msgid "Create" 105 | msgstr "Créer" 106 | 107 | #: cursive/src/main.rs:2308 108 | msgid "Create (ins) " 109 | msgstr "Créer (ins)" 110 | 111 | #: cursive/src/main.rs:606 112 | msgid "Created new password" 113 | msgstr "Créer un nouveau mot de passe" 114 | 115 | #: cursive/src/main.rs:2314 116 | msgid "Delete (del)" 117 | msgstr "Supprimer (del)" 118 | 119 | #: cursive/src/main.rs:737 120 | msgid "Deleted team member from password store" 121 | msgstr "Supprimer un membre d'équipe du stockage de mots de passe" 122 | 123 | #: cursive/src/main.rs:840 cursive/src/main.rs:1690 cursive/src/main.rs:1853 124 | msgid "Directory: " 125 | msgstr "Répertoire:" 126 | 127 | #: cursive/src/main.rs:1292 128 | msgid "Download" 129 | msgstr "" 130 | 131 | #: cursive/src/main.rs:1289 132 | msgid "" 133 | "Download pgp data from keys.openpgp.org and import them into your key ring?" 134 | msgstr "" 135 | 136 | #: cursive/src/main.rs:1979 137 | msgid "Edit password stores" 138 | msgstr "Éditer les stockages de mot de passe" 139 | 140 | #: cursive/src/main.rs:1772 141 | msgid "Edit store config" 142 | msgstr "Éditer la configuration du stockage" 143 | 144 | #: cursive/src/main.rs:1701 cursive/src/main.rs:1863 145 | msgid "Enforce signing of .gpg-id file: " 146 | msgstr "" 147 | 148 | #: cursive/src/helpers.rs:45 149 | msgid "Error" 150 | msgstr "Erreur" 151 | 152 | #: cursive/src/main.rs:2274 cursive/src/wizard.rs:134 153 | msgid "F1: Menu | " 154 | msgstr "F1: Menu |" 155 | 156 | #: cursive/src/main.rs:333 157 | msgid "File History" 158 | msgstr "Historique du fichier" 159 | 160 | #: cursive/src/main.rs:2302 161 | msgid "File History (ctrl-h)" 162 | msgstr "Historique du fichier (ctrl-h)" 163 | 164 | #: cursive/src/main.rs:884 165 | msgid "Full" 166 | msgstr "Entier" 167 | 168 | #: cursive/src/main.rs:1298 169 | msgid "GPG Download" 170 | msgstr "" 171 | 172 | #: cursive/src/main.rs:829 173 | msgid "GPG Key ID: " 174 | msgstr "GPG Clé ID:" 175 | 176 | #: cursive/src/main.rs:443 cursive/src/main.rs:695 177 | msgid "Generate" 178 | msgstr "Générer" 179 | 180 | #: cursive/src/wizard.rs:83 181 | msgid "Git Init" 182 | msgstr "Git Init" 183 | 184 | #: cursive/src/main.rs:2334 185 | msgid "Git Pull (ctrl-f)" 186 | msgstr "Git Pull (ctrl-f)" 187 | 188 | #: cursive/src/main.rs:2340 189 | msgid "Git Push (ctrl-g)" 190 | msgstr "Git Push (ctrl-g)" 191 | 192 | #: cursive/src/main.rs:1254 193 | msgid "Import" 194 | msgstr "" 195 | 196 | #: cursive/src/main.rs:2354 197 | msgid "Import PGP Certificate from text" 198 | msgstr "" 199 | 200 | #: cursive/src/main.rs:1234 cursive/src/main.rs:1275 201 | msgid "Import Results" 202 | msgstr "" 203 | 204 | #: cursive/src/wizard.rs:149 205 | msgid "Init" 206 | msgstr "Init" 207 | 208 | #: cursive/src/wizard.rs:35 209 | msgid "Initialized password repo with Ripasso" 210 | msgstr "Dépôt de mot de passe initialisé avec Ripasso" 211 | 212 | #: cursive/src/main.rs:423 cursive/src/main.rs:639 213 | msgid "" 214 | "It seems like you are trying to save a TOTP code to the password store. This " 215 | "will reduce your 2FA solution to just 1FA, do you want to proceed?" 216 | msgstr "" 217 | 218 | #: cursive/src/main.rs:2396 219 | msgid "Manage" 220 | msgstr "Gérer" 221 | 222 | #: cursive/src/main.rs:1252 223 | msgid "Manual GPG Import" 224 | msgstr "" 225 | 226 | #: cursive/src/main.rs:885 227 | msgid "Marginal" 228 | msgstr "Marginal" 229 | 230 | #: cursive/src/main.rs:1679 cursive/src/main.rs:1843 231 | msgid "Name: " 232 | msgstr "Nom:" 233 | 234 | #: cursive/src/main.rs:886 235 | msgid "Never" 236 | msgstr "Jamais" 237 | 238 | #: cursive/src/main.rs:529 239 | msgid "New file name: " 240 | msgstr "Nouveau nom de fichier:" 241 | 242 | #: cursive/src/main.rs:1908 243 | msgid "New store config" 244 | msgstr "Nouvelle configuration de stockage" 245 | 246 | #: cursive/src/wizard.rs:80 247 | msgid "No" 248 | msgstr "Non" 249 | 250 | #: cursive/src/main.rs:2069 251 | msgid "No home directory set" 252 | msgstr "" 253 | 254 | #: cursive/src/main.rs:898 255 | msgid "Not Usable" 256 | msgstr "" 257 | 258 | #: cursive/src/main.rs:682 259 | msgid "Note: " 260 | msgstr "Note:" 261 | 262 | #: cursive/src/helpers.rs:44 cursive/src/main.rs:334 cursive/src/main.rs:1001 263 | #: cursive/src/main.rs:1076 cursive/src/main.rs:1233 cursive/src/main.rs:1274 264 | #: cursive/src/main.rs:1980 265 | msgid "Ok" 266 | msgstr "Ok" 267 | 268 | #: cursive/src/main.rs:519 269 | msgid "Old file name: " 270 | msgstr "Ancien nom de fichier" 271 | 272 | #: cursive/src/main.rs:2296 273 | msgid "Open (ctrl-o)" 274 | msgstr "Ouvrir (ctrl-o)" 275 | 276 | #: cursive/src/main.rs:2281 277 | msgid "Operations" 278 | msgstr "Opérations" 279 | 280 | #: cursive/src/main.rs:1726 281 | msgid "Own key fingerprint: " 282 | msgstr "" 283 | 284 | #: cursive/src/main.rs:1712 cursive/src/main.rs:1870 285 | msgid "PGP Implementation: " 286 | msgstr "" 287 | 288 | #: cursive/src/main.rs:277 289 | msgid "Password deleted" 290 | msgstr "Mot de passe supprimé" 291 | 292 | #: cursive/src/main.rs:671 293 | msgid "Password: " 294 | msgstr "Mot de passe:" 295 | 296 | #: cursive/src/main.rs:661 297 | msgid "Path: " 298 | msgstr "Chemin:" 299 | 300 | #: cursive/src/main.rs:2347 301 | msgid "Pull PGP Certificates" 302 | msgstr "" 303 | 304 | #: cursive/src/main.rs:1218 305 | msgid "Pulled from remote git repository" 306 | msgstr "Tiré du dépôt distant git" 307 | 308 | #: cursive/src/main.rs:1182 309 | msgid "Pushed to remote git repository" 310 | msgstr "Poussé vers le dépôt distant git" 311 | 312 | #: cursive/src/main.rs:2361 313 | msgid "Quit (esc)" 314 | msgstr "Quitter (esc)" 315 | 316 | #: cursive/src/main.rs:545 317 | msgid "Rename" 318 | msgstr "Renommer" 319 | 320 | #: cursive/src/main.rs:544 321 | msgid "Rename File" 322 | msgstr "Renommer le fichier" 323 | 324 | #: cursive/src/main.rs:2320 325 | msgid "Rename file (ctrl-r)" 326 | msgstr "Renommer le fichier (ctrl-v)" 327 | 328 | #: cursive/src/wizard.rs:95 329 | msgid "" 330 | "Ripasso uses GPG in order to encrypt the stored passwords.\n" 331 | "Please enter your GPG key ID" 332 | msgstr "" 333 | "Ripasso utilise GPG pour chiffrer les mots de passe.\n" 334 | "Entrer votre GPG clé ID s'il-vous-plaît" 335 | 336 | #: cursive/src/main.rs:416 cursive/src/main.rs:424 cursive/src/main.rs:640 337 | #: cursive/src/main.rs:701 cursive/src/main.rs:1773 cursive/src/main.rs:1909 338 | msgid "Save" 339 | msgstr "Sauvegarder" 340 | 341 | #: cursive/src/main.rs:1746 cursive/src/main.rs:1888 342 | #, fuzzy 343 | msgid "Store Members: " 344 | msgstr "Membres d'équipe" 345 | 346 | #: cursive/src/main.rs:2399 347 | msgid "Stores" 348 | msgstr "Stockages" 349 | 350 | #: cursive/src/main.rs:1000 cursive/src/main.rs:1075 351 | msgid "Team Members" 352 | msgstr "Membres d'équipe" 353 | 354 | #: cursive/src/main.rs:2326 355 | msgid "Team Members (ctrl-v)" 356 | msgstr "Membres d'équipe (ctrl-v)" 357 | 358 | #: cursive/src/helpers.rs:37 359 | msgid "Team member with key id {} isn't in your GPG keyring, fetch it first" 360 | msgstr "" 361 | "Le membre d'équipe avec la clé id {} n'est pas dans votre porte-clés GPG, " 362 | "ajoutez-le d'abord" 363 | 364 | #: cursive/src/main.rs:2150 365 | msgid "" 366 | "The password store is backed by a git repository, but there is passwords " 367 | "there that's not in git. Please add them, otherwise they might get lost." 368 | msgstr "" 369 | "Le stockage de mots de passe est supporté par une repo git, mais il y a des " 370 | "mots de passe qui ne sont pas sur git. Ajoutez-les, sinon ils peuvent être " 371 | "perdus." 372 | 373 | #: cursive/src/main.rs:883 374 | msgid "Ultimate" 375 | msgstr "Ultime" 376 | 377 | #: cursive/src/wizard.rs:69 378 | msgid "Unable to write file" 379 | msgstr "Fichier impossible à écrire" 380 | 381 | #: cursive/src/main.rs:887 382 | msgid "Undefined" 383 | msgstr "Indéfini" 384 | 385 | #: cursive/src/main.rs:888 386 | msgid "Unknown" 387 | msgstr "Inconnu" 388 | 389 | #: cursive/src/main.rs:2047 cursive/src/main.rs:2055 390 | msgid "Unknown argument, usage: ripasso-cursive [-h|--help]" 391 | msgstr "Argument invalide, utilisation: ripasso-cursive [-h|--help]" 392 | 393 | #: cursive/src/main.rs:1589 cursive/src/main.rs:1634 cursive/src/main.rs:1823 394 | msgid "Updated config file" 395 | msgstr "Configuration du fichier mise à jour" 396 | 397 | #: cursive/src/main.rs:382 398 | msgid "Updated password entry" 399 | msgstr "Entrée de mot de passe mise à jour" 400 | 401 | #: cursive/src/main.rs:900 402 | msgid "Usable" 403 | msgstr "" 404 | 405 | #: cursive/src/wizard.rs:141 406 | msgid "" 407 | "Welcome to Ripasso, it seems like you don't have a password store directory " 408 | "yet would you like to create it?\n" 409 | "It's created in $HOME/.password-store or where the PASSWORD_STORE_DIR " 410 | "environmental variable points." 411 | msgstr "" 412 | "Bienvenue sur Ripasso, il semble que vous n'ayez pas encore de dossier de " 413 | "stockage pour vos mots de passe. Voulez-vous le créer?\n" 414 | "Il est créé dans $HOME/.password-store ou là où la variable d'environnement " 415 | "PASSWORD_STORE_DIR désigne." 416 | 417 | #: cursive/src/main.rs:274 cursive/src/main.rs:750 cursive/src/main.rs:856 418 | msgid "Yes" 419 | msgstr "Oui" 420 | 421 | #: cursive/src/main.rs:2144 422 | msgid "" 423 | "You haven't configured you name and email in git, doing so will make " 424 | "cooperation with your team easier, you can do it like this:\n" 425 | "git config --global user.name \"John Doe\"\n" 426 | "git config --global user.email \"email@example.com\"\n" 427 | "\n" 428 | "Also consider configuring git to sign your commits with GPG:\n" 429 | "git config --global user.signingkey 3AA5C34371567BD2\n" 430 | "git config --global commit.gpgsign true" 431 | msgstr "" 432 | "Vous n'avez pas configuré votre nom et votre e-mail dans git, cela " 433 | "facilitera la coopération avec votre équipe, vous pouvez le faire comme " 434 | "ceci:\n" 435 | "git config --global user.name \"John Doe\"\n" 436 | "git config --global user.email \"email@example.com\"\n" 437 | "\n" 438 | "Pensez également à configurer git pour signer vos commits avec GPG:\n" 439 | "git config --global user.signingkey 3AA5C34371567BD2\n" 440 | "git config --global commit.gpgsign true" 441 | 442 | #: cursive/src/main.rs:1984 443 | msgid "ctrl-e: Edit | " 444 | msgstr "ctrl-e: Éditer | " 445 | 446 | #: cursive/src/main.rs:1006 cursive/src/main.rs:1081 cursive/src/main.rs:1986 447 | msgid "del: Remove" 448 | msgstr "del: Supprimer" 449 | 450 | #: cursive/src/main.rs:1005 cursive/src/main.rs:1080 cursive/src/main.rs:1985 451 | msgid "ins: Add | " 452 | msgstr "ins: Ajouter | " 453 | 454 | #: cursive/src/main.rs:1113 cursive/src/main.rs:1135 455 | msgid "n/a" 456 | msgstr "n/a" 457 | 458 | #~ msgid "Valid Signing Keys: " 459 | #~ msgstr "Clés de signatures valides:" 460 | 461 | #~ msgid "" 462 | #~ "You have pointed ripasso towards an existing directory without an .gpg-id " 463 | #~ "file, this doesn't seem like a password store directory, quiting." 464 | #~ msgstr "" 465 | #~ "Vous avez pointé ripasso vers un répertoire existant sans un fichier .gpg-" 466 | #~ "id, cela n'a pas l'air d'être un dossier de stockage pour les mots de " 467 | #~ "passe, arrêt. " 468 | -------------------------------------------------------------------------------- /cursive/res/it.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: \n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2024-09-19 15:10+0200\n" 11 | "PO-Revision-Date: 2020-10-17 23:12+0200\n" 12 | "Last-Translator: \n" 13 | "Language-Team: \n" 14 | "Language: it\n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "X-Generator: Poedit 2.3\n" 19 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 20 | 21 | #: cursive/src/main.rs:1166 22 | msgid "" 23 | "A password manager that uses the file format of the standard unix password " 24 | "manager 'pass', implemented in Rust. Ripasso reads $HOME/.password-store/ by " 25 | "default, override this by setting the PASSWORD_STORE_DIR environmental " 26 | "variable." 27 | msgstr "" 28 | "Un manager di password che utilizza il formato di files del manager di " 29 | "password standad in unix 'pass', scritto in Rust. Ripasso legge $HOME/." 30 | "password-store/ per default, ma questo settaggio si puo' cambiare " 31 | "modificando la variabile di environment PASSWORD_STORE_DIR." 32 | 33 | #: cursive/src/main.rs:694 34 | msgid "Add new password" 35 | msgstr "Aggiungi una nuova password" 36 | 37 | #: cursive/src/main.rs:810 38 | msgid "Added team member to password store" 39 | msgstr "Aggiunto un nuovo membro del team al password store" 40 | 41 | #: cursive/src/wizard.rs:75 42 | msgid "Also create a git repository for the encrypted files?" 43 | msgstr "Vuoi anche creare un repository git per i files crittati?" 44 | 45 | #: cursive/src/main.rs:272 46 | msgid "Are you sure you want to delete the password?" 47 | msgstr "Sei sicuro di voler cancellare la password?" 48 | 49 | #: cursive/src/main.rs:748 50 | msgid "Are you sure you want to remove this person?" 51 | msgstr "Sei sicuro di voler rimuovere questa persona?" 52 | 53 | #: cursive/src/main.rs:773 54 | msgid "" 55 | "Can't import team member due to that the GPG trust relationship level isn't " 56 | "Ultimate" 57 | msgstr "" 58 | "Non posso aggiungere un nuovo membro nel team dato che il livello di GPG " 59 | "trust non e' \"ultimate\"" 60 | 61 | #: cursive/src/main.rs:280 cursive/src/main.rs:550 cursive/src/main.rs:704 62 | #: cursive/src/main.rs:758 cursive/src/main.rs:862 cursive/src/main.rs:1253 63 | #: cursive/src/main.rs:1291 cursive/src/main.rs:1777 cursive/src/main.rs:1923 64 | #: cursive/src/wizard.rs:145 65 | msgid "Cancel" 66 | msgstr "Cancel" 67 | 68 | #: cursive/src/main.rs:431 cursive/src/main.rs:450 cursive/src/main.rs:643 69 | msgid "Close" 70 | msgstr "Chiudi" 71 | 72 | #: cursive/src/main.rs:212 73 | #, fuzzy 74 | msgid "Copied MFA code to copy buffer" 75 | msgstr "Password copiata nel copy buffer" 76 | 77 | #: cursive/src/main.rs:237 78 | msgid "Copied file name to copy buffer" 79 | msgstr "Password copiata nel copy buffer" 80 | 81 | #: cursive/src/main.rs:187 82 | #, fuzzy 83 | msgid "Copied first line of password to copy buffer for 40 seconds" 84 | msgstr "Password nel copy buffer per 40 secondi" 85 | 86 | #: cursive/src/main.rs:158 87 | msgid "Copied password to copy buffer for 40 seconds" 88 | msgstr "Password nel copy buffer per 40 secondi" 89 | 90 | #: cursive/src/main.rs:2283 91 | msgid "Copy (ctrl-y)" 92 | msgstr "Copia (ctrl-y)" 93 | 94 | #: cursive/src/main.rs:2290 95 | #, fuzzy 96 | msgid "Copy MFA Code (ctrl-b)" 97 | msgstr "Copia Nomeo (ctrl-u)" 98 | 99 | #: cursive/src/main.rs:2289 100 | msgid "Copy Name (ctrl-u)" 101 | msgstr "Copia Nomeo (ctrl-u)" 102 | 103 | #: cursive/src/wizard.rs:77 cursive/src/wizard.rs:98 cursive/src/wizard.rs:142 104 | msgid "Create" 105 | msgstr "Crea" 106 | 107 | #: cursive/src/main.rs:2308 108 | msgid "Create (ins) " 109 | msgstr "Crea (ins) " 110 | 111 | #: cursive/src/main.rs:606 112 | msgid "Created new password" 113 | msgstr "Nuova password creata" 114 | 115 | #: cursive/src/main.rs:2314 116 | msgid "Delete (del)" 117 | msgstr "Rimuovi (del)" 118 | 119 | #: cursive/src/main.rs:737 120 | msgid "Deleted team member from password store" 121 | msgstr "Eliminato membro del team dal password store" 122 | 123 | #: cursive/src/main.rs:840 cursive/src/main.rs:1690 cursive/src/main.rs:1853 124 | msgid "Directory: " 125 | msgstr "Cartella: " 126 | 127 | #: cursive/src/main.rs:1292 128 | msgid "Download" 129 | msgstr "" 130 | 131 | #: cursive/src/main.rs:1289 132 | msgid "" 133 | "Download pgp data from keys.openpgp.org and import them into your key ring?" 134 | msgstr "" 135 | 136 | #: cursive/src/main.rs:1979 137 | msgid "Edit password stores" 138 | msgstr "Mofica gli store delle passwords" 139 | 140 | #: cursive/src/main.rs:1772 141 | msgid "Edit store config" 142 | msgstr "Modifica la configurazione di store" 143 | 144 | #: cursive/src/main.rs:1701 cursive/src/main.rs:1863 145 | msgid "Enforce signing of .gpg-id file: " 146 | msgstr "" 147 | 148 | #: cursive/src/helpers.rs:45 149 | msgid "Error" 150 | msgstr "Errore" 151 | 152 | #: cursive/src/main.rs:2274 cursive/src/wizard.rs:134 153 | msgid "F1: Menu | " 154 | msgstr "F1: Menu | " 155 | 156 | #: cursive/src/main.rs:333 157 | msgid "File History" 158 | msgstr "Storico dei file" 159 | 160 | #: cursive/src/main.rs:2302 161 | msgid "File History (ctrl-h)" 162 | msgstr "Storico dei file (ctrl-h)" 163 | 164 | #: cursive/src/main.rs:884 165 | msgid "Full" 166 | msgstr "Completo" 167 | 168 | #: cursive/src/main.rs:1298 169 | msgid "GPG Download" 170 | msgstr "" 171 | 172 | #: cursive/src/main.rs:829 173 | msgid "GPG Key ID: " 174 | msgstr "ID della chiave GPG: " 175 | 176 | #: cursive/src/main.rs:443 cursive/src/main.rs:695 177 | msgid "Generate" 178 | msgstr "Genera" 179 | 180 | #: cursive/src/wizard.rs:83 181 | msgid "Git Init" 182 | msgstr "Git Init" 183 | 184 | #: cursive/src/main.rs:2334 185 | msgid "Git Pull (ctrl-f)" 186 | msgstr "Git Pull (ctrl-f)" 187 | 188 | #: cursive/src/main.rs:2340 189 | msgid "Git Push (ctrl-g)" 190 | msgstr "Git Push (ctrl-g)" 191 | 192 | #: cursive/src/main.rs:1254 193 | msgid "Import" 194 | msgstr "" 195 | 196 | #: cursive/src/main.rs:2354 197 | msgid "Import PGP Certificate from text" 198 | msgstr "" 199 | 200 | #: cursive/src/main.rs:1234 cursive/src/main.rs:1275 201 | msgid "Import Results" 202 | msgstr "" 203 | 204 | #: cursive/src/wizard.rs:149 205 | msgid "Init" 206 | msgstr "Inizializza" 207 | 208 | #: cursive/src/wizard.rs:35 209 | msgid "Initialized password repo with Ripasso" 210 | msgstr "Password repo inizializzato con Ripasso" 211 | 212 | #: cursive/src/main.rs:423 cursive/src/main.rs:639 213 | msgid "" 214 | "It seems like you are trying to save a TOTP code to the password store. This " 215 | "will reduce your 2FA solution to just 1FA, do you want to proceed?" 216 | msgstr "" 217 | 218 | #: cursive/src/main.rs:2396 219 | msgid "Manage" 220 | msgstr "Gestisci" 221 | 222 | #: cursive/src/main.rs:1252 223 | msgid "Manual GPG Import" 224 | msgstr "" 225 | 226 | #: cursive/src/main.rs:885 227 | msgid "Marginal" 228 | msgstr "Marginale" 229 | 230 | #: cursive/src/main.rs:1679 cursive/src/main.rs:1843 231 | msgid "Name: " 232 | msgstr "Nome: " 233 | 234 | #: cursive/src/main.rs:886 235 | msgid "Never" 236 | msgstr "Mai" 237 | 238 | #: cursive/src/main.rs:529 239 | msgid "New file name: " 240 | msgstr "Nuovo nome file: " 241 | 242 | #: cursive/src/main.rs:1908 243 | msgid "New store config" 244 | msgstr "Nuova configurazione di store" 245 | 246 | #: cursive/src/wizard.rs:80 247 | msgid "No" 248 | msgstr "No" 249 | 250 | #: cursive/src/main.rs:2069 251 | msgid "No home directory set" 252 | msgstr "" 253 | 254 | #: cursive/src/main.rs:898 255 | msgid "Not Usable" 256 | msgstr "" 257 | 258 | #: cursive/src/main.rs:682 259 | msgid "Note: " 260 | msgstr "Nota: " 261 | 262 | #: cursive/src/helpers.rs:44 cursive/src/main.rs:334 cursive/src/main.rs:1001 263 | #: cursive/src/main.rs:1076 cursive/src/main.rs:1233 cursive/src/main.rs:1274 264 | #: cursive/src/main.rs:1980 265 | msgid "Ok" 266 | msgstr "Ok" 267 | 268 | #: cursive/src/main.rs:519 269 | msgid "Old file name: " 270 | msgstr "Vecchio nome file: " 271 | 272 | #: cursive/src/main.rs:2296 273 | msgid "Open (ctrl-o)" 274 | msgstr "Apri (ctrl-o)" 275 | 276 | #: cursive/src/main.rs:2281 277 | msgid "Operations" 278 | msgstr "Operazioni" 279 | 280 | #: cursive/src/main.rs:1726 281 | msgid "Own key fingerprint: " 282 | msgstr "" 283 | 284 | #: cursive/src/main.rs:1712 cursive/src/main.rs:1870 285 | msgid "PGP Implementation: " 286 | msgstr "" 287 | 288 | #: cursive/src/main.rs:277 289 | msgid "Password deleted" 290 | msgstr "Password rimossa" 291 | 292 | #: cursive/src/main.rs:671 293 | msgid "Password: " 294 | msgstr "Password: " 295 | 296 | #: cursive/src/main.rs:661 297 | msgid "Path: " 298 | msgstr "Percorso: " 299 | 300 | #: cursive/src/main.rs:2347 301 | msgid "Pull PGP Certificates" 302 | msgstr "" 303 | 304 | #: cursive/src/main.rs:1218 305 | msgid "Pulled from remote git repository" 306 | msgstr "Pull dal git repo remoto completato" 307 | 308 | #: cursive/src/main.rs:1182 309 | msgid "Pushed to remote git repository" 310 | msgstr "Push al git repo remoto completato" 311 | 312 | #: cursive/src/main.rs:2361 313 | msgid "Quit (esc)" 314 | msgstr "Esci (esc)" 315 | 316 | #: cursive/src/main.rs:545 317 | msgid "Rename" 318 | msgstr "Rinomina" 319 | 320 | #: cursive/src/main.rs:544 321 | msgid "Rename File" 322 | msgstr "Rinomina File" 323 | 324 | #: cursive/src/main.rs:2320 325 | msgid "Rename file (ctrl-r)" 326 | msgstr "Rinomina file (ctrl-r)" 327 | 328 | #: cursive/src/wizard.rs:95 329 | msgid "" 330 | "Ripasso uses GPG in order to encrypt the stored passwords.\n" 331 | "Please enter your GPG key ID" 332 | msgstr "" 333 | "Ripasso utilizza GPG per crittare le password salvate.\n" 334 | "Per favore inserisci l'ID della tua chiave GPG" 335 | 336 | #: cursive/src/main.rs:416 cursive/src/main.rs:424 cursive/src/main.rs:640 337 | #: cursive/src/main.rs:701 cursive/src/main.rs:1773 cursive/src/main.rs:1909 338 | msgid "Save" 339 | msgstr "Salva" 340 | 341 | #: cursive/src/main.rs:1746 cursive/src/main.rs:1888 342 | #, fuzzy 343 | msgid "Store Members: " 344 | msgstr "Membri del team" 345 | 346 | #: cursive/src/main.rs:2399 347 | msgid "Stores" 348 | msgstr "Stores" 349 | 350 | #: cursive/src/main.rs:1000 cursive/src/main.rs:1075 351 | msgid "Team Members" 352 | msgstr "Membri del team" 353 | 354 | #: cursive/src/main.rs:2326 355 | msgid "Team Members (ctrl-v)" 356 | msgstr "Membri del team (ctrl-v)" 357 | 358 | #: cursive/src/helpers.rs:37 359 | msgid "Team member with key id {} isn't in your GPG keyring, fetch it first" 360 | msgstr "" 361 | "Il membro del team con la chiave GPG con id {} non e' nel tuo keyring GPG, " 362 | "per prima cosa recuperala" 363 | 364 | #: cursive/src/main.rs:2150 365 | msgid "" 366 | "The password store is backed by a git repository, but there is passwords " 367 | "there that's not in git. Please add them, otherwise they might get lost." 368 | msgstr "" 369 | "Lo store delle password si basa su un repository git, ma ci sono passwords " 370 | "che non sono in quel repository. Meglio aggiungerle, altrimenti poterbbero " 371 | "andare perse." 372 | 373 | #: cursive/src/main.rs:883 374 | msgid "Ultimate" 375 | msgstr "Ultimate" 376 | 377 | #: cursive/src/wizard.rs:69 378 | msgid "Unable to write file" 379 | msgstr "Impossibile scrivere il file" 380 | 381 | #: cursive/src/main.rs:887 382 | msgid "Undefined" 383 | msgstr "Non definita" 384 | 385 | #: cursive/src/main.rs:888 386 | msgid "Unknown" 387 | msgstr "Sconosciuta" 388 | 389 | #: cursive/src/main.rs:2047 cursive/src/main.rs:2055 390 | msgid "Unknown argument, usage: ripasso-cursive [-h|--help]" 391 | msgstr "Argomento sconosciuto, per l'aiuto: ripasso-cursive [-h|--help]" 392 | 393 | #: cursive/src/main.rs:1589 cursive/src/main.rs:1634 cursive/src/main.rs:1823 394 | msgid "Updated config file" 395 | msgstr "File di configurazione aggiornato" 396 | 397 | #: cursive/src/main.rs:382 398 | msgid "Updated password entry" 399 | msgstr "Password aggiornata" 400 | 401 | #: cursive/src/main.rs:900 402 | msgid "Usable" 403 | msgstr "" 404 | 405 | #: cursive/src/wizard.rs:141 406 | msgid "" 407 | "Welcome to Ripasso, it seems like you don't have a password store directory " 408 | "yet would you like to create it?\n" 409 | "It's created in $HOME/.password-store or where the PASSWORD_STORE_DIR " 410 | "environmental variable points." 411 | msgstr "" 412 | "Benvenuto in Ripasso. A quanto pare non hai ancora una directory per salvare " 413 | "le tue password, vuoi crearla?\n" 414 | "Directory creata in $HOME/.password-store o dove punta la variabile di " 415 | "environment PASSWORD_STORE_DIR." 416 | 417 | #: cursive/src/main.rs:274 cursive/src/main.rs:750 cursive/src/main.rs:856 418 | msgid "Yes" 419 | msgstr "Si" 420 | 421 | #: cursive/src/main.rs:2144 422 | msgid "" 423 | "You haven't configured you name and email in git, doing so will make " 424 | "cooperation with your team easier, you can do it like this:\n" 425 | "git config --global user.name \"John Doe\"\n" 426 | "git config --global user.email \"email@example.com\"\n" 427 | "\n" 428 | "Also consider configuring git to sign your commits with GPG:\n" 429 | "git config --global user.signingkey 3AA5C34371567BD2\n" 430 | "git config --global commit.gpgsign true" 431 | msgstr "" 432 | "Non hai configurato un nome e un indirizzo email in git, per rendere la " 433 | "collaborazione piu' agevole con il tuo team puoi farlo cosi:\n" 434 | "git config --global user.name \"John Doe\"\n" 435 | "git config --global user.email \"email@example.com\"\n" 436 | "\n" 437 | "Prendi in considerazione di configurare git affinche firmi i tuoi commit con " 438 | "GPG:\n" 439 | "git config --global user.signingkey 3AA5C34371567BD2\n" 440 | "git config --global commit.gpgsign true" 441 | 442 | #: cursive/src/main.rs:1984 443 | msgid "ctrl-e: Edit | " 444 | msgstr "ctrl-e: Modifica | " 445 | 446 | #: cursive/src/main.rs:1006 cursive/src/main.rs:1081 cursive/src/main.rs:1986 447 | msgid "del: Remove" 448 | msgstr "del: Rimuovi" 449 | 450 | #: cursive/src/main.rs:1005 cursive/src/main.rs:1080 cursive/src/main.rs:1985 451 | msgid "ins: Add | " 452 | msgstr "ins: Aggiungi | " 453 | 454 | #: cursive/src/main.rs:1113 cursive/src/main.rs:1135 455 | msgid "n/a" 456 | msgstr "non disponibile" 457 | 458 | #~ msgid "Valid Signing Keys: " 459 | #~ msgstr "Chiavi di firmatura valide: " 460 | 461 | #~ msgid "" 462 | #~ "You have pointed ripasso towards an existing directory without an .gpg-id " 463 | #~ "file, this doesn't seem like a password store directory, quiting." 464 | #~ msgstr "" 465 | #~ "Hai puntato ripasso a una directory gia esistente che non contiene un " 466 | #~ "file .gpg-id, non sembra una directory per password store, chiudo il " 467 | #~ "programma." 468 | -------------------------------------------------------------------------------- /cursive/res/nb.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: \n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2024-09-19 15:10+0200\n" 11 | "PO-Revision-Date: 2022-11-09 18:08+0100\n" 12 | "Last-Translator: \n" 13 | "Language-Team: \n" 14 | "Language: nb\n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 19 | "X-Generator: Poedit 3.1.1\n" 20 | 21 | #: cursive/src/main.rs:1166 22 | msgid "" 23 | "A password manager that uses the file format of the standard unix password " 24 | "manager 'pass', implemented in Rust. Ripasso reads $HOME/.password-store/ by " 25 | "default, override this by setting the PASSWORD_STORE_DIR environmental " 26 | "variable." 27 | msgstr "" 28 | "Et passordhåndteringsprogram som bruker filformatet til Pass (the standard " 29 | "unix password manager) implementert i Rust. Ripasso leser fra $HOME/." 30 | "password-store/ som standard. For å lese fra en annen mappe, sett " 31 | "PASSWORD_STORE_DIR miljøvariabelen." 32 | 33 | #: cursive/src/main.rs:694 34 | msgid "Add new password" 35 | msgstr "Legg til nytt passord" 36 | 37 | #: cursive/src/main.rs:810 38 | msgid "Added team member to password store" 39 | msgstr "La til medlem i passordmappen" 40 | 41 | #: cursive/src/wizard.rs:75 42 | msgid "Also create a git repository for the encrypted files?" 43 | msgstr "Opprett et git-depot for de krypterte filene?" 44 | 45 | #: cursive/src/main.rs:272 46 | msgid "Are you sure you want to delete the password?" 47 | msgstr "Er du sikker på at du vil slette passordet?" 48 | 49 | #: cursive/src/main.rs:748 50 | msgid "Are you sure you want to remove this person?" 51 | msgstr "Er du sikker på at du vil fjerne denne personen?" 52 | 53 | #: cursive/src/main.rs:773 54 | msgid "" 55 | "Can't import team member due to that the GPG trust relationship level isn't " 56 | "Ultimate" 57 | msgstr "" 58 | "Kan ikke importere gruppemedlem, fordi GPG trust relationship level ikke er " 59 | "satt til Ultimate" 60 | 61 | #: cursive/src/main.rs:280 cursive/src/main.rs:550 cursive/src/main.rs:704 62 | #: cursive/src/main.rs:758 cursive/src/main.rs:862 cursive/src/main.rs:1253 63 | #: cursive/src/main.rs:1291 cursive/src/main.rs:1777 cursive/src/main.rs:1923 64 | #: cursive/src/wizard.rs:145 65 | msgid "Cancel" 66 | msgstr "Avbryt" 67 | 68 | #: cursive/src/main.rs:431 cursive/src/main.rs:450 cursive/src/main.rs:643 69 | msgid "Close" 70 | msgstr "Lukk" 71 | 72 | #: cursive/src/main.rs:212 73 | msgid "Copied MFA code to copy buffer" 74 | msgstr "Kopierer MFA kode til utklippstavlen" 75 | 76 | #: cursive/src/main.rs:237 77 | msgid "Copied file name to copy buffer" 78 | msgstr "Kopierer passordet til utklippstavlen" 79 | 80 | #: cursive/src/main.rs:187 81 | #, fuzzy 82 | msgid "Copied first line of password to copy buffer for 40 seconds" 83 | msgstr "Kopierer passordet til utklippstavlen i 40 sekunder" 84 | 85 | #: cursive/src/main.rs:158 86 | msgid "Copied password to copy buffer for 40 seconds" 87 | msgstr "Kopierer passordet til utklippstavlen i 40 sekunder" 88 | 89 | #: cursive/src/main.rs:2283 90 | msgid "Copy (ctrl-y)" 91 | msgstr "Kopier (ctrl-y)" 92 | 93 | #: cursive/src/main.rs:2290 94 | msgid "Copy MFA Code (ctrl-b)" 95 | msgstr "Kopier MFA kode (ctrl-b)" 96 | 97 | #: cursive/src/main.rs:2289 98 | msgid "Copy Name (ctrl-u)" 99 | msgstr "Kopier Navn (ctrl-y)" 100 | 101 | #: cursive/src/wizard.rs:77 cursive/src/wizard.rs:98 cursive/src/wizard.rs:142 102 | msgid "Create" 103 | msgstr "Opprett" 104 | 105 | #: cursive/src/main.rs:2308 106 | msgid "Create (ins) " 107 | msgstr "Opprett (ins) " 108 | 109 | #: cursive/src/main.rs:606 110 | msgid "Created new password" 111 | msgstr "Opprettet et nytt passord" 112 | 113 | #: cursive/src/main.rs:2314 114 | msgid "Delete (del)" 115 | msgstr "Slett (del)" 116 | 117 | #: cursive/src/main.rs:737 118 | msgid "Deleted team member from password store" 119 | msgstr "Slettet medlem fra passordmappen" 120 | 121 | #: cursive/src/main.rs:840 cursive/src/main.rs:1690 cursive/src/main.rs:1853 122 | msgid "Directory: " 123 | msgstr "Mappe: " 124 | 125 | #: cursive/src/main.rs:1292 126 | msgid "Download" 127 | msgstr "Laste ned" 128 | 129 | #: cursive/src/main.rs:1289 130 | msgid "" 131 | "Download pgp data from keys.openpgp.org and import them into your key ring?" 132 | msgstr "" 133 | "Laste ned pgp data fra keys.opengpg.org og importere dem til nøkkelringen?" 134 | 135 | #: cursive/src/main.rs:1979 136 | msgid "Edit password stores" 137 | msgstr "Set op passordsmappar" 138 | 139 | #: cursive/src/main.rs:1772 140 | msgid "Edit store config" 141 | msgstr "Rediger konfigurasjon for passordmappen" 142 | 143 | #: cursive/src/main.rs:1701 cursive/src/main.rs:1863 144 | msgid "Enforce signing of .gpg-id file: " 145 | msgstr "Tvinge signering av .gpg-id-fil: " 146 | 147 | #: cursive/src/helpers.rs:45 148 | msgid "Error" 149 | msgstr "Feil" 150 | 151 | #: cursive/src/main.rs:2274 cursive/src/wizard.rs:134 152 | msgid "F1: Menu | " 153 | msgstr "F1: Meny | " 154 | 155 | #: cursive/src/main.rs:333 156 | msgid "File History" 157 | msgstr "Filhistorikk" 158 | 159 | #: cursive/src/main.rs:2302 160 | msgid "File History (ctrl-h)" 161 | msgstr "Filhistorikk (ctrl-h)" 162 | 163 | #: cursive/src/main.rs:884 164 | msgid "Full" 165 | msgstr "Full" 166 | 167 | #: cursive/src/main.rs:1298 168 | msgid "GPG Download" 169 | msgstr "GPG nedlastning" 170 | 171 | #: cursive/src/main.rs:829 172 | msgid "GPG Key ID: " 173 | msgstr "GPG-nøkkel ID: " 174 | 175 | #: cursive/src/main.rs:443 cursive/src/main.rs:695 176 | msgid "Generate" 177 | msgstr "Generere" 178 | 179 | #: cursive/src/wizard.rs:83 180 | msgid "Git Init" 181 | msgstr "Git Init" 182 | 183 | #: cursive/src/main.rs:2334 184 | msgid "Git Pull (ctrl-f)" 185 | msgstr "Git Pull (ctrl-f)" 186 | 187 | #: cursive/src/main.rs:2340 188 | msgid "Git Push (ctrl-g)" 189 | msgstr "Git Push (ctrl-g)" 190 | 191 | #: cursive/src/main.rs:1254 192 | msgid "Import" 193 | msgstr "Importer" 194 | 195 | #: cursive/src/main.rs:2354 196 | msgid "Import PGP Certificate from text" 197 | msgstr "Importer PGP Certificate fra text" 198 | 199 | #: cursive/src/main.rs:1234 cursive/src/main.rs:1275 200 | msgid "Import Results" 201 | msgstr "Importresultater" 202 | 203 | #: cursive/src/wizard.rs:149 204 | msgid "Init" 205 | msgstr "Initier" 206 | 207 | #: cursive/src/wizard.rs:35 208 | msgid "Initialized password repo with Ripasso" 209 | msgstr "Opprettet en passordmappe med Ripasso" 210 | 211 | #: cursive/src/main.rs:423 cursive/src/main.rs:639 212 | msgid "" 213 | "It seems like you are trying to save a TOTP code to the password store. This " 214 | "will reduce your 2FA solution to just 1FA, do you want to proceed?" 215 | msgstr "" 216 | "Det virker som du prøver å lagre en TOTP-kode i passordlageret. Dette vil " 217 | "redusere 2FA-løsningen din til bare 1FA, vil du fortsette?" 218 | 219 | #: cursive/src/main.rs:2396 220 | msgid "Manage" 221 | msgstr "Behandle" 222 | 223 | #: cursive/src/main.rs:1252 224 | msgid "Manual GPG Import" 225 | msgstr "Manuell GPG-import" 226 | 227 | #: cursive/src/main.rs:885 228 | msgid "Marginal" 229 | msgstr "Ubetydelig" 230 | 231 | #: cursive/src/main.rs:1679 cursive/src/main.rs:1843 232 | msgid "Name: " 233 | msgstr "Navn: " 234 | 235 | #: cursive/src/main.rs:886 236 | msgid "Never" 237 | msgstr "Aldri" 238 | 239 | #: cursive/src/main.rs:529 240 | msgid "New file name: " 241 | msgstr "Nytt filnavn: " 242 | 243 | #: cursive/src/main.rs:1908 244 | msgid "New store config" 245 | msgstr "Ny passordmappe konfigurasjon" 246 | 247 | #: cursive/src/wizard.rs:80 248 | msgid "No" 249 | msgstr "Nei" 250 | 251 | #: cursive/src/main.rs:2069 252 | msgid "No home directory set" 253 | msgstr "Ingen hjemmekatalog satt" 254 | 255 | #: cursive/src/main.rs:898 256 | msgid "Not Usable" 257 | msgstr "Ikke Brukbar" 258 | 259 | #: cursive/src/main.rs:682 260 | msgid "Note: " 261 | msgstr "Notat: " 262 | 263 | #: cursive/src/helpers.rs:44 cursive/src/main.rs:334 cursive/src/main.rs:1001 264 | #: cursive/src/main.rs:1076 cursive/src/main.rs:1233 cursive/src/main.rs:1274 265 | #: cursive/src/main.rs:1980 266 | msgid "Ok" 267 | msgstr "Ok" 268 | 269 | #: cursive/src/main.rs:519 270 | msgid "Old file name: " 271 | msgstr "Gammelt filnavn: " 272 | 273 | #: cursive/src/main.rs:2296 274 | msgid "Open (ctrl-o)" 275 | msgstr "Åpne (ctrl-o)" 276 | 277 | #: cursive/src/main.rs:2281 278 | msgid "Operations" 279 | msgstr "Handlinger" 280 | 281 | #: cursive/src/main.rs:1726 282 | msgid "Own key fingerprint: " 283 | msgstr "Eget nøkkelfingeravtrykk: " 284 | 285 | #: cursive/src/main.rs:1712 cursive/src/main.rs:1870 286 | msgid "PGP Implementation: " 287 | msgstr "PGP-implementering: " 288 | 289 | #: cursive/src/main.rs:277 290 | msgid "Password deleted" 291 | msgstr "Passord slettet" 292 | 293 | #: cursive/src/main.rs:671 294 | msgid "Password: " 295 | msgstr "Passord: " 296 | 297 | #: cursive/src/main.rs:661 298 | msgid "Path: " 299 | msgstr "Søkesti: " 300 | 301 | #: cursive/src/main.rs:2347 302 | msgid "Pull PGP Certificates" 303 | msgstr "Laste ned PGP-sertifikater" 304 | 305 | #: cursive/src/main.rs:1218 306 | msgid "Pulled from remote git repository" 307 | msgstr "Hentet fra eksternt git-depot" 308 | 309 | #: cursive/src/main.rs:1182 310 | msgid "Pushed to remote git repository" 311 | msgstr "Sendt til eksternt git-depot" 312 | 313 | #: cursive/src/main.rs:2361 314 | msgid "Quit (esc)" 315 | msgstr "Avslutt (esc)" 316 | 317 | #: cursive/src/main.rs:545 318 | msgid "Rename" 319 | msgstr "Gi nytt navn" 320 | 321 | #: cursive/src/main.rs:544 322 | msgid "Rename File" 323 | msgstr "Angi nytt filnavn" 324 | 325 | #: cursive/src/main.rs:2320 326 | msgid "Rename file (ctrl-r)" 327 | msgstr "Angi nytt filnavn (ctrl-r)" 328 | 329 | #: cursive/src/wizard.rs:95 330 | msgid "" 331 | "Ripasso uses GPG in order to encrypt the stored passwords.\n" 332 | "Please enter your GPG key ID" 333 | msgstr "" 334 | "Ripasso bruker GPG for å kryptere de lagrede passordene.\n" 335 | "Vennligst oppgi din GPG-nøkkel ID" 336 | 337 | #: cursive/src/main.rs:416 cursive/src/main.rs:424 cursive/src/main.rs:640 338 | #: cursive/src/main.rs:701 cursive/src/main.rs:1773 cursive/src/main.rs:1909 339 | msgid "Save" 340 | msgstr "Lagre" 341 | 342 | #: cursive/src/main.rs:1746 cursive/src/main.rs:1888 343 | msgid "Store Members: " 344 | msgstr "Lagre Medlemmer: " 345 | 346 | #: cursive/src/main.rs:2399 347 | msgid "Stores" 348 | msgstr "Passordmapper" 349 | 350 | #: cursive/src/main.rs:1000 cursive/src/main.rs:1075 351 | msgid "Team Members" 352 | msgstr "Medlemmer" 353 | 354 | #: cursive/src/main.rs:2326 355 | msgid "Team Members (ctrl-v)" 356 | msgstr "Medlemmer (ctrl-v)" 357 | 358 | #: cursive/src/helpers.rs:37 359 | msgid "Team member with key id {} isn't in your GPG keyring, fetch it first" 360 | msgstr "" 361 | "Gruppemedlem med nøkkel id {} er ikke i din GPG nøkkelring, hent den først" 362 | 363 | #: cursive/src/main.rs:2150 364 | msgid "" 365 | "The password store is backed by a git repository, but there is passwords " 366 | "there that's not in git. Please add them, otherwise they might get lost." 367 | msgstr "" 368 | "Passordmappen er håndtert av et git-depot, men det er passord som ikke er " 369 | "sjekket inn i git-depoet ennå. Vennligst legg dem til, ellers kan de " 370 | "forsvinne." 371 | 372 | #: cursive/src/main.rs:883 373 | msgid "Ultimate" 374 | msgstr "Ultimate" 375 | 376 | #: cursive/src/wizard.rs:69 377 | msgid "Unable to write file" 378 | msgstr "Kunne ikke skrive til fil" 379 | 380 | #: cursive/src/main.rs:887 381 | msgid "Undefined" 382 | msgstr "Udefinert" 383 | 384 | #: cursive/src/main.rs:888 385 | msgid "Unknown" 386 | msgstr "Ukjent" 387 | 388 | #: cursive/src/main.rs:2047 cursive/src/main.rs:2055 389 | msgid "Unknown argument, usage: ripasso-cursive [-h|--help]" 390 | msgstr "Ukjent argument, bruk: ripasso-cursive [-h|--help]" 391 | 392 | #: cursive/src/main.rs:1589 cursive/src/main.rs:1634 cursive/src/main.rs:1823 393 | msgid "Updated config file" 394 | msgstr "Oppdatert konfigurasjonsfil" 395 | 396 | #: cursive/src/main.rs:382 397 | msgid "Updated password entry" 398 | msgstr "Oppdater passord" 399 | 400 | #: cursive/src/main.rs:900 401 | msgid "Usable" 402 | msgstr "Brukbar" 403 | 404 | #: cursive/src/wizard.rs:141 405 | msgid "" 406 | "Welcome to Ripasso, it seems like you don't have a password store directory " 407 | "yet would you like to create it?\n" 408 | "It's created in $HOME/.password-store or where the PASSWORD_STORE_DIR " 409 | "environmental variable points." 410 | msgstr "" 411 | "Velkommen til Ripasso! Vi kan ikke se at du har en passordmappe ennå, vil du " 412 | "opprette en?\n" 413 | "Den blir opprettet i $HOME/.password-store eller hvor miljøvariablen " 414 | "PASSWORD_STORE_DIR peker til." 415 | 416 | #: cursive/src/main.rs:274 cursive/src/main.rs:750 cursive/src/main.rs:856 417 | msgid "Yes" 418 | msgstr "Ja" 419 | 420 | #: cursive/src/main.rs:2144 421 | msgid "" 422 | "You haven't configured you name and email in git, doing so will make " 423 | "cooperation with your team easier, you can do it like this:\n" 424 | "git config --global user.name \"John Doe\"\n" 425 | "git config --global user.email \"email@example.com\"\n" 426 | "\n" 427 | "Also consider configuring git to sign your commits with GPG:\n" 428 | "git config --global user.signingkey 3AA5C34371567BD2\n" 429 | "git config --global commit.gpgsign true" 430 | msgstr "" 431 | "Du har ikke konfigurert navn og e-post adresse i git, å konfigurere dette " 432 | "vil gjøre samarbeidet med din gruppe enklere. Du kan gjøre det slik:\n" 433 | "git config --global user.name \"John Doe\"\n" 434 | "git config --global user.email \"email@example.com\"\n" 435 | "\n" 436 | "Vurder også om du skal konfigurere git til å signere dine commits med GPG:\n" 437 | "git config --global user.signingkey 3AA5C34371567BD2\n" 438 | "git config --global commit.gpgsign true" 439 | 440 | #: cursive/src/main.rs:1984 441 | msgid "ctrl-e: Edit | " 442 | msgstr "ctrl-e: Rediger | " 443 | 444 | #: cursive/src/main.rs:1006 cursive/src/main.rs:1081 cursive/src/main.rs:1986 445 | msgid "del: Remove" 446 | msgstr "del: Slett" 447 | 448 | #: cursive/src/main.rs:1005 cursive/src/main.rs:1080 cursive/src/main.rs:1985 449 | msgid "ins: Add | " 450 | msgstr "ins: Legg til | " 451 | 452 | #: cursive/src/main.rs:1113 cursive/src/main.rs:1135 453 | msgid "n/a" 454 | msgstr "i/t" 455 | 456 | #~ msgid "Valid Signing Keys: " 457 | #~ msgstr "Gyldige Signeringsnøkler " 458 | 459 | #~ msgid "People" 460 | #~ msgstr "Personer" 461 | -------------------------------------------------------------------------------- /cursive/res/nn.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: \n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2024-09-19 15:10+0200\n" 11 | "PO-Revision-Date: 2019-12-27 19:09+0100\n" 12 | "Last-Translator: Eivind Syvertsen \n" 13 | "Language-Team: \n" 14 | "Language: nn\n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "X-Generator: Poedit 2.0.6\n" 19 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 20 | 21 | #: cursive/src/main.rs:1166 22 | msgid "" 23 | "A password manager that uses the file format of the standard unix password " 24 | "manager 'pass', implemented in Rust. Ripasso reads $HOME/.password-store/ by " 25 | "default, override this by setting the PASSWORD_STORE_DIR environmental " 26 | "variable." 27 | msgstr "" 28 | "Ein passordhandsamar som nyttar det same filformatet som passordhandsamaren " 29 | "'pass', implementert i Rust. Ripasso les og lagrar passord i $HOME/.password-" 30 | "store/ som standardoppsett. For å lese frå ei anna mappe, sett " 31 | "miljøvariabelen PASSWORD_STORE_DIR." 32 | 33 | #: cursive/src/main.rs:694 34 | msgid "Add new password" 35 | msgstr "Legg til nytt passord" 36 | 37 | #: cursive/src/main.rs:810 38 | msgid "Added team member to password store" 39 | msgstr "La til gruppemedlem i passordlageret" 40 | 41 | #: cursive/src/wizard.rs:75 42 | msgid "Also create a git repository for the encrypted files?" 43 | msgstr "Opprett også eit git-depot for dei krypterte filene?" 44 | 45 | #: cursive/src/main.rs:272 46 | msgid "Are you sure you want to delete the password?" 47 | msgstr "Er du sikker du vil fjerne passordet?" 48 | 49 | #: cursive/src/main.rs:748 50 | msgid "Are you sure you want to remove this person?" 51 | msgstr "Er du sikker du vil fjerne denne personen?" 52 | 53 | #: cursive/src/main.rs:773 54 | msgid "" 55 | "Can't import team member due to that the GPG trust relationship level isn't " 56 | "Ultimate" 57 | msgstr "" 58 | 59 | #: cursive/src/main.rs:280 cursive/src/main.rs:550 cursive/src/main.rs:704 60 | #: cursive/src/main.rs:758 cursive/src/main.rs:862 cursive/src/main.rs:1253 61 | #: cursive/src/main.rs:1291 cursive/src/main.rs:1777 cursive/src/main.rs:1923 62 | #: cursive/src/wizard.rs:145 63 | msgid "Cancel" 64 | msgstr "Avbryt" 65 | 66 | #: cursive/src/main.rs:431 cursive/src/main.rs:450 cursive/src/main.rs:643 67 | msgid "Close" 68 | msgstr "" 69 | 70 | #: cursive/src/main.rs:212 71 | #, fuzzy 72 | msgid "Copied MFA code to copy buffer" 73 | msgstr "Passordet er kopiert til utklippstavla for 40 sekunder" 74 | 75 | #: cursive/src/main.rs:237 76 | #, fuzzy 77 | msgid "Copied file name to copy buffer" 78 | msgstr "Passordet er kopiert til utklippstavla for 40 sekunder" 79 | 80 | #: cursive/src/main.rs:187 81 | #, fuzzy 82 | msgid "Copied first line of password to copy buffer for 40 seconds" 83 | msgstr "Passordet er kopiert til utklippstavla for 40 sekunder" 84 | 85 | #: cursive/src/main.rs:158 86 | msgid "Copied password to copy buffer for 40 seconds" 87 | msgstr "Passordet er kopiert til utklippstavla for 40 sekunder" 88 | 89 | #: cursive/src/main.rs:2283 90 | msgid "Copy (ctrl-y)" 91 | msgstr "Kopier (ctrl-y)" 92 | 93 | #: cursive/src/main.rs:2290 94 | #, fuzzy 95 | msgid "Copy MFA Code (ctrl-b)" 96 | msgstr "Kopier (ctrl-y)" 97 | 98 | #: cursive/src/main.rs:2289 99 | #, fuzzy 100 | msgid "Copy Name (ctrl-u)" 101 | msgstr "Kopier (ctrl-y)" 102 | 103 | #: cursive/src/wizard.rs:77 cursive/src/wizard.rs:98 cursive/src/wizard.rs:142 104 | msgid "Create" 105 | msgstr "Opprett" 106 | 107 | #: cursive/src/main.rs:2308 108 | msgid "Create (ins) " 109 | msgstr "Opprett (ins) " 110 | 111 | #: cursive/src/main.rs:606 112 | msgid "Created new password" 113 | msgstr "Oppretta eit nytt passord" 114 | 115 | #: cursive/src/main.rs:2314 116 | msgid "Delete (del)" 117 | msgstr "Fjern (del)" 118 | 119 | #: cursive/src/main.rs:737 120 | msgid "Deleted team member from password store" 121 | msgstr "Fjerna gruppemedlem frå passordlageret" 122 | 123 | #: cursive/src/main.rs:840 cursive/src/main.rs:1690 cursive/src/main.rs:1853 124 | msgid "Directory: " 125 | msgstr "" 126 | 127 | #: cursive/src/main.rs:1292 128 | msgid "Download" 129 | msgstr "" 130 | 131 | #: cursive/src/main.rs:1289 132 | msgid "" 133 | "Download pgp data from keys.openpgp.org and import them into your key ring?" 134 | msgstr "" 135 | 136 | #: cursive/src/main.rs:1979 137 | #, fuzzy 138 | msgid "Edit password stores" 139 | msgstr "La til gruppemedlem i passordlageret" 140 | 141 | #: cursive/src/main.rs:1772 142 | msgid "Edit store config" 143 | msgstr "" 144 | 145 | #: cursive/src/main.rs:1701 cursive/src/main.rs:1863 146 | msgid "Enforce signing of .gpg-id file: " 147 | msgstr "" 148 | 149 | #: cursive/src/helpers.rs:45 150 | msgid "Error" 151 | msgstr "Feil" 152 | 153 | #: cursive/src/main.rs:2274 cursive/src/wizard.rs:134 154 | msgid "F1: Menu | " 155 | msgstr "F1: Meny | " 156 | 157 | #: cursive/src/main.rs:333 158 | msgid "File History" 159 | msgstr "" 160 | 161 | #: cursive/src/main.rs:2302 162 | msgid "File History (ctrl-h)" 163 | msgstr "" 164 | 165 | #: cursive/src/main.rs:884 166 | msgid "Full" 167 | msgstr "" 168 | 169 | #: cursive/src/main.rs:1298 170 | msgid "GPG Download" 171 | msgstr "" 172 | 173 | #: cursive/src/main.rs:829 174 | msgid "GPG Key ID: " 175 | msgstr "GPG-nøkkel-ID: " 176 | 177 | #: cursive/src/main.rs:443 cursive/src/main.rs:695 178 | msgid "Generate" 179 | msgstr "Generer" 180 | 181 | #: cursive/src/wizard.rs:83 182 | msgid "Git Init" 183 | msgstr "Git Init" 184 | 185 | #: cursive/src/main.rs:2334 186 | msgid "Git Pull (ctrl-f)" 187 | msgstr "Git Pull (ctrl-f)" 188 | 189 | #: cursive/src/main.rs:2340 190 | msgid "Git Push (ctrl-g)" 191 | msgstr "Git Push (ctrl-g)" 192 | 193 | #: cursive/src/main.rs:1254 194 | msgid "Import" 195 | msgstr "" 196 | 197 | #: cursive/src/main.rs:2354 198 | msgid "Import PGP Certificate from text" 199 | msgstr "" 200 | 201 | #: cursive/src/main.rs:1234 cursive/src/main.rs:1275 202 | msgid "Import Results" 203 | msgstr "" 204 | 205 | #: cursive/src/wizard.rs:149 206 | msgid "Init" 207 | msgstr "Initialiser" 208 | 209 | #: cursive/src/wizard.rs:35 210 | msgid "Initialized password repo with Ripasso" 211 | msgstr "Oppretta eit passordlager med Ripasso" 212 | 213 | #: cursive/src/main.rs:423 cursive/src/main.rs:639 214 | msgid "" 215 | "It seems like you are trying to save a TOTP code to the password store. This " 216 | "will reduce your 2FA solution to just 1FA, do you want to proceed?" 217 | msgstr "" 218 | 219 | #: cursive/src/main.rs:2396 220 | msgid "Manage" 221 | msgstr "" 222 | 223 | #: cursive/src/main.rs:1252 224 | msgid "Manual GPG Import" 225 | msgstr "" 226 | 227 | #: cursive/src/main.rs:885 228 | msgid "Marginal" 229 | msgstr "" 230 | 231 | #: cursive/src/main.rs:1679 cursive/src/main.rs:1843 232 | msgid "Name: " 233 | msgstr "" 234 | 235 | #: cursive/src/main.rs:886 236 | msgid "Never" 237 | msgstr "" 238 | 239 | #: cursive/src/main.rs:529 240 | msgid "New file name: " 241 | msgstr "" 242 | 243 | #: cursive/src/main.rs:1908 244 | msgid "New store config" 245 | msgstr "" 246 | 247 | #: cursive/src/wizard.rs:80 248 | msgid "No" 249 | msgstr "Nei" 250 | 251 | #: cursive/src/main.rs:2069 252 | msgid "No home directory set" 253 | msgstr "" 254 | 255 | #: cursive/src/main.rs:898 256 | msgid "Not Usable" 257 | msgstr "" 258 | 259 | #: cursive/src/main.rs:682 260 | msgid "Note: " 261 | msgstr "" 262 | 263 | #: cursive/src/helpers.rs:44 cursive/src/main.rs:334 cursive/src/main.rs:1001 264 | #: cursive/src/main.rs:1076 cursive/src/main.rs:1233 cursive/src/main.rs:1274 265 | #: cursive/src/main.rs:1980 266 | msgid "Ok" 267 | msgstr "Ok" 268 | 269 | #: cursive/src/main.rs:519 270 | msgid "Old file name: " 271 | msgstr "" 272 | 273 | #: cursive/src/main.rs:2296 274 | msgid "Open (ctrl-o)" 275 | msgstr "Opne (ctrl-o)" 276 | 277 | #: cursive/src/main.rs:2281 278 | msgid "Operations" 279 | msgstr "Handlingar" 280 | 281 | #: cursive/src/main.rs:1726 282 | msgid "Own key fingerprint: " 283 | msgstr "" 284 | 285 | #: cursive/src/main.rs:1712 cursive/src/main.rs:1870 286 | msgid "PGP Implementation: " 287 | msgstr "" 288 | 289 | #: cursive/src/main.rs:277 290 | msgid "Password deleted" 291 | msgstr "Passordet blei fjerna" 292 | 293 | #: cursive/src/main.rs:671 294 | msgid "Password: " 295 | msgstr "Passord: " 296 | 297 | #: cursive/src/main.rs:661 298 | msgid "Path: " 299 | msgstr "Søkesti: " 300 | 301 | #: cursive/src/main.rs:2347 302 | msgid "Pull PGP Certificates" 303 | msgstr "" 304 | 305 | #: cursive/src/main.rs:1218 306 | msgid "Pulled from remote git repository" 307 | msgstr "Henta frå eksternt git-depot" 308 | 309 | #: cursive/src/main.rs:1182 310 | msgid "Pushed to remote git repository" 311 | msgstr "Sende til eksternt git-depot" 312 | 313 | #: cursive/src/main.rs:2361 314 | msgid "Quit (esc)" 315 | msgstr "Avslutt (esc)" 316 | 317 | #: cursive/src/main.rs:545 318 | msgid "Rename" 319 | msgstr "" 320 | 321 | #: cursive/src/main.rs:544 322 | msgid "Rename File" 323 | msgstr "" 324 | 325 | #: cursive/src/main.rs:2320 326 | #, fuzzy 327 | msgid "Rename file (ctrl-r)" 328 | msgstr "Gruppemedlemmar (ctrl-v)" 329 | 330 | #: cursive/src/wizard.rs:95 331 | msgid "" 332 | "Ripasso uses GPG in order to encrypt the stored passwords.\n" 333 | "Please enter your GPG key ID" 334 | msgstr "" 335 | "Ripasso nyttar GPG for å kryptere dei lagra passorda.\n" 336 | "Ver venleg og oppgje GPG-nøkkel-ID-en din" 337 | 338 | #: cursive/src/main.rs:416 cursive/src/main.rs:424 cursive/src/main.rs:640 339 | #: cursive/src/main.rs:701 cursive/src/main.rs:1773 cursive/src/main.rs:1909 340 | msgid "Save" 341 | msgstr "Lagre" 342 | 343 | #: cursive/src/main.rs:1746 cursive/src/main.rs:1888 344 | #, fuzzy 345 | msgid "Store Members: " 346 | msgstr "Gruppemedlemmar" 347 | 348 | #: cursive/src/main.rs:2399 349 | msgid "Stores" 350 | msgstr "" 351 | 352 | #: cursive/src/main.rs:1000 cursive/src/main.rs:1075 353 | msgid "Team Members" 354 | msgstr "Gruppemedlemmar" 355 | 356 | #: cursive/src/main.rs:2326 357 | msgid "Team Members (ctrl-v)" 358 | msgstr "Gruppemedlemmar (ctrl-v)" 359 | 360 | #: cursive/src/helpers.rs:37 361 | msgid "Team member with key id {} isn't in your GPG keyring, fetch it first" 362 | msgstr "" 363 | 364 | #: cursive/src/main.rs:2150 365 | msgid "" 366 | "The password store is backed by a git repository, but there is passwords " 367 | "there that's not in git. Please add them, otherwise they might get lost." 368 | msgstr "" 369 | 370 | #: cursive/src/main.rs:883 371 | msgid "Ultimate" 372 | msgstr "" 373 | 374 | #: cursive/src/wizard.rs:69 375 | msgid "Unable to write file" 376 | msgstr "Klarte ikkje å skrive fila" 377 | 378 | #: cursive/src/main.rs:887 379 | msgid "Undefined" 380 | msgstr "" 381 | 382 | #: cursive/src/main.rs:888 383 | msgid "Unknown" 384 | msgstr "" 385 | 386 | #: cursive/src/main.rs:2047 cursive/src/main.rs:2055 387 | msgid "Unknown argument, usage: ripasso-cursive [-h|--help]" 388 | msgstr "" 389 | 390 | #: cursive/src/main.rs:1589 cursive/src/main.rs:1634 cursive/src/main.rs:1823 391 | msgid "Updated config file" 392 | msgstr "" 393 | 394 | #: cursive/src/main.rs:382 395 | #, fuzzy 396 | msgid "Updated password entry" 397 | msgstr "Oppretta eit nytt passord" 398 | 399 | #: cursive/src/main.rs:900 400 | msgid "Usable" 401 | msgstr "" 402 | 403 | #: cursive/src/wizard.rs:141 404 | #, fuzzy 405 | msgid "" 406 | "Welcome to Ripasso, it seems like you don't have a password store directory " 407 | "yet would you like to create it?\n" 408 | "It's created in $HOME/.password-store or where the PASSWORD_STORE_DIR " 409 | "environmental variable points." 410 | msgstr "" 411 | "Velkomen til Ripasso! Det ser ut som du ikkje har noka mappe for " 412 | "passordlageret enno, vil du opprette ei?" 413 | 414 | #: cursive/src/main.rs:274 cursive/src/main.rs:750 cursive/src/main.rs:856 415 | msgid "Yes" 416 | msgstr "Ja" 417 | 418 | #: cursive/src/main.rs:2144 419 | msgid "" 420 | "You haven't configured you name and email in git, doing so will make " 421 | "cooperation with your team easier, you can do it like this:\n" 422 | "git config --global user.name \"John Doe\"\n" 423 | "git config --global user.email \"email@example.com\"\n" 424 | "\n" 425 | "Also consider configuring git to sign your commits with GPG:\n" 426 | "git config --global user.signingkey 3AA5C34371567BD2\n" 427 | "git config --global commit.gpgsign true" 428 | msgstr "" 429 | 430 | #: cursive/src/main.rs:1984 431 | msgid "ctrl-e: Edit | " 432 | msgstr "" 433 | 434 | #: cursive/src/main.rs:1006 cursive/src/main.rs:1081 cursive/src/main.rs:1986 435 | msgid "del: Remove" 436 | msgstr "del: Fjern" 437 | 438 | #: cursive/src/main.rs:1005 cursive/src/main.rs:1080 cursive/src/main.rs:1985 439 | msgid "ins: Add | " 440 | msgstr "ins: Legg til | " 441 | 442 | #: cursive/src/main.rs:1113 cursive/src/main.rs:1135 443 | msgid "n/a" 444 | msgstr "i/t" 445 | -------------------------------------------------------------------------------- /cursive/res/ripasso-cursive.pot: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: PACKAGE VERSION\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2024-09-19 15:10+0200\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "Language: \n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=CHARSET\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | 20 | #: cursive/src/main.rs:1166 21 | msgid "" 22 | "A password manager that uses the file format of the standard unix password " 23 | "manager 'pass', implemented in Rust. Ripasso reads $HOME/.password-store/ by " 24 | "default, override this by setting the PASSWORD_STORE_DIR environmental " 25 | "variable." 26 | msgstr "" 27 | 28 | #: cursive/src/main.rs:694 29 | msgid "Add new password" 30 | msgstr "" 31 | 32 | #: cursive/src/main.rs:810 33 | msgid "Added team member to password store" 34 | msgstr "" 35 | 36 | #: cursive/src/wizard.rs:75 37 | msgid "Also create a git repository for the encrypted files?" 38 | msgstr "" 39 | 40 | #: cursive/src/main.rs:272 41 | msgid "Are you sure you want to delete the password?" 42 | msgstr "" 43 | 44 | #: cursive/src/main.rs:748 45 | msgid "Are you sure you want to remove this person?" 46 | msgstr "" 47 | 48 | #: cursive/src/main.rs:773 49 | msgid "" 50 | "Can't import team member due to that the GPG trust relationship level isn't " 51 | "Ultimate" 52 | msgstr "" 53 | 54 | #: cursive/src/main.rs:280 cursive/src/main.rs:550 cursive/src/main.rs:704 55 | #: cursive/src/main.rs:758 cursive/src/main.rs:862 cursive/src/main.rs:1253 56 | #: cursive/src/main.rs:1291 cursive/src/main.rs:1777 cursive/src/main.rs:1923 57 | #: cursive/src/wizard.rs:145 58 | msgid "Cancel" 59 | msgstr "" 60 | 61 | #: cursive/src/main.rs:431 cursive/src/main.rs:450 cursive/src/main.rs:643 62 | msgid "Close" 63 | msgstr "" 64 | 65 | #: cursive/src/main.rs:212 66 | msgid "Copied MFA code to copy buffer" 67 | msgstr "" 68 | 69 | #: cursive/src/main.rs:237 70 | msgid "Copied file name to copy buffer" 71 | msgstr "" 72 | 73 | #: cursive/src/main.rs:187 74 | msgid "Copied first line of password to copy buffer for 40 seconds" 75 | msgstr "" 76 | 77 | #: cursive/src/main.rs:158 78 | msgid "Copied password to copy buffer for 40 seconds" 79 | msgstr "" 80 | 81 | #: cursive/src/main.rs:2283 82 | msgid "Copy (ctrl-y)" 83 | msgstr "" 84 | 85 | #: cursive/src/main.rs:2290 86 | msgid "Copy MFA Code (ctrl-b)" 87 | msgstr "" 88 | 89 | #: cursive/src/main.rs:2289 90 | msgid "Copy Name (ctrl-u)" 91 | msgstr "" 92 | 93 | #: cursive/src/wizard.rs:77 cursive/src/wizard.rs:98 cursive/src/wizard.rs:142 94 | msgid "Create" 95 | msgstr "" 96 | 97 | #: cursive/src/main.rs:2308 98 | msgid "Create (ins) " 99 | msgstr "" 100 | 101 | #: cursive/src/main.rs:606 102 | msgid "Created new password" 103 | msgstr "" 104 | 105 | #: cursive/src/main.rs:2314 106 | msgid "Delete (del)" 107 | msgstr "" 108 | 109 | #: cursive/src/main.rs:737 110 | msgid "Deleted team member from password store" 111 | msgstr "" 112 | 113 | #: cursive/src/main.rs:840 cursive/src/main.rs:1690 cursive/src/main.rs:1853 114 | msgid "Directory: " 115 | msgstr "" 116 | 117 | #: cursive/src/main.rs:1292 118 | msgid "Download" 119 | msgstr "" 120 | 121 | #: cursive/src/main.rs:1289 122 | msgid "" 123 | "Download pgp data from keys.openpgp.org and import them into your key ring?" 124 | msgstr "" 125 | 126 | #: cursive/src/main.rs:1979 127 | msgid "Edit password stores" 128 | msgstr "" 129 | 130 | #: cursive/src/main.rs:1772 131 | msgid "Edit store config" 132 | msgstr "" 133 | 134 | #: cursive/src/main.rs:1701 cursive/src/main.rs:1863 135 | msgid "Enforce signing of .gpg-id file: " 136 | msgstr "" 137 | 138 | #: cursive/src/helpers.rs:45 139 | msgid "Error" 140 | msgstr "" 141 | 142 | #: cursive/src/main.rs:2274 cursive/src/wizard.rs:134 143 | msgid "F1: Menu | " 144 | msgstr "" 145 | 146 | #: cursive/src/main.rs:333 147 | msgid "File History" 148 | msgstr "" 149 | 150 | #: cursive/src/main.rs:2302 151 | msgid "File History (ctrl-h)" 152 | msgstr "" 153 | 154 | #: cursive/src/main.rs:884 155 | msgid "Full" 156 | msgstr "" 157 | 158 | #: cursive/src/main.rs:1298 159 | msgid "GPG Download" 160 | msgstr "" 161 | 162 | #: cursive/src/main.rs:829 163 | msgid "GPG Key ID: " 164 | msgstr "" 165 | 166 | #: cursive/src/main.rs:443 cursive/src/main.rs:695 167 | msgid "Generate" 168 | msgstr "" 169 | 170 | #: cursive/src/wizard.rs:83 171 | msgid "Git Init" 172 | msgstr "" 173 | 174 | #: cursive/src/main.rs:2334 175 | msgid "Git Pull (ctrl-f)" 176 | msgstr "" 177 | 178 | #: cursive/src/main.rs:2340 179 | msgid "Git Push (ctrl-g)" 180 | msgstr "" 181 | 182 | #: cursive/src/main.rs:1254 183 | msgid "Import" 184 | msgstr "" 185 | 186 | #: cursive/src/main.rs:2354 187 | msgid "Import PGP Certificate from text" 188 | msgstr "" 189 | 190 | #: cursive/src/main.rs:1234 cursive/src/main.rs:1275 191 | msgid "Import Results" 192 | msgstr "" 193 | 194 | #: cursive/src/wizard.rs:149 195 | msgid "Init" 196 | msgstr "" 197 | 198 | #: cursive/src/wizard.rs:35 199 | msgid "Initialized password repo with Ripasso" 200 | msgstr "" 201 | 202 | #: cursive/src/main.rs:423 cursive/src/main.rs:639 203 | msgid "" 204 | "It seems like you are trying to save a TOTP code to the password store. This " 205 | "will reduce your 2FA solution to just 1FA, do you want to proceed?" 206 | msgstr "" 207 | 208 | #: cursive/src/main.rs:2396 209 | msgid "Manage" 210 | msgstr "" 211 | 212 | #: cursive/src/main.rs:1252 213 | msgid "Manual GPG Import" 214 | msgstr "" 215 | 216 | #: cursive/src/main.rs:885 217 | msgid "Marginal" 218 | msgstr "" 219 | 220 | #: cursive/src/main.rs:1679 cursive/src/main.rs:1843 221 | msgid "Name: " 222 | msgstr "" 223 | 224 | #: cursive/src/main.rs:886 225 | msgid "Never" 226 | msgstr "" 227 | 228 | #: cursive/src/main.rs:529 229 | msgid "New file name: " 230 | msgstr "" 231 | 232 | #: cursive/src/main.rs:1908 233 | msgid "New store config" 234 | msgstr "" 235 | 236 | #: cursive/src/wizard.rs:80 237 | msgid "No" 238 | msgstr "" 239 | 240 | #: cursive/src/main.rs:2069 241 | msgid "No home directory set" 242 | msgstr "" 243 | 244 | #: cursive/src/main.rs:898 245 | msgid "Not Usable" 246 | msgstr "" 247 | 248 | #: cursive/src/main.rs:682 249 | msgid "Note: " 250 | msgstr "" 251 | 252 | #: cursive/src/helpers.rs:44 cursive/src/main.rs:334 cursive/src/main.rs:1001 253 | #: cursive/src/main.rs:1076 cursive/src/main.rs:1233 cursive/src/main.rs:1274 254 | #: cursive/src/main.rs:1980 255 | msgid "Ok" 256 | msgstr "" 257 | 258 | #: cursive/src/main.rs:519 259 | msgid "Old file name: " 260 | msgstr "" 261 | 262 | #: cursive/src/main.rs:2296 263 | msgid "Open (ctrl-o)" 264 | msgstr "" 265 | 266 | #: cursive/src/main.rs:2281 267 | msgid "Operations" 268 | msgstr "" 269 | 270 | #: cursive/src/main.rs:1726 271 | msgid "Own key fingerprint: " 272 | msgstr "" 273 | 274 | #: cursive/src/main.rs:1712 cursive/src/main.rs:1870 275 | msgid "PGP Implementation: " 276 | msgstr "" 277 | 278 | #: cursive/src/main.rs:277 279 | msgid "Password deleted" 280 | msgstr "" 281 | 282 | #: cursive/src/main.rs:671 283 | msgid "Password: " 284 | msgstr "" 285 | 286 | #: cursive/src/main.rs:661 287 | msgid "Path: " 288 | msgstr "" 289 | 290 | #: cursive/src/main.rs:2347 291 | msgid "Pull PGP Certificates" 292 | msgstr "" 293 | 294 | #: cursive/src/main.rs:1218 295 | msgid "Pulled from remote git repository" 296 | msgstr "" 297 | 298 | #: cursive/src/main.rs:1182 299 | msgid "Pushed to remote git repository" 300 | msgstr "" 301 | 302 | #: cursive/src/main.rs:2361 303 | msgid "Quit (esc)" 304 | msgstr "" 305 | 306 | #: cursive/src/main.rs:545 307 | msgid "Rename" 308 | msgstr "" 309 | 310 | #: cursive/src/main.rs:544 311 | msgid "Rename File" 312 | msgstr "" 313 | 314 | #: cursive/src/main.rs:2320 315 | msgid "Rename file (ctrl-r)" 316 | msgstr "" 317 | 318 | #: cursive/src/wizard.rs:95 319 | msgid "" 320 | "Ripasso uses GPG in order to encrypt the stored passwords.\n" 321 | "Please enter your GPG key ID" 322 | msgstr "" 323 | 324 | #: cursive/src/main.rs:416 cursive/src/main.rs:424 cursive/src/main.rs:640 325 | #: cursive/src/main.rs:701 cursive/src/main.rs:1773 cursive/src/main.rs:1909 326 | msgid "Save" 327 | msgstr "" 328 | 329 | #: cursive/src/main.rs:1746 cursive/src/main.rs:1888 330 | msgid "Store Members: " 331 | msgstr "" 332 | 333 | #: cursive/src/main.rs:2399 334 | msgid "Stores" 335 | msgstr "" 336 | 337 | #: cursive/src/main.rs:1000 cursive/src/main.rs:1075 338 | msgid "Team Members" 339 | msgstr "" 340 | 341 | #: cursive/src/main.rs:2326 342 | msgid "Team Members (ctrl-v)" 343 | msgstr "" 344 | 345 | #: cursive/src/helpers.rs:37 346 | msgid "Team member with key id {} isn't in your GPG keyring, fetch it first" 347 | msgstr "" 348 | 349 | #: cursive/src/main.rs:2150 350 | msgid "" 351 | "The password store is backed by a git repository, but there is passwords " 352 | "there that's not in git. Please add them, otherwise they might get lost." 353 | msgstr "" 354 | 355 | #: cursive/src/main.rs:883 356 | msgid "Ultimate" 357 | msgstr "" 358 | 359 | #: cursive/src/wizard.rs:69 360 | msgid "Unable to write file" 361 | msgstr "" 362 | 363 | #: cursive/src/main.rs:887 364 | msgid "Undefined" 365 | msgstr "" 366 | 367 | #: cursive/src/main.rs:888 368 | msgid "Unknown" 369 | msgstr "" 370 | 371 | #: cursive/src/main.rs:2047 cursive/src/main.rs:2055 372 | msgid "Unknown argument, usage: ripasso-cursive [-h|--help]" 373 | msgstr "" 374 | 375 | #: cursive/src/main.rs:1589 cursive/src/main.rs:1634 cursive/src/main.rs:1823 376 | msgid "Updated config file" 377 | msgstr "" 378 | 379 | #: cursive/src/main.rs:382 380 | msgid "Updated password entry" 381 | msgstr "" 382 | 383 | #: cursive/src/main.rs:900 384 | msgid "Usable" 385 | msgstr "" 386 | 387 | #: cursive/src/wizard.rs:141 388 | msgid "" 389 | "Welcome to Ripasso, it seems like you don't have a password store directory " 390 | "yet would you like to create it?\n" 391 | "It's created in $HOME/.password-store or where the PASSWORD_STORE_DIR " 392 | "environmental variable points." 393 | msgstr "" 394 | 395 | #: cursive/src/main.rs:274 cursive/src/main.rs:750 cursive/src/main.rs:856 396 | msgid "Yes" 397 | msgstr "" 398 | 399 | #: cursive/src/main.rs:2144 400 | msgid "" 401 | "You haven't configured you name and email in git, doing so will make " 402 | "cooperation with your team easier, you can do it like this:\n" 403 | "git config --global user.name \"John Doe\"\n" 404 | "git config --global user.email \"email@example.com\"\n" 405 | "\n" 406 | "Also consider configuring git to sign your commits with GPG:\n" 407 | "git config --global user.signingkey 3AA5C34371567BD2\n" 408 | "git config --global commit.gpgsign true" 409 | msgstr "" 410 | 411 | #: cursive/src/main.rs:1984 412 | msgid "ctrl-e: Edit | " 413 | msgstr "" 414 | 415 | #: cursive/src/main.rs:1006 cursive/src/main.rs:1081 cursive/src/main.rs:1986 416 | msgid "del: Remove" 417 | msgstr "" 418 | 419 | #: cursive/src/main.rs:1005 cursive/src/main.rs:1080 cursive/src/main.rs:1985 420 | msgid "ins: Add | " 421 | msgstr "" 422 | 423 | #: cursive/src/main.rs:1113 cursive/src/main.rs:1135 424 | msgid "n/a" 425 | msgstr "" 426 | -------------------------------------------------------------------------------- /cursive/res/ru.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: \n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2024-09-19 15:10+0200\n" 11 | "PO-Revision-Date: 2023-02-16 14:28+0100\n" 12 | "Last-Translator: \n" 13 | "Language-Team: \n" 14 | "Language: ru_RU\n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " 19 | "n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n" 20 | "X-Generator: Poedit 3.2.2\n" 21 | 22 | #: cursive/src/main.rs:1166 23 | msgid "" 24 | "A password manager that uses the file format of the standard unix password " 25 | "manager 'pass', implemented in Rust. Ripasso reads $HOME/.password-store/ by " 26 | "default, override this by setting the PASSWORD_STORE_DIR environmental " 27 | "variable." 28 | msgstr "" 29 | "Менеджер паролей, который использует формат файла стандартного менеджера " 30 | "паролей unix «pass», реализованный в Rust. Ripasso по умолчанию читает " 31 | "$HOME/.password-store/. Переопределите это, установив переменную окружения " 32 | "PASSWORD_STORE_DIR." 33 | 34 | #: cursive/src/main.rs:694 35 | msgid "Add new password" 36 | msgstr "Добавить новый пароль" 37 | 38 | #: cursive/src/main.rs:810 39 | msgid "Added team member to password store" 40 | msgstr "Добавить члена команды в хранилище паролей" 41 | 42 | #: cursive/src/wizard.rs:75 43 | msgid "Also create a git repository for the encrypted files?" 44 | msgstr "Также создать git-репозиторий для зашифрованных файлов?" 45 | 46 | #: cursive/src/main.rs:272 47 | msgid "Are you sure you want to delete the password?" 48 | msgstr "Вы уверены, что хотите удалить пароль?" 49 | 50 | #: cursive/src/main.rs:748 51 | msgid "Are you sure you want to remove this person?" 52 | msgstr "Вы уверены, что хотите удалить этого человека?" 53 | 54 | #: cursive/src/main.rs:773 55 | msgid "" 56 | "Can't import team member due to that the GPG trust relationship level isn't " 57 | "Ultimate" 58 | msgstr "" 59 | "Невозможно импортировать члена команды из-за того, что уровень доверительных " 60 | "отношений GPG не является Ultimate" 61 | 62 | #: cursive/src/main.rs:280 cursive/src/main.rs:550 cursive/src/main.rs:704 63 | #: cursive/src/main.rs:758 cursive/src/main.rs:862 cursive/src/main.rs:1253 64 | #: cursive/src/main.rs:1291 cursive/src/main.rs:1777 cursive/src/main.rs:1923 65 | #: cursive/src/wizard.rs:145 66 | msgid "Cancel" 67 | msgstr "Отмена" 68 | 69 | #: cursive/src/main.rs:431 cursive/src/main.rs:450 cursive/src/main.rs:643 70 | msgid "Close" 71 | msgstr "Закрыть" 72 | 73 | #: cursive/src/main.rs:212 74 | msgid "Copied MFA code to copy buffer" 75 | msgstr "Скопированный код MFA успешно копирован в буфер" 76 | 77 | #: cursive/src/main.rs:237 78 | msgid "Copied file name to copy buffer" 79 | msgstr "Скопированное имя файла успешно копирован в буфер" 80 | 81 | #: cursive/src/main.rs:187 82 | #, fuzzy 83 | msgid "Copied first line of password to copy buffer for 40 seconds" 84 | msgstr "Скопирован пароль в буфер на 40 секунд" 85 | 86 | #: cursive/src/main.rs:158 87 | msgid "Copied password to copy buffer for 40 seconds" 88 | msgstr "Скопирован пароль в буфер на 40 секунд" 89 | 90 | #: cursive/src/main.rs:2283 91 | msgid "Copy (ctrl-y)" 92 | msgstr "Копировать (ctrl-y)" 93 | 94 | #: cursive/src/main.rs:2290 95 | msgid "Copy MFA Code (ctrl-b)" 96 | msgstr "Копировать код MFA (ctrl-b)" 97 | 98 | #: cursive/src/main.rs:2289 99 | msgid "Copy Name (ctrl-u)" 100 | msgstr "Копировать имя (ctrl-u)" 101 | 102 | #: cursive/src/wizard.rs:77 cursive/src/wizard.rs:98 cursive/src/wizard.rs:142 103 | msgid "Create" 104 | msgstr "Создать" 105 | 106 | #: cursive/src/main.rs:2308 107 | msgid "Create (ins) " 108 | msgstr "Создать (ins) " 109 | 110 | #: cursive/src/main.rs:606 111 | msgid "Created new password" 112 | msgstr "Создать новый пароль" 113 | 114 | #: cursive/src/main.rs:2314 115 | msgid "Delete (del)" 116 | msgstr "Удалить (del)" 117 | 118 | #: cursive/src/main.rs:737 119 | msgid "Deleted team member from password store" 120 | msgstr "Удалить члена команды из хранилища паролей" 121 | 122 | #: cursive/src/main.rs:840 cursive/src/main.rs:1690 cursive/src/main.rs:1853 123 | msgid "Directory: " 124 | msgstr "Каталог: " 125 | 126 | #: cursive/src/main.rs:1292 127 | msgid "Download" 128 | msgstr "Скачать" 129 | 130 | #: cursive/src/main.rs:1289 131 | msgid "" 132 | "Download pgp data from keys.openpgp.org and import them into your key ring?" 133 | msgstr "" 134 | "Скачать данные pgp с keys.openpgp.org и импортировать их в Вашу связку " 135 | "ключей?" 136 | 137 | #: cursive/src/main.rs:1979 138 | msgid "Edit password stores" 139 | msgstr "Отредактировать хранилище паролей" 140 | 141 | #: cursive/src/main.rs:1772 142 | msgid "Edit store config" 143 | msgstr "Изменить конфигурацию хранилища" 144 | 145 | #: cursive/src/main.rs:1701 cursive/src/main.rs:1863 146 | msgid "Enforce signing of .gpg-id file: " 147 | msgstr "Принудительно подписать файл .gpg-id: " 148 | 149 | #: cursive/src/helpers.rs:45 150 | msgid "Error" 151 | msgstr "Ошибка" 152 | 153 | #: cursive/src/main.rs:2274 cursive/src/wizard.rs:134 154 | msgid "F1: Menu | " 155 | msgstr "F1: Меню | " 156 | 157 | #: cursive/src/main.rs:333 158 | msgid "File History" 159 | msgstr "История файла" 160 | 161 | #: cursive/src/main.rs:2302 162 | msgid "File History (ctrl-h)" 163 | msgstr "История файла" 164 | 165 | #: cursive/src/main.rs:884 166 | msgid "Full" 167 | msgstr "Полное доверие" 168 | 169 | #: cursive/src/main.rs:1298 170 | msgid "GPG Download" 171 | msgstr "Загрузить GPG" 172 | 173 | #: cursive/src/main.rs:829 174 | msgid "GPG Key ID: " 175 | msgstr "Идентификатор ключа GPG: " 176 | 177 | #: cursive/src/main.rs:443 cursive/src/main.rs:695 178 | msgid "Generate" 179 | msgstr "Генерировать" 180 | 181 | #: cursive/src/wizard.rs:83 182 | msgid "Git Init" 183 | msgstr "Git-инициализация" 184 | 185 | #: cursive/src/main.rs:2334 186 | msgid "Git Pull (ctrl-f)" 187 | msgstr "Git Скачивали (ctrl-f)" 188 | 189 | #: cursive/src/main.rs:2340 190 | msgid "Git Push (ctrl-g)" 191 | msgstr "Git Загрузка (ctrl-g)" 192 | 193 | #: cursive/src/main.rs:1254 194 | msgid "Import" 195 | msgstr "Импортировать" 196 | 197 | #: cursive/src/main.rs:2354 198 | msgid "Import PGP Certificate from text" 199 | msgstr "Импорт сертификата PGP из текста" 200 | 201 | #: cursive/src/main.rs:1234 cursive/src/main.rs:1275 202 | msgid "Import Results" 203 | msgstr "Импортировать рузальтаты" 204 | 205 | #: cursive/src/wizard.rs:149 206 | msgid "Init" 207 | msgstr "Инициализация" 208 | 209 | #: cursive/src/wizard.rs:35 210 | msgid "Initialized password repo with Ripasso" 211 | msgstr "Инициализированно хранилище паролей с помощью Ripasso" 212 | 213 | #: cursive/src/main.rs:423 cursive/src/main.rs:639 214 | msgid "" 215 | "It seems like you are trying to save a TOTP code to the password store. This " 216 | "will reduce your 2FA solution to just 1FA, do you want to proceed?" 217 | msgstr "" 218 | "Похоже, вы пытаетесь сохранить код TOTP в хранилище паролей. Это уменьшит " 219 | "ваше решение 2FA до 1FA. Хотите продолжить?" 220 | 221 | #: cursive/src/main.rs:2396 222 | msgid "Manage" 223 | msgstr "Управление" 224 | 225 | #: cursive/src/main.rs:1252 226 | msgid "Manual GPG Import" 227 | msgstr "Ручной импорт GPG" 228 | 229 | #: cursive/src/main.rs:885 230 | msgid "Marginal" 231 | msgstr "Частичное доверие" 232 | 233 | #: cursive/src/main.rs:1679 cursive/src/main.rs:1843 234 | msgid "Name: " 235 | msgstr "Имя: " 236 | 237 | #: cursive/src/main.rs:886 238 | msgid "Never" 239 | msgstr "Никогда" 240 | 241 | #: cursive/src/main.rs:529 242 | msgid "New file name: " 243 | msgstr "Новое имя файла: " 244 | 245 | #: cursive/src/main.rs:1908 246 | msgid "New store config" 247 | msgstr "Новая конфигурация хранилища" 248 | 249 | #: cursive/src/wizard.rs:80 250 | msgid "No" 251 | msgstr "Нет" 252 | 253 | #: cursive/src/main.rs:2069 254 | msgid "No home directory set" 255 | msgstr "Не задан домашний каталог" 256 | 257 | #: cursive/src/main.rs:898 258 | msgid "Not Usable" 259 | msgstr "Не может быть использован" 260 | 261 | #: cursive/src/main.rs:682 262 | msgid "Note: " 263 | msgstr "Примечание: " 264 | 265 | #: cursive/src/helpers.rs:44 cursive/src/main.rs:334 cursive/src/main.rs:1001 266 | #: cursive/src/main.rs:1076 cursive/src/main.rs:1233 cursive/src/main.rs:1274 267 | #: cursive/src/main.rs:1980 268 | msgid "Ok" 269 | msgstr "Окей" 270 | 271 | #: cursive/src/main.rs:519 272 | msgid "Old file name: " 273 | msgstr "Старое имя файла: " 274 | 275 | #: cursive/src/main.rs:2296 276 | msgid "Open (ctrl-o)" 277 | msgstr "Открыть (ctrl-о)" 278 | 279 | #: cursive/src/main.rs:2281 280 | msgid "Operations" 281 | msgstr "Операции" 282 | 283 | #: cursive/src/main.rs:1726 284 | msgid "Own key fingerprint: " 285 | msgstr "Отпечаток собственного ключа: " 286 | 287 | #: cursive/src/main.rs:1712 cursive/src/main.rs:1870 288 | msgid "PGP Implementation: " 289 | msgstr "Имплементрация PGP: " 290 | 291 | #: cursive/src/main.rs:277 292 | msgid "Password deleted" 293 | msgstr "Пароль удален" 294 | 295 | #: cursive/src/main.rs:671 296 | msgid "Password: " 297 | msgstr "Пароль: " 298 | 299 | #: cursive/src/main.rs:661 300 | msgid "Path: " 301 | msgstr "Путь: " 302 | 303 | #: cursive/src/main.rs:2347 304 | msgid "Pull PGP Certificates" 305 | msgstr "Получить сертификаты PGP" 306 | 307 | #: cursive/src/main.rs:1218 308 | msgid "Pulled from remote git repository" 309 | msgstr "Вытащено из удаленного репозитория git" 310 | 311 | #: cursive/src/main.rs:1182 312 | msgid "Pushed to remote git repository" 313 | msgstr "Перенесено в удаленный репозиторий git" 314 | 315 | #: cursive/src/main.rs:2361 316 | msgid "Quit (esc)" 317 | msgstr "Выйти (esc)" 318 | 319 | #: cursive/src/main.rs:545 320 | msgid "Rename" 321 | msgstr "Переименовать" 322 | 323 | #: cursive/src/main.rs:544 324 | msgid "Rename File" 325 | msgstr "Переименовать файл" 326 | 327 | #: cursive/src/main.rs:2320 328 | msgid "Rename file (ctrl-r)" 329 | msgstr "Переименовать файл (ctrl-r)" 330 | 331 | #: cursive/src/wizard.rs:95 332 | msgid "" 333 | "Ripasso uses GPG in order to encrypt the stored passwords.\n" 334 | "Please enter your GPG key ID" 335 | msgstr "" 336 | "Ripasso использует GPG для шифрования сохраненных паролей.\n" 337 | "Пожалуйста, введите идентификатор ключа GPG" 338 | 339 | #: cursive/src/main.rs:416 cursive/src/main.rs:424 cursive/src/main.rs:640 340 | #: cursive/src/main.rs:701 cursive/src/main.rs:1773 cursive/src/main.rs:1909 341 | msgid "Save" 342 | msgstr "Сохранить" 343 | 344 | #: cursive/src/main.rs:1746 cursive/src/main.rs:1888 345 | msgid "Store Members: " 346 | msgstr "Члены хранилища: " 347 | 348 | #: cursive/src/main.rs:2399 349 | msgid "Stores" 350 | msgstr "Хранилище" 351 | 352 | #: cursive/src/main.rs:1000 cursive/src/main.rs:1075 353 | msgid "Team Members" 354 | msgstr "Члены команды" 355 | 356 | #: cursive/src/main.rs:2326 357 | msgid "Team Members (ctrl-v)" 358 | msgstr "Члены команды (ctrl-v)" 359 | 360 | #: cursive/src/helpers.rs:37 361 | msgid "Team member with key id {} isn't in your GPG keyring, fetch it first" 362 | msgstr "" 363 | "Член команды с идентификатором ключа {} не входит в вашу связку ключей GPG, " 364 | "сначала получите его" 365 | 366 | #: cursive/src/main.rs:2150 367 | msgid "" 368 | "The password store is backed by a git repository, but there is passwords " 369 | "there that's not in git. Please add them, otherwise they might get lost." 370 | msgstr "" 371 | "Хранилище паролей поддерживается репозиторием git, но там есть пароли, " 372 | "которых нет в git. Пожалуйста, добавьте их, иначе они могут потеряться." 373 | 374 | #: cursive/src/main.rs:883 375 | msgid "Ultimate" 376 | msgstr "Максимальное доверие" 377 | 378 | #: cursive/src/wizard.rs:69 379 | msgid "Unable to write file" 380 | msgstr "Невозможно записать файл" 381 | 382 | #: cursive/src/main.rs:887 383 | msgid "Undefined" 384 | msgstr "Не определено" 385 | 386 | #: cursive/src/main.rs:888 387 | msgid "Unknown" 388 | msgstr "Неизвестно" 389 | 390 | #: cursive/src/main.rs:2047 cursive/src/main.rs:2055 391 | msgid "Unknown argument, usage: ripasso-cursive [-h|--help]" 392 | msgstr "Неизвестный аргумент, использование: ripasso-cursive [-h|—help]" 393 | 394 | #: cursive/src/main.rs:1589 cursive/src/main.rs:1634 cursive/src/main.rs:1823 395 | msgid "Updated config file" 396 | msgstr "Обновлен файл конфигурации" 397 | 398 | #: cursive/src/main.rs:382 399 | msgid "Updated password entry" 400 | msgstr "Обновленный ввод пароля" 401 | 402 | #: cursive/src/main.rs:900 403 | msgid "Usable" 404 | msgstr "Годный" 405 | 406 | #: cursive/src/wizard.rs:141 407 | msgid "" 408 | "Welcome to Ripasso, it seems like you don't have a password store directory " 409 | "yet would you like to create it?\n" 410 | "It's created in $HOME/.password-store or where the PASSWORD_STORE_DIR " 411 | "environmental variable points." 412 | msgstr "" 413 | "Добро пожаловать в Ripasso! Похоже, у вас еще нет каталога для хранения " 414 | "паролей. Хотели бы вы его создать?\n" 415 | "Он создается в $HOME/.password-store или там, куда указывает " 416 | "PASSWORD_STORE_DIR." 417 | 418 | #: cursive/src/main.rs:274 cursive/src/main.rs:750 cursive/src/main.rs:856 419 | msgid "Yes" 420 | msgstr "Да" 421 | 422 | #: cursive/src/main.rs:2144 423 | msgid "" 424 | "You haven't configured you name and email in git, doing so will make " 425 | "cooperation with your team easier, you can do it like this:\n" 426 | "git config --global user.name \"John Doe\"\n" 427 | "git config --global user.email \"email@example.com\"\n" 428 | "\n" 429 | "Also consider configuring git to sign your commits with GPG:\n" 430 | "git config --global user.signingkey 3AA5C34371567BD2\n" 431 | "git config --global commit.gpgsign true" 432 | msgstr "" 433 | "Вы не настроили свое имя и адрес электронной почты в git, это облегчит " 434 | "сотрудничество с вашей командой, вы можете сделать это следующим образом:\n" 435 | "git config —global user.name «Джон Доу»\n" 436 | "git config —global user.email “email@example.com”\n" 437 | "\n" 438 | "Также рассмотрите возможность настройки git для подписи ваших коммитов с " 439 | "помощью GPG:\n" 440 | "git config —global user.signingkey 3AA5C34371567BD2\n" 441 | "git config —global commit.gpgsign true" 442 | 443 | #: cursive/src/main.rs:1984 444 | msgid "ctrl-e: Edit | " 445 | msgstr "ctrl-e: Редактировать | " 446 | 447 | #: cursive/src/main.rs:1006 cursive/src/main.rs:1081 cursive/src/main.rs:1986 448 | msgid "del: Remove" 449 | msgstr "del: Удалить" 450 | 451 | #: cursive/src/main.rs:1005 cursive/src/main.rs:1080 cursive/src/main.rs:1985 452 | msgid "ins: Add | " 453 | msgstr "ins: Добавить | " 454 | 455 | #: cursive/src/main.rs:1113 cursive/src/main.rs:1135 456 | msgid "n/a" 457 | msgstr "н/д" 458 | -------------------------------------------------------------------------------- /cursive/res/style.toml: -------------------------------------------------------------------------------- 1 | shadow = false 2 | borders = "outset" 3 | 4 | [colors] 5 | 6 | background = "black" 7 | view = "light black" 8 | 9 | # Text 10 | primary = "white" 11 | secondary ="light magenta" 12 | tertiary = "light white" 13 | 14 | title_primary="white" 15 | highlight="light magenta" 16 | highlight_inactive="light magenta" -------------------------------------------------------------------------------- /cursive/src/helpers.rs: -------------------------------------------------------------------------------- 1 | /* Ripasso - a simple password manager 2 | Copyright (C) 2019-2020 Joakim Lundborg, Alexander Kjäll 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, version 3 of the License. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program. If not, see . 15 | */ 16 | 17 | use std::sync::{Arc, Mutex}; 18 | 19 | use arboard::Clipboard; 20 | use cursive::{ 21 | Cursive, 22 | event::Key, 23 | views::{Checkbox, Dialog, EditView, OnEventView, RadioButton, TextView}, 24 | }; 25 | use lazy_static::lazy_static; 26 | use pass::Result; 27 | use ripasso::pass::Recipient; 28 | use ripasso::{crypto::CryptoImpl, pass}; 29 | 30 | lazy_static! { 31 | static ref CLIPBOARD: Arc> = Arc::new(Mutex::new(Clipboard::new().unwrap())); 32 | } 33 | 34 | /// Displays an error in a cursive dialog 35 | pub fn errorbox(ui: &mut Cursive, err: &pass::Error) { 36 | let text = match err { 37 | pass::Error::RecipientNotInKeyRing(key_id) => super::CATALOG 38 | .gettext("Team member with key id {} isn't in your GPG keyring, fetch it first") 39 | .to_string() 40 | .replace("{}", key_id), 41 | _ => format!("{err}"), 42 | }; 43 | 44 | let d = Dialog::around(TextView::new(text)) 45 | .dismiss_button(super::CATALOG.gettext("Ok")) 46 | .title(super::CATALOG.gettext("Error")); 47 | 48 | let ev = OnEventView::new(d).on_event(Key::Esc, |s| { 49 | s.pop_layer(); 50 | }); 51 | 52 | ui.add_layer(ev); 53 | } 54 | 55 | /// Copies content to the clipboard. 56 | pub fn set_clipboard(content: &String) -> Result<()> { 57 | Ok(CLIPBOARD.lock().unwrap().set_text(content)?) 58 | } 59 | 60 | pub fn get_value_from_input(s: &mut Cursive, input_name: &str) -> Option> { 61 | let mut password = None; 62 | s.call_on_name(input_name, |e: &mut EditView| { 63 | password = Some(e.get_content()); 64 | }); 65 | password 66 | } 67 | 68 | pub fn is_checkbox_checked(ui: &mut Cursive, name: &str) -> bool { 69 | let mut checked = false; 70 | ui.call_on_name(name, |l: &mut Checkbox| { 71 | checked = l.is_checked(); 72 | }); 73 | 74 | checked 75 | } 76 | 77 | pub fn is_radio_button_selected(s: &mut Cursive, button_name: &str) -> bool { 78 | let mut selected = false; 79 | s.call_on_name(button_name, |e: &mut RadioButton| { 80 | selected = e.is_selected(); 81 | }); 82 | selected 83 | } 84 | 85 | pub fn recipients_widths(recipients: &[Recipient]) -> (usize, usize) { 86 | let mut max_width_key = 0; 87 | let mut max_width_name = 0; 88 | for recipient in recipients { 89 | if recipient.key_id.len() > max_width_key { 90 | max_width_key = recipient.key_id.len(); 91 | } 92 | if recipient.name.len() > max_width_name { 93 | max_width_name = recipient.name.len(); 94 | } 95 | } 96 | (max_width_key, max_width_name) 97 | } 98 | 99 | #[cfg(test)] 100 | #[path = "tests/helpers.rs"] 101 | mod helpers_tests; 102 | -------------------------------------------------------------------------------- /cursive/src/tests/helpers.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use crate::helpers::{ 4 | get_value_from_input, is_checkbox_checked, is_radio_button_selected, recipients_widths, 5 | }; 6 | use cursive::{ 7 | view::Nameable, 8 | views::{Checkbox, EditView, LinearLayout, RadioButton, RadioGroup}, 9 | }; 10 | use hex::FromHex; 11 | use ripasso::crypto::CryptoImpl; 12 | use ripasso::pass::{Comment, KeyRingStatus, OwnerTrustLevel, Recipient}; 13 | 14 | #[test] 15 | fn test_get_value_from_input() { 16 | let mut siv = cursive::default(); 17 | 18 | let ev = EditView::new() 19 | .content("unit test content") 20 | .with_name("input"); 21 | 22 | siv.add_layer(ev); 23 | 24 | assert_eq!( 25 | Some(Arc::new(String::from("unit test content"))), 26 | get_value_from_input(&mut siv, "input") 27 | ); 28 | } 29 | 30 | #[test] 31 | fn is_checkbox_checked_false() { 32 | let mut siv = cursive::default(); 33 | siv.add_layer(Checkbox::new().with_name("unit_test")); 34 | 35 | assert!(!is_checkbox_checked(&mut siv, "unit_test")); 36 | } 37 | 38 | #[test] 39 | fn is_checkbox_checked_true() { 40 | let mut siv = cursive::default(); 41 | let mut c_b = Checkbox::new(); 42 | c_b.set_checked(true); 43 | siv.add_layer(c_b.with_name("unit_test")); 44 | 45 | assert!(is_checkbox_checked(&mut siv, "unit_test")); 46 | } 47 | 48 | #[test] 49 | fn is_radio_button_selected_false() { 50 | let mut siv = cursive::default(); 51 | 52 | let mut rg = RadioGroup::new(); 53 | let button1 = rg.button(1, "b1").with_name("button1_name"); 54 | let button2 = rg.button(2, "b2").with_name("button2_name"); 55 | 56 | let mut ll = LinearLayout::horizontal(); 57 | ll.add_child(button1); 58 | ll.add_child(button2); 59 | 60 | siv.add_layer(ll); 61 | 62 | assert!(!is_radio_button_selected(&mut siv, "button1_name")); 63 | } 64 | 65 | #[test] 66 | fn is_radio_button_selected_true() { 67 | let mut siv = cursive::default(); 68 | 69 | let mut rg = RadioGroup::new(); 70 | let button1 = rg.button(CryptoImpl::GpgMe, "b1").with_name("button1_name"); 71 | let button2 = rg 72 | .button(CryptoImpl::Sequoia, "b2") 73 | .with_name("button2_name"); 74 | 75 | let mut ll = LinearLayout::horizontal(); 76 | ll.add_child(button1); 77 | ll.add_child(button2); 78 | 79 | siv.add_layer(ll); 80 | 81 | siv.call_on_name("button2_name", |e: &mut RadioButton| { 82 | e.select(); 83 | }); 84 | 85 | assert!(is_radio_button_selected(&mut siv, "button2_name")); 86 | } 87 | 88 | #[test] 89 | fn recipients_widths_empty() { 90 | let (max_width_key, max_width_name) = recipients_widths(&[]); 91 | assert_eq!(0, max_width_key); 92 | assert_eq!(0, max_width_name); 93 | } 94 | 95 | pub fn recipient_alex() -> Recipient { 96 | Recipient { 97 | name: "Alexander Kjäll ".to_owned(), 98 | comment: Comment { 99 | pre_comment: None, 100 | post_comment: None, 101 | }, 102 | key_id: "1D108E6C07CBC406".to_owned(), 103 | fingerprint: Some( 104 | <[u8; 20]>::from_hex("7E068070D5EF794B00C8A9D91D108E6C07CBC406").unwrap(), 105 | ), 106 | key_ring_status: KeyRingStatus::InKeyRing, 107 | trust_level: OwnerTrustLevel::Ultimate, 108 | not_usable: false, 109 | } 110 | } 111 | 112 | #[test] 113 | fn recipients_widths_basic() { 114 | let (max_width_key, max_width_name) = recipients_widths(&[recipient_alex()]); 115 | assert_eq!(16, max_width_key); 116 | assert_eq!(44, max_width_name); 117 | } 118 | -------------------------------------------------------------------------------- /cursive/src/tests/main.rs: -------------------------------------------------------------------------------- 1 | use std::{fs::File, io::Write}; 2 | 3 | use chrono::Local; 4 | use ripasso::pass::{PasswordEntry, RepositoryStatus}; 5 | use tempfile::tempdir; 6 | 7 | use super::*; 8 | 9 | #[test] 10 | fn copy_name_none() { 11 | let mut siv = cursive::default(); 12 | 13 | let entries = SelectView::::new(); 14 | 15 | siv.add_layer(entries.with_name("results")); 16 | 17 | copy_name(&mut siv); 18 | } 19 | 20 | #[test] 21 | fn do_delete_normal() { 22 | let mut siv = cursive::default(); 23 | 24 | let td = tempdir().unwrap(); 25 | std::fs::create_dir(td.path().join(".password-store")).unwrap(); 26 | std::fs::write( 27 | td.path().join(".password-store").join("file.gpg"), 28 | "pgp-data", 29 | ) 30 | .unwrap(); 31 | 32 | let mut store = PasswordStore::new( 33 | "", 34 | &Some(td.path().to_path_buf()), 35 | &None, 36 | &None, 37 | &None, 38 | &CryptoImpl::GpgMe, 39 | &None, 40 | ) 41 | .unwrap(); 42 | store.passwords.push(PasswordEntry::new( 43 | &td.path().join(".password-store"), 44 | &PathBuf::from("file.gpg"), 45 | Ok(Local::now()), 46 | Ok(String::new()), 47 | Ok(SignatureStatus::Good), 48 | RepositoryStatus::NoRepo, 49 | )); 50 | let store: PasswordStoreType = Arc::new(Mutex::new(Arc::new(Mutex::new(store)))); 51 | 52 | let mut entries = SelectView::::new(); 53 | entries.add_all( 54 | store 55 | .lock() 56 | .unwrap() 57 | .lock() 58 | .unwrap() 59 | .passwords 60 | .clone() 61 | .into_iter() 62 | .map(|p| (format!("{:?}", p), p)), 63 | ); 64 | entries.set_selection(0); 65 | 66 | siv.add_layer(entries.with_name("results")); 67 | 68 | siv.call_on_name("results", |l: &mut SelectView| { 69 | assert_eq!(1, l.len()); 70 | }); 71 | do_delete(&mut siv, store); 72 | 73 | siv.call_on_name("results", |l: &mut SelectView| { 74 | assert_eq!(0, l.len()); 75 | }); 76 | } 77 | 78 | #[test] 79 | fn get_selected_password_entry_none() { 80 | let mut siv = cursive::default(); 81 | 82 | let result = get_selected_password_entry(&mut siv); 83 | 84 | assert!(result.is_none()); 85 | } 86 | 87 | #[test] 88 | fn get_selected_password_entry_some() { 89 | let mut siv = cursive::default(); 90 | 91 | let mut sv = SelectView::::new(); 92 | 93 | sv.add_item( 94 | "Item 1", 95 | PasswordEntry::new( 96 | &PathBuf::from("/tmp/"), 97 | &PathBuf::from("file.gpg"), 98 | Ok(Local::now()), 99 | Ok(String::new()), 100 | Ok(SignatureStatus::Good), 101 | RepositoryStatus::NoRepo, 102 | ), 103 | ); 104 | 105 | siv.add_layer(sv.with_name("results")); 106 | 107 | let result = get_selected_password_entry(&mut siv); 108 | 109 | assert!(result.is_some()); 110 | assert_eq!(String::from("file"), result.unwrap().name); 111 | } 112 | 113 | #[test] 114 | fn do_delete_one_entry() { 115 | let dir = tempdir().unwrap(); 116 | std::fs::create_dir_all(dir.path().join(".password-store")).unwrap(); 117 | let mut pass_file = File::create(dir.path().join(".password-store").join("file.gpg")).unwrap(); 118 | pass_file.flush().unwrap(); 119 | 120 | let mut store = PasswordStore::new( 121 | "test", 122 | &Some(dir.path().join(".password-store")), 123 | &None, 124 | &None, 125 | &None, 126 | &CryptoImpl::GpgMe, 127 | &None, 128 | ) 129 | .unwrap(); 130 | store.passwords.push(PasswordEntry::new( 131 | &dir.path().join(".password-store"), 132 | &PathBuf::from("file.gpg"), 133 | Ok(Local::now()), 134 | Ok(String::new()), 135 | Ok(SignatureStatus::Good), 136 | RepositoryStatus::NoRepo, 137 | )); 138 | 139 | let mut siv = cursive::default(); 140 | 141 | let mut sv = SelectView::::new(); 142 | 143 | for (i, item) in store.all_passwords().unwrap().into_iter().enumerate() { 144 | sv.add_item(format!("Item {}", i), item); 145 | } 146 | 147 | assert_eq!(1, sv.len()); 148 | 149 | siv.add_layer(sv.with_name("results")); 150 | siv.add_layer(SelectView::::new().with_name("just to be popped")); 151 | 152 | let store: PasswordStoreType = Arc::new(Mutex::new(Arc::new(Mutex::new(store)))); 153 | do_delete(&mut siv, store); 154 | 155 | let cbr = siv.call_on_name("results", |l: &mut SelectView| { 156 | assert_eq!(0, l.len()); 157 | }); 158 | 159 | assert_eq!(Some(()), cbr); 160 | } 161 | 162 | #[test] 163 | fn render_recipient_label_ultimate() { 164 | let r = Recipient { 165 | name: "Alexander Kjäll ".to_owned(), 166 | comment: pass::Comment { 167 | pre_comment: None, 168 | post_comment: None, 169 | }, 170 | key_id: "1D108E6C07CBC406".to_owned(), 171 | fingerprint: Some( 172 | <[u8; 20]>::from_hex("7E068070D5EF794B00C8A9D91D108E6C07CBC406").unwrap(), 173 | ), 174 | key_ring_status: pass::KeyRingStatus::InKeyRing, 175 | trust_level: OwnerTrustLevel::Ultimate, 176 | not_usable: false, 177 | }; 178 | 179 | let result = render_recipient_label(&r, 20, 20); 180 | 181 | assert_eq!( 182 | String::from( 183 | " \u{fe0f} 1D108E6C07CBC406 Alexander Kjäll Ultimate Usable " 184 | ), 185 | result 186 | ); 187 | } 188 | 189 | #[test] 190 | fn substr_wide_char() { 191 | assert_eq!(String::from("Können"), substr("Können", 0, 6)); 192 | } 193 | 194 | #[test] 195 | fn substr_overlong() { 196 | assert_eq!(String::from("Kö"), substr("Kö", 0, 6)); 197 | } 198 | 199 | #[test] 200 | fn create_label_basic() { 201 | // TODO: Fix this test so that time zones don't mess with it. 202 | 203 | let p = PasswordEntry::new( 204 | &PathBuf::from("/tmp/"), 205 | &PathBuf::from("file.gpg"), 206 | Ok(chrono::DateTime::::from( 207 | chrono::DateTime::parse_from_str("2022-08-14 00:00:00+0000", "%Y-%m-%d %H:%M:%S%z") 208 | .unwrap(), 209 | )), 210 | Ok(String::new()), 211 | Ok(SignatureStatus::Good), 212 | RepositoryStatus::NoRepo, 213 | ); 214 | 215 | let result = create_label(&p, 40); 216 | 217 | assert_eq!(String::from("file 🔒 2022-08-14"), result); 218 | } 219 | 220 | #[test] 221 | fn get_sub_dirs_empty() { 222 | let dir = tempdir().unwrap(); 223 | 224 | let dirs = get_sub_dirs(&dir.path().to_path_buf()).unwrap(); 225 | 226 | assert_eq!(1, dirs.len()); 227 | assert_eq!(PathBuf::from("./"), dirs[0]); 228 | } 229 | 230 | #[test] 231 | fn get_sub_dirs_one_dir() { 232 | let dir = tempdir().unwrap(); 233 | std::fs::create_dir(dir.path().join("one_dir")).unwrap(); 234 | 235 | let dirs = get_sub_dirs(&dir.path().to_path_buf()).unwrap(); 236 | 237 | assert_eq!(1, dirs.len()); 238 | assert_eq!(PathBuf::from("./"), dirs[0]); 239 | } 240 | 241 | #[test] 242 | fn get_sub_dirs_one_dir_with_pgpid() { 243 | let dir = tempdir().unwrap(); 244 | std::fs::create_dir(dir.path().join("one_dir")).unwrap(); 245 | File::create(dir.path().join("one_dir").join(".gpg-id")).unwrap(); 246 | 247 | let dirs = get_sub_dirs(&dir.path().to_path_buf()).unwrap(); 248 | 249 | assert_eq!(2, dirs.len()); 250 | assert_eq!(PathBuf::from("./"), dirs[0]); 251 | assert_eq!(PathBuf::from("one_dir"), dirs[1]); 252 | } 253 | -------------------------------------------------------------------------------- /cursive/src/wizard.rs: -------------------------------------------------------------------------------- 1 | /* Ripasso - a simple password manager 2 | Copyright (C) 2019-2020 Joakim Lundborg, Alexander Kjäll 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, version 3 of the License. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program. If not, see . 15 | */ 16 | 17 | use std::path::PathBuf; 18 | 19 | use cursive::{ 20 | Cursive, CursiveExt, 21 | direction::Orientation, 22 | event::Key, 23 | traits::*, 24 | views::{Dialog, EditView, LinearLayout, OnEventView, SelectView, TextView}, 25 | }; 26 | use ripasso::{crypto::CryptoImpl, git::init_git_repo, pass}; 27 | 28 | use crate::helpers; 29 | 30 | fn create_git_repo(ui: &mut Cursive, password_store_dir: &Option, home: &Option) { 31 | let init_res = init_git_repo(&pass::password_dir(password_store_dir, home).unwrap()); 32 | if init_res.is_err() { 33 | helpers::errorbox(ui, &init_res.err().unwrap()); 34 | } else { 35 | let message = super::CATALOG.gettext("Initialized password repo with Ripasso"); 36 | match pass::PasswordStore::new( 37 | "default", 38 | password_store_dir, 39 | &None, 40 | home, 41 | &None, 42 | &CryptoImpl::GpgMe, 43 | &None, 44 | ) { 45 | Err(err) => helpers::errorbox(ui, &err), 46 | Ok(store) => match store.add_and_commit(&[PathBuf::from(".gpg-id")], message) { 47 | Err(err) => helpers::errorbox(ui, &err), 48 | Ok(_) => ui.quit(), 49 | }, 50 | } 51 | } 52 | } 53 | 54 | fn do_create(ui: &mut Cursive, password_store_dir: &Option, home: &Option) { 55 | let l = ui.find_name::("initial_key_id").unwrap(); 56 | let key_id = (*l.get_content()).clone(); 57 | let mut pass_home = pass::password_dir_raw(password_store_dir, home); 58 | let home = home.clone(); 59 | match std::fs::create_dir_all(&pass_home) { 60 | Err(err) => { 61 | helpers::errorbox(ui, &pass::Error::Io(err)); 62 | ui.quit(); 63 | } 64 | Ok(_) => { 65 | pass_home.push(".gpg-id"); 66 | std::fs::write(pass_home, key_id).unwrap_or_else(|_| { 67 | panic!( 68 | "{}", 69 | super::CATALOG.gettext("Unable to write file").to_string() 70 | ) 71 | }); 72 | 73 | let password_store_dir2 = password_store_dir.clone(); 74 | let d = Dialog::around(TextView::new( 75 | super::CATALOG.gettext("Also create a git repository for the encrypted files?"), 76 | )) 77 | .button(super::CATALOG.gettext("Create"), move |ui: &mut Cursive| { 78 | create_git_repo(ui, &password_store_dir2, &home); 79 | }) 80 | .button(super::CATALOG.gettext("No"), |s| { 81 | s.quit(); 82 | }) 83 | .title(super::CATALOG.gettext("Git Init")); 84 | 85 | ui.add_layer(d); 86 | } 87 | } 88 | } 89 | 90 | fn create_store(ui: &mut Cursive, password_store_dir: &Option, home: &Option) { 91 | let password_store_dir2 = password_store_dir.clone(); 92 | let home = home.clone(); 93 | let home2 = home.clone(); 94 | let d2 = Dialog::around(LinearLayout::new(Orientation::Vertical) 95 | .child(TextView::new(super::CATALOG.gettext("Ripasso uses GPG in order to encrypt the stored passwords.\nPlease enter your GPG key ID"))) 96 | .child(EditView::new().with_name("initial_key_id")) 97 | ) 98 | .button(super::CATALOG.gettext("Create"), move |ui: &mut Cursive| { 99 | do_create(ui, &password_store_dir2, &home); 100 | }); 101 | 102 | let password_store_dir3 = password_store_dir.clone(); 103 | let recipients_event = OnEventView::new(d2).on_event(Key::Enter, move |ui: &mut Cursive| { 104 | do_create(ui, &password_store_dir3, &home2); 105 | }); 106 | 107 | ui.add_layer(recipients_event); 108 | } 109 | 110 | pub fn show_init_menu(password_store_dir: &Option, home: &Option) { 111 | let mut ui = Cursive::default(); 112 | 113 | ui.load_toml(include_str!("../res/style.toml")).unwrap(); 114 | 115 | let results = SelectView::::new() 116 | .with_name("results") 117 | .full_height(); 118 | 119 | let search_box = EditView::new().full_width(); 120 | 121 | ui.add_layer( 122 | LinearLayout::new(Orientation::Vertical) 123 | .child( 124 | Dialog::around( 125 | LinearLayout::new(Orientation::Vertical) 126 | .child(search_box) 127 | .child(results) 128 | .full_width(), 129 | ) 130 | .title("Ripasso"), 131 | ) 132 | .child( 133 | LinearLayout::new(Orientation::Horizontal) 134 | .child(TextView::new(super::CATALOG.gettext("F1: Menu | "))) 135 | .full_width(), 136 | ), 137 | ); 138 | 139 | let password_store_dir2 = password_store_dir.clone(); 140 | let home = home.clone(); 141 | let d = Dialog::around(TextView::new(super::CATALOG.gettext("Welcome to Ripasso, it seems like you don't have a password store directory yet would you like to create it?\nIt's created in $HOME/.password-store or where the PASSWORD_STORE_DIR environmental variable points."))) 142 | .button(super::CATALOG.gettext("Create"), move |ui: &mut Cursive| { 143 | create_store(ui, &password_store_dir2, &home); 144 | }) 145 | .button(super::CATALOG.gettext("Cancel"), |s| { 146 | s.quit(); 147 | std::process::exit(0); 148 | }) 149 | .title(super::CATALOG.gettext("Init")); 150 | 151 | ui.add_layer(d); 152 | 153 | ui.run(); 154 | } 155 | -------------------------------------------------------------------------------- /doc/ripasso-cursive-0.4.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cortex/ripasso/eb4ceffcb6e1f237e8ed0e24cb97b593b34b196e/doc/ripasso-cursive-0.4.0.png -------------------------------------------------------------------------------- /doc/ripasso-cursive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cortex/ripasso/eb4ceffcb6e1f237e8ed0e24cb97b593b34b196e/doc/ripasso-cursive.png -------------------------------------------------------------------------------- /doc/ripasso-gtk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cortex/ripasso/eb4ceffcb6e1f237e8ed0e24cb97b593b34b196e/doc/ripasso-gtk.png -------------------------------------------------------------------------------- /generate_pot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | xgettext cursive/src/*rs -kgettext --sort-output -o cursive/res/ripasso-cursive.pot 4 | 5 | touch cursive/res/sv.po && msgmerge --update cursive/res/sv.po cursive/res/ripasso-cursive.pot 6 | touch cursive/res/nb.po && msgmerge --update cursive/res/nb.po cursive/res/ripasso-cursive.pot 7 | touch cursive/res/nn.po && msgmerge --update cursive/res/nn.po cursive/res/ripasso-cursive.pot 8 | touch cursive/res/fr.po && msgmerge --update cursive/res/fr.po cursive/res/ripasso-cursive.pot 9 | touch cursive/res/it.po && msgmerge --update cursive/res/it.po cursive/res/ripasso-cursive.pot 10 | touch cursive/res/de.po && msgmerge --update cursive/res/de.po cursive/res/ripasso-cursive.pot 11 | touch cursive/res/ru.po && msgmerge --update cursive/res/ru.po cursive/res/ripasso-cursive.pot 12 | touch cursive/res/es.po && msgmerge --update cursive/res/es.po cursive/res/ripasso-cursive.pot 13 | -------------------------------------------------------------------------------- /gtk/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ripasso-gtk" 3 | version = "0.8.0" 4 | authors = ["Joakim Lundborg ", "Alexander Kjäll "] 5 | edition = "2024" 6 | 7 | 8 | [dependencies] 9 | ripasso = { path = "../", version = "0.8.0" } 10 | gtk = { version = "0.9", package = "gtk4", features = ["v4_6"] } 11 | adw = { version = "0.7", package = "libadwaita" } 12 | glib = "0.20" 13 | once_cell = "1" 14 | hex = "0.4" 15 | config = "0.15" 16 | chrono = { version = "0.4", default-features = false, features = ["clock"] } 17 | 18 | [build-dependencies] 19 | glib-build-tools = "0.20" 20 | -------------------------------------------------------------------------------- /gtk/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | glib_build_tools::compile_resources( 3 | &["src/resources"], 4 | "src/resources/resources.gresource.xml", 5 | "ripasso-gtk.gresource", 6 | ); 7 | } 8 | -------------------------------------------------------------------------------- /gtk/src/collection_object/imp.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | cell::RefCell, 3 | path::PathBuf, 4 | sync::{Arc, Mutex}, 5 | }; 6 | 7 | use adw::{prelude::*, subclass::prelude::*}; 8 | use glib::{ParamSpec, ParamSpecString, Value}; 9 | use gtk::{ 10 | gio, glib, 11 | glib::{ParamSpecBoxed, ParamSpecObject}, 12 | }; 13 | use once_cell::sync::{Lazy, OnceCell}; 14 | use ripasso::pass::PasswordStore; 15 | 16 | use crate::utils::PasswordStoreBoxed; 17 | 18 | // Object holding the state 19 | #[derive(Default)] 20 | pub struct CollectionObject { 21 | pub title: RefCell, 22 | pub passwords: OnceCell, 23 | pub store: RefCell>>, 24 | pub user_config_dir: RefCell, 25 | } 26 | 27 | // The central trait for subclassing a GObject 28 | #[glib::object_subclass] 29 | impl ObjectSubclass for CollectionObject { 30 | const NAME: &'static str = "RipassoCollectionObject"; 31 | type Type = super::CollectionObject; 32 | } 33 | 34 | // Trait shared by all GObjects 35 | impl ObjectImpl for CollectionObject { 36 | fn properties() -> &'static [ParamSpec] { 37 | static PROPERTIES: Lazy> = Lazy::new(|| { 38 | vec![ 39 | ParamSpecString::builder("title").build(), 40 | ParamSpecObject::builder::("passwords").build(), 41 | ParamSpecBoxed::builder::("store").build(), 42 | ParamSpecString::builder("user-config-dir").build(), 43 | ] 44 | }); 45 | PROPERTIES.as_ref() 46 | } 47 | 48 | fn set_property(&self, _id: usize, value: &Value, pspec: &ParamSpec) { 49 | match pspec.name() { 50 | "title" => { 51 | let input_value = value 52 | .get() 53 | .expect("The value needs to be of type `String`."); 54 | self.title.replace(input_value); 55 | } 56 | "passwords" => { 57 | let input_value = value 58 | .get() 59 | .expect("The value needs to be of type `gio::ListStore`."); 60 | self.passwords 61 | .set(input_value) 62 | .expect("Could not set password"); 63 | } 64 | "store" => { 65 | let input_value: PasswordStoreBoxed = value 66 | .get() 67 | .expect("The value needs to be of type `PasswordStoreBoxed`."); 68 | 69 | *self.store.borrow_mut() = input_value.into_refcounted(); 70 | } 71 | "user-config-dir" => { 72 | let input_value: String = value 73 | .get() 74 | .expect("The value needs to be of type `String`."); 75 | 76 | *self.user_config_dir.borrow_mut() = PathBuf::from(input_value); 77 | } 78 | _ => unimplemented!(), 79 | } 80 | } 81 | 82 | fn property(&self, _id: usize, pspec: &ParamSpec) -> Value { 83 | match pspec.name() { 84 | "title" => self.title.borrow().to_value(), 85 | "passwords" => self 86 | .passwords 87 | .get() 88 | .expect("Could not get passwords.") 89 | .to_value(), 90 | _ => unimplemented!(), 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /gtk/src/collection_object/mod.rs: -------------------------------------------------------------------------------- 1 | mod imp; 2 | 3 | use std::{ 4 | path::Path, 5 | sync::{Arc, Mutex}, 6 | }; 7 | 8 | use adw::{ 9 | prelude::{ListModelExtManual, *}, 10 | subclass::prelude::*, 11 | }; 12 | use glib::Object; 13 | use gtk::{gio, glib}; 14 | use ripasso::pass::{PasswordEntry, PasswordStore}; 15 | 16 | use crate::{ 17 | password_object::PasswordObject, 18 | utils::{PasswordStoreBoxed, error_dialog}, 19 | }; 20 | 21 | glib::wrapper! { 22 | pub struct CollectionObject(ObjectSubclass); 23 | } 24 | 25 | impl CollectionObject { 26 | pub fn new( 27 | title: &str, 28 | passwords: gio::ListStore, 29 | store: Arc>, 30 | user_config_dir: &Path, 31 | ) -> Self { 32 | let co = Object::builder() 33 | .property("title", title) 34 | .property("passwords", passwords) 35 | .property("store", PasswordStoreBoxed(store)) 36 | .property( 37 | "user-config-dir", 38 | user_config_dir 39 | .to_str() 40 | .expect("can't have non-utf8 in path"), 41 | ) 42 | .build(); 43 | 44 | co 45 | } 46 | 47 | pub fn passwords(&self) -> gio::ListStore { 48 | self.imp() 49 | .passwords 50 | .get() 51 | .expect("Could not get passwords.") 52 | .clone() 53 | } 54 | 55 | pub fn git_pull(&self, parent_window: &impl IsA) { 56 | let res = ripasso::git::pull(&self.imp().store.borrow().as_ref().lock().unwrap()); 57 | 58 | if let Err(e) = res { 59 | error_dialog(&e, parent_window); 60 | } 61 | } 62 | 63 | pub fn git_push(&self, parent_window: &impl IsA) { 64 | let res = ripasso::git::push(&self.imp().store.borrow().as_ref().lock().unwrap()); 65 | 66 | if let Err(e) = res { 67 | error_dialog(&e, parent_window); 68 | } 69 | } 70 | 71 | pub fn pgp_download(&self, parent_window: &impl IsA) { 72 | let res = ripasso::pass::pgp_pull( 73 | &mut self.imp().store.borrow_mut().lock().unwrap(), 74 | &self.imp().user_config_dir.borrow(), 75 | ); 76 | 77 | if let Err(e) = res { 78 | error_dialog(&e, parent_window); 79 | } 80 | } 81 | 82 | pub fn to_collection_data(&self) -> CollectionData { 83 | let title = self.imp().title.borrow().clone(); 84 | let passwords_data = self 85 | .passwords() 86 | .snapshot() 87 | .iter() 88 | .filter_map(Cast::downcast_ref::) 89 | .map(PasswordObject::password_entry) 90 | .collect(); 91 | 92 | CollectionData { 93 | title, 94 | passwords_data, 95 | } 96 | } 97 | 98 | pub fn from_store_data(collection_data: PasswordStore, user_config_dir: &Path) -> Self { 99 | let title = collection_data.get_name().to_string(); 100 | 101 | let mut vec = collection_data 102 | .all_passwords() 103 | .expect("Error loading password list"); 104 | 105 | vec.sort_by(|a, b| a.name.partial_cmp(&b.name).unwrap()); 106 | 107 | let store = Arc::new(Mutex::new(collection_data)); 108 | 109 | let passwords_to_extend: Vec = vec 110 | .into_iter() 111 | .map(|p| PasswordObject::from_password_entry(p, store.clone())) 112 | .collect(); 113 | 114 | let passwords = gio::ListStore::new::(); 115 | passwords.extend_from_slice(&passwords_to_extend); 116 | 117 | Self::new(&title, passwords, store, user_config_dir) 118 | } 119 | } 120 | 121 | #[derive(Default, Clone)] 122 | pub struct CollectionData { 123 | pub title: String, 124 | pub passwords_data: Vec, 125 | } 126 | -------------------------------------------------------------------------------- /gtk/src/com.github.cortex.ripasso-gtk.gschema.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 'All' 11 | Filter of the tasks 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /gtk/src/main.rs: -------------------------------------------------------------------------------- 1 | mod collection_object; 2 | mod password_object; 3 | mod utils; 4 | mod window; 5 | 6 | use adw::prelude::*; 7 | use gtk::{gio, glib}; 8 | use window::Window; 9 | 10 | static APP_ID: &str = "com.github.cortex.ripasso-gtk"; 11 | 12 | fn main() -> glib::ExitCode { 13 | // ripasso-gtk.gresource is produced in the build.rs file 14 | gio::resources_register_include!("ripasso-gtk.gresource") 15 | .expect("Failed to register resources."); 16 | 17 | // Create a new application 18 | let app = adw::Application::builder().application_id(APP_ID).build(); 19 | 20 | // Connect to signals 21 | app.connect_startup(setup_shortcuts); 22 | app.connect_activate(build_ui); 23 | 24 | // Run the application 25 | app.run() 26 | } 27 | 28 | fn setup_shortcuts(app: &adw::Application) { 29 | app.set_accels_for_action("win.git-pull", &["f"]); 30 | app.set_accels_for_action("win.git-push", &["g"]); 31 | app.set_accels_for_action("win.pgp-download", &["p"]); 32 | } 33 | 34 | fn build_ui(app: &adw::Application) { 35 | // Create a new custom window and show it 36 | let window = Window::new(app); 37 | window.show(); 38 | } 39 | -------------------------------------------------------------------------------- /gtk/src/password_object/imp.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | cell::RefCell, 3 | path::PathBuf, 4 | sync::{Arc, Mutex}, 5 | }; 6 | 7 | use adw::{prelude::*, subclass::prelude::*}; 8 | use chrono::{DateTime, Local}; 9 | use glib::{ParamSpec, ParamSpecBoxed, ParamSpecString, Value}; 10 | use gtk::glib; 11 | use once_cell::sync::Lazy; 12 | use ripasso::pass::{PasswordEntry, PasswordStore}; 13 | 14 | use crate::utils::{PasswordStoreBoxed, error_dialog_standalone}; 15 | 16 | // Object holding the state 17 | #[derive(Default)] 18 | pub struct PasswordObject { 19 | pub data: RefCell, 20 | pub store: RefCell>>, 21 | } 22 | 23 | // The central trait for subclassing a GObject 24 | #[glib::object_subclass] 25 | impl ObjectSubclass for PasswordObject { 26 | const NAME: &'static str = "RipassoPasswordObject"; 27 | type Type = super::PasswordObject; 28 | } 29 | 30 | // Trait shared by all GObjects 31 | impl ObjectImpl for PasswordObject { 32 | fn properties() -> &'static [ParamSpec] { 33 | static PROPERTIES: Lazy> = Lazy::new(|| { 34 | vec![ 35 | ParamSpecString::builder("name").build(), 36 | ParamSpecString::builder("path").build(), 37 | ParamSpecString::builder("committed-by").build(), 38 | ParamSpecString::builder("updated").build(), 39 | ParamSpecString::builder("secret").build(), 40 | ParamSpecBoxed::builder::("store").build(), 41 | ] 42 | }); 43 | PROPERTIES.as_ref() 44 | } 45 | 46 | fn set_property(&self, _id: usize, value: &Value, pspec: &ParamSpec) { 47 | match pspec.name() { 48 | "name" => { 49 | let input_value: String = value 50 | .get() 51 | .expect("The value needs to be of type `String`."); 52 | self.data.borrow_mut().name = input_value; 53 | } 54 | "path" => { 55 | let input_value: String = value 56 | .get() 57 | .expect("The value needs to be of type `String`."); 58 | self.data.borrow_mut().path = PathBuf::from(input_value); 59 | } 60 | "updated" => { 61 | let input_value: String = value 62 | .get() 63 | .expect("The value needs to be of type `String`."); 64 | 65 | self.data.borrow_mut().updated = Some( 66 | input_value 67 | .parse::>() 68 | .expect("Failed to parse date"), 69 | ); 70 | } 71 | "committed-by" => { 72 | let input_value = value 73 | .get() 74 | .expect("The value needs to be of type `String`."); 75 | self.data.borrow_mut().committed_by = Some(input_value); 76 | } 77 | "secret" => {} 78 | "store" => { 79 | let input_value: PasswordStoreBoxed = value 80 | .get() 81 | .expect("The value needs to be of type `PasswordStoreBoxed`."); 82 | 83 | *self.store.borrow_mut() = input_value.into_refcounted(); 84 | } 85 | _ => unimplemented!(), 86 | } 87 | } 88 | 89 | fn property(&self, _id: usize, pspec: &ParamSpec) -> Value { 90 | match pspec.name() { 91 | "name" => self.data.borrow().name.to_value(), 92 | "updated" => format!( 93 | "{}", 94 | self.data 95 | .borrow() 96 | .updated 97 | .expect("Expected a git repo") 98 | .format("%Y-%m-%d") 99 | ) 100 | .to_value(), 101 | "committed-by" => self.data.borrow().committed_by.to_value(), 102 | "secret" => { 103 | let store = self.store.borrow(); 104 | let store = store.as_ref().lock().expect("locked store"); 105 | 106 | let res = self.data.borrow().secret(&store); 107 | 108 | match res { 109 | Ok(secret) => secret.to_value(), 110 | Err(e) => { 111 | error_dialog_standalone(&e); 112 | "".to_value() 113 | } 114 | } 115 | } 116 | _ => unimplemented!(), 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /gtk/src/password_object/mod.rs: -------------------------------------------------------------------------------- 1 | mod imp; 2 | 3 | use std::{ 4 | path::PathBuf, 5 | sync::{Arc, Mutex}, 6 | }; 7 | 8 | use adw::subclass::prelude::*; 9 | use chrono::{DateTime, Local}; 10 | use glib::Object; 11 | use gtk::glib; 12 | use ripasso::pass::{Error, PasswordEntry, PasswordStore}; 13 | 14 | use crate::utils::{PasswordStoreBoxed, error_dialog_standalone}; 15 | 16 | glib::wrapper! { 17 | pub struct PasswordObject(ObjectSubclass); 18 | } 19 | 20 | impl PasswordObject { 21 | pub fn new( 22 | name: String, 23 | path: PathBuf, 24 | updated: DateTime, 25 | committed_by: String, 26 | store: Arc>, 27 | ) -> Self { 28 | let po: Self = Object::builder() 29 | .property("name", name) 30 | .property("path", path.to_string_lossy().to_string()) 31 | .property("updated", updated.to_rfc3339()) 32 | .property("committed-by", committed_by) 33 | .property("store", PasswordStoreBoxed(store)) 34 | .build(); 35 | 36 | po 37 | } 38 | 39 | pub fn password_entry(&self) -> PasswordEntry { 40 | self.imp().data.borrow().clone() 41 | } 42 | 43 | pub fn from_password_entry(p_e: PasswordEntry, store: Arc>) -> Self { 44 | let file_date: DateTime = match p_e.updated { 45 | Some(d) => d, 46 | None => match std::fs::metadata(&p_e.path) { 47 | Ok(md) => match md.modified() { 48 | Ok(st) => st.into(), 49 | Err(e) => { 50 | error_dialog_standalone(&Error::Io(e)); 51 | DateTime::::default() 52 | } 53 | }, 54 | Err(e) => { 55 | error_dialog_standalone(&Error::Io(e)); 56 | DateTime::::default() 57 | } 58 | }, 59 | }; 60 | 61 | let commit_name = p_e.committed_by.unwrap_or_else(|| "".into()); 62 | 63 | Self::new(p_e.name, p_e.path, file_date, commit_name, store) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /gtk/src/resources/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | 22 | 25 | 29 | 33 | 34 | 45 | 46 | 67 | 69 | 70 | 72 | image/svg+xml 73 | 75 | 76 | 77 | 78 | 79 | 84 | 90 | 91 | 96 | 103 | 110 | 117 | 120 | 127 | 133 | 141 | 142 | 143 | 149 | 155 | 172 | 173 | 174 | -------------------------------------------------------------------------------- /gtk/src/resources/resources.gresource.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | shortcuts.ui 5 | window.ui 6 | 7 | 8 | -------------------------------------------------------------------------------- /gtk/src/resources/shortcuts.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | True 5 | 6 | 7 | shortcuts 8 | 10 9 | 10 | 11 | General 12 | 13 | 14 | Show shortcuts 15 | win.show-help-overlay 16 | 17 | 18 | 19 | 20 | Git Pull 21 | win.git-pull 22 | 23 | 24 | 25 | 26 | Git Push 27 | win.git-push 28 | 29 | 30 | 31 | 32 | Download PGP Certificates 33 | win.pgp-download 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /gtk/src/resources/window.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | _Git Pull 6 | win.git-pull 7 | 8 | 9 | _Git Push 10 | win.git-push 11 | 12 | 13 | _Download PGP certificates 14 | win.pgp-download 15 | 16 | 17 | _Keyboard Shortcuts 18 | win.show-help-overlay 19 | 20 | 21 | _About 22 | win.about 23 | 24 | 25 | 189 | 190 | -------------------------------------------------------------------------------- /gtk/src/utils.rs: -------------------------------------------------------------------------------- 1 | use std::sync::{Arc, Mutex}; 2 | 3 | use adw::prelude::{DialogExt, GtkWindowExt, WidgetExt}; 4 | use gtk::{MessageDialog, prelude::IsA}; 5 | use ripasso::pass::{Error, PasswordStore}; 6 | 7 | #[derive(Clone, glib::SharedBoxed)] 8 | #[shared_boxed_type(name = "PasswordStoreBoxed")] 9 | pub struct PasswordStoreBoxed(pub Arc>); 10 | 11 | pub fn error_dialog(error: &Error, transient_for: &impl IsA) { 12 | let dialog = MessageDialog::builder() 13 | .buttons(gtk::ButtonsType::Ok) 14 | .title("Application Error") 15 | .use_header_bar(0) 16 | .transient_for(transient_for) 17 | .secondary_text(format!("{error}")) 18 | .build(); 19 | 20 | dialog.connect_response(move |dialog, _| { 21 | // Destroy dialog 22 | dialog.destroy(); 23 | }); 24 | 25 | dialog.show(); 26 | } 27 | 28 | pub fn error_dialog_standalone(error: &Error) { 29 | let dialog = MessageDialog::builder() 30 | .buttons(gtk::ButtonsType::Ok) 31 | .title("Application Error") 32 | .use_header_bar(0) 33 | .secondary_text(format!("{error}")) 34 | .build(); 35 | 36 | dialog.connect_response(move |dialog, _| { 37 | // Destroy dialog 38 | dialog.destroy(); 39 | }); 40 | 41 | dialog.show(); 42 | } 43 | -------------------------------------------------------------------------------- /gtk/src/window/imp.rs: -------------------------------------------------------------------------------- 1 | use std::{cell::RefCell, path::PathBuf}; 2 | 3 | use adw::{Leaflet, subclass::prelude::*}; 4 | use glib::{Propagation, subclass::InitializingObject}; 5 | use gtk::{ 6 | Button, CompositeTemplate, Entry, FilterListModel, ListBox, Stack, gio, glib, 7 | glib::SignalHandlerId, 8 | }; 9 | use once_cell::sync::OnceCell; 10 | 11 | use crate::collection_object::CollectionObject; 12 | 13 | // Object holding the state 14 | #[derive(CompositeTemplate, Default)] 15 | #[template(resource = "/com/github/cortex/ripasso-gtk/window.ui")] 16 | pub struct Window { 17 | #[template_child] 18 | pub entry: TemplateChild, 19 | #[template_child] 20 | pub passwords_list: TemplateChild, 21 | // 👇 all members below are new 22 | #[template_child] 23 | pub collections_list: TemplateChild, 24 | #[template_child] 25 | pub leaflet: TemplateChild, 26 | #[template_child] 27 | pub stack: TemplateChild, 28 | #[template_child] 29 | pub back_button: TemplateChild