Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- **Accounts persistence** (PRD §6.4, PRD-v2 §P1.1, task 20): SQLite `accounts` table (migration `m20260428_000006`) with `id` / `service_name` / `username` / `account_type` / `enabled` / `traffic_left` / `traffic_total` / `valid_until` / `last_validated` / `created_at` columns and a UNIQUE `(service_name, username)` index. New `AccountRepository` driven port (`save` / `find_by_id` / `list` / `list_by_service` / `delete`) and `SqliteAccountRepo` adapter with sea-orm entity + `from_domain` / `into_domain` converters. UNIQUE violations surface as `DomainError::AlreadyExists` instead of leaking storage errors. Domain `Account` aggregate gained `traffic_total`, `last_validated`, `created_at` fields and switched its identifier to `AccountId(String)` so generated account ids match the spec's `TEXT PRIMARY KEY`. `Account::credential_ref()` returns the `keyring://{service}/{username}` URI used to look up the password/token in the OS keychain — credentials are never persisted to SQLite. Unblocks tasks 21-25, 38, 51-56, 75-76.
- **Accounts commands** (PRD §6.4, PRD-v2 §P1.2, task 21): six application-layer command handlers (`add_account`, `update_account`, `delete_account`, `validate_account`, `export_accounts`, `import_accounts`) wired through the `CommandBus` builder. New driven ports `AccountCredentialStore`, `AccountValidator` (with `ValidationOutcome`) and `PassphraseCodec` keep handlers free of plugin / crypto dependencies. `KeyringAccountStore` adapter persists per-account passwords under `vortex-account-{id}` keyring entries; `AesGcmPbkdf2Codec` adapter implements the import / export bundle format using AES-256-GCM with a PBKDF2-HMAC-SHA256 200 000-iteration KDF, fresh per-call salt + nonce, header bound as AAD, and a `VORTACC` magic + version byte so tampered or downgraded bundles fail authentication. Domain events `AccountAdded`, `AccountUpdated`, `AccountDeleted`, `AccountValidated`, `AccountValidationFailed`, `AccountsImported`, `AccountsExported` published via `EventBus` and forwarded by the Tauri bridge as `account-*` browser events. Add rolls back the SQLite row when the keyring write fails so credentials never end up orphaned; import validates every entry up-front and skips `(service_name, username)` pairs already present without inserting partial state. Unblocks task 23 (Vue Accounts).
- **Accounts persistence** (PRD §6.4, PRD-v2 §P1.1, task 20): SQLite `accounts` table (migration `m20260428_000006`) with `id` / `service_name` / `username` / `account_type` / `enabled` / `traffic_left` / `traffic_total` / `valid_until` / `last_validated` / `created_at` columns and a UNIQUE `(service_name, username)` index. New `AccountRepository` driven port (`save` / `find_by_id` / `list` / `list_by_service` / `delete`) and `SqliteAccountRepo` adapter with sea-orm entity + `from_domain` / `into_domain` converters. UNIQUE violations surface as `DomainError::AlreadyExists` instead of leaking storage errors. Domain `Account` aggregate gained `traffic_total`, `last_validated`, `created_at` fields and switched its identifier to `AccountId(String)` so generated account ids match the spec's `TEXT PRIMARY KEY`. `Account::credential_ref()` returns a `keyring://{service}/{username}` URI exposing a logical reference suitable for diagnostics; passwords themselves are never persisted to SQLite — they live in the OS keychain via the `AccountCredentialStore` adapter (added in task 21, keyed by `AccountId`). Unblocks tasks 21-25, 38, 51-56, 75-76.

## [0.2.0-beta] - 2026-04-27

Expand Down
152 changes: 146 additions & 6 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ hex = "0.4.3"
tauri-plugin-dialog = "2.7.0"
md-5 = "0.11.0"
digest = "0.11.2"
aes-gcm = "0.10.3"
pbkdf2 = "0.13.0"
hmac = "0.13.0"
rand = "0.10.1"

[target.'cfg(unix)'.dependencies]
libc = "0.2"
Expand Down
Loading
Loading