github.com/filecoin-project/bacalhau@v0.3.23-0.20230228154132-45c989550ace/dashboard/frontend/src/contexts/user.tsx (about)

     1  import React, { FC, createContext, useMemo, useState, useCallback, useEffect } from 'react'
     2  import axios from 'axios'
     3  import useApi from '../hooks/useApi'
     4  
     5  import {
     6    TokenResponse,
     7    User,
     8  } from '../types'
     9  
    10  export interface IUserContext {
    11    user?: User,
    12    login: {
    13      (username: string, password: string): Promise<boolean>,
    14    },
    15    logout:{
    16      (): Promise<void>,
    17    },
    18    initialise: {
    19      (): Promise<void>,
    20    },
    21  }
    22  
    23  export const getHTTPTokenHeaders = (token: string): {
    24    Authorization: string,
    25  } => ({
    26    Authorization: token ? `Bearer ${token}` : '',
    27  })
    28  
    29  export const setHTTPToken = (token: string) => {
    30    axios.defaults.headers.common = getHTTPTokenHeaders(token)
    31  }
    32  
    33  export const unsetHTTPToken = () => {
    34    axios.defaults.headers.common = getHTTPTokenHeaders('')
    35  }
    36  
    37  export const UserContext = createContext<IUserContext>({
    38    user: undefined,
    39    login: async () => {
    40      return true
    41    },
    42    logout: async () => {},
    43    initialise: async () => {},
    44  })
    45  
    46  export const useUserContext = (): IUserContext => {
    47    const api = useApi()
    48    const [ user, setUser ] = useState<User>()
    49  
    50    const logout = useCallback(async () => {
    51      unsetHTTPToken()
    52      localStorage.removeItem('token')
    53      setUser(undefined)
    54    }, [])
    55  
    56    const loadStatus = useCallback(async () => {
    57      const statusResult = await api.get<User>('/api/v1/admin/status')
    58      if(!statusResult) {
    59        await logout()
    60      }
    61      else {
    62        setUser(statusResult)
    63      }
    64    }, [
    65      logout,
    66    ])
    67  
    68    const initialise = useCallback(async () => {
    69      const token = localStorage.getItem('token')
    70      if(!token) return
    71      setHTTPToken(token)
    72      await loadStatus()
    73    }, [
    74      loadStatus,
    75    ])
    76  
    77    const login = useCallback(async (username: string, password: string): Promise<boolean> => {
    78      try {
    79        const tokenResult = await api.post('/api/v1/admin/login', {
    80          username,
    81          password,
    82        }) as TokenResponse
    83        if(!tokenResult) return false
    84        const token = tokenResult.token
    85        localStorage.setItem('token', token)
    86        setHTTPToken(token)
    87        await loadStatus()
    88        return true
    89      } catch(e: any) {
    90        return false
    91      }
    92    }, [
    93      loadStatus,
    94    ])
    95  
    96    const contextValue = useMemo<IUserContext>(() => ({
    97      user,
    98      login,
    99      logout,
   100      initialise,
   101    }), [
   102      user,
   103      login,
   104      logout,
   105      initialise,
   106    ])
   107  
   108    return contextValue
   109  }
   110  
   111  export const UserContextProvider: FC = ({ children }) => {
   112    const value = useUserContext()
   113    return (
   114      <UserContext.Provider value={ value }>
   115        { children }
   116      </UserContext.Provider>
   117    )
   118  }