forked from
smokesignal.events/smokesignal
The smokesignal.events web application
1use crate::http::errors::LoginError;
2
3/// Validates and filters incoming login requests.
4///
5/// Accepts an optional subject string and validates it for AT Protocol login.
6/// Returns Ok(None) for None or empty inputs, Ok(Some(trimmed)) for valid inputs,
7/// or an error for incomplete AT-handles that need ".bsky.social" suffix.
8pub(crate) fn validate_login_input(subject: Option<&str>) -> Result<Option<String>, LoginError> {
9 let subject = match subject {
10 None => return Ok(None),
11 Some(s) if s.trim().is_empty() => return Ok(None),
12 Some(s) => s.trim(),
13 };
14
15 // Check for valid prefixes (AT-handle, DID, or HTTPS URL)
16 if subject.starts_with('@')
17 || subject.starts_with("https://")
18 || subject.starts_with("at://")
19 || subject.starts_with("did:")
20 {
21 return Ok(Some(subject.to_string()));
22 }
23
24 // Check if it looks like an incomplete AT-handle (alphanumeric with no dots)
25 if subject.chars().all(|c| c.is_alphanumeric()) && !subject.contains('.') {
26 return Err(LoginError::IncompleteHandle);
27 }
28
29 // For any other format, assume it's valid and let the resolver handle it
30 Ok(Some(subject.to_string()))
31}