First stage of the new flow
This commit is contained in:
110
src/routes/auth/google/callback/+server.ts
Normal file
110
src/routes/auth/google/callback/+server.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import { redirect } from '@sveltejs/kit';
|
||||
import type { RequestHandler } from './$types';
|
||||
import { getOAuthClient } from '$lib/google-server.js';
|
||||
|
||||
export const GET: RequestHandler = async ({ url }) => {
|
||||
try {
|
||||
const code = url.searchParams.get('code');
|
||||
const error = url.searchParams.get('error');
|
||||
|
||||
if (error) {
|
||||
console.error('Google OAuth error:', error);
|
||||
throw redirect(302, '/private/events?error=google_auth_denied');
|
||||
}
|
||||
|
||||
if (!code) {
|
||||
throw redirect(302, '/private/events?error=missing_auth_code');
|
||||
}
|
||||
|
||||
// Exchange code for tokens
|
||||
const oauth = getOAuthClient();
|
||||
const { tokens } = await oauth.getToken(code);
|
||||
|
||||
if (!tokens.refresh_token || !tokens.access_token) {
|
||||
throw redirect(302, '/private/events?error=incomplete_tokens');
|
||||
}
|
||||
|
||||
// Create a success page with tokens that closes the popup and communicates with parent
|
||||
const html = `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Google Authentication Success</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
background: #f9fafb;
|
||||
}
|
||||
.container {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.success {
|
||||
color: #059669;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.loading {
|
||||
color: #6b7280;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="success">✓ Authentication successful!</div>
|
||||
<div class="loading">Closing window...</div>
|
||||
</div>
|
||||
<script>
|
||||
(function() {
|
||||
try {
|
||||
// Store tokens in the parent window's localStorage
|
||||
if (window.opener && !window.opener.closed) {
|
||||
window.opener.localStorage.setItem('google_access_token', '${tokens.access_token}');
|
||||
window.opener.localStorage.setItem('google_refresh_token', '${tokens.refresh_token}');
|
||||
|
||||
// Send success message to parent
|
||||
window.opener.postMessage({
|
||||
type: 'GOOGLE_AUTH_SUCCESS',
|
||||
tokens: {
|
||||
accessToken: '${tokens.access_token}',
|
||||
refreshToken: '${tokens.refresh_token}'
|
||||
}
|
||||
}, '*');
|
||||
|
||||
// Close the popup after a short delay to ensure message is received
|
||||
setTimeout(() => {
|
||||
window.close();
|
||||
}, 500);
|
||||
} else {
|
||||
// If no opener, close immediately
|
||||
window.close();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error in auth callback:', error);
|
||||
// Try to close the window anyway
|
||||
setTimeout(() => {
|
||||
window.close();
|
||||
}, 1000);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>`;
|
||||
|
||||
return new Response(html, {
|
||||
headers: {
|
||||
'Content-Type': 'text/html'
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error handling Google OAuth callback:', error);
|
||||
throw redirect(302, '/private/events?error=google_auth_failed');
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user