From 9c49e5e148121e531efcd6a3d76f1cade833a598 Mon Sep 17 00:00:00 2001 From: adlee-was-taken Date: Sun, 19 Apr 2026 20:33:04 -0400 Subject: [PATCH] =?UTF-8?q?chore:=20reconcile=20Plan=201A=20branch=20with?= =?UTF-8?q?=20idfoto=E2=86=92relicario=20rename?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Renames crate directories and sweeps identifiers so Plan 1B can reference the post-rename names throughout. - git mv crates/idfoto-{core,cli,wasm} → crates/relicario-{core,cli,wasm} - sed sweep: idfoto_core/idfoto-core/IdfotoError/IDFOTO_IMAGE/.idfoto/ etc. - All 128 relicario-core tests pass post-sweep Co-Authored-By: Claude Sonnet 4.6 --- Cargo.lock | 114 +++++++++--------- Cargo.toml | 6 +- .../{idfoto-cli => relicario-cli}/Cargo.toml | 6 +- .../{idfoto-cli => relicario-cli}/src/main.rs | 40 +++--- .../Cargo.toml | 2 +- .../src/attachment.rs | 10 +- .../src/crypto.rs | 36 +++--- .../src/error.rs | 20 +-- .../src/generators.rs | 18 +-- .../src/ids.rs | 0 .../src/imgsecret.rs | 32 ++--- .../src/item.rs | 10 +- .../src/item_types/card.rs | 0 .../src/item_types/document.rs | 0 .../src/item_types/identity.rs | 0 .../src/item_types/key.rs | 0 .../src/item_types/login.rs | 0 .../src/item_types/mod.rs | 0 .../src/item_types/secure_note.rs | 0 .../src/item_types/totp.rs | 0 .../src/lib.rs | 6 +- .../src/manifest.rs | 0 .../src/settings.rs | 0 .../src/time.rs | 0 .../src/vault.rs | 0 .../tests/attachments.rs | 6 +- .../tests/field_history.rs | 4 +- .../tests/format_v2.rs | 6 +- .../tests/generators.rs | 2 +- .../tests/integration.rs | 8 +- .../Cargo.toml | 4 +- .../src/lib.rs | 14 +-- 32 files changed, 172 insertions(+), 172 deletions(-) rename crates/{idfoto-cli => relicario-cli}/Cargo.toml (81%) rename crates/{idfoto-cli => relicario-cli}/src/main.rs (95%) rename crates/{idfoto-core => relicario-core}/Cargo.toml (97%) rename crates/{idfoto-core => relicario-core}/src/attachment.rs (93%) rename crates/{idfoto-core => relicario-core}/src/crypto.rs (92%) rename crates/{idfoto-core => relicario-core}/src/error.rs (81%) rename crates/{idfoto-core => relicario-core}/src/generators.rs (93%) rename crates/{idfoto-core => relicario-core}/src/ids.rs (100%) rename crates/{idfoto-core => relicario-core}/src/imgsecret.rs (97%) rename crates/{idfoto-core => relicario-core}/src/item.rs (98%) rename crates/{idfoto-core => relicario-core}/src/item_types/card.rs (100%) rename crates/{idfoto-core => relicario-core}/src/item_types/document.rs (100%) rename crates/{idfoto-core => relicario-core}/src/item_types/identity.rs (100%) rename crates/{idfoto-core => relicario-core}/src/item_types/key.rs (100%) rename crates/{idfoto-core => relicario-core}/src/item_types/login.rs (100%) rename crates/{idfoto-core => relicario-core}/src/item_types/mod.rs (100%) rename crates/{idfoto-core => relicario-core}/src/item_types/secure_note.rs (100%) rename crates/{idfoto-core => relicario-core}/src/item_types/totp.rs (100%) rename crates/{idfoto-core => relicario-core}/src/lib.rs (95%) rename crates/{idfoto-core => relicario-core}/src/manifest.rs (100%) rename crates/{idfoto-core => relicario-core}/src/settings.rs (100%) rename crates/{idfoto-core => relicario-core}/src/time.rs (100%) rename crates/{idfoto-core => relicario-core}/src/vault.rs (100%) rename crates/{idfoto-core => relicario-core}/tests/attachments.rs (92%) rename crates/{idfoto-core => relicario-core}/tests/field_history.rs (97%) rename crates/{idfoto-core => relicario-core}/tests/format_v2.rs (93%) rename crates/{idfoto-core => relicario-core}/tests/generators.rs (99%) rename crates/{idfoto-core => relicario-core}/tests/integration.rs (95%) rename crates/{idfoto-wasm => relicario-wasm}/Cargo.toml (85%) rename crates/{idfoto-wasm => relicario-wasm}/src/lib.rs (97%) diff --git a/Cargo.lock b/Cargo.lock index 3d95328..68b9fa6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -830,63 +830,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "idfoto-cli" -version = "0.1.0" -dependencies = [ - "anyhow", - "arboard", - "clap", - "dirs", - "ed25519-dalek", - "hex", - "idfoto-core", - "rand", - "rpassword", - "serde", - "serde_json", - "zeroize", -] - -[[package]] -name = "idfoto-core" -version = "0.1.0" -dependencies = [ - "argon2", - "bip39", - "chacha20poly1305", - "chrono", - "ed25519-dalek", - "getrandom", - "hex", - "image", - "rand", - "serde", - "serde_json", - "sha2", - "thiserror 2.0.18", - "unicode-normalization", - "url", - "zeroize", - "zxcvbn", -] - -[[package]] -name = "idfoto-wasm" -version = "0.1.0" -dependencies = [ - "data-encoding", - "getrandom", - "hmac", - "idfoto-core", - "image", - "js-sys", - "serde_json", - "sha1", - "wasm-bindgen", - "wasm-bindgen-test", -] - [[package]] name = "idna" version = "1.1.0" @@ -1397,6 +1340,63 @@ version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +[[package]] +name = "relicario-cli" +version = "0.1.0" +dependencies = [ + "anyhow", + "arboard", + "clap", + "dirs", + "ed25519-dalek", + "hex", + "rand", + "relicario-core", + "rpassword", + "serde", + "serde_json", + "zeroize", +] + +[[package]] +name = "relicario-core" +version = "0.1.0" +dependencies = [ + "argon2", + "bip39", + "chacha20poly1305", + "chrono", + "ed25519-dalek", + "getrandom", + "hex", + "image", + "rand", + "serde", + "serde_json", + "sha2", + "thiserror 2.0.18", + "unicode-normalization", + "url", + "zeroize", + "zxcvbn", +] + +[[package]] +name = "relicario-wasm" +version = "0.1.0" +dependencies = [ + "data-encoding", + "getrandom", + "hmac", + "image", + "js-sys", + "relicario-core", + "serde_json", + "sha1", + "wasm-bindgen", + "wasm-bindgen-test", +] + [[package]] name = "rpassword" version = "5.0.1" diff --git a/Cargo.toml b/Cargo.toml index 1b9dee3..801ab1b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [workspace] resolver = "2" members = [ - "crates/idfoto-core", - "crates/idfoto-cli", - "crates/idfoto-wasm", + "crates/relicario-core", + "crates/relicario-cli", + "crates/relicario-wasm", ] diff --git a/crates/idfoto-cli/Cargo.toml b/crates/relicario-cli/Cargo.toml similarity index 81% rename from crates/idfoto-cli/Cargo.toml rename to crates/relicario-cli/Cargo.toml index dd1b7ed..abc59a7 100644 --- a/crates/idfoto-cli/Cargo.toml +++ b/crates/relicario-cli/Cargo.toml @@ -1,15 +1,15 @@ [package] -name = "idfoto-cli" +name = "relicario-cli" version = "0.1.0" edition = "2021" description = "CLI for idfoto password manager" [[bin]] -name = "idfoto" +name = "relicario" path = "src/main.rs" [dependencies] -idfoto-core = { path = "../idfoto-core" } +relicario-core = { path = "../relicario-core" } clap = { version = "4", features = ["derive"] } anyhow = "1" rpassword = "5" diff --git a/crates/idfoto-cli/src/main.rs b/crates/relicario-cli/src/main.rs similarity index 95% rename from crates/idfoto-cli/src/main.rs rename to crates/relicario-cli/src/main.rs index 8a27d5b..d720710 100644 --- a/crates/idfoto-cli/src/main.rs +++ b/crates/relicario-cli/src/main.rs @@ -1,14 +1,14 @@ //! idfoto CLI -- the platform layer for the idfoto password manager. //! //! This binary provides the filesystem, git, and terminal I/O that -//! [`idfoto_core`] intentionally excludes. It is the "glue" between the +//! [`relicario_core`] intentionally excludes. It is the "glue" between the //! platform-agnostic core library and the user's local environment. //! //! ## Vault layout on disk //! //! ```text //! / -//! .idfoto/ +//! .relicario/ //! salt # 32-byte random salt for Argon2id KDF //! params.json # KDF tuning parameters (m, t, p) //! devices.json # registered device public keys @@ -23,10 +23,10 @@ //! //! Every command that accesses vault data follows this sequence: //! -//! 1. Locate the reference image (via `IDFOTO_IMAGE` env var or interactive prompt). +//! 1. Locate the reference image (via `RELICARIO_IMAGE` env var or interactive prompt). //! 2. Prompt for the passphrase (read from stderr, not echoed). //! 3. Extract the 32-byte image secret from the reference JPEG via DCT steganography. -//! 4. Read the vault salt and KDF params from `.idfoto/`. +//! 4. Read the vault salt and KDF params from `.relicario/`. //! 5. Derive the master key: `Argon2id(passphrase || image_secret, salt, params)`. //! 6. Use the master key to decrypt the manifest and/or individual entries. //! @@ -39,7 +39,7 @@ use anyhow::{bail, Context, Result}; use clap::{Parser, Subcommand}; -use idfoto_core::{ +use relicario_core::{ decrypt_entry, decrypt_manifest, encrypt_entry, encrypt_manifest, generate_entry_id, Entry, KdfParams, Manifest, ManifestEntry, }; @@ -57,7 +57,7 @@ use std::process::Command; /// Top-level CLI argument parser. #[derive(Parser)] #[command( - name = "idfoto", + name = "relicario", version, about = "Git-backed password manager with reference image authentication" )] @@ -133,7 +133,7 @@ enum DeviceCommands { // ─── Device entry ─────────────────────────────────────────────────────────── -/// A registered device, stored in `.idfoto/devices.json`. +/// A registered device, stored in `.relicario/devices.json`. /// /// Each device has an ed25519 keypair. The private key lives on the device /// itself (in the user's config directory); only the public key is stored @@ -155,12 +155,12 @@ fn vault_dir() -> PathBuf { std::env::current_dir().expect("failed to get current directory") } -/// Returns the path to the `.idfoto/` configuration directory within the vault. +/// Returns the path to the `.relicario/` configuration directory within the vault. fn idfoto_dir() -> PathBuf { vault_dir().join(".idfoto") } -/// Read the 32-byte vault salt from `.idfoto/salt`. +/// Read the 32-byte vault salt from `.relicario/salt`. /// /// The salt is generated once during `init` and is unique per vault. It is /// not secret (stored in plaintext) -- its purpose is to prevent precomputed @@ -175,7 +175,7 @@ fn read_salt() -> Result<[u8; 32]> { Ok(salt) } -/// Read the KDF parameters from `.idfoto/params.json`. +/// Read the KDF parameters from `.relicario/params.json`. fn read_params() -> Result { let data = fs::read_to_string(idfoto_dir().join("params.json")) .context("failed to read params.json")?; @@ -185,10 +185,10 @@ fn read_params() -> Result { /// Locate the reference image path. /// -/// First checks the `IDFOTO_IMAGE` environment variable (useful for scripting +/// First checks the `RELICARIO_IMAGE` environment variable (useful for scripting /// and testing). If not set, prompts the user interactively. fn get_image_path() -> Result { - if let Ok(path) = std::env::var("IDFOTO_IMAGE") { + if let Ok(path) = std::env::var("RELICARIO_IMAGE") { return Ok(PathBuf::from(path)); } let path = prompt("Reference image path")?; @@ -207,12 +207,12 @@ fn unlock(image_path: &PathBuf) -> Result> { let jpeg_data = fs::read(image_path).context("failed to read reference image")?; let image_secret = - idfoto_core::imgsecret::extract(&jpeg_data).context("failed to extract image secret")?; + relicario_core::imgsecret::extract(&jpeg_data).context("failed to extract image secret")?; let salt = read_salt()?; let params = read_params()?; - let master_key = idfoto_core::derive_master_key(passphrase.as_bytes(), &image_secret, &salt, ¶ms) + let master_key = relicario_core::derive_master_key(passphrase.as_bytes(), &image_secret, &salt, ¶ms) .context("failed to derive master key")?; Ok(master_key) @@ -329,7 +329,7 @@ fn generate_password(length: usize) -> String { /// 5. Prompt for a passphrase (minimum 8 characters, with confirmation). /// 6. Generate a random 32-byte salt. /// 7. Derive the master key from passphrase + image_secret + salt. -/// 8. Create the vault directory structure (.idfoto/, entries/). +/// 8. Create the vault directory structure (.relicario/, entries/). /// 9. Write salt, KDF params, empty devices list, and encrypted empty manifest. /// 10. Initialize git and create the first commit. fn cmd_init(image: PathBuf, output: PathBuf) -> Result<()> { @@ -342,7 +342,7 @@ fn cmd_init(image: PathBuf, output: PathBuf) -> Result<()> { // 3. Embed secret into carrier let reference_jpeg = - idfoto_core::imgsecret::embed(&carrier, &image_secret).context("failed to embed secret")?; + relicario_core::imgsecret::embed(&carrier, &image_secret).context("failed to embed secret")?; // 4. Save reference JPEG fs::write(&output, &reference_jpeg).context("failed to write reference image")?; @@ -371,7 +371,7 @@ fn cmd_init(image: PathBuf, output: PathBuf) -> Result<()> { // 7. Derive master key let params = KdfParams::default(); - let master_key = idfoto_core::derive_master_key(passphrase.as_bytes(), &image_secret, &salt, ¶ms) + let master_key = relicario_core::derive_master_key(passphrase.as_bytes(), &image_secret, &salt, ¶ms) .context("failed to derive master key")?; // 8. Create directory structure @@ -758,7 +758,7 @@ fn cmd_sync() -> Result<()> { // ─── Device management ────────────────────────────────────────────────────── -/// Read the device registry from `.idfoto/devices.json`. +/// Read the device registry from `.relicario/devices.json`. fn read_devices() -> Result> { let path = idfoto_dir().join("devices.json"); let data = fs::read_to_string(&path).context("failed to read devices.json")?; @@ -766,7 +766,7 @@ fn read_devices() -> Result> { Ok(devices) } -/// Write the device registry to `.idfoto/devices.json`. +/// Write the device registry to `.relicario/devices.json`. fn write_devices(devices: &[DeviceEntry]) -> Result<()> { let data = serde_json::to_string_pretty(devices)?; fs::write(idfoto_dir().join("devices.json"), data).context("failed to write devices.json")?; @@ -801,7 +801,7 @@ fn cmd_device_add(name: String) -> Result<()> { // Save private key to the user's config directory (NOT in the vault) let config_dir = dirs::config_dir() .context("failed to find config directory")? - .join("idfoto"); + .join("relicario"); fs::create_dir_all(&config_dir).context("failed to create config directory")?; let key_path = config_dir.join(format!("{}.key", name)); fs::write(&key_path, &private_key_hex).context("failed to write private key")?; diff --git a/crates/idfoto-core/Cargo.toml b/crates/relicario-core/Cargo.toml similarity index 97% rename from crates/idfoto-core/Cargo.toml rename to crates/relicario-core/Cargo.toml index 0ae3a70..0e3b3c7 100644 --- a/crates/idfoto-core/Cargo.toml +++ b/crates/relicario-core/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "idfoto-core" +name = "relicario-core" version = "0.1.0" edition = "2021" description = "Core library for idfoto password manager" diff --git a/crates/idfoto-core/src/attachment.rs b/crates/relicario-core/src/attachment.rs similarity index 93% rename from crates/idfoto-core/src/attachment.rs rename to crates/relicario-core/src/attachment.rs index 84e791d..93fb7cc 100644 --- a/crates/idfoto-core/src/attachment.rs +++ b/crates/relicario-core/src/attachment.rs @@ -43,7 +43,7 @@ impl From<&AttachmentRef> for AttachmentSummary { use zeroize::Zeroizing; use crate::crypto::{decrypt, encrypt}; -use crate::error::{IdfotoError, Result}; +use crate::error::{RelicarioError, Result}; /// Encrypted attachment with the AID derived from plaintext content. #[derive(Debug)] @@ -54,7 +54,7 @@ pub struct EncryptedAttachment { /// Encrypt raw attachment bytes, deriving the [`AttachmentId`] from `sha256(plaintext)`. /// -/// Returns [`IdfotoError::AttachmentTooLarge`] immediately if `plaintext.len() > max_bytes`, +/// Returns [`RelicarioError::AttachmentTooLarge`] immediately if `plaintext.len() > max_bytes`, /// before any crypto work is done. /// /// ## Call-site adaptation @@ -67,7 +67,7 @@ pub fn encrypt_attachment( max_bytes: u64, ) -> Result { if plaintext.len() as u64 > max_bytes { - return Err(IdfotoError::AttachmentTooLarge { + return Err(RelicarioError::AttachmentTooLarge { size: plaintext.len() as u64, max: max_bytes, }); @@ -118,7 +118,7 @@ mod crypto_tests { fn oversize_attachment_rejected() { let plaintext = vec![0u8; 11_000_000]; let err = encrypt_attachment(&plaintext, &key(), 10 * 1024 * 1024); - assert!(matches!(err, Err(IdfotoError::AttachmentTooLarge { .. }))); + assert!(matches!(err, Err(RelicarioError::AttachmentTooLarge { .. }))); } #[test] @@ -127,7 +127,7 @@ mod crypto_tests { let enc = encrypt_attachment(plaintext, &key(), 1024).unwrap(); let wrong = Zeroizing::new([0u8; 32]); let err = decrypt_attachment(&enc.bytes, &wrong); - assert!(matches!(err, Err(IdfotoError::Decrypt))); + assert!(matches!(err, Err(RelicarioError::Decrypt))); } } diff --git a/crates/idfoto-core/src/crypto.rs b/crates/relicario-core/src/crypto.rs similarity index 92% rename from crates/idfoto-core/src/crypto.rs rename to crates/relicario-core/src/crypto.rs index e2d7fa8..8c38d78 100644 --- a/crates/idfoto-core/src/crypto.rs +++ b/crates/relicario-core/src/crypto.rs @@ -41,7 +41,7 @@ //! ``` //! //! Both factors contribute to the derived key -- compromising one without the -//! other is insufficient. The salt is vault-specific and stored in `.idfoto/salt`. +//! other is insufficient. The salt is vault-specific and stored in `.relicario/salt`. use argon2::{Algorithm, Argon2, Params, Version}; use chacha20poly1305::{ @@ -53,7 +53,7 @@ use serde::{Deserialize, Serialize}; use unicode_normalization::UnicodeNormalization; use zeroize::Zeroizing; -use crate::error::{IdfotoError, Result}; +use crate::error::{RelicarioError, Result}; /// Current binary format version. Increment this if the ciphertext layout changes. pub const VERSION_BYTE: u8 = 0x02; @@ -76,7 +76,7 @@ const HEADER_LEN: usize = 1 + NONCE_LEN; // version + nonce /// /// # Errors /// -/// Returns [`IdfotoError::Encrypt`] if the underlying AEAD operation fails +/// Returns [`RelicarioError::Encrypt`] if the underlying AEAD operation fails /// (extremely unlikely in practice). pub fn encrypt(key: &[u8; 32], plaintext: &[u8]) -> Result> { let cipher = XChaCha20Poly1305::new(key.into()); @@ -90,7 +90,7 @@ pub fn encrypt(key: &[u8; 32], plaintext: &[u8]) -> Result> { let ciphertext = cipher .encrypt(&nonce, plaintext) - .map_err(|e| IdfotoError::Encrypt(e.to_string()))?; + .map_err(|e| RelicarioError::Encrypt(e.to_string()))?; // Output: version(1) || nonce(24) || ciphertext+tag let mut output = Vec::with_capacity(HEADER_LEN + ciphertext.len()); @@ -105,27 +105,27 @@ pub fn encrypt(key: &[u8; 32], plaintext: &[u8]) -> Result> { /// /// Validates the version byte and minimum blob length before attempting /// authenticated decryption. If the key is wrong or the data has been -/// tampered with, the Poly1305 tag verification fails and [`IdfotoError::Decrypt`] +/// tampered with, the Poly1305 tag verification fails and [`RelicarioError::Decrypt`] /// is returned -- with no information about which bytes were wrong (preventing /// padding oracle / chosen-ciphertext attacks). /// /// # Errors /// -/// - [`IdfotoError::Format`] if the data is too short or has an unknown version byte. -/// - [`IdfotoError::Decrypt`] if the AEAD tag verification fails (wrong key or +/// - [`RelicarioError::Format`] if the data is too short or has an unknown version byte. +/// - [`RelicarioError::Decrypt`] if the AEAD tag verification fails (wrong key or /// tampered data). pub fn decrypt(key: &[u8; 32], data: &[u8]) -> Result> { // Minimum valid blob: 1 (version) + 24 (nonce) + 16 (tag) = 41 bytes. // A zero-length plaintext produces exactly 41 bytes of output. if data.len() < HEADER_LEN + TAG_LEN { - return Err(IdfotoError::Format( + return Err(RelicarioError::Format( "data too short to be valid ciphertext".into(), )); } let found = data[0]; if found != VERSION_BYTE { - return Err(IdfotoError::UnsupportedFormatVersion { + return Err(RelicarioError::UnsupportedFormatVersion { found, expected: VERSION_BYTE, }); @@ -137,14 +137,14 @@ pub fn decrypt(key: &[u8; 32], data: &[u8]) -> Result> { let cipher = XChaCha20Poly1305::new(key.into()); let plaintext = cipher .decrypt(nonce, ciphertext) - .map_err(|_| IdfotoError::Decrypt)?; + .map_err(|_| RelicarioError::Decrypt)?; Ok(plaintext) } /// Tunable parameters for the Argon2id key derivation function. /// -/// These are stored in the vault's `.idfoto/params.json` so that every client +/// These are stored in the vault's `.relicario/params.json` so that every client /// derives the same master key from the same inputs. Making them configurable /// lets tests use fast params (m=256, t=1, p=1) while production uses strong /// params (m=64MiB, t=3, p=4). @@ -193,8 +193,8 @@ impl Default for KdfParams { /// - `passphrase`: the user's passphrase as raw UTF-8 bytes. /// - `image_secret`: the 32-byte secret extracted from the reference JPEG via /// [`crate::imgsecret::extract`]. -/// - `salt`: a 32-byte vault-specific salt (stored in `.idfoto/salt`). -/// - `params`: the Argon2id tuning parameters (stored in `.idfoto/params.json`). +/// - `salt`: a 32-byte vault-specific salt (stored in `.relicario/salt`). +/// - `params`: the Argon2id tuning parameters (stored in `.relicario/params.json`). /// /// # Returns /// @@ -202,7 +202,7 @@ impl Default for KdfParams { /// /// # Errors /// -/// Returns [`IdfotoError::Kdf`] if the Argon2id parameters are invalid (e.g., +/// Returns [`RelicarioError::Kdf`] if the Argon2id parameters are invalid (e.g., /// memory cost below the library's minimum). pub fn derive_master_key( passphrase: &[u8], @@ -216,7 +216,7 @@ pub fn derive_master_key( params.argon2_p, Some(32), ) - .map_err(|e| IdfotoError::Kdf(e.to_string()))?; + .map_err(|e| RelicarioError::Kdf(e.to_string()))?; let argon2 = Argon2::new(Algorithm::Argon2id, Version::V0x13, argon2_params); @@ -238,7 +238,7 @@ pub fn derive_master_key( let mut output = Zeroizing::new([0u8; 32]); argon2 .hash_password_into(password.as_slice(), salt, output.as_mut()) - .map_err(|e| IdfotoError::Kdf(e.to_string()))?; + .map_err(|e| RelicarioError::Kdf(e.to_string()))?; Ok(output) } @@ -316,7 +316,7 @@ mod tests { let result = decrypt(&wrong_key, &ciphertext); assert!(result.is_err()); - assert!(matches!(result.unwrap_err(), IdfotoError::Decrypt)); + assert!(matches!(result.unwrap_err(), RelicarioError::Decrypt)); } #[test] @@ -410,7 +410,7 @@ mod tests { let key = Zeroizing::new([0u8; 32]); let err = decrypt(&*key, &blob).expect_err("v1 blob should fail decrypt"); match err { - IdfotoError::UnsupportedFormatVersion { found, expected } => { + RelicarioError::UnsupportedFormatVersion { found, expected } => { assert_eq!(found, 0x01); assert_eq!(expected, 0x02); } diff --git a/crates/idfoto-core/src/error.rs b/crates/relicario-core/src/error.rs similarity index 81% rename from crates/idfoto-core/src/error.rs rename to crates/relicario-core/src/error.rs index cd9be18..1bf9cbd 100644 --- a/crates/idfoto-core/src/error.rs +++ b/crates/relicario-core/src/error.rs @@ -1,19 +1,19 @@ -//! Unified error type for the idfoto-core crate. +//! Unified error type for the relicario-core crate. //! //! Every fallible function in this crate returns [`Result`], which is an alias -//! for `std::result::Result`. Using a single error enum keeps the +//! for `std::result::Result`. Using a single error enum keeps the //! public API surface predictable and makes error handling in callers (CLI, WASM //! bindings, mobile FFI) straightforward. use thiserror::Error; -/// All errors that can originate from idfoto-core operations. +/// All errors that can originate from relicario-core operations. /// /// Variants are ordered roughly by the pipeline stage where they occur: /// KDF -> encryption -> decryption -> format parsing -> item lookup -> image /// steganography -> serialization -> device keys. #[derive(Debug, Error)] -pub enum IdfotoError { +pub enum RelicarioError { #[error("key derivation failed: {0}")] Kdf(String), @@ -64,7 +64,7 @@ pub enum IdfotoError { } /// Crate-wide result alias, reducing boilerplate in function signatures. -pub type Result = std::result::Result; +pub type Result = std::result::Result; #[cfg(test)] mod tests { @@ -72,13 +72,13 @@ mod tests { #[test] fn decrypt_error_message_is_opaque() { - let err = IdfotoError::Decrypt; + let err = RelicarioError::Decrypt; assert_eq!(format!("{}", err), "decryption failed"); } #[test] fn weak_passphrase_carries_score() { - let err = IdfotoError::WeakPassphrase { score: 1 }; + let err = RelicarioError::WeakPassphrase { score: 1 }; let s = format!("{}", err); assert!(s.contains("passphrase")); assert!(s.contains("strength")); @@ -86,7 +86,7 @@ mod tests { #[test] fn attachment_too_large_reports_sizes() { - let err = IdfotoError::AttachmentTooLarge { size: 11_000_000, max: 10_485_760 }; + let err = RelicarioError::AttachmentTooLarge { size: 11_000_000, max: 10_485_760 }; let s = format!("{}", err); assert!(s.contains("11000000")); assert!(s.contains("10485760")); @@ -94,13 +94,13 @@ mod tests { #[test] fn item_not_found_carries_id() { - let err = IdfotoError::ItemNotFound("abc123".to_string()); + let err = RelicarioError::ItemNotFound("abc123".to_string()); assert!(format!("{}", err).contains("abc123")); } #[test] fn unsupported_format_version_reports_byte() { - let err = IdfotoError::UnsupportedFormatVersion { found: 0x01, expected: 0x02 }; + let err = RelicarioError::UnsupportedFormatVersion { found: 0x01, expected: 0x02 }; let s = format!("{}", err); assert!(s.contains("01") || s.contains("1")); assert!(s.contains("02") || s.contains("2")); diff --git a/crates/idfoto-core/src/generators.rs b/crates/relicario-core/src/generators.rs similarity index 93% rename from crates/idfoto-core/src/generators.rs rename to crates/relicario-core/src/generators.rs index 36b4930..c54f976 100644 --- a/crates/idfoto-core/src/generators.rs +++ b/crates/relicario-core/src/generators.rs @@ -7,7 +7,7 @@ use rand::rngs::OsRng; use rand::RngCore; use zeroize::Zeroizing; -use crate::error::{IdfotoError, Result}; +use crate::error::{RelicarioError, Result}; use crate::settings::{Capitalization, CharClasses, GeneratorRequest, SymbolCharset}; const SAFE_SYMBOLS: &[u8] = b"!@#$%^&*-_=+"; @@ -21,7 +21,7 @@ pub fn generate_password(req: &GeneratorRequest) -> Result> { GeneratorRequest::Random { length, classes, symbol_charset } => { random_password(*length, classes, symbol_charset) } - GeneratorRequest::Bip39 { .. } => Err(IdfotoError::Format( + GeneratorRequest::Bip39 { .. } => Err(RelicarioError::Format( "use generate_passphrase() for BIP39 requests".into(), )), } @@ -33,7 +33,7 @@ fn random_password( symbol_charset: &SymbolCharset, ) -> Result> { if length == 0 || length > 128 { - return Err(IdfotoError::Format("length must be 1..=128".into())); + return Err(RelicarioError::Format("length must be 1..=128".into())); } let mut charset: Vec = Vec::new(); if classes.lower { charset.extend_from_slice(LOWER); } @@ -45,7 +45,7 @@ fn random_password( SymbolCharset::Extended => EXTENDED_SYMBOLS, SymbolCharset::Custom(s) => { if !s.is_ascii() { - return Err(IdfotoError::Format( + return Err(RelicarioError::Format( "SymbolCharset::Custom must be ASCII-only".into(), )); } @@ -55,7 +55,7 @@ fn random_password( charset.extend_from_slice(symbols); } if charset.is_empty() { - return Err(IdfotoError::Format("at least one character class required".into())); + return Err(RelicarioError::Format("at least one character class required".into())); } let dist = Uniform::from(0..charset.len()); @@ -69,7 +69,7 @@ pub fn generate_passphrase(req: &GeneratorRequest) -> Result> GeneratorRequest::Bip39 { word_count, separator, capitalization } => { bip39_passphrase(*word_count, separator, *capitalization) } - GeneratorRequest::Random { .. } => Err(IdfotoError::Format( + GeneratorRequest::Random { .. } => Err(RelicarioError::Format( "use generate_password() for Random requests".into(), )), } @@ -77,7 +77,7 @@ pub fn generate_passphrase(req: &GeneratorRequest) -> Result> fn bip39_passphrase(word_count: u32, separator: &str, cap: Capitalization) -> Result> { if !matches!(word_count, 3..=12) { - return Err(IdfotoError::Format("word_count must be 3..=12".into())); + return Err(RelicarioError::Format("word_count must be 3..=12".into())); } // bip39 v2 requires entropy 128–256 bits in multiples of 32 bits (4 bytes). // We always generate 128 bits (16 bytes) → 12 words, then take the first @@ -85,7 +85,7 @@ fn bip39_passphrase(word_count: u32, separator: &str, cap: Capitalization) -> Re let mut entropy = Zeroizing::new([0u8; 16]); OsRng.fill_bytes(entropy.as_mut_slice()); let m = Mnemonic::from_entropy_in(Language::English, entropy.as_slice()) - .map_err(|e| IdfotoError::Format(format!("bip39: {e}")))?; + .map_err(|e| RelicarioError::Format(format!("bip39: {e}")))?; let words: Vec = m.words().take(word_count as usize).map(|w| { match cap { Capitalization::Lower => w.to_ascii_lowercase(), @@ -124,7 +124,7 @@ pub fn rate_passphrase(p: &str) -> StrengthEstimate { pub fn validate_passphrase_strength(p: &str) -> Result<()> { let est = rate_passphrase(p); if est.score < 3 { - return Err(IdfotoError::WeakPassphrase { score: est.score }); + return Err(RelicarioError::WeakPassphrase { score: est.score }); } Ok(()) } diff --git a/crates/idfoto-core/src/ids.rs b/crates/relicario-core/src/ids.rs similarity index 100% rename from crates/idfoto-core/src/ids.rs rename to crates/relicario-core/src/ids.rs diff --git a/crates/idfoto-core/src/imgsecret.rs b/crates/relicario-core/src/imgsecret.rs similarity index 97% rename from crates/idfoto-core/src/imgsecret.rs rename to crates/relicario-core/src/imgsecret.rs index 1b22cc5..cfd1686 100644 --- a/crates/idfoto-core/src/imgsecret.rs +++ b/crates/relicario-core/src/imgsecret.rs @@ -39,7 +39,7 @@ //! - Mild cropping (up to ~10% from edges, within the 15% crumple zone) //! - Color space conversions (embedding is in luminance only) -use crate::error::{IdfotoError, Result}; +use crate::error::{RelicarioError, Result}; use image::codecs::jpeg::JpegEncoder; use image::ImageReader; use image::{ImageEncoder, Rgb, RgbImage}; @@ -179,10 +179,10 @@ struct EmbedRegion { fn extract_y_channel(jpeg_bytes: &[u8]) -> Result { let reader = ImageReader::new(Cursor::new(jpeg_bytes)) .with_guessed_format() - .map_err(|e| IdfotoError::ImgSecret(format!("failed to read image: {e}")))?; + .map_err(|e| RelicarioError::ImgSecret(format!("failed to read image: {e}")))?; let img = reader .decode() - .map_err(|e| IdfotoError::ImgSecret(format!("failed to decode image: {e}")))?; + .map_err(|e| RelicarioError::ImgSecret(format!("failed to decode image: {e}")))?; let rgb = img.to_rgb8(); let (width, height) = (rgb.width() as usize, rgb.height() as usize); let mut data = Vec::with_capacity(width * height); @@ -527,10 +527,10 @@ fn select_embed_blocks(region: &EmbedRegion, target_count: usize) -> Vec<(usize, fn reconstruct_jpeg(original_jpeg: &[u8], y_modified: &YChannel) -> Result> { let reader = ImageReader::new(Cursor::new(original_jpeg)) .with_guessed_format() - .map_err(|e| IdfotoError::ImgSecret(format!("failed to read image: {e}")))?; + .map_err(|e| RelicarioError::ImgSecret(format!("failed to read image: {e}")))?; let img = reader .decode() - .map_err(|e| IdfotoError::ImgSecret(format!("failed to decode image: {e}")))?; + .map_err(|e| RelicarioError::ImgSecret(format!("failed to decode image: {e}")))?; let rgb = img.to_rgb8(); let (width, height) = (rgb.width(), rgb.height()); @@ -572,7 +572,7 @@ fn reconstruct_jpeg(original_jpeg: &[u8], y_modified: &YChannel) -> Result Result Result> { let mut y = extract_y_channel(carrier_jpeg)?; if (y.width as u32) < MIN_DIMENSION || (y.height as u32) < MIN_DIMENSION { - return Err(IdfotoError::ImageTooSmall { + return Err(RelicarioError::ImageTooSmall { min_width: MIN_DIMENSION, min_height: MIN_DIMENSION, actual_width: y.width as u32, @@ -616,7 +616,7 @@ pub fn embed(carrier_jpeg: &[u8], secret: &[u8; 32]) -> Result> { let total_blocks = region.blocks_x * region.blocks_y; if total_blocks < BLOCKS_PER_COPY * MIN_COPIES { - return Err(IdfotoError::ImageTooSmall { + return Err(RelicarioError::ImageTooSmall { min_width: MIN_DIMENSION, min_height: MIN_DIMENSION, actual_width: y.width as u32, @@ -669,7 +669,7 @@ pub fn embed(carrier_jpeg: &[u8], secret: &[u8; 32]) -> Result> { /// /// # Errors /// -/// - [`IdfotoError::ExtractionFailed`] if no valid secret could be recovered +/// - [`RelicarioError::ExtractionFailed`] if no valid secret could be recovered /// (image was never watermarked, or was too heavily recompressed/cropped). pub fn extract(jpeg_bytes: &[u8]) -> Result<[u8; 32]> { extract_with_crop_recovery(jpeg_bytes) @@ -695,7 +695,7 @@ fn try_extract_with_layout( ) -> Result<[u8; 32]> { let positions = compute_embed_positions(orig_w, orig_h); if positions.is_empty() { - return Err(IdfotoError::ExtractionFailed); + return Err(RelicarioError::ExtractionFailed); } let region = compute_region(orig_w, orig_h); @@ -750,14 +750,14 @@ fn try_extract_with_layout( let mut result_bits = vec![0u8; SECRET_BITS]; for i in 0..SECRET_BITS { if votes_total[i] == 0 { - return Err(IdfotoError::ExtractionFailed); + return Err(RelicarioError::ExtractionFailed); } let ones = votes_one[i]; let zeros = votes_total[i] - ones; let majority = ones.max(zeros); let confidence = majority as f64 / votes_total[i] as f64; if confidence < 0.60 { - return Err(IdfotoError::ExtractionFailed); + return Err(RelicarioError::ExtractionFailed); } result_bits[i] = if ones > zeros { 1 } else { 0 }; } @@ -785,7 +785,7 @@ fn extract_with_crop_recovery(jpeg_bytes: &[u8]) -> Result<[u8; 32]> { let y = extract_y_channel(jpeg_bytes)?; if (y.width as u32) < MIN_DIMENSION || (y.height as u32) < MIN_DIMENSION { - return Err(IdfotoError::ExtractionFailed); + return Err(RelicarioError::ExtractionFailed); } // Try 1: assume the image is uncropped (original size = current size) @@ -830,7 +830,7 @@ fn extract_with_crop_recovery(jpeg_bytes: &[u8]) -> Result<[u8; 32]> { } } - Err(IdfotoError::ExtractionFailed) + Err(RelicarioError::ExtractionFailed) } // ─── Tests ─────────────────────────────────────────────────────────────────── diff --git a/crates/idfoto-core/src/item.rs b/crates/relicario-core/src/item.rs similarity index 98% rename from crates/idfoto-core/src/item.rs rename to crates/relicario-core/src/item.rs index c29140a..fa65613 100644 --- a/crates/idfoto-core/src/item.rs +++ b/crates/relicario-core/src/item.rs @@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize}; use url::Url; use zeroize::Zeroizing; -use crate::error::{IdfotoError, Result}; +use crate::error::{RelicarioError, Result}; use crate::ids::{AttachmentId, FieldId}; use crate::item_types::TotpConfig; use crate::time::MonthYear; @@ -96,7 +96,7 @@ impl Field { /// Verify kind/value discriminants match. Called after deserialization. pub fn validate(&self) -> Result<()> { if self.kind != self.value.kind() { - return Err(IdfotoError::Format(format!( + return Err(RelicarioError::Format(format!( "field {}: kind {:?} does not match value discriminant {:?}", self.id.as_str(), self.kind, @@ -182,7 +182,7 @@ impl Item { for section in &mut self.sections { if let Some(field) = section.fields.iter_mut().find(|f| &f.id == field_id) { if field.value.kind() != new_value.kind() { - return Err(IdfotoError::Format(format!( + return Err(RelicarioError::Format(format!( "field {}: cannot change kind from {:?} to {:?}", field.id.as_str(), field.value.kind(), new_value.kind() ))); @@ -199,7 +199,7 @@ impl Item { return Ok(()); } } - Err(IdfotoError::Format(format!("field {} not found", field_id.as_str()))) + Err(RelicarioError::Format(format!("field {} not found", field_id.as_str()))) } pub fn soft_delete(&mut self) { @@ -247,7 +247,7 @@ fn serialize_history_value(value: &FieldValue) -> Result> { let s = base32_encode(&cfg.secret); Zeroizing::new(s) } - _ => return Err(IdfotoError::Format("not a history-tracked kind".into())), + _ => return Err(RelicarioError::Format("not a history-tracked kind".into())), }; Ok(s) } diff --git a/crates/idfoto-core/src/item_types/card.rs b/crates/relicario-core/src/item_types/card.rs similarity index 100% rename from crates/idfoto-core/src/item_types/card.rs rename to crates/relicario-core/src/item_types/card.rs diff --git a/crates/idfoto-core/src/item_types/document.rs b/crates/relicario-core/src/item_types/document.rs similarity index 100% rename from crates/idfoto-core/src/item_types/document.rs rename to crates/relicario-core/src/item_types/document.rs diff --git a/crates/idfoto-core/src/item_types/identity.rs b/crates/relicario-core/src/item_types/identity.rs similarity index 100% rename from crates/idfoto-core/src/item_types/identity.rs rename to crates/relicario-core/src/item_types/identity.rs diff --git a/crates/idfoto-core/src/item_types/key.rs b/crates/relicario-core/src/item_types/key.rs similarity index 100% rename from crates/idfoto-core/src/item_types/key.rs rename to crates/relicario-core/src/item_types/key.rs diff --git a/crates/idfoto-core/src/item_types/login.rs b/crates/relicario-core/src/item_types/login.rs similarity index 100% rename from crates/idfoto-core/src/item_types/login.rs rename to crates/relicario-core/src/item_types/login.rs diff --git a/crates/idfoto-core/src/item_types/mod.rs b/crates/relicario-core/src/item_types/mod.rs similarity index 100% rename from crates/idfoto-core/src/item_types/mod.rs rename to crates/relicario-core/src/item_types/mod.rs diff --git a/crates/idfoto-core/src/item_types/secure_note.rs b/crates/relicario-core/src/item_types/secure_note.rs similarity index 100% rename from crates/idfoto-core/src/item_types/secure_note.rs rename to crates/relicario-core/src/item_types/secure_note.rs diff --git a/crates/idfoto-core/src/item_types/totp.rs b/crates/relicario-core/src/item_types/totp.rs similarity index 100% rename from crates/idfoto-core/src/item_types/totp.rs rename to crates/relicario-core/src/item_types/totp.rs diff --git a/crates/idfoto-core/src/lib.rs b/crates/relicario-core/src/lib.rs similarity index 95% rename from crates/idfoto-core/src/lib.rs rename to crates/relicario-core/src/lib.rs index f65b670..634afa8 100644 --- a/crates/idfoto-core/src/lib.rs +++ b/crates/relicario-core/src/lib.rs @@ -1,4 +1,4 @@ -//! # idfoto-core +//! # relicario-core //! //! Platform-agnostic core library for the idfoto password manager. //! @@ -10,7 +10,7 @@ //! //! ## Modules //! -//! - [`error`] — The unified error type ([`IdfotoError`]). +//! - [`error`] — The unified error type ([`RelicarioError`]). //! - [`crypto`] — Argon2id KDF (length-prefixed inputs, Zeroizing output) and //! XChaCha20-Poly1305 AEAD with VERSION_BYTE 0x02. //! - [`ids`] — `ItemId`, `FieldId`, and content-addressed `AttachmentId`. @@ -38,7 +38,7 @@ //! ``` pub mod error; -pub use error::{IdfotoError, Result}; +pub use error::{RelicarioError, Result}; pub mod crypto; pub use crypto::{decrypt, derive_master_key, encrypt, KdfParams, VERSION_BYTE}; diff --git a/crates/idfoto-core/src/manifest.rs b/crates/relicario-core/src/manifest.rs similarity index 100% rename from crates/idfoto-core/src/manifest.rs rename to crates/relicario-core/src/manifest.rs diff --git a/crates/idfoto-core/src/settings.rs b/crates/relicario-core/src/settings.rs similarity index 100% rename from crates/idfoto-core/src/settings.rs rename to crates/relicario-core/src/settings.rs diff --git a/crates/idfoto-core/src/time.rs b/crates/relicario-core/src/time.rs similarity index 100% rename from crates/idfoto-core/src/time.rs rename to crates/relicario-core/src/time.rs diff --git a/crates/idfoto-core/src/vault.rs b/crates/relicario-core/src/vault.rs similarity index 100% rename from crates/idfoto-core/src/vault.rs rename to crates/relicario-core/src/vault.rs diff --git a/crates/idfoto-core/tests/attachments.rs b/crates/relicario-core/tests/attachments.rs similarity index 92% rename from crates/idfoto-core/tests/attachments.rs rename to crates/relicario-core/tests/attachments.rs index 8ecf188..300228b 100644 --- a/crates/idfoto-core/tests/attachments.rs +++ b/crates/relicario-core/tests/attachments.rs @@ -1,7 +1,7 @@ //! Attachment encrypt/decrypt + content-addressed AID + cap enforcement. -use idfoto_core::{ - AttachmentId, IdfotoError, +use relicario_core::{ + AttachmentId, RelicarioError, crypto::KdfParams, decrypt_attachment, derive_master_key, encrypt_attachment, }; @@ -43,7 +43,7 @@ fn cap_enforcement_at_exact_max() { // One byte over — should fail let err = encrypt_attachment(&plaintext, &key, 1023); match err { - Err(IdfotoError::AttachmentTooLarge { size, max }) => { + Err(RelicarioError::AttachmentTooLarge { size, max }) => { assert_eq!(size, 1024); assert_eq!(max, 1023); } diff --git a/crates/idfoto-core/tests/field_history.rs b/crates/relicario-core/tests/field_history.rs similarity index 97% rename from crates/idfoto-core/tests/field_history.rs rename to crates/relicario-core/tests/field_history.rs index 0cfeb16..0376aed 100644 --- a/crates/idfoto-core/tests/field_history.rs +++ b/crates/relicario-core/tests/field_history.rs @@ -1,12 +1,12 @@ //! Field history end-to-end: capture on update, prune by retention policy, //! survive encrypt/decrypt round-trip. -use idfoto_core::{ +use relicario_core::{ Field, FieldValue, HistoryRetention, Item, ItemCore, Section, crypto::KdfParams, derive_master_key, decrypt_item, encrypt_item, }; -use idfoto_core::item_types::LoginCore; +use relicario_core::item_types::LoginCore; use zeroize::Zeroizing; fn key() -> Zeroizing<[u8; 32]> { diff --git a/crates/idfoto-core/tests/format_v2.rs b/crates/relicario-core/tests/format_v2.rs similarity index 93% rename from crates/idfoto-core/tests/format_v2.rs rename to crates/relicario-core/tests/format_v2.rs index 4d94cdf..b4b4a8e 100644 --- a/crates/idfoto-core/tests/format_v2.rs +++ b/crates/relicario-core/tests/format_v2.rs @@ -2,8 +2,8 @@ //! UnsupportedFormatVersion, length-prefix construction guarantees domain //! separation. -use idfoto_core::{ - IdfotoError, +use relicario_core::{ + RelicarioError, crypto::{KdfParams, VERSION_BYTE}, decrypt, derive_master_key, encrypt, }; @@ -33,7 +33,7 @@ fn v1_blob_is_rejected_with_unsupported_format_version() { // decrypt(key: &[u8; 32], data: &[u8]) let err = decrypt(&key, &blob); match err { - Err(IdfotoError::UnsupportedFormatVersion { found, expected }) => { + Err(RelicarioError::UnsupportedFormatVersion { found, expected }) => { assert_eq!(found, 0x01); assert_eq!(expected, 0x02); } diff --git a/crates/idfoto-core/tests/generators.rs b/crates/relicario-core/tests/generators.rs similarity index 99% rename from crates/idfoto-core/tests/generators.rs rename to crates/relicario-core/tests/generators.rs index 8b2b6a7..e53b1cd 100644 --- a/crates/idfoto-core/tests/generators.rs +++ b/crates/relicario-core/tests/generators.rs @@ -11,7 +11,7 @@ //! counts before asserting proportions. The ±5pp tolerance is unchanged because //! sample size is the same (~10k chars). -use idfoto_core::{ +use relicario_core::{ Capitalization, CharClasses, GeneratorRequest, SymbolCharset, generate_passphrase, generate_password, validate_passphrase_strength, }; diff --git a/crates/idfoto-core/tests/integration.rs b/crates/relicario-core/tests/integration.rs similarity index 95% rename from crates/idfoto-core/tests/integration.rs rename to crates/relicario-core/tests/integration.rs index 5cd2d35..83419eb 100644 --- a/crates/idfoto-core/tests/integration.rs +++ b/crates/relicario-core/tests/integration.rs @@ -1,13 +1,13 @@ //! End-to-end integration tests for the typed-item core. -use idfoto_core::{ +use relicario_core::{ crypto::KdfParams, derive_master_key, encrypt_item, decrypt_item, encrypt_manifest, decrypt_manifest, encrypt_settings, decrypt_settings, Field, FieldValue, Item, ItemCore, Manifest, Section, VaultSettings, }; -use idfoto_core::item_types::{LoginCore, SecureNoteCore}; +use relicario_core::item_types::{LoginCore, SecureNoteCore}; use url::Url; use zeroize::Zeroizing; @@ -97,7 +97,7 @@ fn field_history_persists_through_round_trip() { #[test] fn wrong_key_fails_with_opaque_decrypt() { - use idfoto_core::IdfotoError; + use relicario_core::RelicarioError; let salt = [0u8; 32]; let img = [0u8; 32]; @@ -107,5 +107,5 @@ fn wrong_key_fails_with_opaque_decrypt() { let item = Item::new("x".into(), ItemCore::SecureNote(SecureNoteCore::default())); let blob = encrypt_item(&item, &right).unwrap(); let err = decrypt_item(&blob, &wrong); - assert!(matches!(err, Err(IdfotoError::Decrypt))); + assert!(matches!(err, Err(RelicarioError::Decrypt))); } diff --git a/crates/idfoto-wasm/Cargo.toml b/crates/relicario-wasm/Cargo.toml similarity index 85% rename from crates/idfoto-wasm/Cargo.toml rename to crates/relicario-wasm/Cargo.toml index 16c1e24..e82da03 100644 --- a/crates/idfoto-wasm/Cargo.toml +++ b/crates/relicario-wasm/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "idfoto-wasm" +name = "relicario-wasm" version = "0.1.0" edition = "2021" description = "WASM bindings for idfoto password manager" @@ -8,7 +8,7 @@ description = "WASM bindings for idfoto password manager" crate-type = ["cdylib", "rlib"] [dependencies] -idfoto-core = { path = "../idfoto-core" } +relicario-core = { path = "../relicario-core" } wasm-bindgen = "0.2" js-sys = "0.3" serde_json = "1" diff --git a/crates/idfoto-wasm/src/lib.rs b/crates/relicario-wasm/src/lib.rs similarity index 97% rename from crates/idfoto-wasm/src/lib.rs rename to crates/relicario-wasm/src/lib.rs index 0f82f8a..2f791a3 100644 --- a/crates/idfoto-wasm/src/lib.rs +++ b/crates/relicario-wasm/src/lib.rs @@ -1,6 +1,6 @@ //! WASM bindings for the idfoto password manager. //! -//! This crate wraps [`idfoto_core`] for use in a Chrome MV3 browser extension via +//! This crate wraps [`relicario_core`] for use in a Chrome MV3 browser extension via //! `wasm-bindgen`. Every function marked `#[wasm_bindgen]` is callable from //! JavaScript after loading the compiled `.wasm` module. //! @@ -21,10 +21,10 @@ use wasm_bindgen::prelude::*; -use idfoto_core::crypto::{self, KdfParams}; -use idfoto_core::entry::Entry; -use idfoto_core::vault; -use idfoto_core::imgsecret; +use relicario_core::crypto::{self, KdfParams}; +use relicario_core::entry::Entry; +use relicario_core::vault; +use relicario_core::imgsecret; use hmac::{Hmac, Mac}; use sha1::Sha1; @@ -103,7 +103,7 @@ pub fn embed_image_secret(carrier_jpeg: &[u8], secret: &[u8]) -> Result, let secret: [u8; 32] = secret .try_into() .map_err(|_| JsValue::from_str("secret must be exactly 32 bytes"))?; - idfoto_core::imgsecret::embed(carrier_jpeg, &secret) + relicario_core::imgsecret::embed(carrier_jpeg, &secret) .map_err(|e| JsValue::from_str(&e.to_string())) } @@ -142,7 +142,7 @@ pub fn encrypt_manifest(manifest_json: &str, key: &[u8]) -> Result, JsVa let key: &[u8; 32] = key .try_into() .map_err(|_| JsValue::from_str("key must be exactly 32 bytes"))?; - let manifest: idfoto_core::entry::Manifest = + let manifest: relicario_core::entry::Manifest = serde_json::from_str(manifest_json).map_err(|e| JsValue::from_str(&e.to_string()))?; vault::encrypt_manifest(key, &manifest).map_err(|e| JsValue::from_str(&e.to_string())) }