ap_client/lib.rs
1//! Noise Protocol Clients for access-protocol
2//!
3//! This crate provides both remote and user client implementations for
4//! connecting through a proxy using the Noise Protocol.
5//!
6//! ## Features
7//!
8//! - PSK-based authentication using pairing codes
9//! - Noise Protocol NNpsk2 pattern for secure 2-message handshake
10//! - Session caching for reconnection without re-pairing
11//! - Supports both classical (Curve25519) and post-quantum (Kyber768) cryptography
12//!
13//! ## Remote Client Usage (untrusted device)
14//!
15//! ```ignore
16//! use ap_client::{RemoteClient, RemoteClientNotification, RemoteClientRequest,
17//! DefaultProxyClient, IdentityProvider, SessionStore};
18//! use ap_proxy_client::ProxyClientConfig;
19//! use tokio::sync::mpsc;
20//!
21//! // Create proxy client
22//! let proxy_client = Box::new(DefaultProxyClient::new(ProxyClientConfig {
23//! proxy_url: "ws://localhost:8080".to_string(),
24//! identity_keypair: Some(identity_provider.identity().to_owned()),
25//! }));
26//!
27//! let (notification_tx, mut notification_rx) = mpsc::channel(32);
28//! let (request_tx, mut request_rx) = mpsc::channel(32);
29//!
30//! // Connect — spawns event loop internally, returns handle
31//! let client = RemoteClient::connect(
32//! identity_provider,
33//! session_store,
34//! proxy_client,
35//! notification_tx,
36//! request_tx,
37//! ).await?;
38//!
39//! // Pair with rendezvous code
40//! client.pair_with_handshake("ABCDEF123".to_string(), false).await?;
41//!
42//! let query = ap_client::CredentialQuery::Domain("example.com".to_string());
43//! let credential = client.request_credential(&query).await?;
44//! ```
45//!
46//! ## User Client Usage (trusted device)
47//!
48//! ```ignore
49//! use ap_client::{
50//! DefaultProxyClient, IdentityProvider, UserClient, UserClientNotification,
51//! UserClientRequest,
52//! };
53//! use ap_proxy_client::ProxyClientConfig;
54//! use tokio::sync::mpsc;
55//!
56//! // Create proxy client
57//! let proxy_client = Box::new(DefaultProxyClient::new(ProxyClientConfig {
58//! proxy_url: "ws://localhost:8080".to_string(),
59//! identity_keypair: Some(identity_provider.identity().to_owned()),
60//! }));
61//!
62//! let (notification_tx, mut notification_rx) = mpsc::channel(32);
63//! let (request_tx, mut request_rx) = mpsc::channel(32);
64//!
65//! // Connect — spawns event loop internally, returns handle
66//! let client = UserClient::connect(
67//! identity_provider,
68//! session_store,
69//! proxy_client,
70//! notification_tx,
71//! request_tx,
72//! None, // audit_log
73//! ).await?;
74//!
75//! // Already listening. Just use it.
76//! let token = client.get_psk_token(None).await?;
77//! // Or: let code = client.get_rendezvous_token(None).await?;
78//! ```
79
80/// Error types
81pub mod error;
82/// Proxy client trait and default implementation
83pub mod proxy;
84/// Traits for storage implementations
85pub mod traits;
86/// Protocol types and events
87pub mod types;
88
89mod clients;
90pub(crate) mod compat;
91
92pub use clients::remote_client::{
93 RemoteClient, RemoteClientFingerprintReply, RemoteClientNotification, RemoteClientRequest,
94};
95pub use clients::user_client::{
96 CredentialRequestReply, FingerprintVerificationReply, UserClient, UserClientNotification,
97 UserClientRequest,
98};
99pub use error::ClientError;
100#[cfg(feature = "native-websocket")]
101pub use proxy::DefaultProxyClient;
102pub use proxy::ProxyClient;
103pub use traits::{
104 AuditConnectionType, AuditEvent, AuditLog, CredentialFieldSet, IdentityProvider, NoOpAuditLog,
105 SessionStore,
106};
107pub use types::{ConnectionMode, CredentialData, CredentialQuery, PskId};
108
109// Re-export ap-proxy-protocol types
110pub use ap_proxy_protocol::{IdentityFingerprint, RendezvousCode};
111// Re-export PSK type from noise protocol
112pub use ap_noise::{MultiDeviceTransport, Psk};