Merge branch 'master' into username-ban

This commit is contained in:
David Jay
2017-02-06 18:14:13 -08:00
committed by GitHub
16 changed files with 287 additions and 200 deletions
+1 -1
View File
@@ -50,7 +50,7 @@
"configure": {
"enable-pre-moderation": "Enable pre-moderation",
"enable-pre-moderation-text": "Moderators must approve any comment before it is published.",
"require-email-verification": "Require Email Confirmation",
"require-email-verification": "Require Email Verification",
"require-email-verification-text": "New Users must verify their email before commenting",
"include-comment-stream": "Include Comment Stream Description for Readers.",
"include-comment-stream-desc": "Write a message to be added to the top of your comment stream. Pose a topic, include community guidelines, etc.",
+1 -1
View File
@@ -138,7 +138,7 @@ class Embed extends Component {
</div>
: <p>{asset.settings.closedMessage}</p>
}
{!loggedIn && <SignInContainer offset={signInOffset}/>}
{!loggedIn && <SignInContainer requireEmailConfirmation={asset.settings.requireEmailConfirmation} offset={signInOffset}/>}
{loggedIn && user && <ChangeDisplayNameContainer loggedIn={loggedIn} offset={signInOffset} user={user} />}
<Stream
refetch={refetch}
+12 -17
View File
@@ -43,7 +43,6 @@ export const cleanState = () => ({type: actions.CLEAN_STATE});
const signInRequest = () => ({type: actions.FETCH_SIGNIN_REQUEST});
const signInSuccess = (user, isAdmin) => ({type: actions.FETCH_SIGNIN_SUCCESS, user, isAdmin});
const signInFailure = error => ({type: actions.FETCH_SIGNIN_FAILURE, error});
const emailConfirmError = () => ({type: actions.EMAIL_CONFIRM_ERROR});
export const fetchSignIn = (formData) => (dispatch) => {
dispatch(signInRequest());
@@ -58,7 +57,6 @@ export const fetchSignIn = (formData) => (dispatch) => {
// the user might not have a valid email. prompt the user user re-request the confirmation email
dispatch(signInFailure(lang.t('error.emailNotVerified', error.metadata)));
dispatch(emailConfirmError());
} else {
// invalid credentials
@@ -117,15 +115,12 @@ 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) => {
export const fetchSignUp = (formData, redirectUri) => (dispatch) => {
dispatch(signUpRequest());
coralApi('/users', {method: 'POST', body: formData})
coralApi('/users', {method: 'POST', body: formData, headers: {'X-Pym-Url': redirectUri}})
.then(({user}) => {
dispatch(signUpSuccess(user));
setTimeout(() =>{
dispatch(changeView('SIGNIN'));
}, 3000);
})
.catch(error => {
dispatch(signUpFailure(lang.t(`error.${error.message}`)));
@@ -186,20 +181,20 @@ export const checkLogin = () => dispatch => {
});
};
const confirmEmailRequest = () => ({type: actions.CONFIRM_EMAIL_REQUEST});
const confirmEmailSuccess = () => ({type: actions.CONFIRM_EMAIL_SUCCESS});
const confirmEmailFailure = () => ({type: actions.CONFIRM_EMAIL_FAILURE});
const verifyEmailRequest = () => ({type: actions.VERIFY_EMAIL_REQUEST});
const verifyEmailSuccess = () => ({type: actions.VERIFY_EMAIL_SUCCESS});
const verifyEmailFailure = () => ({type: actions.VERIFY_EMAIL_FAILURE});
export const requestConfirmEmail = email => dispatch => {
dispatch(confirmEmailRequest());
return coralApi('/users/resend-confirm', {method: 'POST', body: {email}})
export const requestConfirmEmail = (email, redirectUri) => dispatch => {
dispatch(verifyEmailRequest());
return coralApi('/users/resend-verify', {method: 'POST', body: {email}, headers: {'X-Pym-Url': redirectUri}})
.then(() => {
dispatch(confirmEmailSuccess());
dispatch(verifyEmailSuccess());
})
.catch(err => {
console.log('failed to send email confirmation', err);
console.log('failed to send email verification', err);
// email might have already been confirmed
dispatch(confirmEmailFailure());
// email might have already been verifyed
dispatch(verifyEmailFailure());
});
};
+3 -4
View File
@@ -41,8 +41,7 @@ export const CHECK_LOGIN_FAILURE = 'CHECK_LOGIN_FAILURE';
export const CHECK_CSRF_TOKEN = 'CHECK_CSRF_TOKEN';
export const VERIFY_EMAIL_REQUEST = 'VERIFY_EMAIL_REQUEST';
export const VERIFY_EMAIL_SUCCESS = 'VERIFY_EMAIL_SUCCESS';
export const VERIFY_EMAIL_FAILURE = 'VERIFY_EMAIL_FAILURE';
export const UPDATE_DISPLAYNAME = 'UPDATE_DISPLAYNAME';
export const EMAIL_CONFIRM_ERROR = 'EMAIL_CONFIRM_ERROR';
export const CONFIRM_EMAIL_REQUEST = 'CONFIRM_EMAIL_REQUEST';
export const CONFIRM_EMAIL_SUCCESS = 'CONFIRM_EMAIL_SUCCESS';
export const CONFIRM_EMAIL_FAILURE = 'CONFIRM_EMAIL_FAILURE';
+2 -1
View File
@@ -14,7 +14,8 @@ const buildOptions = (inputOptions = {}) => {
_csrf: csurfDOM ? csurfDOM.content : false
};
const options = Object.assign({}, defaultOptions, inputOptions);
let options = Object.assign({}, defaultOptions, inputOptions);
options.headers = Object.assign({}, defaultOptions.headers, inputOptions.headers);
if (options._csrf) {
switch (options.method.toLowerCase()) {
+14 -14
View File
@@ -12,9 +12,9 @@ const initialState = Map({
error: '',
passwordRequestSuccess: null,
passwordRequestFailure: null,
emailConfirmationFailure: false,
emailConfirmationLoading: false,
emailConfirmationSuccess: false,
emailVerificationFailure: false,
emailVerificationLoading: false,
emailVerificationSuccess: false,
successSignUp: false,
fromSignUp: false
});
@@ -38,9 +38,9 @@ export default function auth (state = initialState, action) {
error: '',
passwordRequestFailure: null,
passwordRequestSuccess: null,
emailConfirmationFailure: false,
emailConfirmationSuccess: false,
emailConfirmationLoading: false,
emailVerificationFailure: false,
emailVerificationSuccess: false,
emailVerificationLoading: false,
successSignUp: false
}));
case actions.SHOW_CREATEDISPLAYNAME_DIALOG :
@@ -134,16 +134,16 @@ export default function auth (state = initialState, action) {
console.log('Action', action);
return state
.setIn(['user', 'displayName'], action.displayName);
case actions.EMAIL_CONFIRM_ERROR:
case actions.VERIFY_EMAIL_FAILURE:
return state
.set('emailConfirmationFailure', true)
.set('emailConfirmationLoading', false);
case actions.CONFIRM_EMAIL_REQUEST:
return state.set('emailConfirmationLoading', true);
case actions.CONFIRM_EMAIL_SUCCESS:
.set('emailVerificationFailure', true)
.set('emailVerificationLoading', false);
case actions.VERIFY_EMAIL_REQUEST:
return state.set('emailVerificationLoading', true);
case actions.VERIFY_EMAIL_SUCCESS:
return state
.set('emailConfirmationSuccess', true)
.set('emailConfirmationLoading', false);
.set('emailVerificationSuccess', true)
.set('emailVerificationLoading', false);
default :
return state;
}
@@ -17,12 +17,7 @@ const SignDialog = ({open, view, handleClose, offset, ...props}) => (
}}>
<span className={styles.close} onClick={handleClose}>×</span>
{view === 'SIGNIN' && <SignInContent {...props} />}
{
view === 'SIGNUP' && <SignUpContent
emailConfirmationLoading={props.emailConfirmationLoading}
emailConfirmationSuccess={props.emailConfirmationSuccess}
{...props} />
}
{view === 'SIGNUP' && <SignUpContent {...props} />}
{view === 'FORGOT' && <ForgotContent {...props} />}
</Dialog>
);
@@ -10,35 +10,28 @@ const SignInContent = ({
handleChange,
handleChangeEmail,
emailToBeResent,
handleResendConfirmation,
emailConfirmationLoading,
emailConfirmationSuccess,
handleResendVerification,
emailVerificationLoading,
emailVerificationSuccess,
formData,
...props
changeView,
handleSignIn,
auth,
fetchSignInFacebook
}) => {
return (
<div>
<div className={styles.header}>
<h1>
{props.auth.emailConfirmationFailure ? lang.t('signIn.emailConfirmCTA') : lang.t('signIn.signIn')}
{auth.emailVerificationFailure ? lang.t('signIn.emailVerifyCTA') : lang.t('signIn.signIn')}
</h1>
</div>
<div className={styles.socialConnections}>
<Button cStyle="facebook" onClick={props.fetchSignInFacebook} full>
{lang.t('signIn.facebookSignIn')}
</Button>
</div>
<div className={styles.separator}>
<h1>
{lang.t('signIn.or')}
</h1>
</div>
{ props.auth.error && <Alert>{props.auth.error}</Alert> }
{ auth.error && <Alert>{auth.error}</Alert> }
{
props.auth.emailConfirmationFailure
? <form onSubmit={handleResendConfirmation}>
<p>{lang.t('signIn.requestNewConfirmEmail')}</p>
auth.emailVerificationFailure
? <form onSubmit={handleResendVerification}>
<p>{lang.t('signIn.requestNewVerifyEmail')}</p>
<FormField
id="confirm-email"
type="email"
@@ -46,41 +39,53 @@ const SignInContent = ({
value={emailToBeResent}
onChange={handleChangeEmail} />
<Button id='resendConfirmEmail' type='submit' cStyle='black' full>Send Email</Button>
{emailConfirmationLoading && <Spinner />}
{emailConfirmationSuccess && <Success />}
{emailVerificationLoading && <Spinner />}
{emailVerificationSuccess && <Success />}
</form>
: <form onSubmit={props.handleSignIn}>
<FormField
id="email"
type="email"
label={lang.t('signIn.email')}
value={formData.email}
onChange={handleChange}
/>
<FormField
id="password"
type="password"
label={lang.t('signIn.password')}
value={formData.password}
onChange={handleChange}
/>
<div className={styles.action}>
{
!props.auth.isLoading ?
<Button id='coralLogInButton' type="submit" cStyle="black" className={styles.signInButton} full>
{lang.t('signIn.signIn')}
</Button>
:
<Spinner />
}
: <div>
<div className={styles.socialConnections}>
<Button cStyle="facebook" onClick={fetchSignInFacebook} full>
{lang.t('signIn.facebookSignIn')}
</Button>
</div>
</form>
<div className={styles.separator}>
<h1>
{lang.t('signIn.or')}
</h1>
</div>
<form onSubmit={handleSignIn}>
<FormField
id="email"
type="email"
label={lang.t('signIn.email')}
value={formData.email}
onChange={handleChange}
/>
<FormField
id="password"
type="password"
label={lang.t('signIn.password')}
value={formData.password}
onChange={handleChange}
/>
<div className={styles.action}>
{
!auth.isLoading ?
<Button id='coralLogInButton' type="submit" cStyle="black" className={styles.signInButton} full>
{lang.t('signIn.signIn')}
</Button>
:
<Spinner />
}
</div>
</form>
</div>
}
<div className={styles.footer}>
<span><a onClick={() => props.changeView('FORGOT')}>{lang.t('signIn.forgotYourPass')}</a></span>
<span><a onClick={() => changeView('FORGOT')}>{lang.t('signIn.forgotYourPass')}</a></span>
<span>
{lang.t('signIn.needAnAccount')}
<a onClick={() => props.changeView('SIGNUP')} id='coralRegister'>
<a onClick={() => changeView('SIGNUP')} id='coralRegister'>
{lang.t('signIn.register')}
</a>
</span>
@@ -90,9 +95,17 @@ const SignInContent = ({
};
SignInContent.propTypes = {
emailConfirmationLoading: PropTypes.bool.isRequired,
emailConfirmationSuccess: PropTypes.bool.isRequired,
handleResendConfirmation: PropTypes.func.isRequired,
auth: PropTypes.shape({
isLoading: PropTypes.bool.isRequired,
error: PropTypes.object,
emailVerificationFailure: PropTypes.bool
}).isRequired,
fetchSignInFacebook: PropTypes.func.isRequired,
handleSignIn: PropTypes.func.isRequired,
changeView: PropTypes.func.isRequired,
emailVerificationLoading: PropTypes.bool.isRequired,
emailVerificationSuccess: PropTypes.bool.isRequired,
handleResendVerification: PropTypes.func.isRequired,
handleChangeEmail: PropTypes.func.isRequired,
emailToBeResent: PropTypes.string.isRequired
};
+142 -77
View File
@@ -1,4 +1,4 @@
import React from 'react';
import React, {PropTypes} from 'react';
import Alert from './Alert';
import {Button, FormField, Spinner, Success} from 'coral-ui';
import styles from './styles.css';
@@ -6,83 +6,148 @@ import I18n from 'coral-framework/modules/i18n/i18n';
import translations from '../translations';
const lang = new I18n(translations);
const SignUpContent = ({handleChange, formData, ...props}) => (
<div>
<div className={styles.header}>
<h1>
{lang.t('signIn.signUp')}
</h1>
</div>
<div className={styles.socialConnections}>
<Button cStyle="facebook" onClick={props.fetchSignUpFacebook} full>
{lang.t('signIn.facebookSignUp')}
</Button>
</div>
<div className={styles.separator}>
<h1>
{lang.t('signIn.or')}
</h1>
</div>
{ props.auth.error && <Alert>{props.auth.error}</Alert> }
<form onSubmit={props.handleSignUp}>
<FormField
id="email"
type="email"
label={lang.t('signIn.email')}
value={formData.email}
showErrors={props.showErrors}
errorMsg={props.errors.email}
onChange={handleChange}
/>
<FormField
id="displayName"
type="text"
label={lang.t('signIn.displayName')}
value={formData.displayName}
showErrors={props.showErrors}
errorMsg={props.errors.displayName}
onChange={handleChange}
/>
<FormField
id="password"
type="password"
label={lang.t('signIn.password')}
value={formData.password}
showErrors={props.showErrors}
errorMsg={props.errors.password}
onChange={handleChange}
minLength="8"
/>
{ props.errors.password && <span className={styles.hint}> Password must be at least 8 characters. </span> }
<FormField
id="confirmPassword"
type="password"
label={lang.t('signIn.confirmPassword')}
value={formData.confirmPassword}
showErrors={props.showErrors}
errorMsg={props.errors.confirmPassword}
onChange={handleChange}
minLength="8"
/>
<div className={styles.action}>
{ !props.auth.isLoading && !props.auth.successSignUp && (
<Button type="submit" cStyle="black" id='coralSignUpButton' className={styles.signInButton} full>
class SignUpContent extends React.Component {
constructor (props) {
super(props);
this.successfulSignup = false;
}
static propTypes = {
emailVerificationEnabled: PropTypes.bool.isRequired,
fetchSignUpFacebook: PropTypes.func.isRequired,
changeView: PropTypes.func.isRequired,
handleSignUp: PropTypes.func.isRequired,
showErrors: PropTypes.bool,
errors: PropTypes.shape({
email: PropTypes.string,
displayName: PropTypes.string,
password: PropTypes.string,
confirmPassword: PropTypes.string,
}),
formData: PropTypes.shape({
email: PropTypes.string,
displayName: PropTypes.string,
password: PropTypes.string,
confirmPassword: PropTypes.string
})
}
render () {
const {
handleChange,
formData,
emailVerificationEnabled,
auth,
errors,
showErrors,
changeView,
handleSignUp,
fetchSignUpFacebook} = this.props;
const beforeSignup = !auth.isLoading && !auth.successSignUp;
const successfulSignup = !auth.isLoading && auth.successSignUp;
// the first time we render a successfulSignup, trigger a timer
if ((this.successfulSignup ^ successfulSignup) && !emailVerificationEnabled) {
setTimeout(() => {
changeView('SIGNIN');
}, 1000);
this.successfulSignup = true;
}
return (
<div>
<div className={styles.header}>
<h1>
{lang.t('signIn.signUp')}
</Button>
)}
{ props.auth.isLoading && <Spinner /> }
{ !props.auth.isLoading && props.auth.successSignUp && <Success /> }
</h1>
</div>
{ auth.error && <Alert>{auth.error}</Alert> }
{ beforeSignup &&
<div>
<div className={styles.socialConnections}>
<Button cStyle="facebook" onClick={fetchSignUpFacebook} full>
{lang.t('signIn.facebookSignUp')}
</Button>
</div>
<div className={styles.separator}>
<h1>
{lang.t('signIn.or')}
</h1>
</div>
<form onSubmit={handleSignUp}>
<FormField
id="email"
type="email"
label={lang.t('signIn.email')}
value={formData.email}
showErrors={showErrors}
errorMsg={errors.email}
onChange={handleChange}
/>
<FormField
id="displayName"
type="text"
label={lang.t('signIn.displayName')}
value={formData.displayName}
showErrors={showErrors}
errorMsg={errors.displayName}
onChange={handleChange}
/>
<FormField
id="password"
type="password"
label={lang.t('signIn.password')}
value={formData.password}
showErrors={showErrors}
errorMsg={errors.password}
onChange={handleChange}
minLength="8"
/>
{ errors.password && <span className={styles.hint}> Password must be at least 8 characters. </span> }
<FormField
id="confirmPassword"
type="password"
label={lang.t('signIn.confirmPassword')}
value={formData.confirmPassword}
showErrors={showErrors}
errorMsg={errors.confirmPassword}
onChange={handleChange}
minLength="8"
/>
<div className={styles.action}>
<Button type="submit" cStyle="black" id='coralSignUpButton' className={styles.signInButton} full>
{lang.t('signIn.signUp')}
</Button>
{ auth.isLoading && <Spinner /> }
</div>
</form>
</div>
}
{
successfulSignup &&
<div>
<Success />
{
emailVerificationEnabled &&
<p>{lang.t('signIn.verifyEmail')}<br /><br />{lang.t('signIn.verifyEmail2')}</p>
}
</div>
}
<div className={styles.footer}>
<span>
{lang.t('signIn.alreadyHaveAnAccount')}
<a id="coralSignInViewTrigger" onClick={() => changeView('SIGNIN')}>
{lang.t('signIn.signIn')}
</a>
</span>
</div>
</div>
</form>
<div className={styles.footer}>
<span>
{lang.t('signIn.alreadyHaveAnAccount')}
<a onClick={() => props.changeView('SIGNIN')}>
{lang.t('signIn.signIn')}
</a>
</span>
</div>
</div>
);
);
}
}
export default SignUpContent;
@@ -1,4 +1,4 @@
import React, {Component} from 'react';
import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import SignDialog from '../components/SignDialog';
import Button from 'coral-ui/components/Button';
@@ -6,6 +6,7 @@ import validate from 'coral-framework/helpers/validate';
import errorMsj from 'coral-framework/helpers/error';
import I18n from 'coral-framework/modules/i18n/i18n';
import translations from '../translations';
import {pym} from 'coral-framework';
const lang = new I18n(translations);
import {
@@ -42,12 +43,16 @@ class SignInContainer extends Component {
this.state = this.initialState;
this.handleChange = this.handleChange.bind(this);
this.handleChangeEmail = this.handleChangeEmail.bind(this);
this.handleResendConfirmation = this.handleResendConfirmation.bind(this);
this.handleResendVerification = this.handleResendVerification.bind(this);
this.handleSignUp = this.handleSignUp.bind(this);
this.handleSignIn = this.handleSignIn.bind(this);
this.addError = this.addError.bind(this);
}
static propTypes = {
requireEmailConfirmation: PropTypes.bool.isRequired
}
componentWillMount () {
this.props.checkLogin();
}
@@ -80,9 +85,9 @@ class SignInContainer extends Component {
this.setState({emailToBeResent: value});
}
handleResendConfirmation(e) {
handleResendVerification(e) {
e.preventDefault();
this.props.requestConfirmEmail(this.state.emailToBeResent)
this.props.requestConfirmEmail(this.state.emailToBeResent, pym.parentUrl || location.href)
.then(() => {
setTimeout(() => {
@@ -133,7 +138,7 @@ class SignInContainer extends Component {
const {fetchSignUp, validForm, invalidForm} = this.props;
this.displayErrors();
if (this.isCompleted() && !Object.keys(errors).length) {
fetchSignUp(this.state.formData);
fetchSignUp(this.state.formData, pym.parentUrl || location.href);
validForm();
} else {
invalidForm(lang.t('signIn.checkTheForm'));
@@ -146,8 +151,9 @@ class SignInContainer extends Component {
}
render() {
const {auth, showSignInDialog, noButton, offset} = this.props;
const {emailConfirmationLoading, emailConfirmationSuccess} = auth;
const {auth, showSignInDialog, noButton, offset, requireEmailConfirmation} = this.props;
const {emailVerificationLoading, emailVerificationSuccess} = auth;
return (
<div>
{!noButton && <Button id='coralSignInButton' onClick={showSignInDialog} full>
@@ -157,8 +163,9 @@ class SignInContainer extends Component {
open={auth.showSignInDialog}
view={auth.view}
offset={offset}
emailConfirmationLoading={emailConfirmationLoading}
emailConfirmationSuccess={emailConfirmationSuccess}
emailVerificationEnabled={requireEmailConfirmation}
emailVerificationLoading={emailVerificationLoading}
emailVerificationSuccess={emailVerificationSuccess}
{...this}
{...this.state}
{...this.props}
@@ -175,12 +182,12 @@ const mapStateToProps = state => ({
const mapDispatchToProps = dispatch => ({
checkLogin: () => dispatch(checkLogin()),
facebookCallback: (err, data) => dispatch(facebookCallback(err, data)),
fetchSignUp: formData => dispatch(fetchSignUp(formData)),
fetchSignUp: (formData, url) => dispatch(fetchSignUp(formData, url)),
fetchSignIn: formData => dispatch(fetchSignIn(formData)),
fetchSignInFacebook: () => dispatch(fetchSignInFacebook()),
fetchSignUpFacebook: () => dispatch(fetchSignUpFacebook()),
fetchForgotPassword: formData => dispatch(fetchForgotPassword(formData)),
requestConfirmEmail: email => dispatch(requestConfirmEmail(email)),
requestConfirmEmail: (email, url) => dispatch(requestConfirmEmail(email, url)),
showSignInDialog: () => dispatch(showSignInDialog()),
changeView: view => dispatch(changeView(view)),
handleClose: () => dispatch(hideSignInDialog()),
+8 -4
View File
@@ -1,8 +1,10 @@
export default {
en: {
'signIn': {
emailConfirmCTA: 'Please verify your email address.',
requestNewConfirmEmail: 'Request another email:',
emailVerifyCTA: 'Please verify your email address.',
requestNewVerifyEmail: 'Request another email:',
verifyEmail: 'Thank you for creating an account! We sent an email to the address you provided to verify your account.',
verifyEmail2: 'You must verify your account before engaging with the community.',
notYou: 'Not you?',
loggedInAs: 'Logged in as',
facebookSignIn: 'Sign in with Facebook',
@@ -40,8 +42,10 @@ export default {
},
es: {
'signIn': {
emailConfirmCTA: 'Por favor verifique su correo electronico.',
requestNewConfirmEmail: 'Enviar otro correo:',
emailVerifyCTA: 'Por favor verifique su correo electronico.',
requestNewVerifyEmail: 'Enviar otro correo:',
verifyEmail: '¡Gracias por crear una cuenta! Le enviamos un correo a la dirección que dio para verificar su cuenta.',
verifyEmail2: 'Debe verificarla antes de poder involucrarse en la comunidad.',
notYou: 'No eres tu?',
loggedInAs: 'Entraste como',
facebookSignIn: 'Entrar con Facebook',
+1 -1
View File
@@ -16,7 +16,7 @@ router.get('/', authorization.needed(), (req, res, next) => {
// POST /email/confirm takes the password confirmation token available as a
// payload parameter and if it verifies, it updates the confirmed_at date on the
// local profile.
router.post('/email/confirm', (req, res, next) => {
router.post('/email/verify', (req, res, next) => {
const {
token
+3 -3
View File
@@ -128,7 +128,7 @@ const SendEmailConfirmation = (app, userID, email, referer) => UsersService
// create a local user.
router.post('/', (req, res, next) => {
const {email, password, displayName} = req.body;
const redirectUri = req.header('Referer');
const redirectUri = req.header('X-Pym-Url') || req.header('Referer');
UsersService
.createLocalUser(email, password, displayName)
@@ -187,9 +187,9 @@ router.post('/:user_id/actions', authorization.needed(), (req, res, next) => {
});
// trigger an email confirmation re-send by a new user
router.post('/resend-confirm', (req, res, next) => {
router.post('/resend-verify', (req, res, next) => {
const {email} = req.body;
const redirectUri = req.header('Referer');
const redirectUri = req.header('X-Pym-Url') || req.header('Referer');
if (!email) {
return next(errors.ErrMissingEmail);
+5
View File
@@ -22,6 +22,8 @@ const embedStreamCommands = {
.setValue('@signUpDialogDisplayName', user.displayName)
.waitForElementVisible('@signUpButton')
.click('@signUpButton')
.waitForElementVisible('@signInViewTrigger')
.click('@signInViewTrigger')
.waitForElementVisible('@logInButton')
.click('@logInButton')
.waitForElementVisible('@logoutButton', 5000);
@@ -102,6 +104,9 @@ module.exports = {
signUpButton: {
selector: '#coralSignUpButton'
},
signInViewTrigger: {
selector: '#coralSignInViewTrigger'
},
logoutButton: {
selector: '.commentStream #logout'
},
+5 -2
View File
@@ -4,8 +4,10 @@ const mocks = require('../mocks');
const mockComment = 'I read the comments';
const mockReply = 'This is a test reply';
const mockUser = {
email: `${new Date().getTime()}@test.com`,
name: 'testuser',
email: `${Date.now()}@test.com`,
name: `testuser${Math.random()
.toString()
.slice(-5)}`,
pw: 'testtest'
};
@@ -39,6 +41,7 @@ module.exports = {
.setValue('#password', mockUser.pw)
.setValue('#confirmPassword', mockUser.pw)
.click('#coralSignUpButton')
.pause(5000)
.waitForElementVisible('#coralLogInButton', 10000)
.click('#coralLogInButton')
.waitForElementVisible('.coral-plugin-commentbox-button', 4000)
+7 -7
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1">
<title>Confirm Email</title>
<title>Email Verification</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="https://code.getmdl.io/1.2.1/material.indigo-pink.min.css">
@@ -43,14 +43,14 @@
<div id="root">
<div class="coral-card-wide mdl-card mdl-shadow--2dp">
<div class="mdl-card__title">
<h2 class="mdl-card__title-text">Confirm Email Address</h2>
<h2 class="mdl-card__title-text">Verify Email Address</h2>
</div>
<div class="mdl-card__supporting-text">
Click the button below to confirm your new user account.
Click the button below to verify the email on your new user account.
</div>
<div class="mdl-card__actions mdl-card--border">
<a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect" id="confirm-email">
Confirm
<a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect" id="verify-email">
Verify
</a>
<div style="display: none" id="p2" class="mdl-progress mdl-js-progress mdl-progress__indeterminate"></div>
</div>
@@ -71,7 +71,7 @@
$('.error-console').removeClass('active');
$.ajax({
url: '/api/v1/account/email/confirm',
url: '/api/v1/account/email/verify',
contentType: 'application/json',
method: 'POST',
headers: {
@@ -85,7 +85,7 @@
});
}
$('#confirm-email').on('click', handleClick);
$('#verify-email').on('click', handleClick);
});
</script>
</body>