@@ -21,7 +21,7 @@ import {AsgardeoRuntimeError} from '@asgardeo/browser';2025, WSO2 LLC. (https://
2121
2222import { FC , ReactElement , ReactNode } from 'react' ;
2323import { Navigate } from 'react-router' ;
24- import { useAsgardeo , AsgardeoRuntimeError } from '@asgardeo/react' ;
24+ import { useAsgardeo , AsgardeoRuntimeError , navigate } from '@asgardeo/react' ;
2525
2626/**
2727 * Props for the ProtectedRoute component.
@@ -45,6 +45,37 @@ export interface ProtectedRouteProps {
4545 * Custom loading element to render while authentication status is being determined.
4646 */
4747 loader ?: ReactNode ;
48+ /**
49+ * Custom sign-in function to override the default behavior.
50+ * If provided, this function will be called instead of the default signIn method
51+ * when the user is not authenticated and no fallback or redirectTo is specified.
52+ * This allows you to pass additional parameters or implement custom sign-in logic.
53+ *
54+ * @param defaultSignIn - The default signIn method from useAsgardeo hook
55+ * @param signInOptions - Merged sign-in options (context + component props)
56+ */
57+ onSignIn ?: ( defaultSignIn : ( options ?: Record < string , any > ) => void , signInOptions ?: Record < string , any > ) => void ;
58+ /**
59+ * Additional parameters to pass to the authorize request.
60+ * These will be merged with the default signInOptions from the Asgardeo context.
61+ * Common options include:
62+ * - prompt: "login" | "none" | "consent" | "select_account"
63+ * - fidp: Federation Identity Provider identifier
64+ * - kc_idp_hint: Keycloak identity provider hint
65+ * - login_hint: Hint to help with the username/identifier in the login form
66+ * - max_age: Maximum authentication age in seconds
67+ * - ui_locales: End-user's preferred languages and scripts for the user interface
68+ *
69+ * @example
70+ * ```tsx
71+ * signInOptions={{
72+ * prompt: "login",
73+ * fidp: "OrganizationSSO",
74+ * login_hint: "user@example .com"
75+ * }}
76+ * ```
77+ */
78+ signInOptions ?: Record < string , any > ;
4879}
4980
5081/**
@@ -80,9 +111,47 @@ export interface ProtectedRouteProps {
80111 * }
81112 * />
82113 * ```
114+ *
115+ * @example With custom sign-in parameters
116+ * ```tsx
117+ * <Route
118+ * path="/secure"
119+ * element={
120+ * <ProtectedRoute signInOptions={{ prompt: "login", fidp: "OrganizationSSO" }}>
121+ * <SecureContent />
122+ * </ProtectedRoute>
123+ * }
124+ * />
125+ * ```
126+ *
127+ * @example With custom sign-in handler
128+ * ```tsx
129+ * <Route
130+ * path="/custom"
131+ * element={
132+ * <ProtectedRoute
133+ * onSignIn={(defaultSignIn, options) => {
134+ * // Custom logic before sign-in
135+ * console.log('Initiating custom sign-in');
136+ * defaultSignIn({ ...options, prompt: "login" });
137+ * }}
138+ * signInOptions={{ fidp: "CustomIDP" }}
139+ * >
140+ * <CustomContent />
141+ * </ProtectedRoute>
142+ * }
143+ * />
144+ * ```
83145 */
84- const ProtectedRoute : FC < ProtectedRouteProps > = ( { children, fallback, redirectTo, loader = null } ) => {
85- const { isSignedIn, isLoading} = useAsgardeo ( ) ;
146+ const ProtectedRoute : FC < ProtectedRouteProps > = ( {
147+ children,
148+ fallback,
149+ redirectTo,
150+ loader = null ,
151+ onSignIn,
152+ signInOptions : overriddenSignInOptions = { } ,
153+ } ) => {
154+ const { isSignedIn, isLoading, signIn, signInOptions, signInUrl} = useAsgardeo ( ) ;
86155
87156 // Always wait for loading to finish before making authentication decisions
88157 if ( isLoading ) {
@@ -101,11 +170,34 @@ const ProtectedRoute: FC<ProtectedRouteProps> = ({children, fallback, redirectTo
101170 return < Navigate to = { redirectTo } replace /> ;
102171 }
103172
173+ if ( ! isSignedIn ) {
174+ if ( signInUrl ) {
175+ navigate ( signInUrl ) ;
176+ } else {
177+ if ( onSignIn ) {
178+ onSignIn ( signIn , overriddenSignInOptions ) ;
179+ } else {
180+ ( async ( ) => {
181+ try {
182+ await signIn ( overriddenSignInOptions ?? signInOptions ) ;
183+ } catch ( error ) {
184+ throw new AsgardeoRuntimeError (
185+ 'Sign-in failed in ProtectedRoute.' ,
186+ 'ProtectedRoute-SignInError-001' ,
187+ 'react-router' ,
188+ `An error occurred during sign-in: ${ ( error as Error ) . message } ` ,
189+ ) ;
190+ }
191+ } ) ( ) ;
192+ }
193+ }
194+ }
195+
104196 throw new AsgardeoRuntimeError (
105- '"fallback" or "redirectTo" prop is required .' ,
106- 'ProtectedRoute-ValidationError -001' ,
197+ 'ProtectedRoute misconfiguration .' ,
198+ 'ProtectedRoute-Misconfiguration -001' ,
107199 'react-router' ,
108- 'Either "fallback" or "redirectTo" prop must be provided to handle unauthenticated users .' ,
200+ 'The internal handler failed to process the state. Please try with a fallback or redirectTo prop .' ,
109201 ) ;
110202} ;
111203
0 commit comments