-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.tsx
126 lines (102 loc) · 3.07 KB
/
index.tsx
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
/** @author [email protected] */
import axios from "axios";
import React, { createContext, useContext, useEffect, useState } from "react";
import nookies from "nookies";
import { useRouter } from "next/router";
type ISession = {
status: "loading" | "authenticated" | "unauthenticated";
data: any;
};
type IAuth = {
signIn: (url: string, data: object) => Promise<any>;
signOut: (options: { redirectUrl: string }) => void;
session: ISession;
};
function getAccessToken(req = null) {
let token = null;
if (req && req.cookies) {
token = req.cookies["auth_session"];
} else {
token = nookies.get()["auth_session"];
}
if (token) {
return token;
} else {
return false;
}
}
function api(req = null) {
const accessToken = getAccessToken(req);
const api = axios.create({});
if (accessToken) {
api.defaults.headers.common["Authorization"] = `Bearer ${accessToken}`;
}
api.interceptors.response.use(
(response) => response,
(error) => {
// the status 401 is "Unauthorized"
if (error.response?.status === 401) {
// remove the cookie
nookies.destroy(null, "auth_session", { path: "/" });
// redirect to main page
window.location.href = "/";
}
return Promise.reject(error);
}
);
return api;
}
const GhostlexlyAuthContext = createContext(null);
function GhostlexlyAuthProvider({ children, userDataUrl = "/api/me", cookieExpireInDays = 31 }) {
const router = useRouter();
const [userData, setUserData] = useState<ISession>({ status: "loading", data: null });
const accessToken = getAccessToken();
const signOut = ({ redirectUrl }) => {
const cookies = nookies.get();
if (cookies["auth_session"]) {
nookies.destroy(null, "auth_session", { path: "/" });
}
try {
router.push(redirectUrl);
} catch (err) {}
};
const signIn = async (url: string, data: object) => {
return axios.post(url, data).then((res) => {
if (res.status === 200 && res.data.access_token) {
nookies.set(null, "auth_session", res.data.access_token, {
maxAge: cookieExpireInDays * 24 * 60 * 60, // 31 days by default
path: "/",
});
// -- set user data in the context
setUserData({ status: "authenticated", data: res.data });
// -- return user data
return res.data;
} else {
return false;
}
});
};
useEffect(() => {
if (accessToken) {
api()
.get(userDataUrl)
.then((res) => {
setUserData({ status: "authenticated", data: res.data });
})
.catch((err) => {
setUserData({ status: "unauthenticated", data: null });
});
} else {
setUserData({ status: "unauthenticated", data: null });
}
}, [accessToken, userDataUrl]);
return (
<GhostlexlyAuthContext.Provider value={{ session: userData, signOut, signIn }}>
{children}
</GhostlexlyAuthContext.Provider>
);
}
function useAuth(): IAuth {
return useContext(GhostlexlyAuthContext);
}
export { useAuth, GhostlexlyAuthProvider, api, getAccessToken };