File size: 3,600 Bytes
0ed5b20
 
a296341
0ed5b20
a296341
 
0ed5b20
 
a296341
0ed5b20
 
 
 
 
 
 
 
 
 
 
 
 
 
a296341
 
0ed5b20
 
a296341
0ed5b20
a296341
0ed5b20
a296341
 
 
 
 
0ed5b20
 
a296341
 
0ed5b20
 
 
a296341
0ed5b20
 
 
 
 
 
 
 
a296341
 
0ed5b20
 
 
 
 
 
a2c0551
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0ed5b20
 
 
 
 
b48537f
0ed5b20
 
 
 
 
 
 
 
 
 
 
 
 
 
b48537f
 
 
0ed5b20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a296341
 
0ed5b20
 
 
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
132
133
134
135
136
137
138
139
140
"use client"

import { useEffect } from "react"
import { useSearchParams } from "next/navigation"
import { OAuthResult, oauthHandleRedirectIfPresent, oauthLoginUrl } from "@huggingface/hub"

import { usePersistedOAuth } from "./usePersistedOAuth"
import { getValidOAuth } from "./getValidOAuth"
import { useDynamicConfig } from "./useDynamicConfig"

export function useOAuth({
  debug = false
}: {
  debug?: boolean
} = {
  debug: false
}): {
  clientId: string
  redirectUrl: string
  scopes: string
  canLogin: boolean
  login: () => Promise<void>
  isLoggedIn: boolean
  enableOAuth: boolean
  enableOAuthWall: boolean
  oauthResult?: OAuthResult
 } {
  const { config, isConfigReady } = useDynamicConfig()

  const [oauthResult, setOAuthResult] = usePersistedOAuth()

  const clientId = config.oauthClientId
  const redirectUrl = config.oauthRedirectUrl
  const scopes = config.oauthScopes
  const enableOAuth = config.enableHuggingFaceOAuth
  const enableOAuthWall = config.enableHuggingFaceOAuthWall

  const searchParams = useSearchParams()
  const code = searchParams?.get("code") || ""
  const state = searchParams?.get("state") || ""

  const hasReceivedFreshOAuth = Boolean(code && state)

  const canLogin: boolean = Boolean(isConfigReady && clientId && enableOAuth)
  const isLoggedIn = Boolean(oauthResult)

  if (debug) {
    console.log("useOAuth debug:", {
      oauthResult,
      clientId,
      redirectUrl,
      scopes,
      enableOAuth,
      enableOAuthWall,
      code,
      state,
      hasReceivedFreshOAuth,
      canLogin,
      isLoggedIn,
    })

    /*
    useOAuth debug: {
      oauthResult: '',
      clientId: '........',
      redirectUrl: 'http://localhost:3000',
      scopes: 'openid profile inference-api',
      isOAuthEnabled: true,
      code: '...........',
      state: '{"nonce":".........","redirectUri":"http://localhost:3000"}',
      hasReceivedFreshOAuth: true,
      canLogin: false,
      isLoggedIn: false
    }
    */
  }

  useEffect(() => {
    // no need to perfor the rest if the operation is there is nothing in the url
    if (hasReceivedFreshOAuth) {

      (async () => {
        const maybeValidOAuth = await oauthHandleRedirectIfPresent()

        const newOAuth = getValidOAuth(maybeValidOAuth)

        if (!newOAuth) {
          if (debug) {
            console.log("useOAuth::useEffect 1: got something in the url but no valid oauth data to show.. something went terribly wrong")
          }
        } else {
          if (debug) {
            console.log("useOAuth::useEffect 1: correctly received the new oauth result, saving it to local storage:", newOAuth)
          }
          setOAuthResult(newOAuth)

          // once set we can (brutally) reload the page
          window.location.href = `//${window.location.host}${window.location.pathname}`
        }
      })()
    }
  }, [debug, hasReceivedFreshOAuth])

  // for debugging purpose
  useEffect(() => {
    if (!debug) {
      return
    }
    console.log(`useOAuth::useEffect 2: canLogin? ${canLogin}`)
    if (!canLogin) {
      return
    }
    console.log(`useOAuth::useEffect2: isLoggedIn? ${isLoggedIn}`)
    if (!isLoggedIn) {
      return
    }
    console.log(`useOAuth::useEffect 2: oauthResult:`, oauthResult)
  }, [debug, canLogin, isLoggedIn, oauthResult])

  const login = async () => {
    window.location.href = await oauthLoginUrl({
      clientId,
      redirectUrl,
      scopes,
    })
  }

  return {
    clientId,
    redirectUrl,
    scopes,
    canLogin,
    login,
    isLoggedIn,
    enableOAuth,
    enableOAuthWall,
    oauthResult
  }
}