mirror of
https://github.com/wassname/talk.git
synced 2026-07-07 18:38:22 +08:00
User Email Availability check
This commit is contained in:
@@ -30,8 +30,8 @@ export const fetchSignIn = (formData) => dispatch => {
|
||||
// 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});
|
||||
const signInFacebookSuccess = user => ({type: actions.FETCH_SIGNIN_FACEBOOK_SUCCESS, user});
|
||||
const signInFacebookFailure = error => ({type: actions.FETCH_SIGNIN_FACEBOOK_FAILURE, error});
|
||||
|
||||
export const fetchSignInFacebook = () => dispatch => {
|
||||
dispatch(signInFacebookRequest());
|
||||
@@ -58,15 +58,15 @@ export const facebookCallback = (err, data) => dispatch => {
|
||||
// Sign Up Actions
|
||||
|
||||
const signUpRequest = () => ({type: actions.FETCH_SIGNUP_REQUEST});
|
||||
const signUpSuccess = () => ({type: actions.FETCH_SIGNUP_SUCCESS});
|
||||
const signUpFailure = () => ({type: actions.FETCH_SIGNUP_FAILURE});
|
||||
const signUpSuccess = user => ({type: actions.FETCH_SIGNUP_SUCCESS, user});
|
||||
const signUpFailure = error => ({type: actions.FETCH_SIGNUP_FAILURE, error});
|
||||
|
||||
export const fetchSignUp = () => dispatch => {
|
||||
export const fetchSignUp = formData => dispatch => {
|
||||
dispatch(signUpRequest());
|
||||
fetch(`${base}/auth`, getInit('POST'))
|
||||
fetch(`${base}/user`, getInit('POST', formData))
|
||||
.then(handleResp)
|
||||
.then(() => dispatch(signUpSuccess()))
|
||||
.catch(error => dispatch(signUpFailure(error)));
|
||||
.then(({user}) => signUpSuccess(user))
|
||||
.catch((error) => signUpFailure(error));
|
||||
};
|
||||
|
||||
// Forgot Password Actions
|
||||
@@ -97,3 +97,27 @@ export const logout = () => dispatch => {
|
||||
.catch(error => dispatch(logOutFailure(error)));
|
||||
};
|
||||
|
||||
// Availability Checks Actions
|
||||
|
||||
const availabilityRequest = () => ({type: actions.FETCH_AVAILABILITY_REQUEST});
|
||||
const availabilitySuccess = () => ({type: actions.FETCH_AVAILABILITY_SUCCESS});
|
||||
const availabilityFailure = () => ({type: actions.FETCH_AVAILABILITY_FAILURE});
|
||||
|
||||
const availableField = field => ({type: actions.AVAILABLE_FIELD, field});
|
||||
const unavailableField = field => ({type: actions.UNAVAILABLE_FIELD, field});
|
||||
|
||||
export const fetchCheckAvailability = formData => dispatch => {
|
||||
dispatch(availabilityRequest());
|
||||
fetch(`${base}/user/availability`, getInit('POST', formData))
|
||||
.then(handleResp)
|
||||
.then(({status}) => {
|
||||
const [field] = Object.keys(formData);
|
||||
dispatch(availabilitySuccess());
|
||||
if (status === 'available') {
|
||||
return dispatch(availableField(field));
|
||||
}
|
||||
return dispatch(unavailableField(field));
|
||||
})
|
||||
.catch((error) => availabilityFailure(error));
|
||||
};
|
||||
|
||||
|
||||
@@ -23,3 +23,10 @@ export const FETCH_FORGOT_PASSWORD_FAILURE = 'FETCH_FORGOT_PASSWORD_FAILURE';
|
||||
export const LOGOUT_REQUEST = 'LOGOUT_REQUEST';
|
||||
export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS';
|
||||
export const LOGOUT_FAILURE = 'LOGOUT_FAILURE';
|
||||
|
||||
export const FETCH_AVAILABILITY_REQUEST = 'FETCH_AVAILABILITY_REQUEST';
|
||||
export const FETCH_AVAILABILITY_SUCCESS = 'FETCH_AVAILABILITY_SUCCESS';
|
||||
export const FETCH_AVAILABILITY_FAILURE = 'FETCH_AVAILABILITY_FAILURE';
|
||||
|
||||
export const AVAILABLE_FIELD = 'AVAILABLE_FIELD';
|
||||
export const UNAVAILABLE_FIELD = 'UNAVAILABLE_FIELD';
|
||||
|
||||
@@ -20,6 +20,8 @@ export const getInit = (method, body) => {
|
||||
export const handleResp = res => {
|
||||
if (res.status === 401) {
|
||||
throw new Error('Not Authorized to make this request');
|
||||
} else if (res.status === 500) {
|
||||
throw new Error(res.json());
|
||||
} else if (res.status > 399) {
|
||||
throw new Error('Error! Status ', res.status);
|
||||
} else if (res.status === 204) {
|
||||
|
||||
@@ -10,21 +10,24 @@ import {
|
||||
FETCH_SIGNIN_SUCCESS,
|
||||
FETCH_SIGNIN_FACEBOOK_SUCCESS,
|
||||
FETCH_SIGNIN_FACEBOOK_FAILURE,
|
||||
LOGOUT_SUCCESS
|
||||
LOGOUT_SUCCESS,
|
||||
FETCH_SIGNUP_FAILURE,
|
||||
AVAILABLE_FIELD,
|
||||
UNAVAILABLE_FIELD
|
||||
} from '../constants/auth';
|
||||
|
||||
const initialState = Map({
|
||||
auth: Map(),
|
||||
isLoading: false,
|
||||
loggedIn: false,
|
||||
user: null,
|
||||
showSignInDialog: false,
|
||||
view: 'SIGNIN',
|
||||
signInError: ''
|
||||
signInError: '',
|
||||
signUpError: '',
|
||||
emailAvailable: true,
|
||||
displayNameAvailable: true,
|
||||
});
|
||||
|
||||
export const getEmail = state => state.auth.formData.email;
|
||||
|
||||
export default function auth (state = initialState, action) {
|
||||
switch (action.type) {
|
||||
case SHOW_SIGNIN_DIALOG :
|
||||
@@ -60,10 +63,20 @@ export default function auth (state = initialState, action) {
|
||||
return state
|
||||
.set('error', action.error)
|
||||
.set('user', null);
|
||||
case FETCH_SIGNUP_FAILURE:
|
||||
console.log(action);
|
||||
return state
|
||||
.set('signUpError', action.error);
|
||||
case LOGOUT_SUCCESS:
|
||||
return state
|
||||
.set('loggedIn', false)
|
||||
.set('user', null);
|
||||
case AVAILABLE_FIELD:
|
||||
return state
|
||||
.set(`${action.field}Available`, true);
|
||||
case UNAVAILABLE_FIELD:
|
||||
return state
|
||||
.set(`${action.field}Available`, false);
|
||||
default :
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import React from 'react';
|
||||
import styles from './styles.css';
|
||||
|
||||
import Button from 'coral-ui/components/Button';
|
||||
import FormField from './FormField';
|
||||
import Alert from './Alert';
|
||||
import Spinner from 'coral-ui/components/Spinner';
|
||||
|
||||
import styles from './styles.css';
|
||||
import I18n from 'coral-framework/modules/i18n/i18n';
|
||||
import translations from '../translations';
|
||||
const lang = new I18n(translations);
|
||||
@@ -27,7 +25,7 @@ const SignInContent = ({handleChange, formData, ...props}) => (
|
||||
{lang.t('signIn.or')}
|
||||
</h1>
|
||||
</div>
|
||||
{ props.signInError && <Alert>{props.signInError}</Alert> }
|
||||
{ props.auth.signInError && <Alert>{props.auth.signInError}</Alert> }
|
||||
<form onSubmit={props.handleSignIn}>
|
||||
<FormField
|
||||
id="email"
|
||||
@@ -44,7 +42,7 @@ const SignInContent = ({handleChange, formData, ...props}) => (
|
||||
onChange={handleChange}
|
||||
/>
|
||||
{
|
||||
!props.isLoading ?
|
||||
!props.auth.isLoading ?
|
||||
<Button type="submit" cStyle="black" className={styles.signInButton}>
|
||||
{lang.t('signIn.signIn')}
|
||||
</Button>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import React from 'react';
|
||||
import styles from './styles.css';
|
||||
import FormField from './FormField';
|
||||
import Alert from './Alert';
|
||||
import Button from 'coral-ui/components/Button';
|
||||
import Spinner from 'coral-ui/components/Spinner';
|
||||
import styles from './styles.css';
|
||||
import I18n from 'coral-framework/modules/i18n/i18n';
|
||||
import translations from '../translations';
|
||||
const lang = new I18n(translations);
|
||||
@@ -24,6 +25,7 @@ const SignUpContent = ({handleChange, formData, ...props}) => (
|
||||
{lang.t('signIn.or')}
|
||||
</h1>
|
||||
</div>
|
||||
{ props.auth.signUpError && <Alert>{props.auth.signUpError}</Alert> }
|
||||
<form onSubmit={props.handleSignUp}>
|
||||
<FormField
|
||||
id="email"
|
||||
@@ -34,6 +36,7 @@ const SignUpContent = ({handleChange, formData, ...props}) => (
|
||||
errorMsg={props.errors.email}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
{ !props.auth.emailAvailable && <Alert>This email is not available.</Alert> }
|
||||
<FormField
|
||||
id="username"
|
||||
type="text"
|
||||
@@ -43,6 +46,7 @@ const SignUpContent = ({handleChange, formData, ...props}) => (
|
||||
errorMsg={props.errors.username}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
{ !props.auth.displayNameAvailable && <Alert>This username is not available.</Alert> }
|
||||
<FormField
|
||||
id="password"
|
||||
type="password"
|
||||
@@ -61,9 +65,8 @@ const SignUpContent = ({handleChange, formData, ...props}) => (
|
||||
errorMsg={props.errors.confirmPassword}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
|
||||
{
|
||||
!props.isLoading ?
|
||||
!props.auth.isLoading ?
|
||||
<Button type="submit" cStyle="black" className={styles.signInButton}>
|
||||
{lang.t('signIn.signUp')}
|
||||
</Button>
|
||||
|
||||
@@ -15,7 +15,8 @@ import {
|
||||
hideSignInDialog,
|
||||
fetchSignInFacebook,
|
||||
fetchForgotPassword,
|
||||
facebookCallback
|
||||
facebookCallback,
|
||||
fetchCheckAvailability
|
||||
} from '../../coral-framework/actions/auth';
|
||||
|
||||
class SignInContainer extends Component {
|
||||
@@ -76,6 +77,13 @@ class SignInContainer extends Component {
|
||||
...state,
|
||||
errors
|
||||
}));
|
||||
|
||||
// Check Availability
|
||||
|
||||
if (name === 'email' || name === 'displayName') {
|
||||
this.props.checkAvailability({[name]: value});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,14 +134,11 @@ class SignInContainer extends Component {
|
||||
Sign in to comment
|
||||
</Button>
|
||||
<SignDialog
|
||||
open={auth.get('showSignInDialog')}
|
||||
message={auth.get('message')}
|
||||
view={auth.get('view')}
|
||||
isLoading={auth.get('isLoading')}
|
||||
open={auth.showSignInDialog}
|
||||
view={auth.view}
|
||||
showErrors={showErrors}
|
||||
formData={formData}
|
||||
errors={errors}
|
||||
signInError={auth.get('signInError')}
|
||||
{...this}
|
||||
{...this.props}
|
||||
/>
|
||||
@@ -142,7 +147,9 @@ class SignInContainer extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = ({auth}) => ({auth});
|
||||
const mapStateToProps = (state) => ({
|
||||
auth: state.auth.toJS()
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
facebookCallback: (err, data) => dispatch(facebookCallback(err, data)),
|
||||
@@ -152,7 +159,8 @@ const mapDispatchToProps = dispatch => ({
|
||||
fetchForgotPassword: (formData) => dispatch(fetchForgotPassword(formData)),
|
||||
showSignInDialog: () => dispatch(showSignInDialog()),
|
||||
changeView: (view) => dispatch(changeView(view)),
|
||||
handleClose: () => dispatch(hideSignInDialog())
|
||||
handleClose: () => dispatch(hideSignInDialog()),
|
||||
checkAvailability: (formData) => dispatch(fetchCheckAvailability(formData))
|
||||
});
|
||||
|
||||
export default connect(
|
||||
|
||||
@@ -60,4 +60,48 @@ router.get('/', (req, res, next) => {
|
||||
.catch(next);
|
||||
});
|
||||
|
||||
router.post('/', (req, res, next) => {
|
||||
const {email, password, displayName} = req.query;
|
||||
|
||||
User
|
||||
.createLocalUser(email, password, displayName)
|
||||
.then(user => {
|
||||
res.status(201).send(user);
|
||||
})
|
||||
.catch(err => {
|
||||
next(err);
|
||||
});
|
||||
});
|
||||
|
||||
router.post('/availability', (req, res, next) => {
|
||||
const {email} = req.body;
|
||||
|
||||
if (email) {
|
||||
return User.count({
|
||||
profiles: {
|
||||
$elemMatch: {
|
||||
id: email,
|
||||
provider: 'local'
|
||||
}
|
||||
}
|
||||
})
|
||||
.then(count => {
|
||||
if (count) {
|
||||
res.json({
|
||||
status: 'unavailable'
|
||||
});
|
||||
} else {
|
||||
res.json({
|
||||
status: 'available'
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
next(err);
|
||||
});
|
||||
}
|
||||
|
||||
return res.status(404).send('Wrong parameters');
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
Reference in New Issue
Block a user