mecha10_auth/
lib.rs

1//! Mecha10 Authentication Library
2//!
3//! Shared authentication services for CLI and launcher.
4//!
5//! ## Features
6//!
7//! - Device code OAuth 2.0 flow (RFC 8628) for browser-based authentication
8//! - Credentials storage at ~/.mecha10/credentials.json
9//! - Support for custom auth server URLs via MECHA10_AUTH_URL environment variable
10//!
11//! ## Usage
12//!
13//! ```rust,no_run
14//! use mecha10_auth::{AuthService, CredentialsService};
15//!
16//! async fn login() -> anyhow::Result<()> {
17//!     let auth_service = AuthService::new();
18//!     let credentials_service = CredentialsService::new();
19//!
20//!     // Run device code flow
21//!     let credentials = auth_service.run_device_code_flow(|device_code| {
22//!         println!("Go to: {}", device_code.verification_uri);
23//!         println!("Enter code: {}", device_code.user_code);
24//!     }).await?;
25//!
26//!     // Save credentials
27//!     credentials_service.save(&credentials)?;
28//!     Ok(())
29//! }
30//! ```
31
32mod credentials;
33mod service;
34pub mod types;
35
36pub use credentials::{default_credentials_path, CredentialsService};
37pub use service::AuthService;
38pub use types::{AuthError, Credentials, DeviceCodeResponse, DeviceCodeStatus};
39
40/// Default auth URL for production
41pub const DEFAULT_AUTH_URL: &str = "https://mecha.industries/api/auth";
42
43/// Environment variable name for custom auth URL
44pub const AUTH_URL_ENV_VAR: &str = "MECHA10_AUTH_URL";
45
46/// Get the auth URL, checking environment variable first
47///
48/// Priority:
49/// 1. MECHA10_AUTH_URL environment variable
50/// 2. DEFAULT_AUTH_URL constant
51pub fn get_auth_url() -> String {
52    std::env::var(AUTH_URL_ENV_VAR).unwrap_or_else(|_| DEFAULT_AUTH_URL.to_string())
53}
54
55/// Display the device code flow instructions in a formatted box
56pub fn display_device_code_instructions(device_code: &DeviceCodeResponse) {
57    println!("┌────────────────────────────────────────────────────────┐");
58    println!("│  Open this URL in your browser:                        │");
59    println!("│                                                        │");
60    println!("│    {:<50}  │", &device_code.verification_uri);
61    println!("│                                                        │");
62    println!("│  Then enter this code:                                 │");
63    println!("│                                                        │");
64    println!(
65        "│    {}                                        │",
66        device_code.user_code
67    );
68    println!("│                                                        │");
69    println!("└────────────────────────────────────────────────────────┘");
70    println!();
71    println!("Waiting for browser authorization...");
72    println!("(You can use a different device if this machine has no browser)");
73}
74
75/// Try to open the verification URL in the default browser
76pub fn open_browser(url: &str) {
77    let _ = open::that(url);
78}