Merge branch 'dev' into till-dev

This commit is contained in:
Wuesteon 2025-12-15 14:10:34 +01:00
commit 660cbd654f
21 changed files with 552 additions and 1679 deletions

View file

@ -81,13 +81,21 @@ export type { ContactsClientConfig, ContactSearchOptions } from './clients/conta
* ```typescript
* import { initializeWebAuth } from '@manacore/shared-auth';
*
* // Basic setup (interceptor only for auth URL)
* const { authService, tokenManager } = initializeWebAuth({
* baseUrl: 'https://api.example.com',
* baseUrl: 'https://auth.example.com',
* });
*
* // With backend URL (interceptor for both auth and backend - recommended)
* const { authService, tokenManager } = initializeWebAuth({
* baseUrl: 'https://auth.example.com',
* backendUrl: 'https://api.example.com',
* });
* ```
*/
export function initializeWebAuth(config: {
baseUrl: string;
backendUrl?: string;
storageKeys?: Partial<import('./types').StorageKeys>;
}) {
// Set up adapters
@ -99,8 +107,15 @@ export function initializeWebAuth(config: {
const authService = _createAuthService(config);
const tokenManager = _createTokenManager(authService);
// Set up interceptor
// Set up interceptor for auth URL
_setupFetchInterceptor(authService, tokenManager);
// Set up interceptor for backend URL if provided (for automatic token refresh on 401)
if (config.backendUrl) {
_setupFetchInterceptor(authService, tokenManager, {
backendUrl: config.backendUrl,
});
}
return { authService, tokenManager };
}

View file

@ -201,8 +201,9 @@ async function makeRequestWithToken(
}
/**
* Check if response indicates token expiration
* Only return true for explicit token expiration, not generic unauthorized errors
* Check if response indicates a token issue that warrants a refresh attempt
* Any 401 response should trigger a refresh attempt - if the refresh fails,
* then we know the session is truly invalid
*/
function isTokenExpiredResponse(responseData: Record<string, unknown>): boolean {
const error = responseData.error as Record<string, unknown> | undefined;
@ -211,13 +212,21 @@ function isTokenExpiredResponse(responseData: Record<string, unknown>): boolean
).toLowerCase();
const errorCode = String(responseData.code || error?.code || '');
// Only trigger refresh for explicit token expiration messages
// Trigger refresh for any token-related auth error
// This includes:
// - Explicit expiration: "jwt expired", "token expired"
// - Generic validation failures: "invalid token", "token validation failed"
// - Backend passthrough errors: "exp claim", "claim timestamp"
return (
errorMessage.includes('jwt expired') ||
errorMessage.includes('token expired') ||
errorMessage.includes('token has expired') ||
errorMessage.includes('invalid token') ||
errorMessage.includes('token validation failed') ||
errorMessage.includes('claim') || // Catches jose errors like "exp claim timestamp check failed"
errorCode === 'PGRST301' ||
errorCode === 'TOKEN_EXPIRED'
errorCode === 'TOKEN_EXPIRED' ||
errorCode === 'ERR_JWT_EXPIRED'
);
}