mirror of
https://github.com/wassname/talk.git
synced 2026-07-28 11:27:05 +08:00
416 lines
11 KiB
JavaScript
416 lines
11 KiB
JavaScript
import jwtDecode from 'jwt-decode';
|
|
import bowser from 'bowser';
|
|
import * as actions from '../constants/auth';
|
|
import { notify } from 'coral-framework/actions/notification';
|
|
import t from 'coral-framework/services/i18n';
|
|
import get from 'lodash/get';
|
|
|
|
export const updateStatus = status => ({
|
|
type: actions.UPDATE_STATUS,
|
|
status,
|
|
});
|
|
|
|
export const showSignInDialog = () => ({
|
|
type: actions.SHOW_SIGNIN_DIALOG,
|
|
});
|
|
|
|
export const hideSignInDialog = () => dispatch => {
|
|
if (window.opener && window.opener !== window) {
|
|
// TODO: We need to address this when we refactor the
|
|
// login popup out of the embed.
|
|
|
|
// we are in a popup
|
|
window.close();
|
|
} else {
|
|
dispatch(checkLogin());
|
|
}
|
|
dispatch({ type: actions.HIDE_SIGNIN_DIALOG });
|
|
};
|
|
|
|
export const resetSignInDialog = () => dispatch => {
|
|
dispatch({ type: actions.HIDE_SIGNIN_DIALOG });
|
|
};
|
|
|
|
export const focusSignInDialog = () => ({
|
|
type: actions.FOCUS_SIGNIN_DIALOG,
|
|
});
|
|
|
|
export const blurSignInDialog = () => ({
|
|
type: actions.BLUR_SIGNIN_DIALOG,
|
|
});
|
|
|
|
export const showCreateUsernameDialog = () => ({
|
|
type: actions.SHOW_CREATEUSERNAME_DIALOG,
|
|
});
|
|
|
|
export const hideCreateUsernameDialog = () => ({
|
|
type: actions.HIDE_CREATEUSERNAME_DIALOG,
|
|
});
|
|
|
|
export const updateUsername = username => ({
|
|
type: actions.UPDATE_USERNAME,
|
|
username,
|
|
});
|
|
|
|
export const changeView = view => dispatch => {
|
|
dispatch({
|
|
type: actions.CHANGE_VIEW,
|
|
view,
|
|
});
|
|
|
|
switch (view) {
|
|
case 'SIGNUP':
|
|
window.resizeTo(500, 800);
|
|
break;
|
|
case 'FORGOT':
|
|
window.resizeTo(500, 400);
|
|
break;
|
|
default:
|
|
window.resizeTo(500, 550);
|
|
}
|
|
};
|
|
|
|
export const cleanState = () => ({
|
|
type: actions.CLEAN_STATE,
|
|
});
|
|
|
|
// Sign In Actions
|
|
|
|
const signInRequest = email => ({
|
|
type: actions.FETCH_SIGNIN_REQUEST,
|
|
email,
|
|
});
|
|
|
|
const signInFailure = error => ({
|
|
type: actions.FETCH_SIGNIN_FAILURE,
|
|
error,
|
|
});
|
|
|
|
//==============================================================================
|
|
// AUTH TOKEN
|
|
//==============================================================================
|
|
|
|
export const handleAuthToken = token => (dispatch, _, { localStorage }) => {
|
|
if (localStorage) {
|
|
localStorage.setItem('exp', jwtDecode(token).exp);
|
|
localStorage.setItem('token', token);
|
|
}
|
|
|
|
dispatch({ type: 'HANDLE_AUTH_TOKEN' });
|
|
};
|
|
|
|
//==============================================================================
|
|
// SIGN IN
|
|
//==============================================================================
|
|
|
|
export const fetchSignIn = formData => {
|
|
return (dispatch, _, { rest }) => {
|
|
dispatch(signInRequest(formData.email));
|
|
|
|
return rest('/auth/local', { method: 'POST', body: formData })
|
|
.then(({ token }) => {
|
|
if (!bowser.safari && !bowser.ios) {
|
|
dispatch(handleAuthToken(token));
|
|
}
|
|
dispatch(hideSignInDialog());
|
|
})
|
|
.catch(error => {
|
|
console.error(error);
|
|
if (error.metadata) {
|
|
// the user might not have a valid email. prompt the user user re-request the confirmation email
|
|
dispatch(
|
|
signInFailure(t('error.email_not_verified', error.metadata))
|
|
);
|
|
} else if (error.translation_key === 'NOT_AUTHORIZED') {
|
|
// invalid credentials
|
|
dispatch(signInFailure(t('error.email_password'), error.metadata));
|
|
} else {
|
|
dispatch(signInFailure(error));
|
|
}
|
|
});
|
|
};
|
|
};
|
|
|
|
//==============================================================================
|
|
// SIGN IN - FACEBOOK
|
|
//==============================================================================
|
|
|
|
const signInFacebookRequest = () => ({
|
|
type: actions.FETCH_SIGNIN_FACEBOOK_REQUEST,
|
|
});
|
|
|
|
const signInFacebookSuccess = user => ({
|
|
type: actions.FETCH_SIGNIN_FACEBOOK_SUCCESS,
|
|
user,
|
|
});
|
|
|
|
const signInFacebookFailure = error => ({
|
|
type: actions.FETCH_SIGNIN_FACEBOOK_FAILURE,
|
|
error,
|
|
});
|
|
|
|
export const fetchSignInFacebook = () => (dispatch, _, { rest }) => {
|
|
dispatch(signInFacebookRequest());
|
|
window.open(
|
|
`${rest.uri}/auth/facebook`,
|
|
'Continue with Facebook',
|
|
'menubar=0,resizable=0,width=500,height=500,top=200,left=500'
|
|
);
|
|
};
|
|
|
|
//==============================================================================
|
|
// SIGN UP - FACEBOOK
|
|
//==============================================================================
|
|
|
|
const signUpFacebookRequest = () => ({
|
|
type: actions.FETCH_SIGNUP_FACEBOOK_REQUEST,
|
|
});
|
|
|
|
export const fetchSignUpFacebook = () => (dispatch, _, { rest }) => {
|
|
dispatch(signUpFacebookRequest());
|
|
window.open(
|
|
`${rest.uri}/auth/facebook`,
|
|
'Continue with Facebook',
|
|
'menubar=0,resizable=0,width=500,height=500,top=200,left=500'
|
|
);
|
|
};
|
|
|
|
export const facebookCallback = (err, data) => dispatch => {
|
|
if (err) {
|
|
dispatch(signInFacebookFailure(err));
|
|
return;
|
|
}
|
|
try {
|
|
dispatch(handleAuthToken(data.token));
|
|
dispatch(signInFacebookSuccess(data.user));
|
|
dispatch(hideSignInDialog());
|
|
} catch (err) {
|
|
dispatch(signInFacebookFailure(err));
|
|
return;
|
|
}
|
|
};
|
|
|
|
//==============================================================================
|
|
// SIGN UP
|
|
//==============================================================================
|
|
|
|
const signUpRequest = () => ({ type: actions.FETCH_SIGNUP_REQUEST });
|
|
const signUpSuccess = user => ({ type: actions.FETCH_SIGNUP_SUCCESS, user });
|
|
const signUpFailure = error => ({ type: actions.FETCH_SIGNUP_FAILURE, error });
|
|
|
|
export const fetchSignUp = formData => (dispatch, getState, { rest }) => {
|
|
const redirectUri = getState().auth.redirectUri;
|
|
dispatch(signUpRequest());
|
|
|
|
rest('/users', {
|
|
method: 'POST',
|
|
body: formData,
|
|
headers: { 'X-Pym-Url': redirectUri },
|
|
})
|
|
.then(({ user }) => {
|
|
dispatch(signUpSuccess(user));
|
|
})
|
|
.catch(error => {
|
|
console.error(error);
|
|
const errorMessage = error.translation_key
|
|
? t(`error.${error.translation_key}`)
|
|
: error.toString();
|
|
dispatch(signUpFailure(errorMessage));
|
|
});
|
|
};
|
|
|
|
//==============================================================================
|
|
// FORGOT PASSWORD
|
|
//==============================================================================
|
|
|
|
const forgotPasswordRequest = () => ({
|
|
type: actions.FETCH_FORGOT_PASSWORD_REQUEST,
|
|
});
|
|
|
|
const forgotPasswordSuccess = () => ({
|
|
type: actions.FETCH_FORGOT_PASSWORD_SUCCESS,
|
|
});
|
|
|
|
const forgotPasswordFailure = error => ({
|
|
type: actions.FETCH_FORGOT_PASSWORD_FAILURE,
|
|
error,
|
|
});
|
|
|
|
export const fetchForgotPassword = email => (dispatch, getState, { rest }) => {
|
|
dispatch(forgotPasswordRequest(email));
|
|
const redirectUri = getState().auth.redirectUri;
|
|
rest('/account/password/reset', {
|
|
method: 'POST',
|
|
body: { email, loc: redirectUri },
|
|
})
|
|
.then(() => dispatch(forgotPasswordSuccess()))
|
|
.catch(error => {
|
|
console.error(error);
|
|
const errorMessage = error.translation_key
|
|
? t(`error.${error.translation_key}`)
|
|
: error.toString();
|
|
dispatch(forgotPasswordFailure(errorMessage));
|
|
});
|
|
};
|
|
|
|
//==============================================================================
|
|
// LOGOUT
|
|
//==============================================================================
|
|
|
|
export const logout = () => async (
|
|
dispatch,
|
|
_,
|
|
{ rest, client, pym, localStorage }
|
|
) => {
|
|
await rest('/auth', { method: 'DELETE' });
|
|
|
|
if (localStorage) {
|
|
localStorage.removeItem('token');
|
|
localStorage.removeItem('exp');
|
|
}
|
|
|
|
// Reset the websocket.
|
|
client.resetWebsocket();
|
|
|
|
dispatch({ type: actions.LOGOUT });
|
|
pym.sendMessage('coral-auth-changed');
|
|
};
|
|
|
|
//==============================================================================
|
|
// CHECK LOGIN
|
|
//==============================================================================
|
|
|
|
const checkLoginRequest = () => ({ type: actions.CHECK_LOGIN_REQUEST });
|
|
const checkLoginFailure = error => ({
|
|
type: actions.CHECK_LOGIN_FAILURE,
|
|
error,
|
|
});
|
|
|
|
const checkLoginSuccess = (user, isAdmin) => ({
|
|
type: actions.CHECK_LOGIN_SUCCESS,
|
|
user,
|
|
isAdmin,
|
|
});
|
|
|
|
const ErrNotLoggedIn = new Error('Not logged in');
|
|
|
|
export const checkLogin = () => (
|
|
dispatch,
|
|
_,
|
|
{ rest, client, pym, localStorage }
|
|
) => {
|
|
dispatch(checkLoginRequest());
|
|
rest('/auth')
|
|
.then(result => {
|
|
if (!result.user) {
|
|
if (localStorage) {
|
|
localStorage.removeItem('token');
|
|
localStorage.removeItem('exp');
|
|
}
|
|
throw ErrNotLoggedIn;
|
|
}
|
|
|
|
// Reset the websocket.
|
|
client.resetWebsocket();
|
|
|
|
dispatch(checkLoginSuccess(result.user));
|
|
pym.sendMessage('coral-auth-changed', JSON.stringify(result.user));
|
|
|
|
// This is for login via social. Usernames should be set.
|
|
if (
|
|
get(result.user, 'status.username.status') === 'UNSET' &&
|
|
!get(result.user, 'status.banned.status')
|
|
) {
|
|
dispatch(showCreateUsernameDialog());
|
|
}
|
|
})
|
|
.catch(error => {
|
|
if (error !== ErrNotLoggedIn) {
|
|
console.error(error);
|
|
}
|
|
if (error.status && error.status === 401 && localStorage) {
|
|
// Unauthorized.
|
|
localStorage.removeItem('token');
|
|
localStorage.removeItem('exp');
|
|
}
|
|
const errorMessage = error.translation_key
|
|
? t(`error.${error.translation_key}`)
|
|
: error.toString();
|
|
dispatch(checkLoginFailure(errorMessage));
|
|
});
|
|
};
|
|
|
|
export const validForm = () => ({ type: actions.VALID_FORM });
|
|
export const invalidForm = error => ({ type: actions.INVALID_FORM, error });
|
|
|
|
//==============================================================================
|
|
// VERIFY EMAIL
|
|
//==============================================================================
|
|
|
|
const verifyEmailRequest = () => ({
|
|
type: actions.VERIFY_EMAIL_REQUEST,
|
|
});
|
|
|
|
const verifyEmailSuccess = () => ({
|
|
type: actions.VERIFY_EMAIL_SUCCESS,
|
|
});
|
|
|
|
const verifyEmailFailure = error => ({
|
|
type: actions.VERIFY_EMAIL_FAILURE,
|
|
error,
|
|
});
|
|
|
|
export const requestConfirmEmail = email => (dispatch, getState, { rest }) => {
|
|
const redirectUri = getState().auth.redirectUri;
|
|
dispatch(verifyEmailRequest());
|
|
return rest('/users/resend-verify', {
|
|
method: 'POST',
|
|
body: { email },
|
|
headers: { 'X-Pym-Url': redirectUri },
|
|
})
|
|
.then(() => {
|
|
dispatch(verifyEmailSuccess());
|
|
})
|
|
.catch(error => {
|
|
console.error(error);
|
|
dispatch(verifyEmailFailure(error));
|
|
throw error;
|
|
});
|
|
};
|
|
|
|
// Login Popup actions.
|
|
export const setRequireEmailVerification = required => ({
|
|
type: actions.SET_REQUIRE_EMAIL_VERIFICATION,
|
|
required,
|
|
});
|
|
|
|
export const setRedirectUri = uri => ({
|
|
type: actions.SET_REDIRECT_URI,
|
|
uri,
|
|
});
|
|
|
|
//==============================================================================
|
|
// Edit Username
|
|
//==============================================================================
|
|
|
|
const editUsernameFailure = error => ({
|
|
type: actions.EDIT_USERNAME_FAILURE,
|
|
error,
|
|
});
|
|
const editUsernameSuccess = () => ({ type: actions.EDIT_USERNAME_SUCCESS });
|
|
|
|
export const editName = username => (dispatch, _, { rest }) => {
|
|
return rest('/account/username', { method: 'PUT', body: { username } })
|
|
.then(() => {
|
|
dispatch(editUsernameSuccess());
|
|
dispatch(notify('success', t('framework.success_name_update')));
|
|
})
|
|
.catch(error => {
|
|
console.error(error);
|
|
const errorMessage = error.translation_key
|
|
? t(`error.${error.translation_key}`)
|
|
: error.toString();
|
|
dispatch(editUsernameFailure(errorMessage));
|
|
});
|
|
};
|