-
Notifications
You must be signed in to change notification settings - Fork 2
fix auth0 #206
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix auth0 #206
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also a lint, ignore this |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,78 +7,94 @@ import { WhiteBackground } from "../components/WhiteBackground"; | |
| import { FullPageLoadingSpinner } from "../components/FullPageLoadingSpinner"; | ||
| import Button from "../components/Button"; | ||
| import { getAllForms } from "../forms/forms"; | ||
| import { createGetAuthToken } from "../utils/authUtils"; | ||
| import "./FormsLandingPage.css"; | ||
|
|
||
| const FormsLandingPage = () => { | ||
| const { getAccessTokenSilently } = useAuth0(); | ||
| const navigate = useNavigate(); | ||
| const [formsStatus, setFormsStatus] = useState({}); | ||
| const [loading, setLoading] = useState(true); | ||
| const [error, setError] = useState(null); | ||
|
|
||
| const allForms = useMemo(() => getAllForms(), []); | ||
|
|
||
| useEffect(() => { | ||
| const fetchAllFormsStatus = async () => { | ||
| setLoading(true); | ||
| const token = await getAccessTokenSilently(); | ||
| const statusPromises = allForms.map(async (form) => { | ||
| try { | ||
| const statusRes = await axios.get( | ||
| `${process.env.REACT_APP_BACKEND_URL}/application/form-status`, | ||
| { | ||
| headers: { Authorization: `Bearer ${token}` }, | ||
| params: { form_key: form.formKey }, | ||
| } | ||
| ); | ||
|
|
||
| const isOpen = Boolean(statusRes.data?.is_open); | ||
| try { | ||
| setLoading(true); | ||
| setError(null); | ||
|
|
||
| const getAuthToken = createGetAuthToken(getAccessTokenSilently, setError); | ||
| const token = await getAuthToken(); | ||
| if (!token) { | ||
| setLoading(false); | ||
| return; | ||
| } | ||
|
|
||
| let hasSubmitted = false; | ||
| const statusPromises = allForms.map(async (form) => { | ||
| try { | ||
| await axios.get( | ||
| `${process.env.REACT_APP_BACKEND_URL}/application`, | ||
| const statusRes = await axios.get( | ||
| `${process.env.REACT_APP_BACKEND_URL}/application/form-status`, | ||
| { | ||
| headers: { Authorization: `Bearer ${token}` }, | ||
| params: { form_key: form.formKey }, | ||
| } | ||
| ); | ||
| hasSubmitted = true; | ||
| } catch (error) { | ||
| if (error.response?.status !== 404) { | ||
| console.error( | ||
| `Error checking submission for ${form.formKey}:`, | ||
| error | ||
|
|
||
| const isOpen = Boolean(statusRes.data?.is_open); | ||
|
|
||
| let hasSubmitted = false; | ||
| try { | ||
| await axios.get( | ||
| `${process.env.REACT_APP_BACKEND_URL}/application`, | ||
| { | ||
| headers: { Authorization: `Bearer ${token}` }, | ||
| params: { form_key: form.formKey }, | ||
| } | ||
| ); | ||
| hasSubmitted = true; | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is just to make sure errors get caught here -- wasn't visible before |
||
| } catch (error) { | ||
| if (error.response?.status !== 404) { | ||
| console.error( | ||
| `Error checking submission for ${form.formKey}:`, | ||
| error | ||
| ); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return { | ||
| formKey: form.formKey, | ||
| isOpen, | ||
| hasSubmitted, | ||
| }; | ||
| } catch (error) { | ||
| console.error(`Error fetching status for ${form.formKey}:`, error); | ||
| return { | ||
| formKey: form.formKey, | ||
| isOpen: false, | ||
| hasSubmitted: false, | ||
| error: true, | ||
| }; | ||
| } | ||
| }); | ||
|
|
||
| const results = await Promise.all(statusPromises); | ||
| const statusMap = {}; | ||
| results.forEach((result) => { | ||
| statusMap[result.formKey] = result; | ||
| }); | ||
| setFormsStatus(statusMap); | ||
| setLoading(false); | ||
| return { | ||
| formKey: form.formKey, | ||
| isOpen, | ||
| hasSubmitted, | ||
| }; | ||
| } catch (error) { | ||
| console.error(`Error fetching status for ${form.formKey}:`, error); | ||
| return { | ||
| formKey: form.formKey, | ||
| isOpen: false, | ||
| hasSubmitted: false, | ||
| error: true, | ||
| }; | ||
| } | ||
| }); | ||
|
|
||
| const results = await Promise.all(statusPromises); | ||
| const statusMap = {}; | ||
| results.forEach((result) => { | ||
| statusMap[result.formKey] = result; | ||
| }); | ||
| setFormsStatus(statusMap); | ||
| setLoading(false); | ||
| } catch (err) { | ||
| console.error("Error in fetchAllFormsStatus:", err); | ||
| setError("Failed to load."); | ||
| setLoading(false); | ||
| } | ||
| }; | ||
|
|
||
| fetchAllFormsStatus(); | ||
| }, [getAccessTokenSilently, allForms]); | ||
| }, [allForms, getAccessTokenSilently]); | ||
|
|
||
| const handleFormClick = (formKey) => { | ||
| navigate(`/form?formKey=${formKey}`); | ||
|
|
@@ -110,6 +126,7 @@ const FormsLandingPage = () => { | |
| <Navbar /> | ||
| <WhiteBackground /> | ||
| {loading && <FullPageLoadingSpinner />} | ||
| {error && <div style={{ color: "red", padding: "1rem" }}>{error}</div>} | ||
| <div className="forms-landing-container"> | ||
| <h1 className="forms-landing-title">Applications & Forms</h1> | ||
| <p className="forms-landing-subtitle"> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| import { useAuth0 } from "@auth0/auth0-react"; | ||
|
|
||
| let loginWithRedirect = null; | ||
|
|
||
| export const setLoginWithRedirect = (loginFn) => { | ||
| loginWithRedirect = loginFn; | ||
| }; | ||
|
|
||
| export const createGetAuthToken = (getAccessTokenSilently, onError) => { | ||
| return async () => { | ||
| try { | ||
| return await getAccessTokenSilently(); | ||
| } catch (tokenError) { | ||
| const errorMessage = tokenError.message || ""; | ||
| const errorCode = tokenError.error || ""; | ||
|
|
||
| console.error("Auth token error:", { | ||
| errorMessage, | ||
| errorCode, | ||
| tokenError, | ||
| }); | ||
|
|
||
| if ( | ||
| errorMessage.includes("Missing Refresh Token") || | ||
| errorCode === "login_required" || | ||
| errorCode === "consent_required" || | ||
| errorCode === "missing_refresh_token" || | ||
| errorCode === "invalid_grant" | ||
| ) { | ||
| if (loginWithRedirect) { | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is the main fix -- force relogin on any of the above issues. |
||
| loginWithRedirect(); | ||
| } else if (onError) { | ||
| onError("Session expired. Please log in again."); | ||
| } | ||
| throw tokenError; | ||
| } | ||
|
|
||
| if (errorMessage.includes("timeout") || errorCode === "timeout") { | ||
| if (onError) { | ||
| onError("Authentication took too long. Please try again."); | ||
| } | ||
| throw tokenError; | ||
| } | ||
|
|
||
| if (onError) { | ||
| onError( | ||
| `Authentication error: ${errorMessage || errorCode || "Unknown error"}` | ||
| ); | ||
| } | ||
| throw tokenError; | ||
| } | ||
| }; | ||
| }; | ||
|
|
||
| export const useInitializeAuth = () => { | ||
| const { loginWithRedirect } = useAuth0(); | ||
| setLoginWithRedirect(loginWithRedirect); | ||
| }; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is just fixing some lints that were cluttering up my console