File size: 3,933 Bytes
0ed5b20
 
a296341
0ed5b20
a296341
 
0ed5b20
 
a296341
b022cb9
 
3b81d2d
0ed5b20
 
 
 
 
 
 
 
 
 
 
 
 
 
a296341
 
0ed5b20
 
a296341
0ed5b20
a296341
0ed5b20
a296341
3b81d2d
 
 
 
a296341
 
0ed5b20
 
a296341
 
0ed5b20
 
 
b022cb9
 
a296341
0ed5b20
 
b022cb9
 
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
141
142
143
144
145
146
147
148
149
"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"
import { useLocalStorage } from "usehooks-ts"
import { useShouldDisplayLoginWall } from "./useShouldDisplayLoginWall"
import { getOAuthRedirectUrl } from "./getOAuthRedirectUrl"

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 redirectUrl = getOAuthRedirectUrl()

  const scopes = config.oauthScopes
  const enableOAuth = config.enableHuggingFaceOAuth

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

  const hasReceivedFreshOAuth = Boolean(code && state)

  // note: being able to log into hugging face using the popup
  // is different from seeing the "login wall"
  const canLogin: boolean = Boolean(isConfigReady && clientId && enableOAuth)
  const isLoggedIn = Boolean(oauthResult)

  const enableOAuthWall = useShouldDisplayLoginWall() 

  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
  }
}