react-session.manager.sk 1.1.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/index.js CHANGED
@@ -1,292 +1,295 @@
1
- import React, { createContext, useState, useEffect, useCallback } from "react";
2
- import versionCompare from "./components/versionCompare";
3
- import getDeviceFingerprint from "./components/FingerPrint";
4
- // Notifications
5
- import { ToastContainer, toast } from "react-toastify";
6
- import "react-toastify/dist/ReactToastify.css";
7
- import "./styling/toast.css";
8
-
9
- // Icons
10
- import { GppBad, Update, BrowserUpdated, Logout } from "@mui/icons-material";
11
-
12
- export const SessionManager = createContext({
13
- isLoggedIn: null,
14
- header: null,
15
- isAdmin: null,
16
- userInfo: null,
17
- refreshData: null,
18
- setHeader: null,
19
- setLoggedin: null,
20
- setRefreshData: null,
21
- hasRole: null,
22
- deviceUID: null,
23
- loadingUser: null,
24
- });
25
-
26
- const SessionManagerProvider = ({
27
- AuthenticatedAxiosObject,
28
- refreshTimer,
29
- dataRefresh,
30
- userLoader,
31
- refreshToken,
32
- appVersion,
33
- toastOptions,
34
- children,
35
- }) => {
36
- // Set deivce UID
37
- const [deviceUID, setDeviceUID] = useState(
38
- localStorage.getItem("deviceUID") || false
39
- );
40
-
41
- useEffect(() => {
42
- if (!deviceUID) {
43
- const uid = getDeviceFingerprint();
44
- setDeviceUID(uid);
45
- AuthenticatedAxiosObject.defaults.headers.common["deviceUID"] = uid;
46
- }
47
- }, [deviceUID, AuthenticatedAxiosObject]);
48
-
49
- // State to hold the selected header name
50
- const [current, setCurrent] = useState("");
51
-
52
- AuthenticatedAxiosObject.defaults.withCredentials = true;
53
- AuthenticatedAxiosObject.defaults.headers.common["Authorization"] = current;
54
- AuthenticatedAxiosObject.defaults.headers.common["deviceUID"] = deviceUID;
55
- AuthenticatedAxiosObject.defaults.headers.common["appVersion"] = appVersion;
56
-
57
- const fromPrevious = useCallback(
58
- (auth, remember) => {
59
- setCurrent(auth);
60
- setTimeout(() => {
61
- refreshToken()
62
- .then((data) => {
63
- if (data.refreshed) {
64
- const token = `Bearer ${data.access_token}`;
65
- setCurrent(token);
66
- AuthenticatedAxiosObject.defaults.headers.common[
67
- "Authorization"
68
- ] = token;
69
- if (remember) localStorage.setItem("Authorization", token);
70
- sessionStorage.setItem("Authorization", token);
71
- }
72
- })
73
- .catch((err) => {
74
- console.log(err);
75
- console.log("Missing/Invalid Token");
76
- localStorage.removeItem("Authorization");
77
- sessionStorage.removeItem("Authorization");
78
- });
79
- }, 100);
80
- },
81
- [AuthenticatedAxiosObject, refreshToken]
82
- );
83
-
84
- useEffect(() => {
85
- const local_auth = localStorage.getItem("Authorization");
86
- const sess_auth = sessionStorage.getItem("Authorization");
87
-
88
- if (local_auth) fromPrevious(local_auth, true);
89
- else if (sess_auth) fromPrevious(sess_auth, false);
90
- return () => clearInterval(fromPrevious);
91
- }, [current, fromPrevious]);
92
-
93
- // Wrap setHeader to store new header names in localStorage
94
- const setHeader = (header) => {
95
- setCurrent(header);
96
- };
97
-
98
- const [currentLoggin, setCurrentLoggedIn] = useState(false);
99
- const [isAdmin, setIsAdmin] = useState(false);
100
- const [userInfo, setUserInfo] = useState({});
101
- const [loadingUser, setLoadingUser] = useState(true);
102
-
103
- useEffect(() => {
104
- setTimeout(() => {
105
- userLoader()
106
- .then((res) => {
107
- const data = res.data;
108
- setCurrentLoggedIn(data.logged_in);
109
- setIsAdmin(data.is_admin);
110
- setUserInfo(data.Info);
111
- })
112
- .catch((err) => {
113
- console.log(err);
114
- })
115
- .finally(() => {
116
- setLoadingUser(false);
117
- });
118
- }, 100);
119
- }, [current, currentLoggin, userLoader]);
120
-
121
- const setLoggedin = (status) => {
122
- setCurrentLoggedIn(status);
123
- };
124
-
125
- useEffect(() => {
126
- const tokenRefreshTimer = () => {
127
- const mins = refreshTimer || 60;
128
- return mins * 60 * 1000 || 10000;
129
- };
130
-
131
- let interval = null;
132
- if (currentLoggin) {
133
- const remember = localStorage.getItem("Authorization") ? true : false;
134
- interval = setInterval(() => {
135
- fromPrevious(sessionStorage.getItem("Authorization"), remember);
136
- }, tokenRefreshTimer());
137
- } else {
138
- clearInterval(interval);
139
- }
140
- return () => clearInterval(interval);
141
- }, [current, fromPrevious, currentLoggin, refreshTimer]);
142
-
143
- useEffect(() => {
144
- const customInterceptor = () => {
145
- AuthenticatedAxiosObject.interceptors.response.use(
146
- (response) => {
147
- return response;
148
- },
149
- (error) => {
150
- if (error?.response?.status === 455) {
151
- try {
152
- const status = error.response.data.logged_in || false;
153
- if (!status) {
154
- console.log("Session ended");
155
- setCurrentLoggedIn(false);
156
- AuthenticatedAxiosObject.defaults.headers.common[
157
- "Authorization"
158
- ] = ``;
159
- toast.info(
160
- "Your session in no longer valid, please login again.",
161
- { toastId: "Forced_log_out", icon: <Logout /> }
162
- );
163
- }
164
- } catch (err) {
165
- throw err;
166
- }
167
- }
168
- if (error?.response?.status === 426) {
169
- sessionStorage.setItem("appVersionOld", true);
170
- sessionStorage.setItem(
171
- "requiredVersion",
172
- error.response.data.minVersion
173
- );
174
- let reloads = sessionStorage.getItem("appReloads") || 0;
175
- if (reloads < 2) {
176
- sessionStorage.setItem("appReloads", reloads + 1);
177
- setTimeout(() => {
178
- window.location.reload();
179
- }, 1000 * reloads);
180
- } else {
181
- toast.warning(
182
- "The application needs to be updated please wait for some time then reload the page.",
183
- {
184
- toastId: "appReloadError",
185
- icon: <Update />,
186
- }
187
- );
188
- }
189
- }
190
-
191
- if (!error?.response?.status) {
192
- if (error?.code !== "ERR_CANCELED" && error?.message !== "canceled")
193
- toast.error(
194
- "The server is not responding, please reload or try again later.",
195
- { toastId: "ERR_CONNECTION_REFUSED", icon: <GppBad /> }
196
- );
197
- }
198
- throw error;
199
- }
200
- );
201
- };
202
- return customInterceptor;
203
- }, [AuthenticatedAxiosObject, currentLoggin]);
204
-
205
- // We will use the below to refresh our data about the user when ever we flag refreshData as true
206
- const [refreshData, setRefreshFlag] = useState(false);
207
-
208
- useEffect(() => {
209
- const refreshDelay = () => {
210
- const mins = dataRefresh || 60;
211
- return mins * 60 * 1000 || 10000;
212
- };
213
-
214
- const timer = setTimeout(() => setRefreshFlag(true), refreshDelay());
215
- return () => clearTimeout(timer);
216
- }, [dataRefresh]);
217
-
218
- useEffect(() => {
219
- if (refreshData) {
220
- userLoader().then((res) => {
221
- const data = res.data;
222
- setUserInfo(data.Info);
223
- setRefreshData(false);
224
- });
225
- }
226
- }, [refreshData, userLoader]);
227
-
228
- const setRefreshData = (status) => {
229
- setRefreshFlag(status);
230
- };
231
-
232
- // Check if user has specific role
233
-
234
- const hasRole = (roles) => {
235
- const found = roles.some((r) => userInfo?.roles?.indexOf(r) >= 0);
236
- return found;
237
- };
238
-
239
- const contextValue = {
240
- isLoggedIn: currentLoggin,
241
- header: current,
242
- isAdmin: isAdmin,
243
- userInfo: userInfo,
244
- refreshData: refreshData,
245
- setHeader: setHeader,
246
- setLoggedin: setLoggedin,
247
- setRefreshData: setRefreshData,
248
- hasRole: hasRole,
249
- deviceUID: deviceUID,
250
- loadingUser: loadingUser,
251
- };
252
-
253
- return (
254
- <SessionManager.Provider value={contextValue}>
255
- <ToastContainer
256
- position="top-left"
257
- autoClose={5000}
258
- closeOnClick
259
- pauseOnFocusLoss
260
- pauseOnHover
261
- newestOnTop={false}
262
- toastClassName={"custToast materialToast"}
263
- {...toastOptions}
264
- />
265
- <VersionProtection appVersion={appVersion} />
266
- {children}
267
- </SessionManager.Provider>
268
- );
269
- };
270
-
271
- function VersionProtection(appVersion) {
272
- const oldVersion = sessionStorage.getItem("appVersionOld") || false;
273
- useEffect(() => {
274
- if (
275
- oldVersion &&
276
- sessionStorage.getItem("requiredVersion") &&
277
- versionCompare(appVersion, sessionStorage.getItem("requiredVersion"))
278
- ) {
279
- toast.success("Your application has been updated", {
280
- toastId: "appReload",
281
- icon: <BrownserUpdated />,
282
- });
283
- sessionStorage.removeItem("appVersionOld");
284
- sessionStorage.removeItem("requiredVersion");
285
- sessionStorage.removeItem("appReloads");
286
- }
287
- }, [oldVersion]);
288
-
289
- return <></>;
290
- }
291
-
292
- export default SessionManagerProvider;
1
+ import React, { createContext, useState, useEffect, useCallback } from "react";
2
+ import versionCompare from "./components/versionCompare";
3
+ import getDeviceFingerprint from "./components/FingerPrint";
4
+ // Notifications
5
+ import { ToastContainer, toast } from "react-toastify";
6
+ import "react-toastify/dist/ReactToastify.css";
7
+ import "./styling/toast.css";
8
+
9
+ // Icons
10
+ import { GppBad, Update, BrowserUpdated, Logout } from "@mui/icons-material";
11
+
12
+ export const SessionManager = createContext({
13
+ isLoggedIn: null,
14
+ header: null,
15
+ isAdmin: null,
16
+ userInfo: null,
17
+ refreshData: null,
18
+ setHeader: null,
19
+ setLoggedin: null,
20
+ setRefreshData: null,
21
+ hasRole: null,
22
+ deviceUID: null,
23
+ loadingUser: null,
24
+ });
25
+
26
+ const SessionManagerProvider = ({
27
+ AuthenticatedAxiosObject,
28
+ refreshTimer,
29
+ dataRefresh,
30
+ userLoader,
31
+ refreshToken,
32
+ appVersion,
33
+ toastOptions,
34
+ children,
35
+ }) => {
36
+ // Set deivce UID
37
+ const [deviceUID, setDeviceUID] = useState(
38
+ localStorage.getItem("deviceUID") || false
39
+ );
40
+
41
+ useEffect(() => {
42
+ if (!deviceUID) {
43
+ const uid = getDeviceFingerprint();
44
+ setDeviceUID(uid);
45
+ AuthenticatedAxiosObject.defaults.headers.common["deviceUID"] = uid;
46
+ }
47
+ }, [deviceUID, AuthenticatedAxiosObject]);
48
+
49
+ // State to hold the selected header name
50
+ const [current, setCurrent] = useState("");
51
+
52
+ AuthenticatedAxiosObject.defaults.withCredentials = true;
53
+ AuthenticatedAxiosObject.defaults.headers.common["Authorization"] = current;
54
+ AuthenticatedAxiosObject.defaults.headers.common["deviceUID"] = deviceUID;
55
+ AuthenticatedAxiosObject.defaults.headers.common["appVersion"] = appVersion;
56
+
57
+ const fromPrevious = useCallback(
58
+ (auth, remember) => {
59
+ setCurrent(auth);
60
+ setTimeout(() => {
61
+ refreshToken()
62
+ .then((data) => {
63
+ if (data.refreshed) {
64
+ const token = `Bearer ${data.access_token}`;
65
+ setCurrent(token);
66
+ AuthenticatedAxiosObject.defaults.headers.common[
67
+ "Authorization"
68
+ ] = token;
69
+ if (remember) localStorage.setItem("Authorization", token);
70
+ sessionStorage.setItem("Authorization", token);
71
+ }
72
+ })
73
+ .catch((err) => {
74
+ console.log(err);
75
+ console.log("Missing/Invalid Token");
76
+ localStorage.removeItem("Authorization");
77
+ sessionStorage.removeItem("Authorization");
78
+ });
79
+ }, 100);
80
+ },
81
+ [AuthenticatedAxiosObject, refreshToken]
82
+ );
83
+
84
+ useEffect(() => {
85
+ const local_auth = localStorage.getItem("Authorization");
86
+ const sess_auth = sessionStorage.getItem("Authorization");
87
+
88
+ if (local_auth) fromPrevious(local_auth, true);
89
+ else if (sess_auth) fromPrevious(sess_auth, false);
90
+ return () => clearInterval(fromPrevious);
91
+ }, [current, fromPrevious]);
92
+
93
+ // Wrap setHeader to store new header names in localStorage
94
+ const setHeader = (header) => {
95
+ setCurrent(header);
96
+ };
97
+
98
+ const [currentLoggin, setCurrentLoggedIn] = useState(false);
99
+ const [isAdmin, setIsAdmin] = useState(false);
100
+ const [userInfo, setUserInfo] = useState({});
101
+ const [loadingUser, setLoadingUser] = useState(true);
102
+
103
+ useEffect(() => {
104
+ setTimeout(() => {
105
+ userLoader()
106
+ .then((res) => {
107
+ const data = res.data;
108
+ setCurrentLoggedIn(data.logged_in);
109
+ setIsAdmin(data.is_admin);
110
+ setUserInfo(data.Info);
111
+ })
112
+ .catch((err) => {
113
+ console.log(err);
114
+ })
115
+ .finally(() => {
116
+ setLoadingUser(false);
117
+ });
118
+ }, 100);
119
+ }, [current, currentLoggin, userLoader]);
120
+
121
+ const setLoggedin = (status) => {
122
+ setCurrentLoggedIn(status);
123
+ };
124
+
125
+ useEffect(() => {
126
+ const tokenRefreshTimer = () => {
127
+ const mins = refreshTimer || 60;
128
+ return mins * 60 * 1000 || 10000;
129
+ };
130
+
131
+ let interval = null;
132
+ if (currentLoggin) {
133
+ const remember = localStorage.getItem("Authorization") ? true : false;
134
+ interval = setInterval(() => {
135
+ fromPrevious(sessionStorage.getItem("Authorization"), remember);
136
+ }, tokenRefreshTimer());
137
+ } else {
138
+ clearInterval(interval);
139
+ }
140
+ return () => clearInterval(interval);
141
+ }, [current, fromPrevious, currentLoggin, refreshTimer]);
142
+
143
+ useEffect(() => {
144
+ const customInterceptor = () => {
145
+ AuthenticatedAxiosObject.interceptors.response.use(
146
+ (response) => {
147
+ return response;
148
+ },
149
+ (error) => {
150
+ if (error?.response?.status === 455) {
151
+ try {
152
+ const status = error.response.data.logged_in || false;
153
+ if (!status) {
154
+ console.log("Session ended");
155
+ setCurrentLoggedIn(false);
156
+ AuthenticatedAxiosObject.defaults.headers.common[
157
+ "Authorization"
158
+ ] = ``;
159
+ toast.info(
160
+ "Your session in no longer valid, please login again.",
161
+ { toastId: "Forced_log_out", icon: <Logout /> }
162
+ );
163
+ }
164
+ } catch (err) {
165
+ throw err;
166
+ }
167
+ }
168
+ if (error?.response?.status === 426) {
169
+ sessionStorage.setItem("appVersionOld", true);
170
+ sessionStorage.setItem(
171
+ "requiredVersion",
172
+ error.response.data.minVersion
173
+ );
174
+ let reloads = sessionStorage.getItem("appReloads") || 0;
175
+ if (reloads < 2) {
176
+ sessionStorage.setItem("appReloads", reloads + 1);
177
+ setTimeout(() => {
178
+ window.location.reload();
179
+ }, 1000 * reloads);
180
+ } else {
181
+ toast.warning(
182
+ "The application needs to be updated please wait for some time then reload the page.",
183
+ {
184
+ toastId: "appReloadError",
185
+ icon: <Update />,
186
+ }
187
+ );
188
+ }
189
+ }
190
+
191
+ if (!error?.response?.status) {
192
+ if (error?.code !== "ERR_CANCELED" && error?.message !== "canceled")
193
+ toast.error(
194
+ "The server is not responding, please reload or try again later.",
195
+ { toastId: "ERR_CONNECTION_REFUSED", icon: <GppBad /> }
196
+ );
197
+ }
198
+ throw error;
199
+ }
200
+ );
201
+ };
202
+ return customInterceptor;
203
+ }, [AuthenticatedAxiosObject, currentLoggin]);
204
+
205
+ // We will use the below to refresh our data about the user when ever we flag refreshData as true
206
+ const [refreshData, setRefreshFlag] = useState(false);
207
+
208
+ useEffect(() => {
209
+ const refreshDelay = () => {
210
+ const mins = dataRefresh || 60;
211
+ return mins * 60 * 1000 || 10000;
212
+ };
213
+
214
+ const timer = setTimeout(() => setRefreshFlag(true), refreshDelay());
215
+ return () => clearTimeout(timer);
216
+ }, [dataRefresh]);
217
+
218
+ useEffect(() => {
219
+ if (refreshData) {
220
+ userLoader().then((res) => {
221
+ const data = res.data;
222
+ setUserInfo(data.Info);
223
+ setRefreshData(false);
224
+ });
225
+ }
226
+ }, [refreshData, userLoader]);
227
+
228
+ const setRefreshData = (status) => {
229
+ setRefreshFlag(status);
230
+ };
231
+
232
+ // Check if user has specific role
233
+
234
+ const hasRole = (roles) => {
235
+ const found = roles.some((r) => userInfo?.roles?.indexOf(r) >= 0);
236
+ return found;
237
+ };
238
+
239
+ const contextValue = {
240
+ isLoggedIn: currentLoggin,
241
+ header: current,
242
+ isAdmin: isAdmin,
243
+ userInfo: userInfo,
244
+ refreshData: refreshData,
245
+ setHeader: setHeader,
246
+ setLoggedin: setLoggedin,
247
+ setRefreshData: setRefreshData,
248
+ hasRole: hasRole,
249
+ deviceUID: deviceUID,
250
+ loadingUser: loadingUser,
251
+ };
252
+
253
+ return (
254
+ <SessionManager.Provider value={contextValue}>
255
+ <ToastContainer
256
+ position="top-left"
257
+ autoClose={5000}
258
+ closeOnClick
259
+ pauseOnFocusLoss
260
+ pauseOnHover
261
+ newestOnTop={false}
262
+ toastClassName={"custToast materialToast"}
263
+ {...toastOptions}
264
+ />
265
+ <VersionProtection appVersion={appVersion} />
266
+ {children}
267
+ </SessionManager.Provider>
268
+ );
269
+ };
270
+
271
+ function VersionProtection({ appVersion }) {
272
+ const oldVersion = sessionStorage.getItem("appVersionOld") || false;
273
+ useEffect(() => {
274
+ if (
275
+ oldVersion &&
276
+ sessionStorage.getItem("requiredVersion") &&
277
+ versionCompare(appVersion, sessionStorage.getItem("requiredVersion"))
278
+ ) {
279
+ console.log("Update Success Toast");
280
+ toast.success("Your application has been updated", {
281
+ toastId: "appReload",
282
+ icon: <BrowserUpdated />,
283
+ onClose: () => {
284
+ sessionStorage.removeItem("appVersionOld");
285
+ sessionStorage.removeItem("requiredVersion");
286
+ sessionStorage.removeItem("appReloads");
287
+ },
288
+ });
289
+ }
290
+ }, [oldVersion]);
291
+
292
+ return <></>;
293
+ }
294
+
295
+ export default SessionManagerProvider;