Fix Keycloak auth: optional chaining for useAuth hook

This commit is contained in:
Chris Rai
2026-01-31 23:42:53 -05:00
parent c0917724f2
commit 1c55b0b562
4 changed files with 23 additions and 10 deletions

View File

@@ -2,6 +2,12 @@ REACT_APP_AUTH_CALLBACK_URL=http://localhost:3000
REACT_APP_AUTH_SERVICE_URL=http://localhost/compute_auth REACT_APP_AUTH_SERVICE_URL=http://localhost/compute_auth
REACT_APP_CERT_SERVICE_URL=http://localhost/certificate REACT_APP_CERT_SERVICE_URL=http://localhost/certificate
REACT_APP_ENV=local REACT_APP_ENV=local
# Keycloak OIDC
REACT_APP_KEYCLOAK_ENABLED=true
REACT_APP_KEYCLOAK_URL=https://keycloak.mini.cloud.fiskerinc.com
REACT_APP_KEYCLOAK_REALM=compute-auth
REACT_APP_KEYCLOAK_CLIENT_ID=ota-portal
REACT_APP_MAGNA_PROVIDER=Magna REACT_APP_MAGNA_PROVIDER=Magna
REACT_APP_MAGNA_GROUP_ID=68273225-9da4-4fa7-aea5-38e16ec471fe REACT_APP_MAGNA_GROUP_ID=68273225-9da4-4fa7-aea5-38e16ec471fe
REACT_APP_OTA_SERVICE_URL=http://localhost/ota_update REACT_APP_OTA_SERVICE_URL=http://localhost/ota_update

View File

@@ -24,11 +24,19 @@ function AppContent() {
); );
} }
const onSigninCallback = () => {
// Remove OIDC params from URL after signin
window.history.replaceState({}, document.title, window.location.pathname);
};
function App() { function App() {
// Only wrap with AuthProvider if Keycloak is enabled // Only wrap with AuthProvider if Keycloak is enabled
if (isKeycloakEnabled()) { if (isKeycloakEnabled()) {
return ( return (
<AuthProvider {...keycloakConfig}> <AuthProvider
{...keycloakConfig}
onSigninCallback={onSigninCallback}
>
<AppContent /> <AppContent />
</AuthProvider> </AuthProvider>
); );

View File

@@ -1,6 +1,7 @@
import { Button } from "@material-ui/core"; import { Button } from "@material-ui/core";
import clsx from "clsx"; import clsx from "clsx";
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { useAuth } from "react-oidc-context";
import { useUserContext } from "../Contexts/UserContext"; import { useUserContext } from "../Contexts/UserContext";
import useStyles from "../useStyles"; import useStyles from "../useStyles";
@@ -12,9 +13,8 @@ const getCode = (search) => {
return s.get("code"); return s.get("code");
}; };
// Keycloak-enabled version of the form // Keycloak-enabled version of the form - only rendered when inside AuthProvider
function KeycloakSignInForm() { function KeycloakSignInForm() {
const { useAuth } = require("react-oidc-context");
const classes = useStyles(); const classes = useStyles();
const { getAuthorizeURL, signIn, signInWithKeycloak, fetching } = useUserContext(); const { getAuthorizeURL, signIn, signInWithKeycloak, fetching } = useUserContext();
const auth = useAuth(); const auth = useAuth();
@@ -23,19 +23,18 @@ function KeycloakSignInForm() {
useEffect(() => { useEffect(() => {
const code = getCode(document.location.search); const code = getCode(document.location.search);
// Only process if it's a Cognito code (not a Keycloak callback) // Only process if it's a Cognito code (not a Keycloak callback)
// Keycloak uses 'state' param that react-oidc-context handles if (!code || auth?.isLoading || auth?.isAuthenticated) return;
if (!code || auth.isLoading || auth.isAuthenticated) return;
signIn(code); signIn(code);
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
// Handle Keycloak authentication callback // Handle Keycloak authentication callback
useEffect(() => { useEffect(() => {
if (auth.isAuthenticated && auth.user) { if (auth?.isAuthenticated && auth?.user) {
signInWithKeycloak(auth.user); signInWithKeycloak(auth.user);
} }
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [auth.isAuthenticated, auth.user]); }, [auth?.isAuthenticated, auth?.user]);
const handleKeycloakLogin = () => { const handleKeycloakLogin = () => {
auth.signinRedirect(); auth.signinRedirect();
@@ -62,9 +61,9 @@ function KeycloakSignInForm() {
color="primary" color="primary"
className={classes.submit} className={classes.submit}
onClick={handleKeycloakLogin} onClick={handleKeycloakLogin}
disabled={fetching || auth.isLoading} disabled={fetching || auth?.isLoading}
> >
{auth.isLoading ? "Loading..." : "Sign In with Keycloak"} {auth?.isLoading ? "Loading..." : "Sign In with Keycloak"}
</Button> </Button>
<p><strong>Note: Your email address will be used as the user id</strong></p> <p><strong>Note: Your email address will be used as the user id</strong></p>

View File

@@ -10,7 +10,7 @@ export const keycloakConfig = {
redirect_uri: CALLBACK_URL, redirect_uri: CALLBACK_URL,
post_logout_redirect_uri: CALLBACK_URL, post_logout_redirect_uri: CALLBACK_URL,
response_type: 'code', response_type: 'code',
scope: 'openid profile email roles', scope: 'openid',
// Handle silent renew and callback automatically // Handle silent renew and callback automatically
automaticSilentRenew: true, automaticSilentRenew: true,
loadUserInfo: true, loadUserInfo: true,