Pup

v1.x

AccountsEmail Verification

By default when a new user signs up, Pup will send that user an email using the verifyEmail template defined in /imports/startup/server/accounts/email-templates.js. The email verification process in Pup is non-blocking, meaning, when a user signs up they're logged in and a message is displayed at the top of the app until they verify their email address.

If you'd like to customize this behavior to be blocking, the user's current verification status is defined as a prop on the <App /> component in /imports/ui/layouts/App/App.js that you can use to control behavior in your own product.

The route used for verifying an email address is also defined in /imports/ui/layouts/App/App.js visible at the /verify-email/:token path. When a user visits this path (automatically generated when the user signs up or when they request to re-send the verification email), Meteor's Accounts.verifyEmail() method is called, passing in the token generated when the verification email is sent.

Because the verification process is relatively quick (causing a jarring user experience), a two second delay is added before the user is redirected to the /documents route if their verification is successful.

Welcome email is sent after verification

Once a user has completed verification, a call to the users.sendWelcomeEmail method defined in /imports/api/Users/methods.js is made which triggers a call to the sendWelcomeEmail() module located at /imports/api/Users/send-welcome-email.js.

/imports/startup/server/accounts/email-templates.js
import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';

const name = 'Application Name';
const email = '<support@application.com>';
const from = `${name} ${email}`;
const emailTemplates = Accounts.emailTemplates;

emailTemplates.siteName = name;
emailTemplates.from = from;

emailTemplates.verifyEmail = {
  subject() {
    return `[${name}] Verify Your Email Address`;
  },
  text(user, url) {
    const userEmail = user.emails[0].address;
    const urlWithoutHash = url.replace('#/', '');
    if (Meteor.isDevelopment) console.info(`Verify Email Link: ${urlWithoutHash}`); // eslint-disable-line
    return `Hey, ${user.profile.name.first}! Welcome to ${name}.\n\nTo verify your email address (${userEmail}), click the link below:\n\n${urlWithoutHash}\n\nIf you feel something is wrong, please contact our support team: ${email}.`;
  },
};

[...]
/imports/ui/pages/VerifyEmail/VerifyEmail.js
import React from 'react';
import PropTypes from 'prop-types';
import { Alert } from 'react-bootstrap';
import { Accounts } from 'meteor/accounts-base';
import { Bert } from 'meteor/themeteorchef:bert';

class VerifyEmail extends React.Component {
  constructor(props) {
    super(props);
    this.state = { error: null };
  }

  componentDidMount() {
    const { match, history } = this.props;
    Accounts.verifyEmail(match.params.token, (error) => {
      if (error) {
        Bert.alert(error.reason, 'danger');
        this.setState({ error: `${error.reason}. Please try again.` });
      } else {
        setTimeout(() => {
          Bert.alert('All set, thanks!', 'success');
          history.push('/documents');
        }, 2000);
      }
    });
  }

  render() {
    return (<div className="VerifyEmail">
      <Alert bsStyle={!this.state.error ? 'info' : 'danger'}>
        {!this.state.error ? 'Verifying...' : this.state.error}
      </Alert>
    </div>);
  }
}

VerifyEmail.propTypes = {
  match: PropTypes.object.isRequired,
  history: PropTypes.object.isRequired,
};

export default VerifyEmail;