feat: added oauth based login and registration (#1)

Co-authored-by: Sharang Parnerkar <parnerkarsharang@gmail.com>
Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
2026-02-18 09:21:46 +00:00
parent b8aad0e23c
commit 1072770d11
36 changed files with 7420 additions and 26 deletions

View File

@@ -0,0 +1,56 @@
use crate::infrastructure::{
auth_callback, auth_login, logout, PendingOAuthStore, UserState, UserStateInner,
};
use dioxus::prelude::*;
use axum::routing::get;
use axum::Extension;
use time::Duration;
use tower_sessions::{cookie::Key, MemoryStore, SessionManagerLayer};
/// Start the Axum server with Dioxus fullstack, session management,
/// and Keycloak OAuth routes.
///
/// # Errors
///
/// Returns `Error` if the tokio runtime or TCP listener fails to start.
pub fn server_start(app: fn() -> Element) -> Result<(), super::Error> {
tokio::runtime::Runtime::new()?.block_on(async move {
let state: UserState = UserStateInner {
access_token: "abcd".into(),
sub: "abcd".into(),
refresh_token: "abcd".into(),
..Default::default()
}
.into();
let key = Key::generate();
let store = MemoryStore::default();
let session = SessionManagerLayer::new(store)
.with_secure(false)
// Lax is required so the browser sends the session cookie
// on the redirect back from Keycloak (cross-origin GET).
// Strict would silently drop the cookie on that navigation.
.with_same_site(tower_sessions::cookie::SameSite::Lax)
.with_expiry(tower_sessions::Expiry::OnInactivity(Duration::hours(24)))
.with_signed(key);
let addr = dioxus_cli_config::fullstack_address_or_localhost();
let listener = tokio::net::TcpListener::bind(addr).await?;
// Layers are applied AFTER serve_dioxus_application so they
// wrap both the custom Axum routes AND the Dioxus server
// function routes (e.g. check_auth needs Session access).
let router = axum::Router::new()
.route("/auth", get(auth_login))
.route("/auth/callback", get(auth_callback))
.route("/logout", get(logout))
.serve_dioxus_application(ServeConfig::new(), app)
.layer(Extension(PendingOAuthStore::default()))
.layer(Extension(state))
.layer(session);
info!("Serving at {addr}");
axum::serve(listener, router.into_make_service()).await?;
Ok(())
})
}