mod common;
mod join;
#[cfg(feature = "lan-pairing")]
mod lan;
#[cfg(feature = "lan-pairing")]
mod lan_server;
#[cfg(feature = "lan-pairing")]
mod mdns;
mod offline;
mod online;
use anyhow::Result;
use auths_core::config::EnvironmentConfig;
use clap::Parser;
#[cfg(not(feature = "lan-pairing"))]
const DEFAULT_REGISTRY: &str = "http://localhost:3000";
#[derive(Parser, Debug, Clone)]
#[command(about = "Link devices to your identity")]
pub struct PairCommand {
#[clap(long, value_name = "CODE")]
pub join: Option<String>,
#[clap(long, value_name = "URL")]
pub registry: Option<String>,
#[clap(long, hide_short_help = true)]
pub no_qr: bool,
#[clap(
long,
visible_alias = "expiry",
value_name = "SECONDS",
default_value = "300"
)]
pub timeout: u64,
#[clap(long, hide_short_help = true)]
pub offline: bool,
#[clap(
long,
value_delimiter = ',',
default_value = "sign_commit",
hide_short_help = true
)]
pub capabilities: Vec<String>,
#[cfg(feature = "lan-pairing")]
#[clap(long, hide_short_help = true)]
pub no_mdns: bool,
}
pub fn handle_pair(cmd: PairCommand, env_config: &EnvironmentConfig) -> Result<()> {
match (&cmd.join, &cmd.registry, cmd.offline) {
(None, _, true) => {
offline::handle_initiate_offline(cmd.no_qr, cmd.timeout, &cmd.capabilities)
}
(Some(code), Some(registry), _) => {
let rt = tokio::runtime::Runtime::new()?;
rt.block_on(join::handle_join(code, registry, env_config))
}
#[cfg(feature = "lan-pairing")]
(Some(code), None, _) => {
let rt = tokio::runtime::Runtime::new()?;
rt.block_on(lan::handle_join_lan(code, env_config))
}
#[cfg(not(feature = "lan-pairing"))]
(Some(code), None, _) => {
let rt = tokio::runtime::Runtime::new()?;
rt.block_on(join::handle_join(code, DEFAULT_REGISTRY, env_config))
}
(None, Some(registry), _) => {
let rt = tokio::runtime::Runtime::new()?;
rt.block_on(online::handle_initiate_online(
registry,
cmd.no_qr,
cmd.timeout,
&cmd.capabilities,
env_config,
))
}
#[cfg(feature = "lan-pairing")]
(None, None, false) => {
let rt = tokio::runtime::Runtime::new()?;
rt.block_on(lan::handle_initiate_lan(
cmd.no_qr,
cmd.no_mdns,
cmd.timeout,
&cmd.capabilities,
env_config,
))
}
#[cfg(not(feature = "lan-pairing"))]
(None, None, false) => {
let rt = tokio::runtime::Runtime::new()?;
rt.block_on(online::handle_initiate_online(
DEFAULT_REGISTRY,
cmd.no_qr,
cmd.timeout,
&cmd.capabilities,
env_config,
))
}
}
}
#[cfg(test)]
mod tests {
use auths_core::pairing::normalize_short_code;
#[test]
fn test_code_normalization() {
let codes = vec![
("AB3DEF", "AB3DEF"),
("ab3def", "AB3DEF"),
("AB3 DEF", "AB3DEF"),
("AB3-DEF", "AB3DEF"),
("a b 3 d e f", "AB3DEF"),
];
for (input, expected) in codes {
let normalized = normalize_short_code(input);
assert_eq!(normalized, expected, "Input: '{}'", input);
}
}
}