From 6d811747ee8760ecbafd8bb350d794bc0c2f0aac Mon Sep 17 00:00:00 2001 From: Felipe Cardoso Date: Fri, 31 Oct 2025 22:10:48 +0100 Subject: [PATCH] Enhance input validation and error handling in `authStore` - Added robust validation for `user` object fields to ensure non-empty strings. - Improved `calculateExpiry` with value range checks and warnings for invalid `expiresIn`. - Incorporated try-catch in `initializeAuth` to log errors and prevent app crashes during auth initialization. --- frontend/src/stores/authStore.ts | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/frontend/src/stores/authStore.ts b/frontend/src/stores/authStore.ts index 05aa754..e8031b2 100644 --- a/frontend/src/stores/authStore.ts +++ b/frontend/src/stores/authStore.ts @@ -50,8 +50,15 @@ function isValidToken(token: string): boolean { * @returns Unix timestamp */ function calculateExpiry(expiresIn?: number): number { - // Default to 15 minutes if not provided - const seconds = expiresIn || 900; + // Default to 15 minutes if not provided or invalid + let seconds = expiresIn || 900; + + // Validate positive number and prevent overflow + if (seconds <= 0 || seconds > 31536000) { // Max 1 year + console.warn(`Invalid expiresIn value: ${expiresIn}, using default 900s`); + seconds = 900; + } + return Date.now() + seconds * 1000; } @@ -67,8 +74,10 @@ export const useAuthStore = create((set, get) => ({ // Set complete auth state (user + tokens) setAuth: async (user, accessToken, refreshToken, expiresIn) => { // Validate inputs - if (!user || !user.id || !user.email) { - throw new Error('Invalid user object'); + if (!user || !user.id || !user.email || + typeof user.id !== 'string' || typeof user.email !== 'string' || + user.id.trim() === '' || user.email.trim() === '') { + throw new Error('Invalid user object: id and email must be non-empty strings'); } if (!isValidToken(accessToken) || !isValidToken(refreshToken)) { @@ -116,8 +125,10 @@ export const useAuthStore = create((set, get) => ({ // Update user only setUser: (user) => { - if (!user || !user.id || !user.email) { - throw new Error('Invalid user object'); + if (!user || !user.id || !user.email || + typeof user.id !== 'string' || typeof user.email !== 'string' || + user.id.trim() === '' || user.email.trim() === '') { + throw new Error('Invalid user object: id and email must be non-empty strings'); } set({ user }); @@ -178,7 +189,13 @@ export const useAuthStore = create((set, get) => ({ /** * Initialize auth store from storage * Call this on app startup + * Errors are logged but don't throw to prevent app crashes */ export async function initializeAuth(): Promise { - await useAuthStore.getState().loadAuthFromStorage(); + try { + await useAuthStore.getState().loadAuthFromStorage(); + } catch (error) { + // Log error but don't throw - app should continue even if auth init fails + console.error('Failed to initialize auth:', error); + } }