auth-context-provider/src/index.tsx

133 lines
2.6 KiB
TypeScript
Raw Normal View History

2020-07-15 10:40:48 +07:00
import React from 'react'
import BaseContextProvider, {
baseUseContext,
2020-07-15 13:37:51 +07:00
baseWithContext,
baseContextWrap
2020-07-15 10:40:48 +07:00
} from 'base-context-provider'
2020-07-16 10:39:05 +07:00
import { LocalStorageToken, TokenInstance } from './TokenInstance'
import ResponseError from './ResponseError'
2020-07-15 08:29:58 +07:00
2020-07-15 10:40:48 +07:00
export interface AuthContextProps {
authUrl: string
storageType?: 'localStorage' | 'cookies'
2020-07-15 08:29:58 +07:00
}
2020-07-15 10:40:48 +07:00
export interface AuthState<T> {
isLogin: boolean
isFetchingUser: boolean
user: T
2020-07-16 10:39:05 +07:00
tokenInstance?: TokenInstance
2020-07-15 08:29:58 +07:00
}
2020-07-15 10:40:48 +07:00
2020-07-16 10:39:05 +07:00
2020-07-15 10:40:48 +07:00
const Context = React.createContext({})
class AuthContextProvider extends BaseContextProvider<
AuthContextProps,
AuthState<any>
> {
2020-07-16 10:39:05 +07:00
state: AuthState<any> = {
2020-07-15 10:40:48 +07:00
isLogin: false,
isFetchingUser: false,
user: {
username: ''
}
}
2020-07-16 10:39:05 +07:00
constructor(props: AuthContextProps) {
super(props)
this.state.tokenInstance = new LocalStorageToken()
}
2020-07-15 10:40:48 +07:00
getContext() {
return Context
}
2020-07-16 10:39:05 +07:00
fetchUser: (username: string, password: string) => void = async (
username,
password
) => {
2020-07-15 10:40:48 +07:00
this.setState({
isFetchingUser: true
})
const { authUrl } = this.props
const response = await fetch(authUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ username, password })
})
const data = await response.json()
2020-07-16 10:39:05 +07:00
if (response.status >= 400) {
return Promise.reject(new ResponseError("Error while fetching data", data ))
}
// eslint-disable-next-line no-unused-expressions
this.state.tokenInstance?.setToken(data.token)
this.setState((oldState) => {
return {
...oldState,
user: {
...oldState.user,
username
},
isLogin: true,
isFetchingUser: false
}
})
return Promise.resolve("")
2020-07-15 10:40:48 +07:00
}
2020-07-16 10:39:05 +07:00
login = async ({
username,
password
}: {
username: string
password: string
}) => {
return this.fetchUser(username, password)
2020-07-15 10:40:48 +07:00
}
logout = async () => {
this.setState({
isLogin: false,
user: {
username: ''
}
})
2020-07-16 10:39:05 +07:00
this.state.tokenInstance?.setToken("")
2020-07-15 10:40:48 +07:00
return Promise.resolve(true)
}
2020-07-16 10:39:05 +07:00
getToken = ()=>{
return this.state.tokenInstance?.getToken()
}
2020-07-15 10:40:48 +07:00
getContextReturnValue() {
return {
...this.state,
login: this.login,
2020-07-16 10:39:05 +07:00
logout: this.logout,
getToken: this.getToken
2020-07-15 10:40:48 +07:00
}
}
}
// @ts-ignore
AuthContextProvider.defaultProps = {
storageType: 'localStorage'
}
2020-07-15 13:37:51 +07:00
export const wrapAuthContext = baseContextWrap(AuthContextProvider)
2020-07-15 10:40:48 +07:00
export const useAuthContext = baseUseContext(Context)
export const withAuthContext = baseWithContext(Context, 'auth')
export default AuthContextProvider