use pubky_common::crypto::PublicKey;
use url::Url;
use super::{
DeepLinkParseError,
query_params::{append_direct_signup_params, optional_query, parse_homeserver},
typed_deep_link::{DeepLinkIntent, DeepLinkParams, TypedDeepLink},
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct DirectSignupIntent;
impl DeepLinkIntent for DirectSignupIntent {
const NAME: &'static str = "direct_signup";
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DirectSignupParams {
pub homeserver: PublicKey,
pub signup_token: Option<String>,
}
impl DeepLinkParams for DirectSignupParams {
fn parse(url: &Url) -> Result<Self, DeepLinkParseError> {
Ok(Self {
homeserver: parse_homeserver(url)?,
signup_token: optional_query(url, "st"),
})
}
fn append_query_pairs(&self, url: &mut Url) {
append_direct_signup_params(url, &self.homeserver, self.signup_token.as_deref());
}
}
pub type DirectSignupDeepLink = TypedDeepLink<DirectSignupIntent, DirectSignupParams>;
#[cfg(test)]
mod tests {
use std::str::FromStr;
use super::*;
use crate::actors::auth::deep_links::DeepLinkScheme;
const HOMESERVER: &str = "5jsjx1o6fzu6aeeo697r3i5rx15zq41kikcye8wtwdqm4nb4tryo";
#[test]
fn parses_direct_signup_deep_link() {
let deep_link: DirectSignupDeepLink = format!("pubkyauth://direct_signup?hs={HOMESERVER}")
.parse()
.unwrap();
assert_eq!(deep_link.scheme(), DeepLinkScheme::PubkyAuth);
assert_eq!(deep_link.intent(), "direct_signup");
assert_eq!(deep_link.params().homeserver.z32(), HOMESERVER);
assert_eq!(deep_link.params().signup_token, None);
}
#[test]
fn parses_direct_signup_deep_link_with_token() {
let deep_link: DirectSignupDeepLink =
format!("pubkyauth://direct_signup?hs={HOMESERVER}&st=1234567890")
.parse()
.unwrap();
assert_eq!(deep_link.params().signup_token, Some("1234567890".into()));
}
#[test]
fn direct_signup_deep_link_round_trips() {
let deep_link = DirectSignupDeepLink::new(
DeepLinkScheme::PubkyAuth,
DirectSignupParams {
homeserver: PublicKey::from_str(HOMESERVER).unwrap(),
signup_token: None,
},
);
assert_eq!(
deep_link.to_string(),
format!("pubkyauth://direct_signup?hs={HOMESERVER}")
);
assert_eq!(
DirectSignupDeepLink::parse_url(&deep_link.to_url()).unwrap(),
deep_link
);
}
#[test]
fn rejects_missing_homeserver() {
let error = "pubkyauth://direct_signup"
.parse::<DirectSignupDeepLink>()
.unwrap_err();
assert!(matches!(
error,
DeepLinkParseError::MissingQueryParameter("hs")
));
}
}