feat(auth): add username sign-in mode and recovery kits (#3215)

This commit is contained in:
Hampus authored and GitHub committed 2026-10-05 14:10:07 +02:00
1 parent bf3d73a5f7
commit e1eecc3b6c
355 files changed
+52138 -24097

No files matched your search

+4
View File
@@ -55,6 +55,10 @@ impl MultiValueForm {
self.fields.contains_key(key)
}
pub fn has_key_starting_with(&self, prefix: &str) -> bool {
self.fields.keys().any(|key| key.starts_with(prefix))
}
pub fn values(&self, key: &str) -> &[String] {
self.fields.get(key).map(Vec::as_slice).unwrap_or_default()
}
+1
View File
@@ -3,3 +3,4 @@
pub mod bigint;
pub mod forms;
pub mod timestamps;
pub mod user_tag;
+69
View File
@@ -0,0 +1,69 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
use std::future::Future;
tokio::task_local! {
static UNIQUE_USERNAMES: bool;
}
pub async fn with_unique_usernames<F: Future>(unique_usernames: bool, future: F) -> F::Output {
UNIQUE_USERNAMES.scope(unique_usernames, future).await
}
pub fn sync_with_unique_usernames<R>(unique_usernames: bool, f: impl FnOnce() -> R) -> R {
UNIQUE_USERNAMES.sync_scope(unique_usernames, f)
}
pub fn unique_usernames() -> bool {
UNIQUE_USERNAMES.try_with(|value| *value).unwrap_or(false)
}
pub fn shows_discriminator(discriminator: &str, is_bot: bool) -> bool {
is_bot || !unique_usernames() || discriminator.trim().parse::<u16>() != Ok(0)
}
pub fn user_tag(username: &str, discriminator: &str, is_bot: bool) -> String {
if shows_discriminator(discriminator, is_bot) {
format!("{username}#{discriminator}")
} else {
username.to_owned()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn email_mode_keeps_every_tag() {
assert_eq!(user_tag("alice", "0000", false), "alice#0000");
assert_eq!(user_tag("alice", "0042", false), "alice#0042");
sync_with_unique_usernames(false, || {
assert_eq!(user_tag("alice", "0000", false), "alice#0000");
assert_eq!(user_tag("bot", "0000", true), "bot#0000");
});
}
#[test]
fn username_mode_hides_zero_tag_for_humans() {
sync_with_unique_usernames(true, || {
assert_eq!(user_tag("alice", "0000", false), "alice");
assert_eq!(user_tag("alice", "0", false), "alice");
assert!(!shows_discriminator("0000", false));
});
}
#[test]
fn username_mode_keeps_bot_and_non_zero_tags() {
sync_with_unique_usernames(true, || {
assert_eq!(user_tag("helper", "4363", true), "helper#4363");
assert_eq!(user_tag("helper", "0000", true), "helper#0000");
assert_eq!(user_tag("legacy", "0042", false), "legacy#0042");
});
}
#[test]
fn mode_defaults_to_email_outside_a_request() {
assert!(!unique_usernames());
}
}