fractal-auth
Version:
Fractal Studios Core login
225 lines (195 loc) • 7.27 kB
JavaScript
import { BehaviorSubject } from 'rxjs';
import { fetchWrapper, history } from './helpers';
import Cookies from 'universal-cookie';
const { FRACTAL_CORE_LOGIN_URL, FRACTAL_CORE_LOGIN_URL_DEV } = require('./config.json');
const userSubject = new BehaviorSubject(null);
const baseUrl = process.env.REACT_APP_ENV === 'dev' ? `${FRACTAL_CORE_LOGIN_URL_DEV}/accounts` : `${FRACTAL_CORE_LOGIN_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,
authToken,
register,
verifyEmail,
forgotPassword,
validateResetToken,
resetPassword,
getAll,
getById,
create,
update,
updateAvatar,
updateBanner,
verify,
banUser,
updateUserRole,
delete: _delete,
reportBug,
supportRequest,
setAuthToken,
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, product) {
return fetchWrapper.post(`${baseUrl}/authenticate`, { email, username: email, password, product })
.then(user => {
// publish user to subscribers and start timer to refresh token
userSubject.next(user.account);
startAuthTokenTimer();
setAuthToken(user.refreshToken, user.account.jwtToken)
return user;
});
}
function logout(product) {
// revoke token, stop refresh timer, publish null to user subscribers and redirect to login page
fetchWrapper.post(`${baseUrl}/revoke-token`, { product }).then(() => {
stopAuthTokenTimer();
userSubject.next(null);
cookies.remove('authtoken');
cookies.remove('jwtToken');
history.push('/auth');
history.go();
});
}
function authToken(product) {
return fetchWrapper.post(`${baseUrl}/auth-token`, { product })
.then(user => {
// publish user to subscribers and start timer to refresh token
userSubject.next(user.account);
startAuthTokenTimer();
setAuthToken(user.authToken, user.account.jwtToken);
return user;
});
}
function setAuthToken(authToken, jwtToken) {
var expires = new Date(Date.now() + 15000 * 24 * 60 * 60 * 1000);
if (jwtToken) {
cookies.set('jwtToken', jwtToken, { path: '/', expires: expires });
}
cookies.set('authtoken', authToken, { path: '/', expires: expires });
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;
});
}
function updateBanner(id, formData) {
return fetchWrapper.upload(`${baseUrl}/user-banner/${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 authTokenTimeout;
function startAuthTokenTimer() {
// 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);
authTokenTimeout = setTimeout(authToken, timeout);
}
function stopAuthTokenTimer() {
clearTimeout(authTokenTimeout);
}