···1919hex = "0.4"
2020jwt-compact = { version = "0.8.0", features = ["es256k"] }
2121scrypt = "0.11"
2222-#lettre = { version = "0.11.18", default-features = false, features = ["pool", "tokio1-rustls", "smtp-transport", "hostname", "builder"] }
2323-#lettre = { version = "0.11", default-features = false, features = ["builder", "webpki-roots", "rustls", "aws-lc-rs", "smtp-transport", "tokio1", "tokio1-rustls"] }
2222+#Leaveing these two cause I think it is needed by the
2423aws-lc-rs = "1.13.0"
2525-lettre = { version = "0.11", default-features = false, features = ["builder", "webpki-roots", "rustls", "aws-lc-rs", "smtp-transport", "tokio1", "tokio1-rustls"] }
2624rustls = { version = "0.23", default-features = false, features = ["tls12", "std", "logging", "aws_lc_rs"] }
2525+lettre = { version = "0.11", default-features = false, features = ["builder", "webpki-roots", "rustls", "aws-lc-rs", "smtp-transport", "tokio1", "tokio1-rustls"] }
2726handlebars = { version = "6.3.2", features = ["rust-embed"] }
2827rust-embed = "8.7.2"
2928axum-template = { version = "3.0.0", features = ["handlebars"] }
+3
src/main.rs
···175175 .finish()
176176 .expect("failed to create governor config. this should not happen and is a bug");
177177178178+ // let create_account_limiter_time: Option<String> =
179179+ // env::var("GATEKEEPER_CREATE_ACCOUNT_LIMITER_WINDOW").unwrap_or_else(|_| None);
180180+178181 let create_session_governor_limiter = create_session_governor_conf.limiter().clone();
179182 let sign_in_governor_limiter = sign_in_governor_conf.limiter().clone();
180183 let interval = Duration::from_secs(60);
+40-17
src/middleware.rs
···11use crate::helpers::json_error_response;
22use axum::extract::Request;
33+use axum::http::header::AUTHORIZATION;
34use axum::http::{HeaderMap, StatusCode};
45use axum::middleware::Next;
56use axum::response::IntoResponse;
···1213#[derive(Clone, Debug)]
1314pub struct Did(pub Option<String>);
14151616+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1717+pub enum AuthScheme {
1818+ Bearer,
1919+ DPoP,
2020+}
2121+1522#[derive(Serialize, Deserialize)]
1623pub struct TokenClaims {
1724 pub sub: String,
1825}
19262027pub async fn extract_did(mut req: Request, next: Next) -> impl IntoResponse {
2121- let token = extract_bearer(req.headers());
2828+ let auth = extract_auth(req.headers());
22292323- match token {
2424- Ok(token) => {
2525- match token {
3030+ match auth {
3131+ Ok(auth_opt) => {
3232+ match auth_opt {
2633 None => json_error_response(StatusCode::BAD_REQUEST, "TokenRequired", "")
2734 .expect("Error creating an error response"),
2828- Some(token) => {
2929- let token = UntrustedToken::new(&token);
3535+ Some((scheme, token_str)) => {
3636+ // For Bearer, validate JWT and extract DID from `sub`.
3737+ // For DPoP, we currently only pass through and do not validate here; insert None DID.
3838+ // match scheme {
3939+ // AuthScheme::Bearer => {
4040+ let token = UntrustedToken::new(&token_str);
3041 if token.is_err() {
3142 return json_error_response(StatusCode::BAD_REQUEST, "TokenRequired", "")
3243 .expect("Error creating an error response");
···4960 .expect("Error creating an error response");
5061 }
5162 let token = token.expect("Already checked for error,");
5252- //Not going to worry about expiration since it still goes to the PDS
6363+ // Not going to worry about expiration since it still goes to the PDS
5364 req.extensions_mut()
5465 .insert(Did(Some(token.claims().custom.sub.clone())));
6666+ // }
6767+ // AuthScheme::DPoP => {
6868+ // // No DID extraction from DPoP here; leave None
6969+ // req.extensions_mut().insert(Did(None));
7070+ // }
7171+ // }
7272+5573 next.run(req).await
5674 }
5775 }
···6482 }
6583}
66846767-fn extract_bearer(headers: &HeaderMap) -> Result<Option<String>, String> {
8585+fn extract_auth(headers: &HeaderMap) -> Result<Option<(AuthScheme, String)>, String> {
6886 match headers.get(axum::http::header::AUTHORIZATION) {
6987 None => Ok(None),
7070- Some(hv) => match hv.to_str() {
7171- Err(_) => Err("Authorization header is not valid".into()),
7272- Ok(s) => {
7373- // Accept forms like: "Bearer <token>" (case-sensitive for the scheme here)
7474- let mut parts = s.splitn(2, ' ');
7575- match (parts.next(), parts.next()) {
7676- (Some("Bearer"), Some(tok)) if !tok.is_empty() => Ok(Some(tok.to_string())),
7777- _ => Err("Authorization header must be in format 'Bearer <token>'".into()),
8888+ Some(hv) => {
8989+ match hv.to_str() {
9090+ Err(_) => Err("Authorization header is not valid".into()),
9191+ Ok(s) => {
9292+ // Accept forms like: "Bearer <token>" or "DPoP <token>" (case-sensitive for the scheme here)
9393+ let mut parts = s.splitn(2, ' ');
9494+ match (parts.next(), parts.next()) {
9595+ (Some("Bearer"), Some(tok)) if !tok.is_empty() =>
9696+ Ok(Some((AuthScheme::Bearer, tok.to_string()))),
9797+ (Some("DPoP"), Some(tok)) if !tok.is_empty() =>
9898+ Ok(Some((AuthScheme::DPoP, tok.to_string()))),
9999+ _ => Err("Authorization header must be in format 'Bearer <token>' or 'DPoP <token>'".into()),
100100+ }
78101 }
79102 }
8080- },
103103+ }
81104 }
82105}