From 1458ea92a41788a0f33e86e621817613f46055eb Mon Sep 17 00:00:00 2001 From: tv Date: Sat, 7 Nov 2026 22:35:09 +0100 Subject: dashboard: own links over the API, and CORS GET /admin/dashboard/links/own and its event stream: a node's own links, as LINKS_REPLY carried them, for other members' dashboards with a token. CORS for the members' dashboard origins and --cors-origins, without credentials. Auth plan M3. --- src/config/mod.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src/config') 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 @@ -137,6 +137,13 @@ pub(crate) const OPTIONS: &[OptionSpec] = &[ Some("7d"), "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, @@ -557,6 +564,8 @@ pub(crate) struct Settings { pub(crate) protocol_writers: Vec, #[serde(default)] pub(crate) bootstrap_users: Vec, + #[serde(default)] + pub(crate) cors_origins: Vec, #[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)" -- cgit v1.3.1