diff options
Diffstat (limited to 'src/config')
| -rw-r--r-- | src/config/mod.rs | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/src/config/mod.rs b/src/config/mod.rs index 60ad413..f0e5dc5 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -138,6 +138,13 @@ pub(crate) const OPTIONS: &[OptionSpec] = &[ "How long after a login (POST /auth/login) its tokens may be refreshed; then the user logs in again.", ), option( + "cors-origins", + Kind::List, + "ORIGIN,[ORIGIN...]", + None, + "Origins (scheme://host[:port]) whose pages may read this node's own links and refresh tokens here, with a token (docs/access.md, Tokens): the dashboards of other members are allowed anyway, as the member list names them (dashboard-url). Without credentials: a page sends its token itself.", + ), + option( "bootstrap-users", Kind::List, "USER,[USER...]", @@ -557,6 +564,8 @@ pub(crate) struct Settings { pub(crate) protocol_writers: Vec<String>, #[serde(default)] pub(crate) bootstrap_users: Vec<String>, + #[serde(default)] + pub(crate) cors_origins: Vec<String>, #[serde( default = "default_token_lifetime", with = "crate::units::duration_option" @@ -790,6 +799,16 @@ impl Settings { if self.remake.is_some() && !self.genesis { bail!("remake makes a new swarm's document; it needs genesis"); } + if let Some(bad) = self.cors_origins.iter().find(|origin| { + url::Url::parse(origin) + .ok() + .filter(|url| url.origin().is_tuple()) + .is_none_or(|url| url.origin().ascii_serialization() != **origin) + }) { + bail!( + "cors-origins: {bad:?} isn't an origin (scheme://host[:port], no path; * isn't taken)" + ); + } if !self.bootstrap_users.is_empty() && !self.genesis { bail!( "bootstrap-users names the first users of a new swarm; it needs genesis (drop it once the swarm exists)" |
