Appearance
应用服务接口约定(v0.1)
CLI(pn)和桌面 App 都通过同一个服务层操作保险库:Rust crate passno-service,对外是一个 PassnoService trait。桌面端用 Tauri command 暴露同名方法(snake_case),前端 TypeScript 接口和下面的定义一一对应(camelCase 字段)。
改这份约定要同时改 Rust 和 TypeScript 两边,并更新本文。
类型
rust
pub struct Status { pub initialized: bool, pub locked: bool, pub vault_path: String, pub item_count: u32 }
pub struct InitResult {
pub secret_key: String, // 例如 "A3-K7Q2PZ-…",只在这里显示一次
pub emergency_kit_markdown: String,
}
pub enum ItemKind { Login, Password, SecureNote, Card, Identity, SshKey, ApiCredential, Document, Wifi, Custom }
pub struct ItemSummary {
pub id: String, pub kind: ItemKind, pub title: String,
pub subtitle: String, // 登录类条目显示用户名,卡片显示尾号,其他为空
pub primary_url: Option<String>, pub tags: Vec<String>,
pub favorite: bool, pub archived: bool, pub vault: String,
pub updated_at: i64, // Unix 秒
pub has_totp: bool,
}
pub struct ItemFilter {
pub query: Option<String>, pub kind: Option<ItemKind>, pub tag: Option<String>,
pub vault: Option<String>, pub include_archived: bool, pub favorites_only: bool,
}
pub enum FieldType { Text, Concealed, Email, Url, Phone, Date, MonthYear, Address, Menu, Reference, File, Totp, SshKey }
pub struct FieldView {
pub id: String, pub label: String, pub section: Option<String>,
pub field_type: FieldType, pub designation: Option<String>, // "username" | "password"
pub value: Option<String>, // 隐藏类字段(Concealed / Totp / SshKey)为 None,要用 reveal_field 取
pub concealed: bool,
}
pub struct Item {
pub summary: ItemSummary, pub urls: Vec<String>, pub fields: Vec<FieldView>,
pub notes: Option<String>, pub created_at: i64,
pub password_history_count: u32,
}
pub struct ItemDraft {
pub kind: ItemKind, pub title: String, pub urls: Vec<String>,
pub fields: Vec<FieldDraft>, pub notes: Option<String>, pub tags: Vec<String>, pub favorite: bool,
}
pub struct FieldDraft { pub id: Option<String>, pub label: String, pub section: Option<String>,
pub field_type: FieldType, pub designation: Option<String>, pub value: String }
pub enum GeneratorKind { Random, Passphrase, Pin }
pub struct GeneratorOptions {
pub kind: GeneratorKind, pub length: u32, // Random/Pin 是字符数,Passphrase 是单词数
pub uppercase: bool, pub digits: bool, pub symbols: bool, pub avoid_ambiguous: bool,
pub separator: Option<String>, pub capitalize: bool,
pub for_domain: Option<String>, // 有值时套用 PMR 网站规则
}
pub struct Generated { pub password: String, pub entropy_bits: f64, pub strength: Strength, pub rules_applied: Option<String> }
pub enum Strength { Weak, Fair, Strong, VeryStrong }
pub struct TotpCode { pub code: String, pub period: u32, pub remaining: u32 }
pub enum ImportFormat { OnePux, OnePasswordCsv, AppleCsv }
pub struct ImportPreview {
pub format: ImportFormat, pub accounts: u32, pub vaults: Vec<String>, pub items: u32,
pub attachments: u32, pub by_kind: Vec<(ItemKind, u32)>,
pub not_migrated: Vec<String>, // 用户能看懂的说明,例如"通行密钥(1Password 桌面版导不出)"
pub warnings: Vec<String>,
}
pub enum DuplicatePolicy { Skip, KeepBoth }
pub struct ImportReport { pub imported: u32, pub skipped_duplicates: u32, pub downgraded_fields: Vec<String>, pub errors: Vec<String> }
pub struct Stats { pub total: u32, pub weak: u32, pub reused: u32, pub missing_totp_where_supported: u32 }方法
| 方法 | 说明 | 错误 |
|---|---|---|
status() -> Status | 不需要解锁 | — |
init(master_password) -> InitResult | 新建保险库,生成 Secret Key | AlreadyInitialized、WeakPassword |
unlock(master_password, secret_key: Option) | secret_key 为 None 时从本机的 SecretKeyStore 读取 | WrongPassword、SecretKeyMissing |
lock() | 清空内存里的密钥 | — |
list_items(filter) -> Vec<ItemSummary> | 按 updated_at 倒序 | Locked |
get_item(id) -> Item | 隐藏类字段的值为 None | Locked、NotFound |
reveal_field(item_id, field_id) -> String | 只有本人操作的界面和交互式终端可以调用 | Locked、NotFound |
create_item(draft) -> String | 返回新 id | Locked、Invalid |
update_item(id, draft) | 修改密码时,旧值进历史 | Locked、NotFound、Invalid |
delete_item(id) / restore_item(id) | 软删除,进回收站 | Locked、NotFound |
generate(options) -> Generated | 不需要解锁 | Invalid |
totp(item_id) -> TotpCode | Locked、NotFound、NoTotp | |
import_preview(path, format) -> ImportPreview | 只读,不写保险库 | Locked、ParseError |
import_commit(path, format, policy) -> ImportReport | 幂等:同一来源的 UUID 不会重复导入 | Locked、ParseError |
stats() -> Stats | Locked |
错误
rust
pub enum ServiceError {
NotInitialized, AlreadyInitialized, Locked, WrongPassword, SecretKeyMissing, WeakPassword,
NotFound, Invalid(String), NoTotp, ParseError(String), Io(String), Internal(String),
}CLI 退出码对应:
| 错误 | 退出码 |
|---|---|
| Invalid | 2 |
| Locked / WrongPassword / SecretKeyMissing | 3 |
| NotFound | 5 |
| 其余 | 1 |
Tauri 侧: 返回 { code: "Locked", message: "…" },前端按 code 处理。