File size: 3,155 Bytes
d3f86d8 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
<script>
import { onMount } from 'svelte';
import { goto } from '$app/navigation';
import { page } from '$app/stores';
let status = 'Processing...';
let error = null;
onMount(async () => {
try {
const code = $page.url.searchParams.get('code');
const state = $page.url.searchParams.get('state');
const errorParam = $page.url.searchParams.get('error');
const errorDescription = $page.url.searchParams.get('error_description');
if (errorParam) {
error = errorDescription || errorParam;
status = 'Authentication failed';
return;
}
if (!code) {
error = 'No authorization code received';
status = 'Authentication failed';
return;
}
// Verify state parameter (optional but recommended)
const storedState = sessionStorage.getItem('oauth_state');
if (storedState && state !== storedState) {
error = 'Invalid state parameter';
status = 'Authentication failed';
return;
}
// Exchange code for access token
const tokenResponse = await fetch('/api/auth/token', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ code }),
});
if (!tokenResponse.ok) {
const errorText = await tokenResponse.text();
console.error('Token exchange failed:', errorText);
throw new Error(`Failed to exchange code for token: ${errorText}`);
}
const tokenData = await tokenResponse.json();
// Store access token (in a real app, you'd want secure storage)
localStorage.setItem('hf_access_token', tokenData.access_token);
status = 'Successfully authenticated!';
// Redirect back to main app after a short delay
setTimeout(() => {
goto('/');
}, 2000);
} catch (err) {
error = err.message;
status = 'Authentication failed';
}
});
</script>
<svelte:head>
<title>Authenticating with Hugging Face - HFStudio</title>
</svelte:head>
<div class="min-h-screen flex items-center justify-center bg-gray-50">
<div class="max-w-md w-full bg-white rounded-lg shadow-md p-6">
<div class="text-center">
<img src="/assets/hf-logo.png" alt="HF Logo" class="w-12 h-12 mx-auto mb-4" />
<h1 class="text-xl font-semibold mb-2">HFStudio Authentication</h1>
{#if error}
<div class="text-red-600 mb-4">
<p class="font-medium">{status}</p>
<p class="text-sm mt-1">{error}</p>
</div>
<button
on:click={() => goto('/')}
class="px-4 py-2 bg-gradient-to-r from-amber-400 to-orange-500 text-white rounded-lg hover:from-amber-500 hover:to-orange-600 transition-colors"
>
Return to HFStudio
</button>
{:else}
<div class="text-gray-600 mb-4">
<div class="animate-spin w-8 h-8 border-2 border-amber-400 border-t-transparent rounded-full mx-auto mb-2"></div>
<p>{status}</p>
</div>
{/if}
</div>
</div>
</div> |