Skip to main content

web/
config.rs

1use server::config::{ConfigError, config};
2
3fn get_env_var(var_name: &str) -> String {
4    std::env::var(var_name).unwrap_or_else(|_| panic!("{var_name} must be set"))
5}
6
7/// Public-facing SSH endpoint advertised in the
8/// `/account/ssh-key` "key added" snippet. All three values are
9/// optional — operators set them via env (`SSH_HOSTNAME`,
10/// `SSH_PORT`, `SSH_HOST_FINGERPRINT`) on the deployment ConfigMap.
11#[derive(Debug, Clone)]
12pub struct SshConnectInfo {
13    pub hostname: String,
14    pub port: u16,
15    pub host_fingerprint: String,
16}
17
18impl SshConnectInfo {
19    fn from_env() -> Self {
20        Self {
21            hostname: std::env::var("SSH_HOSTNAME")
22                .unwrap_or_else(|_| "ssh.example.invalid".to_string()),
23            port: std::env::var("SSH_PORT")
24                .ok()
25                .and_then(|raw| raw.parse::<u16>().ok())
26                .unwrap_or(2222),
27            host_fingerprint: std::env::var("SSH_HOST_FINGERPRINT")
28                .unwrap_or_else(|_| "(not configured)".to_string()),
29        }
30    }
31}
32
33#[derive(Debug, Clone)]
34pub struct Config {
35    pub site_url: String,
36
37    pub redis_url: String,
38    pub client_origin: String,
39
40    pub access_token_private_key: String,
41    pub access_token_public_key: String,
42    pub access_token_expires_in: String,
43    pub access_token_max_age: i64,
44
45    pub refresh_token_private_key: String,
46    pub refresh_token_public_key: String,
47    pub refresh_token_expires_in: String,
48    pub refresh_token_max_age: i64,
49
50    pub ssh: SshConnectInfo,
51}
52
53impl Config {
54    pub async fn init() -> Result<Config, ConfigError> {
55        let site_url = config("site_url")
56            .await?
57            .ok_or(ConfigError::NoConfig("site_url".to_string()))?
58            .to_string();
59
60        let client_origin = config("client_origin")
61            .await?
62            .ok_or(ConfigError::NoConfig("client_origin".to_string()))?
63            .to_string();
64
65        let redis_url = config("redis_url")
66            .await?
67            .ok_or(ConfigError::NoConfig("redis_url".to_string()))?
68            .to_string();
69
70        let access_token_private_key = config("access_token_private_key")
71            .await?
72            .ok_or(ConfigError::NoConfig(
73                "access_token_private_key".to_string(),
74            ))?
75            .to_string();
76
77        let access_token_public_key = config("access_token_public_key")
78            .await?
79            .ok_or(ConfigError::NoConfig("access_token_public_key".to_string()))?
80            .to_string();
81
82        let access_token_expires_in = config("access_token_expired_in")
83            .await?
84            .ok_or(ConfigError::NoConfig("access_token_expired_in".to_string()))?
85            .to_string();
86
87        let access_token_max_age = config("access_token_maxage")
88            .await?
89            .ok_or(ConfigError::NoConfig("access_token_maxage".to_string()))?
90            .to_string();
91
92        let refresh_token_private_key = config("refresh_token_private_key")
93            .await?
94            .ok_or(ConfigError::NoConfig(
95                "refresh_token_private_key".to_string(),
96            ))?
97            .to_string();
98
99        let refresh_token_public_key = config("refresh_token_public_key")
100            .await?
101            .ok_or(ConfigError::NoConfig(
102                "refresh_token_public_key".to_string(),
103            ))?
104            .to_string();
105
106        let refresh_token_expires_in = config("refresh_token_expired_in")
107            .await?
108            .ok_or(ConfigError::NoConfig(
109                "refresh_token_expired_in".to_string(),
110            ))?
111            .to_string();
112
113        let refresh_token_max_age = config("refresh_token_maxage")
114            .await?
115            .ok_or(ConfigError::NoConfig("refresh_token_maxage".to_string()))?
116            .to_string();
117
118        Ok(Config {
119            site_url,
120            redis_url,
121            client_origin,
122            access_token_private_key,
123            access_token_public_key,
124            refresh_token_private_key,
125            refresh_token_public_key,
126            access_token_expires_in,
127            refresh_token_expires_in,
128            access_token_max_age: access_token_max_age.parse::<i64>().unwrap(),
129            refresh_token_max_age: refresh_token_max_age.parse::<i64>().unwrap(),
130            ssh: SshConnectInfo::from_env(),
131        })
132    }
133}