feat(react-auth): add onLoginFallback to createAuthProvider config

Allows dashboards to provide fallback login logic (e.g. mock credentials)
when the API is unavailable. Used by admin-dashboard-web.
This commit is contained in:
saravanakumardb1 2026-02-12 22:21:25 -08:00
parent 832eccafed
commit 11e79aa4f9
3 changed files with 26 additions and 7 deletions

View File

@ -21,7 +21,7 @@ import type { AuthConfig, AuthContextValue, BaseUser } from './types.js';
* ```
*/
export function createAuthProvider<TUser extends BaseUser = BaseUser>(config: AuthConfig<TUser>) {
const { storagePrefix, loginEndpoint, mapLoginResponse, onLogout } = config;
const { storagePrefix, loginEndpoint, mapLoginResponse, onLoginFallback, onLogout } = config;
const USER_KEY = `${storagePrefix}_auth_user`;
const TOKEN_KEY = `${storagePrefix}_access_token`;
@ -64,6 +64,18 @@ export function createAuthProvider<TUser extends BaseUser = BaseUser>(config: Au
return true;
}
// Try fallback (e.g. mock credentials) when API is unavailable
if (error && onLoginFallback) {
const fallback = await onLoginFallback(email, password, error);
if (fallback) {
setUser(fallback.user);
localStorage.setItem(USER_KEY, JSON.stringify(fallback.user));
localStorage.setItem(TOKEN_KEY, fallback.accessToken);
localStorage.setItem(REFRESH_KEY, fallback.refreshToken);
return true;
}
}
return false;
},
[api]

View File

@ -1,2 +1,2 @@
export { createAuthProvider } from './auth-context.js';
export type { BaseUser, AuthContextValue, AuthConfig } from './types.js';
export type { BaseUser, AuthContextValue, AuthConfig, LoginResult } from './types.js';

View File

@ -13,13 +13,20 @@ export interface AuthContextValue<TUser extends BaseUser = BaseUser> {
logout: () => void;
}
export interface LoginResult<TUser extends BaseUser = BaseUser> {
user: TUser;
accessToken: string;
refreshToken: string;
}
export interface AuthConfig<TUser extends BaseUser = BaseUser> {
storagePrefix: string;
loginEndpoint: string;
mapLoginResponse: (data: unknown) => {
user: TUser;
accessToken: string;
refreshToken: string;
};
mapLoginResponse: (data: unknown) => LoginResult<TUser>;
onLoginFallback?: (
email: string,
password: string,
error: string
) => Promise<LoginResult<TUser> | null>;
onLogout?: () => void;
}