use ciborium::from_reader;
use ic_auth_types::{ByteBufB64, SignedDelegationCompact, deterministic_cbor_into_vec};
use serde::{Deserialize, Serialize, de::DeserializeOwned};
use std::str::FromStr;
#[derive(Debug)]
pub struct DeepLinkRequest<'a, T: Serialize> {
pub os: &'a str, pub action: &'a str, pub next_url: Option<&'a str>, pub payload: Option<T>, }
impl<T> DeepLinkRequest<'_, T>
where
T: Serialize,
{
pub fn to_url(&self, endpoint: &url::Url) -> url::Url {
let mut url = endpoint.clone();
url.query_pairs_mut()
.append_pair("os", self.os)
.append_pair("action", self.action);
if let Some(next_url) = self.next_url {
url.query_pairs_mut().append_pair("next_url", next_url);
}
if let Some(payload) = &self.payload {
let data =
deterministic_cbor_into_vec(payload).expect("Failed to serialize payload to CBOR");
url.set_fragment(Some(ByteBufB64(data).to_string().as_str()));
}
url
}
}
#[derive(Debug)]
pub struct DeepLinkResponse {
pub url: url::Url,
pub os: String,
pub action: String, pub payload: Option<ByteBufB64>, }
impl DeepLinkResponse {
pub fn from_url(url: url::Url) -> Result<Self, String> {
let mut query_pairs = url.query_pairs();
let payload = match url.fragment() {
Some(f) => Some(ByteBufB64::from_str(f).map_err(|err| format!("{err:?}"))?),
None => None,
};
Ok(DeepLinkResponse {
os: query_pairs
.find(|(k, _)| k == "os")
.map(|(_, v)| v.to_string())
.unwrap_or_default(),
action: query_pairs
.find(|(k, _)| k == "action")
.map(|(_, v)| v.to_string())
.unwrap_or_default(),
payload,
url,
})
}
pub fn get_payload<T: DeserializeOwned>(&self) -> Result<T, String> {
if let Some(payload) = &self.payload {
Ok(from_reader(payload.as_slice()).map_err(|err| format!("{err:?}"))?)
} else {
Err("Payload is missing in the deep link response".to_string())
}
}
}
#[derive(Clone, Default, Deserialize, Serialize)]
pub struct SignInRequest {
#[serde(rename = "s")]
pub session_pubkey: ByteBufB64,
#[serde(rename = "m")]
pub max_time_to_live: u64, }
#[derive(Clone, Default, Deserialize, Serialize)]
pub struct SignInResponse {
#[serde(rename = "u")]
pub user_pubkey: ByteBufB64,
#[serde(rename = "d")]
pub delegations: Vec<SignedDelegationCompact>,
#[serde(rename = "a")]
pub authn_method: String,
#[serde(rename = "o")]
pub origin: String,
}