tangled
alpha
login
or
join now
nonbinary.computer
/
weaver
atproto blogging
24
fork
atom
overview
issues
2
pulls
pipelines
some cleanup
Orual
1 month ago
85733a97
8b6741eb
+12
-54
2 changed files
expand all
collapse all
unified
split
crates
weaver-app
src
lib.rs
main.rs
+12
crates/weaver-app/src/lib.rs
···
53
subdomain_app::{extract_subdomain, lookup_subdomain_context},
54
};
55
0
0
0
0
0
56
#[derive(Debug, Clone, Routable, PartialEq)]
57
#[rustfmt::skip]
58
pub enum Route {
···
179
);
180
return None;
181
};
0
0
0
0
0
0
0
182
// Look up notebook by global path
183
let result = lookup_subdomain_context(&fetcher, &subdomain).await;
184
if result.is_none() {
···
53
subdomain_app::{extract_subdomain, lookup_subdomain_context},
54
};
55
56
+
/// Reserved subdomains that should not be used for notebooks.
57
+
const RESERVED_SUBDOMAINS: &[&str] = &[
58
+
"www", "api", "admin", "app", "auth", "cdn", "alpha", "beta", "staging", "index",
59
+
];
60
+
61
#[derive(Debug, Clone, Routable, PartialEq)]
62
#[rustfmt::skip]
63
pub enum Route {
···
184
);
185
return None;
186
};
187
+
188
+
// Check if subdomain is reserved
189
+
if RESERVED_SUBDOMAINS.contains(&subdomain.as_str()) {
190
+
tracing::info!(subdomain, "Reserved subdomain, skipping notebook lookup");
191
+
return None;
192
+
}
193
+
194
// Look up notebook by global path
195
let result = lookup_subdomain_context(&fetcher, &subdomain).await;
196
if result.is_none() {
-54
crates/weaver-app/src/main.rs
···
118
#[cfg(not(feature = "server"))]
119
dioxus::launch(App);
120
}
121
-
122
-
/// Extract subdomain from host if it matches base domain pattern.
123
-
#[cfg(feature = "server")]
124
-
fn extract_subdomain<'a>(host: &'a str, base: &str) -> Option<&'a str> {
125
-
let suffix = format!(".{}", base);
126
-
if host.ends_with(&suffix) && host.len() > suffix.len() {
127
-
Some(&host[..host.len() - suffix.len()])
128
-
} else {
129
-
None
130
-
}
131
-
}
132
-
133
-
/// Look up notebook by global path.
134
-
///
135
-
/// Returns SubdomainContext if a notebook with publishGlobal=true exists for this path.
136
-
#[cfg(feature = "server")]
137
-
async fn lookup_global_notebook(
138
-
fetcher: &Arc<fetch::Fetcher>,
139
-
path: &str,
140
-
) -> Option<SubdomainContext> {
141
-
use jacquard::IntoStatic;
142
-
use jacquard::smol_str::SmolStr;
143
-
use jacquard::smol_str::ToSmolStr;
144
-
use jacquard::types::string::Did;
145
-
use jacquard::xrpc::XrpcClient;
146
-
use weaver_api::sh_weaver::notebook::resolve_global_notebook::ResolveGlobalNotebook;
147
-
148
-
let request = ResolveGlobalNotebook::new().path(path).build();
149
-
150
-
match fetcher.send(request).await {
151
-
Ok(response) => {
152
-
let output = response.into_output().ok()?;
153
-
let notebook = output.notebook;
154
-
155
-
let owner = notebook.uri.authority().clone().into_static();
156
-
let rkey = notebook.uri.rkey()?.0.to_smolstr();
157
-
let notebook_path = notebook
158
-
.path
159
-
.map(|p| SmolStr::new(p.as_ref()))
160
-
.unwrap_or_else(|| SmolStr::new(path));
161
-
162
-
Some(SubdomainContext {
163
-
owner,
164
-
notebook_path,
165
-
notebook_rkey: rkey,
166
-
notebook_title: notebook.title.clone().unwrap_or_default().to_smolstr(),
167
-
})
168
-
}
169
-
Err(e) => {
170
-
tracing::debug!(path = path, error = %e, "Global notebook lookup failed");
171
-
None
172
-
}
173
-
}
174
-
}
···
118
#[cfg(not(feature = "server"))]
119
dioxus::launch(App);
120
}
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0