diff --git a/lib/auth.ts b/lib/auth.ts index 2e5ab46..007c7f0 100644 --- a/lib/auth.ts +++ b/lib/auth.ts @@ -8,15 +8,18 @@ const GOOGLE_REDIRECT_URI = typeof window !== 'undefined' * Initiates Google OAuth authentication flow */ export const signInWithGoogle = () => { + const state = generateOAuthState(); + const params = new URLSearchParams({ client_id: GOOGLE_CLIENT_ID, redirect_uri: GOOGLE_REDIRECT_URI, response_type: 'code', scope: 'email profile', prompt: 'select_account', + state: state, }); - // In a real implementation, you would have proper error handling and secure state management + // Redirect to Google's OAuth endpoint window.location.href = `https://accounts.google.com/o/oauth2/v2/auth?${params.toString()}`; }; @@ -67,4 +70,34 @@ export const logoutUser = () => { if (typeof window === 'undefined') return; sessionStorage.removeItem('currentUser'); window.location.href = '/login'; -}; \ No newline at end of file +}; + +/** + * Generates and stores a state parameter for OAuth to prevent CSRF attacks + */ +export const generateOAuthState = () => { + if (typeof window === 'undefined') return ''; + + // Generate a random string for state + const state = Math.random().toString(36).substring(2, 15); + + // Store the state in session storage to validate later + sessionStorage.setItem('oauthState', state); + + return state; +}; + +/** + * Validates the state parameter returned from OAuth to prevent CSRF attacks + */ +export const validateOAuthState = (state: string): boolean => { + if (typeof window === 'undefined') return false; + + const storedState = sessionStorage.getItem('oauthState'); + + // Clean up the stored state regardless of validity + sessionStorage.removeItem('oauthState'); + + // Validate that the returned state matches what we stored + return state === storedState; +}; \ No newline at end of file