axum rewrite #35

Merged
radical merged 21 commits from staging into main 2025-07-20 17:25:04 +00:00
11 changed files with 1034 additions and 18 deletions
Showing only changes of commit 969b517e18 - Show all commits

View file

@ -62,4 +62,6 @@ random-string = "1.1"
lettre = { version = "0.11", features = ["tokio1", "tokio1-native-tls"] }
chrono = { version = "0.4.41", features = ["serde"] }
tracing-subscriber = "0.3.19"
rand = "0.9.1"

View file

@ -0,0 +1,2 @@
-- This file should undo anything in `up.sql`
ALTER TABLE refresh_tokens ALTER COLUMN device_name TYPE varchar(16);

View file

@ -0,0 +1,2 @@
-- Your SQL goes here
ALTER TABLE refresh_tokens ALTER COLUMN device_name TYPE varchar(64);

View file

@ -21,7 +21,7 @@ use crate::{
schema::*,
utils::{
PASSWORD_REGEX, generate_token, new_refresh_token_cookie,
user_uuid_from_identifier,
user_uuid_from_identifier, generate_device_name
},
};
@ -29,7 +29,6 @@ use crate::{
pub struct LoginInformation {
username: String,
password: String,
device_name: String,
}
pub async fn response(
@ -72,12 +71,14 @@ pub async fn response(
use refresh_tokens::dsl as rdsl;
let device_name = generate_device_name();
insert_into(refresh_tokens::table)
.values((
rdsl::token.eq(&refresh_token),
rdsl::uuid.eq(uuid),
rdsl::created_at.eq(current_time),
rdsl::device_name.eq(&login_information.device_name),
rdsl::device_name.eq(&device_name),
))
.execute(&mut conn)
.await?;
@ -94,7 +95,7 @@ pub async fn response(
.execute(&mut conn)
.await?;
let mut response = (StatusCode::OK, Json(Response { access_token })).into_response();
let mut response = (StatusCode::OK, Json(Response { access_token, device_name })).into_response();
response.headers_mut().append(
"Set-Cookie",

View file

@ -27,6 +27,7 @@ mod verify_email;
#[derive(Serialize)]
pub struct Response {
access_token: String,
device_name: String,
}

View file

@ -19,8 +19,7 @@ use crate::{
schema::{
access_tokens::{self, dsl},
refresh_tokens::{self, dsl as rdsl},
},
utils::{generate_token, new_refresh_token_cookie},
}, utils::{generate_token, new_refresh_token_cookie}
};
pub async fn post(
@ -69,6 +68,7 @@ pub async fn post(
}
let current_time = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs() as i64;
let mut device_name: String = String::new();
if lifetime > 1987200 {
let new_refresh_token = generate_token::<32>()?;
@ -79,11 +79,13 @@ pub async fn post(
rdsl::token.eq(&new_refresh_token),
rdsl::created_at.eq(current_time),
))
.execute(&mut conn)
.returning(rdsl::device_name)
.get_result::<String>(&mut conn)
.await
{
Ok(_) => {
Ok(existing_device_name) => {
refresh_token = new_refresh_token;
device_name = existing_device_name;
}
Err(error) => {
error!("{error}");
@ -102,7 +104,7 @@ pub async fn post(
.execute(&mut conn)
.await?;
let mut response = (StatusCode::OK, Json(Response { access_token })).into_response();
let mut response = (StatusCode::OK, Json(Response { access_token, device_name })).into_response();
// TODO: Dont set this when refresh token is unchanged
response.headers_mut().append(

View file

@ -30,7 +30,7 @@ use crate::{
},
utils::{
EMAIL_REGEX, PASSWORD_REGEX, USERNAME_REGEX, generate_token,
new_refresh_token_cookie,
new_refresh_token_cookie, generate_device_name
},
};
@ -39,7 +39,6 @@ pub struct AccountInformation {
identifier: String,
email: String,
password: String,
device_name: String,
}
#[derive(Serialize)]
@ -137,12 +136,14 @@ pub async fn post(
let current_time = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs() as i64;
let device_name = generate_device_name();
insert_into(refresh_tokens::table)
.values((
rdsl::token.eq(&refresh_token),
rdsl::uuid.eq(uuid),
.values((
rdsl::token.eq(&refresh_token),
rdsl::uuid.eq(uuid),
rdsl::created_at.eq(current_time),
rdsl::device_name.eq(&account_information.device_name),
rdsl::device_name.eq(&device_name),
))
.execute(&mut conn)
.await?;
@ -161,7 +162,7 @@ pub async fn post(
Member::new(&app_state, uuid, initial_guild).await?;
}
let mut response = (StatusCode::OK, Json(Response {access_token})).into_response();
let mut response = (StatusCode::OK, Json(Response {access_token, device_name})).into_response();
response.headers_mut().append(
"Set-Cookie",

View file

@ -8,7 +8,6 @@ use objects::MailClient;
use socketioxide::SocketIo;
use std::{sync::Arc, time::SystemTime};
use tower_http::cors::{AllowOrigin, CorsLayer};
mod config;
use config::{Config, ConfigBuilder};
use diesel_migrations::{EmbeddedMigrations, MigrationHarness, embed_migrations};
@ -17,6 +16,8 @@ pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!();
type Conn =
deadpool::managed::Object<AsyncDieselConnectionManager<diesel_async::AsyncPgConnection>>;
mod config;
mod wordlist;
mod api;
pub mod error;
pub mod objects;

View file

@ -103,7 +103,7 @@ diesel::table! {
token -> Varchar,
uuid -> Uuid,
created_at -> Int8,
#[max_length = 16]
#[max_length = 64]
device_name -> Varchar,
}
}

View file

@ -1,4 +1,5 @@
use std::sync::LazyLock;
use rand::{seq::IndexedRandom};
use axum::body::Bytes;
use axum_extra::extract::cookie::{Cookie, SameSite};
@ -19,6 +20,7 @@ use crate::{
error::Error,
objects::{HasIsAbove, HasUuid},
schema::users,
wordlist::{ADJECTIVES, ANIMALS}
};
pub static EMAIL_REGEX: LazyLock<Regex> = LazyLock::new(|| {
@ -207,3 +209,12 @@ impl AppState {
.await
}
}
pub fn generate_device_name() -> String {
let mut rng = rand::rng();
let adjective = ADJECTIVES.choose(&mut rng).unwrap();
let animal = ANIMALS.choose(&mut rng).unwrap();
return [*adjective, *animal].join(" ")
}

993
src/wordlist.rs Normal file
View file

@ -0,0 +1,993 @@
pub const ANIMALS: [&'static str; 223] = [
"Aardvark",
"Albatross",
"Alligator",
"Alpaca",
"Ant",
"Anteater",
"Antelope",
"Ape",
"Armadillo",
"Donkey",
"Baboon",
"Badger",
"Barracuda",
"Bat",
"Bear",
"Beaver",
"Bee",
"Bison",
"Boar",
"Buffalo",
"Butterfly",
"Camel",
"Capybara",
"Caribou",
"Cassowary",
"Cat",
"Caterpillar",
"Cattle",
"Chamois",
"Cheetah",
"Chicken",
"Chimpanzee",
"Chinchilla",
"Chough",
"Clam",
"Cobra",
"Cockroach",
"Cod",
"Cormorant",
"Coyote",
"Crab",
"Crane",
"Crocodile",
"Crow",
"Curlew",
"Deer",
"Dinosaur",
"Dog",
"Dogfish",
"Dolphin",
"Dotterel",
"Dove",
"Dragonfly",
"Duck",
"Dugong",
"Dunlin",
"Eagle",
"Echidna",
"Eel",
"Eland",
"Elephant",
"Elk",
"Emu",
"Falcon",
"Ferret",
"Finch",
"Fish",
"Flamingo",
"Fly",
"Fox",
"Frog",
"Gaur",
"Gazelle",
"Gerbil",
"Giraffe",
"Gnat",
"Gnu",
"Goat",
"Goldfinch",
"Goldfish",
"Goose",
"Gorilla",
"Goshawk",
"Grasshopper",
"Grouse",
"Guanaco",
"Gull",
"Hamster",
"Hare",
"Hawk",
"Hedgehog",
"Heron",
"Herring",
"Hippopotamus",
"Hornet",
"Horse",
"Hummingbird",
"Hyena",
"Ibex",
"Ibis",
"Jackal",
"Jaguar",
"Jay",
"Jellyfish",
"Kangaroo",
"Kingfisher",
"Koala",
"Kookabura",
"Kouprey",
"Kudu",
"Lapwing",
"Lark",
"Lemur",
"Leopard",
"Lion",
"Llama",
"Lobster",
"Locust",
"Loris",
"Louse",
"Lyrebird",
"Magpie",
"Mallard",
"Manatee",
"Mandrill",
"Mantis",
"Marten",
"Meerkat",
"Mink",
"Mole",
"Mongoose",
"Monkey",
"Moose",
"Mosquito",
"Mouse",
"Mule",
"Narwhal",
"Newt",
"Nightingale",
"Octopus",
"Okapi",
"Opossum",
"Oryx",
"Ostrich",
"Otter",
"Owl",
"Oyster",
"Panther",
"Parrot",
"Partridge",
"Peafowl",
"Pelican",
"Penguin",
"Pheasant",
"Pig",
"Pigeon",
"Pony",
"Porcupine",
"Porpoise",
"Quail",
"Quelea",
"Quetzal",
"Rabbit",
"Raccoon",
"Rail",
"Ram",
"Rat",
"Raven",
"Red Deer",
"Red Panda",
"Reindeer",
"Rhinoceros",
"Rook",
"Salamander",
"Salmon",
"Sand Dollar",
"Sandpiper",
"Sardine",
"Scorpion",
"Seahorse",
"Seal",
"Shark",
"Sheep",
"Shrew",
"Skunk",
"Snail",
"Snake",
"Sparrow",
"Spider",
"Spoonbill",
"Squid",
"Squirrel",
"Starling",
"Stingray",
"Stinkbug",
"Stork",
"Swallow",
"Swan",
"Tapir",
"Tarsier",
"Termite",
"Tiger",
"Toad",
"Trout",
"Turkey",
"Turtle",
"Viper",
"Vulture",
"Wallaby",
"Walrus",
"Wasp",
"Weasel",
"Whale",
"Wildcat",
"Wolf",
"Wolverine",
"Wombat",
"Woodcock",
"Woodpecker",
"Worm",
"Wren",
"Yak",
"Zebra",
];
pub const ADJECTIVES: [&'static str; 765] = [
"Other",
"Such",
"First",
"Many",
"New",
"More",
"Same",
"Own",
"Good",
"Different",
"Great",
"Long",
"High",
"Social",
"Little",
"Much",
"Important",
"Small",
"Most",
"Large",
"Old",
"Few",
"General",
"Second",
"Public",
"Last",
"Several",
"Early",
"Certain",
"Economic",
"Least",
"Common",
"Present",
"Next",
"Local",
"Best",
"Particular",
"Young",
"Various",
"Necessary",
"Whole",
"Only",
"True",
"Able",
"Major",
"Full",
"Low",
"Available",
"Real",
"Similar",
"Total",
"Special",
"Less",
"Short",
"Specific",
"Single",
"Self",
"National",
"Individual",
"Clear",
"Personal",
"Higher",
"Better",
"Third",
"Natural",
"Greater",
"Open",
"Difficult",
"Current",
"Further",
"Main",
"Physical",
"Foreign",
"Lower",
"Strong",
"Private",
"Likely",
"International",
"Significant",
"Late",
"Basic",
"Hard",
"Modern",
"Simple",
"Normal",
"Sure",
"Central",
"Original",
"Effective",
"Following",
"Direct",
"Final",
"Cultural",
"Big",
"Recent",
"Complete",
"Financial",
"Positive",
"Primary",
"Appropriate",
"Legal",
"European",
"Equal",
"Larger",
"Average",
"Historical",
"Critical",
"Wide",
"Traditional",
"Additional",
"Active",
"Complex",
"Former",
"Independent",
"Entire",
"Actual",
"Close",
"Constant",
"Previous",
"Easy",
"Serious",
"Potential",
"Fine",
"Industrial",
"Subject",
"Future",
"Internal",
"Initial",
"Well",
"Essential",
"Dark",
"Popular",
"Successful",
"Standard",
"Year",
"Past",
"Ready",
"Professional",
"Wrong",
"Very",
"Proper",
"Separate",
"Heavy",
"Civil",
"Responsible",
"Considerable",
"Light",
"Cold",
"Above",
"Older",
"Practical",
"External",
"Sufficient",
"Interesting",
"Upper",
"Scientific",
"Key",
"Annual",
"Limited",
"Smaller",
"Southern",
"Earlier",
"Commercial",
"Powerful",
"Later",
"Like",
"Clinical",
"Ancient",
"Educational",
"Typical",
"Technical",
"Environmental",
"Formal",
"Aware",
"Beautiful",
"Variable",
"Obvious",
"Secondary",
"Enough",
"Urban",
"Regular",
"Relevant",
"Greatest",
"Spiritual",
"Time",
"Double",
"Happy",
"Term",
"Multiple",
"Dependent",
"Correct",
"Northern",
"Middle",
"Rural",
"Official",
"Fundamental",
"Numerous",
"Overall",
"Usual",
"Native",
"Regional",
"Highest",
"North",
"Agricultural",
"Literary",
"Broad",
"Perfect",
"Experimental",
"Fourth",
"Global",
"Ordinary",
"Related",
"Apparent",
"Daily",
"Principal",
"Contemporary",
"Severe",
"Reasonable",
"Subsequent",
"Worth",
"Longer",
"Emotional",
"Intellectual",
"Unique",
"Pure",
"Familiar",
"American",
"Solid",
"Brief",
"Famous",
"Fresh",
"Day",
"Corresponding",
"Characteristic",
"Maximum",
"Detailed",
"Outside",
"Theoretical",
"Fair",
"Opposite",
"Capable",
"Visual",
"Interested",
"Joint",
"Adequate",
"Based",
"Substantial",
"Unable",
"Structural",
"Soft",
"False",
"Largest",
"Inner",
"Mean",
"Extensive",
"Excellent",
"Rapid",
"Absolute",
"Consistent",
"Continuous",
"Administrative",
"Strange",
"Willing",
"Alternative",
"Slow",
"Distinct",
"Safe",
"Permanent",
"Front",
"Corporate",
"Academic",
"Thin",
"Nineteenth",
"Universal",
"Functional",
"Unknown",
"Careful",
"Narrow",
"Evident",
"Sound",
"Classical",
"Minor",
"Weak",
"Suitable",
"Chief",
"Extreme",
"Yellow",
"Warm",
"Mixed",
"Flat",
"Huge",
"Vast",
"Stable",
"Valuable",
"Rare",
"Visible",
"Sensitive",
"Mechanical",
"State",
"Radical",
"Extra",
"Superior",
"Conventional",
"Thick",
"Dominant",
"Post",
"Collective",
"Younger",
"Efficient",
"Linear",
"Organic",
"Oral",
"Century",
"Creative",
"Vertical",
"Dynamic",
"Empty",
"Minimum",
"Cognitive",
"Logical",
"Afraid",
"Equivalent",
"Quick",
"Near",
"Concrete",
"Mass",
"Acute",
"Sharp",
"Easier",
"Quiet",
"Adult",
"Accurate",
"Ideal",
"Partial",
"Bright",
"Identical",
"Conservative",
"Magnetic",
"Frequent",
"Electronic",
"Fixed",
"Square",
"Cross",
"Clean",
"Back",
"Organizational",
"Constitutional",
"Genetic",
"Ultimate",
"Secret",
"Vital",
"Dramatic",
"Objective",
"Round",
"Alive",
"Straight",
"Unusual",
"Rational",
"Electric",
"Mutual",
"Class",
"Competitive",
"Revolutionary",
"Statistical",
"Random",
"Musical",
"Crucial",
"Racial",
"Sudden",
"Acid",
"Content",
"Temporary",
"Line",
"Remarkable",
"Exact",
"Valid",
"Helpful",
"Nice",
"Comprehensive",
"United",
"Level",
"Fifth",
"Nervous",
"Expensive",
"Prominent",
"Healthy",
"Liquid",
"Institutional",
"Silent",
"Sweet",
"Strategic",
"Molecular",
"Comparative",
"Called",
"Electrical",
"Raw",
"Acceptable",
"Scale",
"Violent",
"All",
"Desirable",
"Tall",
"Steady",
"Wonderful",
"Sub",
"Distant",
"Progressive",
"Enormous",
"Horizontal",
"And",
"Intense",
"Smooth",
"Applicable",
"Over",
"Animal",
"Abstract",
"Wise",
"Worst",
"Gold",
"Precise",
"Legislative",
"Remote",
"Technological",
"Outer",
"Uniform",
"Slight",
"Attractive",
"Evil",
"Tiny",
"Royal",
"Angry",
"Advanced",
"Friendly",
"Dear",
"Busy",
"Spatial",
"Rough",
"Primitive",
"Judicial",
"Systematic",
"Lateral",
"Sorry",
"Plain",
"Off",
"Comfortable",
"Definite",
"Massive",
"Firm",
"Widespread",
"Prior",
"Twentieth",
"Mathematical",
"Verbal",
"Marginal",
"Excessive",
"Stronger",
"Gross",
"World",
"Productive",
"Wider",
"Glad",
"Linguistic",
"Patient",
"Symbolic",
"Earliest",
"Plastic",
"Type",
"Prime",
"Eighteenth",
"Blind",
"Neutral",
"Guilty",
"Hand",
"Extraordinary",
"Metal",
"Surprising",
"Fellow",
"York",
"Grand",
"Thermal",
"Artificial",
"Five",
"Lowest",
"Genuine",
"Dimensional",
"Optical",
"Unlikely",
"Developmental",
"Reliable",
"Executive",
"Comparable",
"Satisfactory",
"Golden",
"Diverse",
"Preliminary",
"Wooden",
"Noble",
"Part",
"Striking",
"Cool",
"Classic",
"Elderly",
"Four",
"Temporal",
"Indirect",
"Romantic",
"Intermediate",
"Differential",
"Passive",
"Life",
"Voluntary",
"Out",
"Adjacent",
"Behavioral",
"Exclusive",
"Closed",
"Inherent",
"Inevitable",
"Complicated",
"Quantitative",
"Respective",
"Artistic",
"Probable",
"Anxious",
"Informal",
"Strict",
"Fiscal",
"Ideological",
"Profound",
"Extended",
"Eternal",
"Known",
"Infinite",
"Proud",
"Honest",
"Peculiar",
"Absent",
"Pleasant",
"Optimal",
"Renal",
"Static",
"Outstanding",
"Presidential",
"Digital",
"Integrated",
"Legitimate",
"Curious",
"Aggressive",
"Deeper",
"Elementary",
"History",
"Surgical",
"Occasional",
"Flexible",
"Convenient",
"Solar",
"Atomic",
"Isolated",
"Latest",
"Sad",
"Conceptual",
"Underlying",
"Everyday",
"Cost",
"Intensive",
"Odd",
"Subjective",
"Mid",
"Worthy",
"Pale",
"Meaningful",
"Therapeutic",
"Making",
"Circular",
"Realistic",
"Multi",
"Child",
"Sophisticated",
"Down",
"Leading",
"Intelligent",
"Governmental",
"Numerical",
"Minimal",
"Diagnostic",
"Indigenous",
"Aesthetic",
"Distinctive",
"Operational",
"Sole",
"Material",
"Fast",
"Bitter",
"Broader",
"Brilliant",
"Peripheral",
"Rigid",
"Automatic",
"Lesser",
"Routine",
"Favorable",
"Cooperative",
"Cardiac",
"Arbitrary",
"Loose",
"Favorite",
"Subtle",
"Uncertain",
"Hostile",
"Monthly",
"Naval",
"Physiological",
"Historic",
"Developed",
"Skilled",
"Anterior",
"Pro",
"Gentle",
"Loud",
"Pulmonary",
"Innocent",
"Provincial",
"Mild",
"Page",
"Specialized",
"Bare",
"Excess",
"Inter",
"Shaped",
"Theological",
"Sensory",
"The",
"Stress",
"Novel",
"Working",
"Shorter",
"Secular",
"Geographical",
"Intimate",
"Liable",
"Selective",
"Influential",
"Modest",
"Successive",
"Continued",
"Water",
"Expert",
"Municipal",
"Marine",
"Thirty",
"Adverse",
"Wacky",
"Closer",
"Virtual",
"Peaceful",
"Mobile",
"Sixth",
"Immune",
"Coastal",
"Representative",
"Lead",
"Forward",
"Faithful",
"Crystal",
"Protective",
"Elaborate",
"Tremendous",
"Welcoming",
"Abnormal",
"Grateful",
"Proportional",
"Dual",
"Operative",
"Precious",
"Sympathetic",
"Accessible",
"Lovely",
"Spinal",
"Even",
"Marked",
"Observed",
"Point",
"Mature",
"Competent",
"Residential",
"Impressive",
"Unexpected",
"Nearby",
"Unnecessary",
"Generous",
"Cerebral",
"Unpublished",
"Delicate",
"Analytical",
"Tropical",
"Statutory",
"Cell",
"Weekly",
"End",
"Online",
"Beneficial",
"Aged",
"Tough",
"Eager",
"Ongoing",
"Silver",
"Persistent",
"Calm",
"Nearest",
"Hidden",
"Magic",
"Pretty",
"Wealthy",
"Exciting",
"Decisive",
"Confident",
"Invisible",
"Notable",
"Medium",
"Manual",
"Select",
"Thorough",
"Causal",
"Giant",
"Bigger",
"Pink",
"Improved",
"Immense",
"Hour",
"Intact",
"Grade",
"Dense",
"Hungry",
"Biggest",
"Abundant",
"Handsome",
"Retail",
"Insufficient",
"Irregular",
"Intrinsic",
"Residual",
"Follow",
"Fluid",
"Mysterious",
"Descriptive",
"Elastic",
"Destructive",
"Architectural",
"Synthetic",
"Continental",
"Evolutionary",
"Lucky",
"Bold",
"Funny",
"Peak",
"Smallest",
"Reluctant",
"Suspicious",
"Smart",
"Mighty",
"Brave",
"Humble",
"Vocal",
"Obscure",
"Innovative",
];