Files
talk/client/coral-framework/actions/auth.js
T
Wyatt Johnson 6a04b66d84 fix: token handling
- Fixes #1728
2018-07-27 14:08:53 -06:00

126 lines
2.9 KiB
JavaScript

import * as actions from '../constants/auth';
import jwtDecode from 'jwt-decode';
function cleanAuthData(localStorage) {
localStorage.removeItem('token');
localStorage.removeItem('exp');
}
export const checkLogin = () => (
dispatch,
_,
{ rest, client, pym, localStorage }
) => {
dispatch(checkLoginRequest());
rest('/auth')
.then(result => {
if (!result.user) {
cleanAuthData(localStorage);
dispatch(checkLoginSuccess(null));
client.resetWebsocket();
return;
}
dispatch(checkLoginSuccess(result.user));
pym.sendMessage('coral-auth-changed', JSON.stringify(result.user));
client.resetWebsocket();
})
.catch(error => {
if (error.status && error.status === 401 && localStorage) {
// Unauthorized.
cleanAuthData(localStorage);
client.resetWebsocket();
} else {
console.error(error);
}
dispatch(checkLoginFailure(error));
});
};
const checkLoginRequest = () => ({ type: actions.CHECK_LOGIN_REQUEST });
const checkLoginFailure = error => ({
type: actions.CHECK_LOGIN_FAILURE,
error,
});
const checkLoginSuccess = user => ({
type: actions.CHECK_LOGIN_SUCCESS,
user,
});
export const setAuthToken = token => (dispatch, _, { localStorage }) => {
localStorage.setItem('exp', jwtDecode(token).exp);
localStorage.setItem('token', token);
// Dispatch the set auth token action. For some browsers and situations, we
// may not be able to persist the auth token any other way. Keep it in redux!
dispatch({ type: actions.SET_AUTH_TOKEN, token });
dispatch(checkLogin());
};
export const handleSuccessfulLogin = (user, token) => (
dispatch,
_,
{ client, localStorage, postMessage }
) => {
const { exp } = jwtDecode(token);
localStorage.setItem('exp', exp);
localStorage.setItem('token', token);
// Send the message via the messages service to the window.opener if it
// exists.
if (window.opener) {
postMessage.post(
actions.HANDLE_SUCCESSFUL_LOGIN,
{ user, token },
window.opener
);
}
client.resetWebsocket();
dispatch({
type: actions.HANDLE_SUCCESSFUL_LOGIN,
user,
token,
});
};
/**
* Logout
*/
export const logout = () => async (
dispatch,
_,
{ rest, client, pym, localStorage }
) => {
try {
await rest('/auth', { method: 'DELETE' });
} catch (err) {
// We ignore any REST related errors from the delete action, which may/may
// not have had a cookie/token attached to it. The logout action was still
// called, so we still want to cleanup.
}
// Clear the auth data persisted to localStorage.
cleanAuthData(localStorage);
// Reset the websocket.
client.resetWebsocket();
dispatch({ type: actions.LOGOUT });
pym.sendMessage('coral-auth-changed');
};
export const updateStatus = status => ({
type: actions.UPDATE_STATUS,
status,
});
export const updateUsername = username => ({
type: actions.UPDATE_USERNAME,
username,
});