fractal-login
Version:
Fractal Studios core login
208 lines (178 loc) • 6.45 kB
JavaScript
import { BehaviorSubject } from 'rxjs';
import { fetchWrapper, history } from './helpers';
import Cookies from 'universal-cookie';
const config = require('config.json');
const userSubject = new BehaviorSubject(null);
const baseUrl = `${config.REACT_APP_API_URL}/accounts`;
const bugUrl = `${process.env.REACT_APP_API_URL}/bug`;
const requestUrl = `${process.env.REACT_APP_API_URL}/support`;
const cookies = new Cookies();
export const accountService = {
login,
logout,
refreshToken,
register,
verifyEmail,
forgotPassword,
validateResetToken,
resetPassword,
getAll,
getById,
create,
update,
updateAvatar,
verify,
banUser,
updateUserRole,
delete: _delete,
reportBug,
supportRequest,
setRefreshToken,
user: userSubject.asObservable(),
get userValue() { return userSubject.value }
};
function reportBug(bug) {
return fetchWrapper.put(`${bugUrl}/${userSubject.value.id}`, bug);
}
function supportRequest(request) {
return fetchWrapper.put(`${requestUrl}/${userSubject.value.id}`, request);
}
function login(email, password) {
return fetchWrapper.post(`${baseUrl}/authenticate`, { email, username: email, password })
.then(user => {
// publish user to subscribers and start timer to refresh token
userSubject.next(user.account);
startRefreshTokenTimer();
cookies.set('refreshToken', user.refreshToken, {
path: '/',
expires: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)
});
return { user };
});
}
function logout() {
// revoke token, stop refresh timer, publish null to user subscribers and redirect to login page
fetchWrapper.post(`${baseUrl}/revoke-token`, {});
stopRefreshTokenTimer();
userSubject.next(null);
history.push('/auth');
history.go();
}
function refreshToken() {
return fetchWrapper.post(`${baseUrl}/refresh-token`, {})
.then(user => {
// publish user to subscribers and start timer to refresh token
userSubject.next(user.account);
startRefreshTokenTimer();
cookies.set('refreshToken', user.refreshToken, { path: '/' });
return user;
});
}
function setRefreshToken(refreshToken) {
cookies.set('refreshToken', refreshToken, { path: '/' });
return true;
}
function register(params) {
return fetchWrapper.post(`${baseUrl}/register`, params);
}
function verifyEmail(token) {
return fetchWrapper.post(`${baseUrl}/verify-email`, { token });
}
function forgotPassword(email) {
return fetchWrapper.post(`${baseUrl}/forgot-password`, { email });
}
function validateResetToken(token) {
return fetchWrapper.post(`${baseUrl}/validate-reset-token`, { token });
}
function resetPassword({ token, password, confirmPassword }) {
return fetchWrapper.post(`${baseUrl}/reset-password`, { token, password, confirmPassword });
}
function getAll() {
return fetchWrapper.get(baseUrl);
}
function getById(id) {
return fetchWrapper.get(`${baseUrl}/${id}`);
}
function create(params) {
return fetchWrapper.post(baseUrl, params);
}
function update(id, params) {
return fetchWrapper.put(`${baseUrl}/${id}`, params)
.then(user => {
// update stored user if the logged in user updated their own record
if (user.id === userSubject.value.id) {
// publish updated user to subscribers
user = { ...userSubject.value, ...user };
userSubject.next(user);
}
return user;
});
}
function updateAvatar(id, formData) {
return fetchWrapper.upload(`${baseUrl}/user-profile/${id}`, formData)
.then(user => {
// update stored user if the logged in user updated their own record
if (user.id === userSubject.value.id) {
// publish updated user to subscribers
user = { ...userSubject.value, ...user };
userSubject.next(user);
}
return user;
});
}
// prefixed with underscore because 'delete' is a reserved word in javascript
function _delete(id) {
return fetchWrapper.delete(`${baseUrl}/${id}`)
.then(x => {
return x;
});
}
function verify(id) {
return fetchWrapper.put(`${baseUrl}/${id}/verify`, {})
.then(user => {
// update stored user if the logged in user updated their own record
if (user.id === userSubject.value.id) {
// publish updated user to subscribers
user = { ...userSubject.value, ...user };
userSubject.next(user);
}
return user;
});
}
function updateUserRole(id, role) {
return fetchWrapper.put(`${baseUrl}/${id}/update-role`, role)
.then(user => {
// update stored user if the logged in user updated their own record
if (user.id === userSubject.value.id) {
// publish updated user to subscribers
user = { ...userSubject.value, ...user };
userSubject.next(user);
}
return user;
});
}
function banUser(id) {
return fetchWrapper.put(`${baseUrl}/${id}/ban-user`, {})
.then(user => {
// update stored user if the logged in user updated their own record
if (user.id === userSubject.value.id) {
// publish updated user to subscribers
user = { ...userSubject.value, ...user };
userSubject.next(user);
}
return user;
});
}
// helper functions
let refreshTokenTimeout;
function startRefreshTokenTimer() {
// parse json object from base64 encoded jwt token
const jwtToken = JSON.parse(atob(userSubject.value.jwtToken.split('.')[1]));
// set a timeout to refresh the token a minute before it expires
const expires = new Date(jwtToken.exp * 1000);
const timeout = expires.getTime() - Date.now() - (60 * 1000);
refreshTokenTimeout = setTimeout(refreshToken, timeout);
}
function stopRefreshTokenTimer() {
clearTimeout(refreshTokenTimeout);
}