241 lines
5.0 KiB
JavaScript
241 lines
5.0 KiB
JavaScript
import { createContext, useContext, useEffect, useReducer, useRef } from 'react';
|
|
import PropTypes from 'prop-types';
|
|
import { useRouter } from 'next/router';
|
|
|
|
const HANDLERS = {
|
|
INITIALIZE: 'INITIALIZE',
|
|
SIGN_IN: 'SIGN_IN',
|
|
SIGN_OUT: 'SIGN_OUT'
|
|
};
|
|
|
|
const initialState = {
|
|
isAuthenticated: false,
|
|
isLoading: true,
|
|
user: null
|
|
};
|
|
|
|
const handlers = {
|
|
[HANDLERS.INITIALIZE]: (state, action) => {
|
|
const user = action.payload;
|
|
|
|
return {
|
|
...state,
|
|
...(
|
|
// if payload (user) is provided, then is authenticated
|
|
user
|
|
? ({
|
|
isAuthenticated: true,
|
|
isLoading: false,
|
|
user
|
|
})
|
|
: ({
|
|
isLoading: false
|
|
})
|
|
)
|
|
};
|
|
},
|
|
[HANDLERS.SIGN_IN]: (state, action) => {
|
|
const user = action.payload;
|
|
|
|
return {
|
|
...state,
|
|
isAuthenticated: true,
|
|
user
|
|
};
|
|
},
|
|
[HANDLERS.SIGN_OUT]: (state) => {
|
|
return {
|
|
...state,
|
|
isAuthenticated: false,
|
|
user: null
|
|
};
|
|
}
|
|
};
|
|
|
|
const reducer = (state, action) => (
|
|
handlers[action.type] ? handlers[action.type](state, action) : state
|
|
);
|
|
|
|
// The role of this context is to propagate authentication state through the App tree.
|
|
|
|
export const AuthContext = createContext({ undefined });
|
|
|
|
export const AuthProvider = (props) => {
|
|
const { children } = props;
|
|
const [state, dispatch] = useReducer(reducer, initialState);
|
|
const initialized = useRef(false);
|
|
const router = useRouter();
|
|
|
|
const initialize = async () => {
|
|
// Prevent from calling twice in development mode with React.StrictMode enabled
|
|
if (initialized.current) {
|
|
return;
|
|
}
|
|
|
|
initialized.current = true;
|
|
|
|
let isAuthenticated = false;
|
|
|
|
try {
|
|
isAuthenticated = window.sessionStorage.getItem('authenticated') === 'true';
|
|
} catch (err) {
|
|
console.error(err);
|
|
}
|
|
|
|
console.log("isAuthenticated: ", isAuthenticated)
|
|
if (isAuthenticated) {
|
|
const user = {
|
|
id: '5e86809283e28b96d2d38537',
|
|
avatar: '/assets/avatars/default-avatar.png',
|
|
name: 'Oktopus',
|
|
email: 'anika.visser@devias.io',
|
|
token: localStorage.getItem("token")
|
|
};
|
|
|
|
dispatch({
|
|
type: HANDLERS.INITIALIZE,
|
|
payload: user
|
|
});
|
|
|
|
console.log("AUTH CONTEXT --> auth.user.token:", user.token)
|
|
} else {
|
|
dispatch({
|
|
type: HANDLERS.INITIALIZE
|
|
});
|
|
}
|
|
};
|
|
|
|
useEffect(
|
|
() => {
|
|
initialize();
|
|
},
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
[]
|
|
);
|
|
|
|
const skip = () => {
|
|
try {
|
|
window.sessionStorage.setItem('authenticated', 'true');
|
|
} catch (err) {
|
|
console.error(err);
|
|
}
|
|
|
|
const user = {
|
|
id: '5e86809283e28b96d2d38537',
|
|
avatar: '/assets/avatars/default-avatar.png',
|
|
name: 'Oktopus',
|
|
email: 'anika.visser@devias.io',
|
|
};
|
|
|
|
dispatch({
|
|
type: HANDLERS.SIGN_IN,
|
|
payload: user
|
|
});
|
|
};
|
|
|
|
const signIn = async (email, password) => {
|
|
|
|
var myHeaders = new Headers();
|
|
myHeaders.append("Content-Type", "application/json");
|
|
|
|
var raw = JSON.stringify({
|
|
"email": email,
|
|
"password": password
|
|
});
|
|
|
|
var requestOptions = {
|
|
method: 'PUT',
|
|
headers: myHeaders,
|
|
body: raw,
|
|
redirect: 'follow'
|
|
};
|
|
|
|
let result = await fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT+"/auth/login", requestOptions)
|
|
|
|
if (result.status != 200) {
|
|
throw new Error('Please check your email and password');
|
|
}
|
|
|
|
const token = await result.json()
|
|
|
|
|
|
try {
|
|
window.sessionStorage.setItem('authenticated', 'true');
|
|
window.sessionStorage.setItem('email',email)
|
|
} catch (err) {
|
|
console.error(err);
|
|
}
|
|
|
|
const user = {
|
|
id: '5e86809283e28b96d2d38537',
|
|
avatar: '/assets/avatars/default-avatar.png',
|
|
name: 'Oktopus',
|
|
email: email,
|
|
token: token
|
|
};
|
|
|
|
localStorage.setItem("token", token)
|
|
|
|
dispatch({
|
|
type: HANDLERS.SIGN_IN,
|
|
payload: user
|
|
});
|
|
};
|
|
|
|
const signUp = async (email, name, password) => {
|
|
var myHeaders = new Headers();
|
|
myHeaders.append("Content-Type", "application/json");
|
|
|
|
var raw = JSON.stringify({
|
|
"email": email,
|
|
"password": password,
|
|
"name": name
|
|
});
|
|
|
|
var requestOptions = {
|
|
method: 'POST',
|
|
headers: myHeaders,
|
|
body: raw,
|
|
redirect: 'follow'
|
|
};
|
|
|
|
let result = await fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT+"/auth/admin/register", requestOptions)
|
|
|
|
if (result.status == 200) {
|
|
router.push("/auth/login")
|
|
}else{
|
|
const content = await result.json()
|
|
throw new Error(content);
|
|
}
|
|
|
|
};
|
|
|
|
const signOut = () => {
|
|
dispatch({
|
|
type: HANDLERS.SIGN_OUT
|
|
});
|
|
};
|
|
|
|
return (
|
|
<AuthContext.Provider
|
|
value={{
|
|
...state,
|
|
skip,
|
|
signIn,
|
|
signUp,
|
|
signOut,
|
|
}}
|
|
>
|
|
{children}
|
|
</AuthContext.Provider>
|
|
);
|
|
};
|
|
|
|
AuthProvider.propTypes = {
|
|
children: PropTypes.node
|
|
};
|
|
|
|
export const AuthConsumer = AuthContext.Consumer;
|
|
|
|
export const useAuthContext = () => useContext(AuthContext);
|