-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathauth-context.tsx
More file actions
67 lines (54 loc) · 1.85 KB
/
auth-context.tsx
File metadata and controls
67 lines (54 loc) · 1.85 KB
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
'use client';
import React from 'react';
import axios from 'axios';
import { ClientAuthData, BaseAuthData, AuthResData } from '@/types';
export type AuthContextValue = {
signin: (data: AuthResData) => void;
authData: ClientAuthData;
signout: () => void;
};
export type AuthProviderProps = Readonly<{
children?: React.ReactNode;
initAuthData: BaseAuthData;
}>;
const AuthContext = React.createContext<AuthContextValue | null>(null);
const injectAuthAxios = (baseAuthData: BaseAuthData) => {
const authAxios = axios.create({
headers: { Authorization: baseAuthData.token },
baseURL: baseAuthData.backendUrl,
withCredentials: true,
});
return { ...baseAuthData, authAxios };
};
export function AuthProvider({ initAuthData, children }: AuthProviderProps) {
const [authData, setAuthData] = React.useState<ClientAuthData>(
injectAuthAxios(initAuthData)
);
const signin = (authResData: AuthResData) => {
setAuthData(injectAuthAxios({ ...authData, ...authResData }));
};
const signout = React.useCallback(() => {
setAuthData(injectAuthAxios({ ...authData, user: null, token: '' }));
}, [authData]);
React.useEffect(() => {
const { authAxios } = authData;
authAxios.defaults.validateStatus = (status) => {
// If server respond with an unauthorized status
if (status === 401) {
authAxios.defaults.headers.Authorization = ''; // Delete auth header
signout(); // Signout unauthorized user
}
return status >= 200 && status < 300; // Default status validation
};
}, [authData, signout]);
return (
<AuthContext value={{ authData, signin, signout }}>{children}</AuthContext>
);
}
export function useAuthData() {
const authData = React.useContext(AuthContext);
if (!authData) {
throw new Error('`useAuthData` must be called within `AuthProvider`');
}
return authData;
}