User Email Availability check

This commit is contained in:
Belen Curcio
2016-11-16 16:55:47 -03:00
parent 954f6d9ee3
commit bd47495b63
8 changed files with 128 additions and 29 deletions
+32 -8
View File
@@ -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));
};
+7
View File
@@ -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) {
+18 -5
View File
@@ -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(
+44
View File
@@ -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;