forked from 77media/video-flow
90 lines
2.8 KiB
TypeScript
90 lines
2.8 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect } from 'react';
|
|
import { useRouter, useSearchParams } from 'next/navigation';
|
|
import { validateOAuthState } from '@/lib/auth';
|
|
import { toast } from '@/hooks/use-toast';
|
|
|
|
export function OAuthCallbackHandler() {
|
|
const searchParams = useSearchParams();
|
|
const router = useRouter();
|
|
|
|
useEffect(() => {
|
|
// Check if this is an OAuth callback
|
|
const state = searchParams.get('state');
|
|
const session = searchParams.get('session');
|
|
const userJson = searchParams.get('user');
|
|
const error = searchParams.get('error');
|
|
|
|
// Log debug information
|
|
console.log('OAuth callback handler running with params:', {
|
|
state: state || 'not present',
|
|
session: session ? 'present' : 'not present',
|
|
userJson: userJson ? 'present' : 'not present',
|
|
error: error || 'none'
|
|
});
|
|
|
|
// Handle error case
|
|
if (error) {
|
|
console.error('OAuth error:', error);
|
|
toast({
|
|
title: 'Authentication Error',
|
|
description: `Google sign-in failed: ${error}`,
|
|
variant: 'destructive',
|
|
});
|
|
router.push(`/login?error=${error}`);
|
|
return;
|
|
}
|
|
|
|
// If we have state and session, this might be an OAuth callback
|
|
if (state && session) {
|
|
// Validate the state parameter to prevent CSRF
|
|
const isValid = validateOAuthState(state);
|
|
|
|
if (!isValid) {
|
|
// State validation failed, possible CSRF attack
|
|
console.error('OAuth state validation failed');
|
|
toast({
|
|
title: 'Authentication Error',
|
|
description: 'Security validation failed. Please try signing in again.',
|
|
variant: 'destructive',
|
|
});
|
|
router.push('/login?error=invalid_state');
|
|
return;
|
|
}
|
|
|
|
console.log('OAuth state validation successful');
|
|
|
|
// State is valid, process the login
|
|
if (userJson) {
|
|
try {
|
|
const user = JSON.parse(decodeURIComponent(userJson));
|
|
console.log('OAuth user data parsed successfully');
|
|
|
|
// Store the user in session
|
|
sessionStorage.setItem('currentUser', JSON.stringify(user));
|
|
|
|
// Show success message
|
|
toast({
|
|
title: 'Signed in successfully',
|
|
description: `Welcome ${user.name}!`,
|
|
});
|
|
|
|
// Remove the query parameters from the URL
|
|
router.replace('/');
|
|
} catch (error) {
|
|
console.error('Failed to parse user data', error);
|
|
toast({
|
|
title: 'Authentication Error',
|
|
description: 'Failed to process authentication data',
|
|
variant: 'destructive',
|
|
});
|
|
router.push('/login?error=invalid_user_data');
|
|
}
|
|
}
|
|
}
|
|
}, [searchParams, router]);
|
|
|
|
// This is a utility component that doesn't render anything
|
|
return null;
|
|
}
|