Initial Commit

This commit is contained in:
Eric Gullickson
2025-09-17 16:09:15 -05:00
parent 0cdb9803de
commit a052040e3a
373 changed files with 437090 additions and 6773 deletions

View File

@@ -28,35 +28,102 @@ export const Auth0Provider: React.FC<Auth0ProviderProps> = ({ children }) => {
domain={domain}
clientId={clientId}
authorizationParams={{
redirect_uri: window.location.origin,
redirect_uri: window.location.hostname === "admin.motovaultpro.com" ? "https://admin.motovaultpro.com/callback" : window.location.origin + "/callback",
audience: audience,
}}
onRedirectCallback={onRedirectCallback}
cacheLocation="localstorage"
useRefreshTokens={true}
>
<TokenInjector>{children}</TokenInjector>
</BaseAuth0Provider>
);
};
// Component to inject token into API client
// Component to inject token into API client with mobile support
const TokenInjector: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const { getAccessTokenSilently, isAuthenticated } = useAuth0();
const [retryCount, setRetryCount] = React.useState(0);
// Helper function to get token with retry logic for mobile devices
const getTokenWithRetry = async (maxRetries = 3, delayMs = 500): Promise<string | null> => {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
// Progressive fallback strategy for mobile compatibility
let tokenOptions;
if (attempt === 0) {
// First attempt: try cache first
tokenOptions = { timeoutInSeconds: 15, cacheMode: 'on' as const };
} else if (attempt === 1) {
// Second attempt: force refresh
tokenOptions = { timeoutInSeconds: 20, cacheMode: 'off' as const };
} else {
// Final attempt: default behavior with longer timeout
tokenOptions = { timeoutInSeconds: 30 };
}
const token = await getAccessTokenSilently(tokenOptions);
console.log(`Token acquired successfully on attempt ${attempt + 1}`);
return token;
} catch (error: any) {
console.warn(`Token acquisition attempt ${attempt + 1} failed:`, error.message || error);
// On mobile, Auth0 might need more time - wait and retry
if (attempt < maxRetries - 1) {
const delay = delayMs * Math.pow(2, attempt); // Exponential backoff
console.log(`Waiting ${delay}ms before retry...`);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
console.error('All token acquisition attempts failed');
return null;
};
React.useEffect(() => {
let interceptorId: number | undefined;
if (isAuthenticated) {
// Add token to all API requests
// Pre-warm token cache for mobile devices with delay
const initializeToken = async () => {
// Give Auth0 a moment to fully initialize on mobile
await new Promise(resolve => setTimeout(resolve, 100));
try {
const token = await getTokenWithRetry();
if (token) {
console.log('Token pre-warming successful');
setRetryCount(0);
} else {
console.error('Failed to acquire token after retries - will retry on API calls');
setRetryCount(prev => prev + 1);
}
} catch (error) {
console.error('Token initialization failed:', error);
setRetryCount(prev => prev + 1);
}
};
initializeToken();
// Add token to all API requests with enhanced error handling
interceptorId = apiClient.interceptors.request.use(async (config) => {
try {
const token = await getAccessTokenSilently();
config.headers.Authorization = `Bearer ${token}`;
} catch (error) {
console.error('Failed to get access token:', error);
const token = await getTokenWithRetry();
if (token) {
config.headers.Authorization = `Bearer ${token}`;
} else {
console.error('No token available for request to:', config.url);
// Allow request to proceed - backend will return 401 if needed
}
} catch (error: any) {
console.error('Failed to get access token for request:', error.message || error);
// Allow request to proceed - backend will return 401 if needed
}
return config;
});
} else {
setRetryCount(0);
}
// Cleanup function to remove interceptor
@@ -65,7 +132,7 @@ const TokenInjector: React.FC<{ children: React.ReactNode }> = ({ children }) =>
apiClient.interceptors.request.eject(interceptorId);
}
};
}, [isAuthenticated, getAccessTokenSilently]);
}, [isAuthenticated, getAccessTokenSilently, retryCount]);
return <>{children}</>;
};