feat: implement auth callback page

This page will allow users to redirect to their previous path when they sign in.
This commit is contained in:
alphafetus committed 2026-01-15 08:37:43 -05:00
1 parent 4e8f4a3c5e
commit d42573bf65
4 files changed
+66 -22

No files matched your search

+3 -6
View File
@@ -1,10 +1,9 @@
use crate::pages::{AboutPage, HomePage, ProviderPortal, ComparisonTestPage, ScholarshipInfoPage, TestPage, ProviderContactPage, LoanerShell, LoanerFallback, LoanerBorrowForm, LoanerReturnForm};
use crate::pages::{AboutPage, HomePage, ProviderPortal, ComparisonTestPage, ScholarshipInfoPage, TestPage, ProviderContactPage, LoanerShell, LoanerFallback, LoanerBorrowForm, LoanerReturnForm, AuthCallbackPage};
use leptos::prelude::*;
use leptos_meta::{MetaTags, Stylesheet, Title, provide_meta_context};
use leptos_oidc::{Auth, AuthParameters, AuthSignal, Challenge};
use leptos_router::{components::{Route, Router, Routes, ParentRoute}, path};
use crate::components::ToastList;
use leptos::logging::log;
pub fn shell(options: LeptosOptions) -> impl IntoView {
view! {
@@ -66,15 +65,12 @@ pub fn AppWithRoutes() -> impl IntoView {
provide_meta_context();
let current_origin = use_origin();
log!("Current origin: {}", current_origin);
// Authentication setup
let parameters = AuthParameters {
issuer: "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_Lfjuy5zaM".into(),
client_id: "10jr2h3vtpu9n7gj46pvg5qo2q".into(),
redirect_uri: format!("{}/", use_origin()),
// redirect_uri: Url::parse(format!("{}", current_origin).as_str()).unwrap().to_string(),
// redirect_uri: Url::parse("http://localhost:3000").unwrap().to_string(),
redirect_uri: format!("{}/auth/callback", current_origin),
post_logout_redirect_uri: current_origin,
scope: Some("openid%20profile%20email".into()),
audience: None,
@@ -103,6 +99,7 @@ pub fn AppWithRoutes() -> impl IntoView {
// TODO Create a 404 page
<Routes fallback=|| "Page not found.".into_view()>
<Route path=path!("") view=HomePage />
<Route path=path!("/auth/callback") view=AuthCallbackPage />
<Route path=path!("/about") view=AboutPage />
<Route path=path!("/test_page") view=TestPage />
<Route path=path!("/comparison") view=ComparisonTestPage />
+37
View File
@@ -0,0 +1,37 @@
use leptos::prelude::*;
use leptos_oidc::AuthSignal;
use leptos_router::hooks::use_navigate;
#[component]
pub fn AuthCallbackPage() -> impl IntoView {
// This should wait for authentication, read the values in session storage, and then redirect
// to the correct page. The session storage should contain a path, which we'll need to check.
let auth = expect_context::<AuthSignal>();
let navigate = use_navigate();
Effect::new(move || {
// Wait for auth to load, then read information.
if let Some(_) = auth.get().authenticated() {
// Read the sessionStorage to get the last navigated path.
let storage_opt = window().session_storage().ok().flatten();
let path = storage_opt
.and_then(|storage| storage.get_item("post_login_path").ok().flatten())
.unwrap_or_else(|| "/".to_string());
// Clear storage in case we need to reauth again
if let Some(storage) = window().session_storage().ok().flatten() {
let _ = storage.remove_item("post_login_path");
}
// Redirect to the stored path
navigate(&path, Default::default());
}
});
view! {
<div class="flex flex-col w-full mx-auto items-center justify-center">
<p>"Completing the login process..."</p>
</div>
}
}
+3 -1
View File
@@ -9,8 +9,10 @@ mod test_page;
mod unauthenticated_page;
mod utils;
mod provider_contact;
mod auth_callback;
pub use self::{
about_page::*, comparison_test::*, home_page::*, loaner_page::*, provider_portal::*,
test_page::*, unauthenticated_page::*, scholarship_info::*, provider_contact::*
test_page::*, unauthenticated_page::*, scholarship_info::*, provider_contact::*,
auth_callback::*,
};
+23 -15
View File
@@ -2,35 +2,43 @@ use crate::components::ActionButton;
use leptos::logging::log;
use leptos::prelude::*;
use leptos_oidc::AuthSignal;
use leptos_router::hooks::{use_navigate, use_location};
#[component]
pub fn UnauthenticatedPage() -> impl IntoView {
let auth = use_context::<AuthSignal>().expect("AuthSignal not present in LoginLink");
let login_url = move || {
let login_url = Memo::new(move |_| {
auth.with(|auth| {
auth.unauthenticated()
.map(|unauthenticated| unauthenticated.login_url())
})
});
Effect::new(move || log!("Generated login url: {:?}", login_url.get()));
let navigate = use_navigate();
let location = use_location();
let on_click = move |_| {
let current_path = location.pathname.get();
let storage_opt = window().session_storage().ok().flatten();
if let Some(session_storage) = storage_opt {
let _ = session_storage.set_item("post_login_path", &current_path);
}
if let Some(url) = login_url.get() {
navigate(&url, Default::default())
}
};
Effect::new(move || log!("Generated login url: {:?}", login_url()));
let navigate = leptos_router::hooks::use_navigate();
view! (
view! {
<div class="flex h-screen justify-center items-center pb-50">
<div class="bg-white p-8 border rounded-lg shadow-lg">
<h3> "You're not signed in. Please sign in with your Region 15 email." </h3>
<h3>"You're not signed in. Please sign in with your Region 15 email."</h3>
<div class="flex pt-4 justify-center items-center">
<ActionButton on:click=move |_| {
if let Some(url) = login_url() {
navigate(&url, Default::default())
}
}>
"Sign in"
</ActionButton>
<ActionButton on:click=on_click>"Sign in"</ActionButton>
</div>
</div>
</div>
)
}
}