Git · dadoum.zone
Repositories
Help
Report an Issue
apple-crates
Code
Commits
Branches
Tags
Search
Tree:
a74924e
Branches
Tags
main
apple-crates
sharing
src
info.rs
Refactor and unify a lot of things for another project and implement airdrop support
Dadoum
commited
a74924e
at 2026-10-25 22:15:58
info.rs
Blame
History
Raw
//! `getMyInfo`: the account's own identity info, chiefly the **validation //! record** (`aidvr`, the Apple-signed blob binding the account's validated //! handles to its certificate) and when to ask again. //! //! The reply layout is what a live `getMyInfo` returned (field names and JSON //! types; the request body is empty). use base64::Engine; use base64::prelude::BASE64_STANDARD; use serde::{Deserialize, Deserializer, Serialize}; use crate::impl_sharing_request; #[derive(Debug, Default, Serialize)] pub struct GetMyInfo {} #[derive(Debug, Deserialize)] pub struct MyInfo { /// The validation record, DER CMS, base64 in the JSON. #[serde(default, deserialize_with = "base64_content")] pub aidvr: Option<Vec<u8>>, #[serde(rename = "serverAidvrId")] pub server_aidvr_id: Option<String>, #[serde(rename = "altDsId")] pub alt_dsid: Option<String>, /// Milliseconds until the validation record should be refreshed. #[serde(rename = "msUntilNextCheck")] pub ms_until_next_check: Option<u64>, #[serde(rename = "validatedEmails", default)] pub validated_emails: Vec<String>, #[serde(rename = "validatedPhones", default)] pub validated_phones: Vec<String>, #[serde(rename = "firstName")] pub first_name: Option<String>, #[serde(rename = "lastName")] pub last_name: Option<String>, /// The rest of the account struct (`certificate`, `version`, ...). #[serde(flatten)] pub other: serde_json::Map<String, serde_json::Value>, } impl_sharing_request!(GetMyInfo, "getMyInfo", MyInfo); fn base64_content<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Option<Vec<u8>>, D::Error> { use serde::de::Error; Option::<String>::deserialize(deserializer)? .map(|content| BASE64_STANDARD.decode(content).map_err(D::Error::custom)) .transpose() } #[cfg(test)] mod tests { use super::*; #[test] fn parses_the_live_reply_layout() { let reply: MyInfo = serde_json::from_str( r#"{"aidvr":"AQID","altDsId":"000000-00-x","serverAidvrId":"ab", "msUntilNextCheck":2592000000,"validatedEmails":["a@example.invalid"], "validatedPhones":["15550100"],"firstName":"A","lastName":"B", "certificate":{"certificate":null},"version":1,"responseCode":0}"#, ) .unwrap(); assert_eq!(reply.aidvr, Some(vec![1, 2, 3])); assert_eq!(reply.ms_until_next_check, Some(2_592_000_000)); assert_eq!(reply.validated_emails, ["a@example.invalid"]); assert!(reply.other.contains_key("version")); } }