From 81b46581ab79f8f5e9e132e00e5d1b8e9182dd46 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sun, 15 Nov 2020 04:07:33 +0300 Subject: feat: implement authentication --- src/hooks/useAuth.tsx | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/hooks/useAuth.tsx (limited to 'src/hooks/useAuth.tsx') diff --git a/src/hooks/useAuth.tsx b/src/hooks/useAuth.tsx new file mode 100644 index 0000000..39351ae --- /dev/null +++ b/src/hooks/useAuth.tsx @@ -0,0 +1,70 @@ +import React, { + useEffect, useCallback, useMemo, useContext, createContext +} from 'react'; +import { User } from '../types'; +import { post } from '../requests'; +import { useUser } from './APIClient'; +import useLocalStorage from './useLocalStorage'; + + +interface ContextType { + user: User | undefined, + login: (username: string, password: string, remember?: boolean) => Promise; + logout: () => void; + isAuthenticated: boolean; +} + +const authContext = createContext({ + user: undefined, + login: async () => false, + logout: () => {}, + isAuthenticated: false +}); + +const useProvideAuth = () => { + const [remember, setRemember] = useLocalStorage('remember'); + const [username, setUsername] = useLocalStorage('username'); + const [token, setToken] = useLocalStorage('token'); + const { data: user } = useUser(username); + + const isAuthenticated = useMemo(() => Boolean(username), [username]); + + const logout = useCallback(() => { + setToken(null); + setUsername(null); + }, [setToken, setUsername]); + + useEffect(() => { + // If should not remember, logout + if (!remember) logout(); + }, [remember, logout]); + + + const login: ContextType['login'] = (name, password, shouldRemember = true) => { + return post('/authentication', { + strategy: 'local', + username: name, + password + }).then(response => { + setToken(response.data.accessToken); + setUsername(name); + setRemember(shouldRemember ? 'true' : null); + return true; + }).catch(() => false); + }; + + return { + user, login, logout, token, isAuthenticated + }; +}; + +export const AuthProvider: React.FC = ({ children }) => { + const auth = useProvideAuth(); + const { Provider } = authContext; + return {children}; +}; + +export const useAuth = (): ContextType => { + return useContext(authContext); +}; + -- cgit v1.2.3