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>