mirror of
https://github.com/narrrl/proton-sdk-rs.git
synced 2026-11-04 00:47:01 +01:00
151 lines
4.1 KiB
Rust
151 lines
4.1 KiB
Rust
//! Serde DTOs for the account/user/address/key-salt endpoints.
|
|
//!
|
|
//! Proton encodes booleans as integers (`0`/`1`), so flag fields are kept as
|
|
//! `i32` with `is_*` accessors rather than relying on bool deserialization.
|
|
//!
|
|
//! A few fields are kept for wire-format fidelity but not yet read.
|
|
#![allow(dead_code)]
|
|
|
|
use serde::Deserialize;
|
|
|
|
use crate::ids::{AddressId, AddressKeyId, UserId, UserKeyId};
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub(super) struct UserResponse {
|
|
#[serde(rename = "User")]
|
|
pub user: UserDto,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub(super) struct UserDto {
|
|
#[serde(rename = "ID")]
|
|
pub id: UserId,
|
|
/// Total account storage in bytes (all Proton products).
|
|
#[serde(rename = "MaxSpace")]
|
|
pub max_space: i64,
|
|
/// Used account storage in bytes.
|
|
#[serde(rename = "UsedSpace")]
|
|
pub used_space: i64,
|
|
#[serde(rename = "Keys")]
|
|
pub keys: Vec<UserKeyDto>,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub(super) struct UserKeyDto {
|
|
#[serde(rename = "ID")]
|
|
pub id: UserKeyId,
|
|
#[serde(rename = "PrivateKey")]
|
|
pub private_key: String,
|
|
#[serde(rename = "Primary")]
|
|
pub primary: i32,
|
|
#[serde(rename = "Active")]
|
|
pub active: i32,
|
|
}
|
|
|
|
impl UserKeyDto {
|
|
pub fn is_active(&self) -> bool {
|
|
self.active != 0
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub(super) struct AddressListResponse {
|
|
#[serde(rename = "Addresses")]
|
|
pub addresses: Vec<AddressDto>,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub(super) struct AddressDto {
|
|
#[serde(rename = "ID")]
|
|
pub id: AddressId,
|
|
#[serde(rename = "Email")]
|
|
pub email: String,
|
|
#[serde(rename = "Status")]
|
|
pub status: i32,
|
|
#[serde(rename = "Order")]
|
|
pub order: i32,
|
|
#[serde(rename = "Keys")]
|
|
pub keys: Vec<AddressKeyDto>,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub(super) struct AddressKeyDto {
|
|
#[serde(rename = "ID")]
|
|
pub id: AddressKeyId,
|
|
#[serde(rename = "PrivateKey")]
|
|
pub private_key: String,
|
|
#[serde(rename = "Token")]
|
|
pub token: Option<String>,
|
|
#[serde(rename = "Signature")]
|
|
pub signature: Option<String>,
|
|
#[serde(rename = "Primary")]
|
|
pub primary: i32,
|
|
#[serde(rename = "Active")]
|
|
pub active: i32,
|
|
}
|
|
|
|
impl AddressKeyDto {
|
|
pub fn is_active(&self) -> bool {
|
|
self.active != 0
|
|
}
|
|
|
|
pub fn is_primary(&self) -> bool {
|
|
self.primary != 0
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub(super) struct KeySaltListResponse {
|
|
#[serde(rename = "KeySalts")]
|
|
pub key_salts: Vec<KeySalt>,
|
|
}
|
|
|
|
/// A per-key bcrypt salt from `core/v4/keys/salts`.
|
|
///
|
|
/// `core/v4/keys/salts` requires the `locked` scope, which only a
|
|
/// password-authenticated access token carries — a token obtained through
|
|
/// `auth/v4/refresh` does not, and the endpoint then answers 403 (code 9101).
|
|
/// Salts change only when the user changes their password, so callers that
|
|
/// resume a session from persisted tokens should persist the salts alongside
|
|
/// them and hand them back via
|
|
/// [`AccountClient::with_key_salts`](super::AccountClient::with_key_salts).
|
|
#[derive(Debug, Clone, Deserialize, serde::Serialize)]
|
|
pub struct KeySalt {
|
|
#[serde(rename = "ID")]
|
|
pub key_id: String,
|
|
/// Base64-encoded 16-byte salt; `null` for keys without a salt.
|
|
#[serde(rename = "KeySalt")]
|
|
pub value: Option<String>,
|
|
}
|
|
|
|
/// Response for `core/v4/keys/all` — the active public keys for an email
|
|
/// address. Mirrors C# `AddressPublicKeyListResponse`.
|
|
#[derive(Debug, Deserialize)]
|
|
pub(super) struct AddressPublicKeyListResponse {
|
|
#[serde(rename = "Address")]
|
|
pub address: PublicKeyListAddress,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub(super) struct PublicKeyListAddress {
|
|
#[serde(rename = "Keys")]
|
|
pub keys: Vec<PublicKeyEntry>,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub(super) struct PublicKeyEntry {
|
|
/// Status flags; bit `1` = not compromised, bit `2` = not obsolete.
|
|
#[serde(rename = "Flags")]
|
|
pub flags: i32,
|
|
#[serde(rename = "PublicKey")]
|
|
pub public_key: String,
|
|
}
|
|
|
|
impl PublicKeyEntry {
|
|
/// Bit `1` of `Flags` (C# `PublicKeyStatus.IsNotCompromised`): only
|
|
/// non-compromised keys are used to verify authorship.
|
|
pub fn is_not_compromised(&self) -> bool {
|
|
self.flags & 1 != 0
|
|
}
|
|
}
|