File size: 5,868 Bytes
22665fb
3f84555
22665fb
 
f91a47c
 
 
22665fb
 
f91a47c
 
22665fb
f91a47c
 
22665fb
 
 
 
f91a47c
22665fb
f91a47c
 
22665fb
f91a47c
 
 
 
 
 
 
22665fb
 
 
 
 
f91a47c
22665fb
f91a47c
22665fb
 
 
f91a47c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22665fb
 
 
 
f91a47c
22665fb
 
 
f91a47c
22665fb
 
 
f91a47c
 
 
22665fb
 
 
 
f91a47c
22665fb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f91a47c
 
 
22665fb
 
 
 
f91a47c
22665fb
 
 
f91a47c
 
22665fb
 
 
f91a47c
 
 
22665fb
 
 
 
 
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>OAuth in a static Space (Vanilla JS)</title>
    <link rel="stylesheet" href="style.css" />
    <style>
      body { font-family: sans-serif; background: #fafafd; color: #222; }
      .card { max-width: 420px; margin: 2rem auto 0 auto; background: #fff; border-radius: 8px; box-shadow: 0 2px 8px #0001; padding: 2rem; }
      #status { margin-top: 1rem; word-break: break-all; color: #b00; }
      button, img { margin-top: 1rem; }
      pre { background: #eee; padding: 1em; border-radius: 4px; margin-top: 1rem; }
      #signout { margin-left: 0; }
    </style>
  </head>
  <body>
    <div class="card">
      <h1>OAuth in a static Space (Vanilla JS)</h1>
      <p>
        This is a demonstration of the Hugging Face OAuth flow in a <b>static Space</b> using only vanilla JS.<br>
        No external libraries are needed – just copy this HTML file in your Space!
      </p>
      <p>
        Click "Sign in with HF" to start the authentication flow.<br>
        After authenticating, your access token and user info will be displayed below.<br>
        <i>(Tokens are only stored locally in your browser and never sent anywhere else.)</i>
      </p>
      <img src="https://huggingface.co/datasets/huggingface/badges/resolve/main/sign-in-with-huggingface-xl-dark.svg"
           alt="Sign in with Hugging Face" id="signin" style="cursor:pointer;display:none;max-width:100%;">
      <button id="signout" style="display:none;">Sign out</button>
      <div id="status"></div>
      <pre id="userinfo" style="display:none"></pre>
    </div>
    <script>
      // Utiliser le client_id injecté par Hugging Face dans l'environnement du Space
      const CLIENT_ID = window.huggingface?.variables?.OAUTH_CLIENT_ID;
      const REDIRECT_URI = window.location.origin + window.location.pathname;
      const HF_OAUTH_URL = 'https://huggingface.co/oauth/authorize';
      const HF_TOKEN_URL = 'https://huggingface.co/oauth/token';

      // Helper pour afficher l'état et les infos utilisateur
      function showLoggedIn(userinfo) {
        document.getElementById('signin').style.display = 'none';
        document.getElementById('signout').style.display = '';
        document.getElementById('status').textContent = 'Logged in!';
        document.getElementById('userinfo').style.display = '';
        document.getElementById('userinfo').textContent = userinfo;
      }
      function showLoggedOut() {
        document.getElementById('signin').style.display = '';
        document.getElementById('signout').style.display = 'none';
        document.getElementById('status').textContent = '';
        document.getElementById('userinfo').style.display = 'none';
        document.getElementById('userinfo').textContent = '';
      }

      // Sign in button
      document.getElementById('signin').onclick = function () {
        const state = Math.random().toString(36).slice(2);
        localStorage.setItem('hf_oauth_state', state);
        const url = `${HF_OAUTH_URL}?client_id=${CLIENT_ID}` +
          `&redirect_uri=${encodeURIComponent(REDIRECT_URI)}` +
          `&response_type=code&scope=openid%20profile&state=${state}&prompt=consent`;
        window.location = url;
      };

      // Sign out button
      document.getElementById('signout').onclick = function () {
        localStorage.removeItem('hf_oauth_token');
        localStorage.removeItem('hf_oauth_userinfo');
        localStorage.removeItem('hf_oauth_state');
        showLoggedOut();
        window.history.replaceState({}, '', window.location.pathname);
      };

      // Handle OAuth callback
      window.onload = async function () {
        // If returning from OAuth redirect
        const params = new URLSearchParams(window.location.search);
        if (params.has('code') && params.has('state')) {
          const state = params.get('state');
          if (state !== localStorage.getItem('hf_oauth_state')) {
            document.getElementById('status').textContent = 'Invalid state, possible CSRF detected.';
            return;
          }
          const code = params.get('code');
          const body = new URLSearchParams({
            client_id: CLIENT_ID,
            grant_type: 'authorization_code',
            code: code,
            redirect_uri: REDIRECT_URI
          });
          document.getElementById('status').textContent = 'Exchanging code for token...';
          const resp = await fetch(HF_TOKEN_URL, {
            method: 'POST',
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            body
          });
          const data = await resp.json();
          if (data.access_token) {
            localStorage.setItem('hf_oauth_token', data.access_token);
            // Fetch userinfo
            const respUser = await fetch('https://huggingface.co/oauth/userinfo', {
              headers: { Authorization: `Bearer ${data.access_token}` }
            });
            const userinfo = await respUser.json();
            const userinfoStr = JSON.stringify(userinfo, null, 2);
            localStorage.setItem('hf_oauth_userinfo', userinfoStr);
            showLoggedIn(userinfoStr);
            // Clean up URL
            window.history.replaceState({}, '', window.location.pathname);
          } else {
            document.getElementById('status').textContent = 'OAuth failed: ' + JSON.stringify(data);
            showLoggedOut();
          }
          return;
        }

        // Already logged in?
        const token = localStorage.getItem('hf_oauth_token');
        const userinfo = localStorage.getItem('hf_oauth_userinfo');
        if (token && userinfo) {
          showLoggedIn(userinfo);
        } else {
          showLoggedOut();
        }
      };
    </script>
  </body>
</html>