summaryrefslogtreecommitdiffstats
path: root/webapp/components/signup
diff options
context:
space:
mode:
authorDavid Lu <david.lu97@outlook.com>2016-08-22 15:33:01 -0400
committerJoram Wilander <jwawilander@gmail.com>2016-08-22 15:33:01 -0400
commitca351b617fc1d412d1a4ae37835a697468769fe6 (patch)
treecc4e776d405b3a6c1d7fa6f627fc57e60734a143 /webapp/components/signup
parent391d685aa4d05cc4316d4770d47eed16dcfb650c (diff)
downloadchat-ca351b617fc1d412d1a4ae37835a697468769fe6.tar.gz
chat-ca351b617fc1d412d1a4ae37835a697468769fe6.tar.bz2
chat-ca351b617fc1d412d1a4ae37835a697468769fe6.zip
PLT-2951 Improved signup process (#3771)
Diffstat (limited to 'webapp/components/signup')
-rw-r--r--webapp/components/signup/components/signup_email.jsx507
-rw-r--r--webapp/components/signup/components/signup_ldap.jsx233
-rw-r--r--webapp/components/signup/signup_controller.jsx333
3 files changed, 1073 insertions, 0 deletions
diff --git a/webapp/components/signup/components/signup_email.jsx b/webapp/components/signup/components/signup_email.jsx
new file mode 100644
index 000000000..2d4b3f277
--- /dev/null
+++ b/webapp/components/signup/components/signup_email.jsx
@@ -0,0 +1,507 @@
+// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+import LoadingScreen from 'components/loading_screen.jsx';
+
+import * as GlobalActions from 'actions/global_actions.jsx';
+import {track} from 'actions/analytics_actions.jsx';
+
+import BrowserStore from 'stores/browser_store.jsx';
+
+import * as Utils from 'utils/utils.jsx';
+import Client from 'client/web_client.jsx';
+import Constants from 'utils/constants.jsx';
+
+import React from 'react';
+import {FormattedMessage, FormattedHTMLMessage} from 'react-intl';
+import {browserHistory, Link} from 'react-router/es6';
+
+import logoImage from 'images/logo.png';
+
+export default class SignupEmail extends React.Component {
+ static get propTypes() {
+ return {
+ location: React.PropTypes.object
+ };
+ }
+
+ constructor(props) {
+ super(props);
+
+ this.handleSubmit = this.handleSubmit.bind(this);
+
+ this.getInviteInfo = this.getInviteInfo.bind(this);
+ this.renderEmailSignup = this.renderEmailSignup.bind(this);
+ this.isUserValid = this.isUserValid.bind(this);
+
+ this.state = this.getInviteInfo();
+ }
+
+ getInviteInfo() {
+ let data = this.props.location.query.d;
+ let hash = this.props.location.query.h;
+ const inviteId = this.props.location.query.id;
+ let email = '';
+ let teamDisplayName = '';
+ let teamName = '';
+ let teamId = '';
+ let loading = true;
+ let serverError = '';
+ let noOpenServerError = false;
+
+ if (hash && hash.length > 0) {
+ const parsedData = JSON.parse(data);
+ email = parsedData.email;
+ teamDisplayName = parsedData.display_name;
+ teamName = parsedData.name;
+ teamId = parsedData.id;
+ loading = false;
+ } else if (inviteId && inviteId.length > 0) {
+ loading = true;
+ Client.getInviteInfo(
+ inviteId,
+ (inviteData) => {
+ if (!inviteData) {
+ return;
+ }
+
+ serverError = '';
+ teamDisplayName = inviteData.display_name;
+ teamName = inviteData.name;
+ teamId = inviteData.id;
+ },
+ () => {
+ noOpenServerError = true;
+ serverError = (
+ <FormattedMessage
+ id='signup_user_completed.invalid_invite'
+ defaultMessage='The invite link was invalid. Please speak with your Administrator to receive an invitation.'
+ />
+ );
+ }
+ );
+
+ loading = false;
+ data = null;
+ hash = null;
+ } else {
+ loading = false;
+ }
+
+ return {
+ data,
+ hash,
+ email,
+ teamDisplayName,
+ teamName,
+ teamId,
+ inviteId,
+ loading,
+ serverError,
+ noOpenServerError
+ };
+ }
+
+ finishSignup() {
+ GlobalActions.emitInitialLoad(
+ () => {
+ const query = this.props.location.query;
+ GlobalActions.loadDefaultLocale();
+ if (query.redirect_to) {
+ browserHistory.push(query.redirect_to);
+ } else {
+ browserHistory.push('/select_team');
+ }
+ }
+ );
+ }
+
+ handleSignupSuccess(user, data) {
+ track('signup', 'signup_user_02_complete');
+ Client.loginById(
+ data.id,
+ user.password,
+ '',
+ () => {
+ if (this.state.hash > 0) {
+ BrowserStore.setGlobalItem(this.state.hash, JSON.stringify({usedBefore: true}));
+ }
+
+ GlobalActions.emitInitialLoad(
+ () => {
+ const query = this.props.location.query;
+ if (query.redirect_to) {
+ browserHistory.push(query.redirect_to);
+ } else {
+ browserHistory.push('/select_team');
+ }
+ }
+ );
+ },
+ (err) => {
+ if (err.id === 'api.user.login.not_verified.app_error') {
+ browserHistory.push('/should_verify_email?email=' + encodeURIComponent(user.email) + '&teamname=' + encodeURIComponent(this.state.teamName));
+ } else {
+ this.setState({serverError: err.message});
+ }
+ }
+ );
+ }
+
+ isUserValid() {
+ const providedEmail = this.refs.email.value.trim();
+ if (!providedEmail) {
+ this.setState({
+ nameError: '',
+ emailError: (<FormattedMessage id='signup_user_completed.required'/>),
+ passwordError: '',
+ serverError: ''
+ });
+ return false;
+ }
+
+ if (!Utils.isEmail(providedEmail)) {
+ this.setState({
+ nameError: '',
+ emailError: (<FormattedMessage id='signup_user_completed.validEmail'/>),
+ passwordError: '',
+ serverError: ''
+ });
+ return false;
+ }
+
+ const providedUsername = this.refs.name.value.trim().toLowerCase();
+ if (!providedUsername) {
+ this.setState({
+ nameError: (<FormattedMessage id='signup_user_completed.required'/>),
+ emailError: '',
+ passwordError: '',
+ serverError: ''
+ });
+ return false;
+ }
+
+ const usernameError = Utils.isValidUsername(providedUsername);
+ if (usernameError === 'Cannot use a reserved word as a username.') {
+ this.setState({
+ nameError: (<FormattedMessage id='signup_user_completed.reserved'/>),
+ emailError: '',
+ passwordError: '',
+ serverError: ''
+ });
+ return false;
+ } else if (usernameError) {
+ this.setState({
+ nameError: (
+ <FormattedMessage
+ id='signup_user_completed.usernameLength'
+ values={{
+ min: Constants.MIN_USERNAME_LENGTH,
+ max: Constants.MAX_USERNAME_LENGTH
+ }}
+ />
+ ),
+ emailError: '',
+ passwordError: '',
+ serverError: ''
+ });
+ return false;
+ }
+
+ const providedPassword = this.refs.password.value;
+ const pwdError = Utils.isValidPassword(providedPassword);
+ if (pwdError) {
+ this.setState({
+ nameError: '',
+ emailError: '',
+ passwordError: pwdError,
+ serverError: ''
+ });
+ return false;
+ }
+
+ return true;
+ }
+
+ handleSubmit(e) {
+ e.preventDefault();
+
+ if (this.isUserValid()) {
+ this.setState({
+ nameError: '',
+ emailError: '',
+ passwordError: '',
+ serverError: ''
+ });
+
+ const user = {
+ email: this.refs.email.value.trim(),
+ username: this.refs.name.value.trim().toLowerCase(),
+ password: this.refs.password.value,
+ allow_marketing: true
+ };
+
+ Client.createUserWithInvite(user,
+ this.state.data,
+ this.state.hash,
+ this.state.inviteId,
+ this.handleSignupSuccess.bind(this, user),
+ (err) => {
+ this.setState({serverError: err.message});
+ }
+ );
+ }
+ }
+
+ renderEmailSignup() {
+ let emailError = null;
+ let emailHelpText = (
+ <span className='help-block'>
+ <FormattedMessage
+ id='signup_user_completed.emailHelp'
+ defaultMessage='Valid email required for sign-up'
+ />
+ </span>
+ );
+ let emailDivStyle = 'form-group';
+ if (this.state.emailError) {
+ emailError = (<label className='control-label'>{this.state.emailError}</label>);
+ emailHelpText = '';
+ emailDivStyle += ' has-error';
+ }
+
+ let nameError = null;
+ let nameHelpText = (
+ <span className='help-block'>
+ <FormattedMessage
+ id='signup_user_completed.userHelp'
+ defaultMessage="Username must begin with a letter, and contain between {min} to {max} lowercase characters made up of numbers, letters, and the symbols '.', '-' and '_'"
+ values={{
+ min: Constants.MIN_USERNAME_LENGTH,
+ max: Constants.MAX_USERNAME_LENGTH
+ }}
+ />
+ </span>
+ );
+ let nameDivStyle = 'form-group';
+ if (this.state.nameError) {
+ nameError = <label className='control-label'>{this.state.nameError}</label>;
+ nameHelpText = '';
+ nameDivStyle += ' has-error';
+ }
+
+ let passwordError = null;
+ let passwordDivStyle = 'form-group';
+ if (this.state.passwordError) {
+ passwordError = <label className='control-label'>{this.state.passwordError}</label>;
+ passwordDivStyle += ' has-error';
+ }
+
+ let yourEmailIs = null;
+ if (this.state.email) {
+ yourEmailIs = (
+ <FormattedHTMLMessage
+ id='signup_user_completed.emailIs'
+ defaultMessage="Your email address is <strong>{email}</strong>. You'll use this address to sign in to {siteName}."
+ values={{
+ email: this.state.email,
+ siteName: global.window.mm_config.SiteName
+ }}
+ />
+ );
+ }
+
+ let emailContainerStyle = 'margin--extra';
+ if (this.state.email) {
+ emailContainerStyle = 'hidden';
+ }
+
+ return (
+ <form>
+ <div className='inner__content'>
+ <div className={emailContainerStyle}>
+ <h5><strong>
+ <FormattedMessage
+ id='signup_user_completed.whatis'
+ defaultMessage="What's your email address?"
+ />
+ </strong></h5>
+ <div className={emailDivStyle}>
+ <input
+ type='email'
+ ref='email'
+ className='form-control'
+ defaultValue={this.state.email}
+ placeholder=''
+ maxLength='128'
+ autoFocus={true}
+ spellCheck='false'
+ autoCapitalize='off'
+ />
+ {emailError}
+ {emailHelpText}
+ </div>
+ </div>
+ {yourEmailIs}
+ <div className='margin--extra'>
+ <h5><strong>
+ <FormattedMessage
+ id='signup_user_completed.chooseUser'
+ defaultMessage='Choose your username'
+ />
+ </strong></h5>
+ <div className={nameDivStyle}>
+ <input
+ type='text'
+ ref='name'
+ className='form-control'
+ placeholder=''
+ maxLength={Constants.MAX_USERNAME_LENGTH}
+ spellCheck='false'
+ autoCapitalize='off'
+ />
+ {nameError}
+ {nameHelpText}
+ </div>
+ </div>
+ <div className='margin--extra'>
+ <h5><strong>
+ <FormattedMessage
+ id='signup_user_completed.choosePwd'
+ defaultMessage='Choose your password'
+ />
+ </strong></h5>
+ <div className={passwordDivStyle}>
+ <input
+ type='password'
+ ref='password'
+ className='form-control'
+ placeholder=''
+ maxLength='128'
+ spellCheck='false'
+ />
+ {passwordError}
+ </div>
+ </div>
+ <p className='margin--extra'>
+ <button
+ type='submit'
+ onClick={this.handleSubmit}
+ className='btn-primary btn'
+ >
+ <FormattedMessage
+ id='signup_user_completed.create'
+ defaultMessage='Create Account'
+ />
+ </button>
+ </p>
+ </div>
+ </form>
+ );
+ }
+
+ render() {
+ track('signup', 'signup_user_01_welcome');
+
+ let serverError = null;
+ if (this.state.serverError) {
+ serverError = (
+ <div className={'form-group has-error'}>
+ <label className='control-label'>{this.state.serverError}</label>
+ </div>
+ );
+ }
+
+ if (this.state.loading) {
+ return (<LoadingScreen/>);
+ }
+
+ let emailSignup;
+ if (global.window.mm_config.EnableSignUpWithEmail === 'true') {
+ emailSignup = this.renderEmailSignup();
+ } else {
+ return null;
+ }
+
+ let terms = null;
+ if (!this.state.noOpenServerError && emailSignup) {
+ terms = (
+ <p>
+ <FormattedHTMLMessage
+ id='create_team.agreement'
+ defaultMessage="By proceeding to create your account and use {siteName}, you agree to our <a href='/static/help/terms.html'>Terms of Service</a> and <a href='/static/help/privacy.html'>Privacy Policy</a>. If you do not agree, you cannot use {siteName}."
+ values={{
+ siteName: global.window.mm_config.SiteName
+ }}
+ />
+ </p>
+ );
+ }
+
+ if (this.state.noOpenServerError) {
+ emailSignup = null;
+ }
+
+ let description = null;
+ if (global.window.mm_license.IsLicensed === 'true' && global.window.mm_license.CustomBrand === 'true' && global.window.mm_config.EnableCustomBrand === 'true') {
+ description = global.window.mm_config.CustomDescriptionText;
+ } else {
+ description = (
+ <FormattedMessage
+ id='web.root.signup_info'
+ defaultMessage='All team communication in one place, searchable and accessible anywhere'
+ />
+ );
+ }
+
+ return (
+ <div>
+ <div className='signup-header'>
+ <Link to='/signup_user_complete'>
+ <span className='fa fa-chevron-left'/>
+ <FormattedMessage
+ id='web.header.back'
+ />
+ </Link>
+ </div>
+ <div className='col-sm-12'>
+ <div className='signup-team__container padding--less'>
+ <img
+ className='signup-team-logo'
+ src={logoImage}
+ />
+ <h1>{global.window.mm_config.SiteName}</h1>
+ <h4 className='color--light'>
+ {description}
+ </h4>
+ <h4 className='color--light'>
+ <FormattedMessage
+ id='signup_user_completed.lets'
+ defaultMessage="Let's create your account"
+ />
+ </h4>
+ <span className='color--light'>
+ <FormattedMessage
+ id='signup_user_completed.haveAccount'
+ defaultMessage='Already have an account?'
+ />
+ {' '}
+ <Link
+ to={'/login'}
+ query={this.props.location.query}
+ >
+ <FormattedMessage
+ id='signup_user_completed.signIn'
+ defaultMessage='Click here to sign in.'
+ />
+ </Link>
+ </span>
+ {emailSignup}
+ {serverError}
+ {terms}
+ </div>
+ </div>
+ </div>
+ );
+ }
+}
diff --git a/webapp/components/signup/components/signup_ldap.jsx b/webapp/components/signup/components/signup_ldap.jsx
new file mode 100644
index 000000000..92089f2f7
--- /dev/null
+++ b/webapp/components/signup/components/signup_ldap.jsx
@@ -0,0 +1,233 @@
+// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+import FormError from 'components/form_error.jsx';
+
+import * as GlobalActions from 'actions/global_actions.jsx';
+import {track} from 'actions/analytics_actions.jsx';
+
+import * as Utils from 'utils/utils.jsx';
+import Client from 'client/web_client.jsx';
+
+import React from 'react';
+import {FormattedMessage, FormattedHTMLMessage} from 'react-intl';
+import {browserHistory, Link} from 'react-router/es6';
+
+import logoImage from 'images/logo.png';
+
+export default class SignupLdap extends React.Component {
+ static get propTypes() {
+ return {
+ location: React.PropTypes.object
+ };
+ }
+
+ constructor(props) {
+ super(props);
+
+ this.handleLdapSignup = this.handleLdapSignup.bind(this);
+ this.handleLdapSignupSuccess = this.handleLdapSignupSuccess.bind(this);
+
+ this.state = ({
+ ldapError: ''
+ });
+ }
+
+ handleLdapSignup(e) {
+ e.preventDefault();
+
+ this.setState({ldapError: ''});
+
+ Client.webLoginByLdap(
+ this.refs.id.value.trim(),
+ this.refs.password.value,
+ null,
+ this.handleLdapSignupSuccess,
+ (err) => {
+ this.setState({
+ ldapError: err.message
+ });
+ }
+ );
+ }
+
+ handleLdapSignupSuccess() {
+ if (this.props.location.query.id || this.props.location.query.h) {
+ Client.addUserToTeamFromInvite(
+ this.props.location.query.d,
+ this.props.location.query.h,
+ this.props.location.query.id,
+ () => {
+ this.finishSignup();
+ },
+ () => {
+ // there's not really a good way to deal with this, so just let the user log in like normal
+ this.finishSignup();
+ }
+ );
+ } else {
+ this.finishSignup();
+ }
+ }
+
+ finishSignup() {
+ GlobalActions.emitInitialLoad(
+ () => {
+ GlobalActions.loadDefaultLocale();
+ browserHistory.push('/select_team');
+ }
+ );
+ }
+
+ render() {
+ track('signup', 'signup_user_01_welcome');
+
+ let ldapIdPlaceholder;
+ if (global.window.mm_config.LdapLoginFieldName) {
+ ldapIdPlaceholder = global.window.mm_config.LdapLoginFieldName;
+ } else {
+ ldapIdPlaceholder = Utils.localizeMessage('login.ldap_username', 'LDAP Username');
+ }
+
+ let errorClass = '';
+ if (this.state.ldapError) {
+ errorClass += ' has-error';
+ }
+
+ let ldapSignup;
+ if (global.window.mm_config.EnableLdap === 'true' && global.window.mm_license.IsLicensed === 'true' && global.window.mm_license.LDAP) {
+ ldapSignup = (
+ <div className='inner__content'>
+ <h5>
+ <strong>
+ <FormattedMessage
+ id='signup.ldap'
+ defaultMessage='LDAP Credentials'
+ />
+ </strong>
+ </h5>
+ <form
+ onSubmit={this.handleLdapSignup}
+ >
+ <div className='signup__email-container'>
+ <FormError
+ error={this.state.ldapError}
+ margin={true}
+ />
+ <div className={'form-group' + errorClass}>
+ <input
+ className='form-control'
+ name='ldapId'
+ ref='id'
+ placeholder={ldapIdPlaceholder}
+ spellCheck='false'
+ autoCapitalize='off'
+ />
+ </div>
+ <div className={'form-group' + errorClass}>
+ <input
+ type='password'
+ className='form-control'
+ name='password'
+ ref='password'
+ placeholder={Utils.localizeMessage('login.password', 'Password')}
+ spellCheck='false'
+ />
+ </div>
+ <div className='form-group'>
+ <button
+ type='submit'
+ className='btn btn-primary'
+ disabled={!this.state.ldapId || !this.state.ldapPassword}
+ >
+ <FormattedMessage
+ id='login.signIn'
+ defaultMessage='Sign in'
+ />
+ </button>
+ </div>
+ </div>
+ </form>
+ </div>
+ );
+ } else {
+ return null;
+ }
+
+ let terms = null;
+ if (ldapSignup) {
+ terms = (
+ <p>
+ <FormattedHTMLMessage
+ id='create_team.agreement'
+ defaultMessage="By proceeding to create your account and use {siteName}, you agree to our <a href='/static/help/terms.html'>Terms of Service</a> and <a href='/static/help/privacy.html'>Privacy Policy</a>. If you do not agree, you cannot use {siteName}."
+ values={{
+ siteName: global.window.mm_config.SiteName
+ }}
+ />
+ </p>
+ );
+ }
+
+ let description = null;
+ if (global.window.mm_license.IsLicensed === 'true' && global.window.mm_license.CustomBrand === 'true' && global.window.mm_config.EnableCustomBrand === 'true') {
+ description = global.window.mm_config.CustomDescriptionText;
+ } else {
+ description = (
+ <FormattedMessage
+ id='web.root.signup_info'
+ defaultMessage='All team communication in one place, searchable and accessible anywhere'
+ />
+ );
+ }
+
+ return (
+ <div>
+ <div className='signup-header'>
+ <Link to='/signup_user_complete'>
+ <span className='fa fa-chevron-left'/>
+ <FormattedMessage
+ id='web.header.back'
+ />
+ </Link>
+ </div>
+ <div className='col-sm-12'>
+ <div className='signup-team__container padding--less'>
+ <img
+ className='signup-team-logo'
+ src={logoImage}
+ />
+ <h1>{global.window.mm_config.SiteName}</h1>
+ <h4 className='color--light'>
+ {description}
+ </h4>
+ <h4 className='color--light'>
+ <FormattedMessage
+ id='signup_user_completed.lets'
+ defaultMessage="Let's create your account"
+ />
+ </h4>
+ <span className='color--light'>
+ <FormattedMessage
+ id='signup_user_completed.haveAccount'
+ defaultMessage='Already have an account?'
+ />
+ {' '}
+ <Link
+ to={'/login'}
+ query={this.props.location.query}
+ >
+ <FormattedMessage
+ id='signup_user_completed.signIn'
+ defaultMessage='Click here to sign in.'
+ />
+ </Link>
+ </span>
+ {ldapSignup}
+ {terms}
+ </div>
+ </div>
+ </div>
+ );
+ }
+}
diff --git a/webapp/components/signup/signup_controller.jsx b/webapp/components/signup/signup_controller.jsx
new file mode 100644
index 000000000..a0587bba9
--- /dev/null
+++ b/webapp/components/signup/signup_controller.jsx
@@ -0,0 +1,333 @@
+// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+import React from 'react';
+
+import FormError from 'components/form_error.jsx';
+import LoadingScreen from 'components/loading_screen.jsx';
+
+import UserStore from 'stores/user_store.jsx';
+import BrowserStore from 'stores/browser_store.jsx';
+
+import * as AsyncClient from 'utils/async_client.jsx';
+import Client from 'client/web_client.jsx';
+import * as GlobalActions from 'actions/global_actions.jsx';
+
+import logoImage from 'images/logo.png';
+import ErrorBar from 'components/error_bar.jsx';
+
+import {FormattedMessage} from 'react-intl';
+import {browserHistory, Link} from 'react-router/es6';
+
+export default class SignupController extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.renderSignupControls = this.renderSignupControls.bind(this);
+
+ let loading = false;
+ let serverError = '';
+ let noOpenServerError = false;
+ let usedBefore = false;
+
+ if (props.location.query) {
+ loading = true;
+ const hash = props.location.query.h;
+
+ if (hash && hash.length > 0 && !UserStore.getCurrentUser()) {
+ usedBefore = BrowserStore.getGlobalItem(hash);
+ loading = false;
+ } else if (global.window.mm_config.EnableOpenServer !== 'true' && !UserStore.getNoAccounts()) {
+ noOpenServerError = true;
+ loading = false;
+ serverError = (
+ <FormattedMessage
+ id='signup_user_completed.no_open_server'
+ defaultMessage='This server does not allow open signups. Please speak with your Administrator to receive an invitation.'
+ />
+ );
+ }
+ }
+
+ this.state = {
+ loading,
+ serverError,
+ noOpenServerError,
+ usedBefore
+ };
+ }
+
+ componentDidMount() {
+ AsyncClient.checkVersion();
+
+ if (this.props.location.query) {
+ const hash = this.props.location.query.h;
+ const data = this.props.location.query.d;
+ const inviteId = this.props.location.query.id;
+
+ if ((inviteId && inviteId.length > 0) || (hash && hash.length > 0)) {
+ if (UserStore.getCurrentUser()) {
+ Client.addUserToTeamFromInvite(
+ data,
+ hash,
+ inviteId,
+ (team) => {
+ GlobalActions.emitInitialLoad(
+ () => {
+ browserHistory.push('/' + team.name + '/channels/town-square');
+ }
+ );
+ },
+ (err) => {
+ this.setState({ // eslint-disable-line react/no-did-mount-set-state
+ serverError: err.message
+ });
+ }
+ );
+ } else if (!this.state.usedBefore) {
+ Client.getInviteInfo(
+ inviteId,
+ (inviteData) => {
+ if (!inviteData) {
+ return;
+ }
+
+ this.setState({ // eslint-disable-line react/no-did-mount-set-state
+ serverError: '',
+ loading: false
+ });
+ },
+ () => {
+ this.setState({ // eslint-disable-line react/no-did-mount-set-state
+ noOpenServerError: true,
+ loading: false,
+ serverError: (
+ <FormattedMessage
+ id='signup_user_completed.invalid_invite'
+ defaultMessage='The invite link was invalid. Please speak with your Administrator to receive an invitation.'
+ />
+ )
+ });
+ }
+ );
+ }
+ } else if (UserStore.getCurrentUser()) {
+ browserHistory.push('/select_team');
+ } else {
+ this.setState({ // eslint-disable-line react/no-did-mount-set-state
+ loading: false
+ });
+ }
+ }
+ }
+
+ renderSignupControls() {
+ let signupControls = [];
+
+ if (global.window.mm_config.EnableSignUpWithEmail === 'true') {
+ signupControls.push(
+ <Link
+ className='btn btn-custom-login btn--full email'
+ key='email'
+ to={'/signup_email' + window.location.search}
+ >
+
+ <span className='icon fa fa-envelope'/>
+ <span>
+ <FormattedMessage
+ id='signup.email'
+ defaultMessage='Email and Password'
+ />
+ </span>
+ </Link>
+ );
+ }
+
+ if (global.window.mm_config.EnableSignUpWithGitLab === 'true') {
+ signupControls.push(
+ <a
+ className='btn btn-custom-login btn--full gitlab'
+ key='gitlab'
+ href={Client.getOAuthRoute() + '/gitlab/signup' + window.location.search}
+ >
+ <span className='icon'/>
+ <span>
+ <FormattedMessage
+ id='signup.gitlab'
+ defaultMessage='GitLab Single-Sign-On'
+ />
+ </span>
+ </a>
+ );
+ }
+
+ if (global.window.mm_config.EnableSignUpWithGoogle === 'true') {
+ signupControls.push(
+ <a
+ className='btn btn-custom-login btn--full google'
+ key='google'
+ href={Client.getOAuthRoute() + '/google/signup' + window.location.search}
+ >
+ <span className='icon'/>
+ <span>
+ <FormattedMessage
+ id='signup.google'
+ defaultMessage='Google Account'
+ />
+ </span>
+ </a>
+ );
+ }
+
+ if (global.window.mm_config.EnableSignUpWithOffice365 === 'true') {
+ signupControls.push(
+ <a
+ className='btn btn-custom-login btn--full office365'
+ key='office365'
+ href={Client.getOAuthRoute() + '/office365/signup' + window.location.search}
+ >
+ <span className='icon'/>
+ <span>
+ <FormattedMessage
+ id='signup.office365'
+ defaultMessage='Office 365'
+ />
+ </span>
+ </a>
+ );
+ }
+
+ if (global.window.mm_license.IsLicensed === 'true' && global.window.mm_config.EnableLdap === 'true') {
+ signupControls.push(
+ <Link
+ className='btn btn-custom-login btn--full ldap'
+ key='ldap'
+ to={'/signup_ldap'}
+ >
+ <span className='icon fa fa-folder-open fa--margin-top'/>
+ <span>
+ <FormattedMessage
+ id='signup.ldap'
+ defaultMessage='LDAP Credentials'
+ />
+ </span>
+ </Link>
+ );
+ }
+
+ if (global.window.mm_license.IsLicensed === 'true' && global.window.mm_config.EnableSaml === 'true') {
+ let query = '';
+ if (window.location.search) {
+ query = '&action=signup';
+ } else {
+ query = '?action=signup';
+ }
+
+ signupControls.push(
+ <a
+ className='btn btn-custom-login btn--full saml'
+ key='saml'
+ href={'/login/sso/saml' + window.location.search + query}
+ >
+ <span className='icon fa fa-lock fa--margin-top'/>
+ <span>
+ {global.window.mm_config.SamlLoginButtonText}
+ </span>
+ </a>
+ );
+ }
+
+ if (signupControls.length === 0) {
+ const signupDisabledError = (
+ <FormattedMessage
+ id='signup_user_completed.none'
+ defaultMessage='No user creation method has been enabled. Please contact an administrator for access.'
+ />
+ );
+ signupControls = (
+ <FormError
+ error={signupDisabledError}
+ margin={true}
+ />
+ );
+ }
+
+ return signupControls;
+ }
+
+ render() {
+ if (this.state.loading) {
+ return (<LoadingScreen/>);
+ }
+
+ if (this.state.usedBefore) {
+ return (
+ <div>
+ <FormattedMessage
+ id='signup_user_completed.expired'
+ defaultMessage="You've already completed the signup process for this invitation or this invitation has expired."
+ />
+ </div>
+ );
+ }
+
+ let signupControls = this.renderSignupControls();
+
+ let serverError = null;
+ if (this.state.serverError) {
+ serverError = (
+ <div className={'form-group has-error'}>
+ <label className='control-label'>{this.state.serverError}</label>
+ </div>
+ );
+ }
+
+ if (this.state.noOpenServerError || this.state.usedBefore) {
+ signupControls = null;
+ }
+
+ return (
+ <div>
+ <ErrorBar/>
+ <div className='signup-header'>
+ <Link to='/'>
+ <span className='fa fa-chevron-left'/>
+ <FormattedMessage
+ id='web.header.back'
+ />
+ </Link>
+ </div>
+ <div className='col-sm-12'>
+ <div className='signup-team__container'>
+ <img
+ className='signup-team-logo'
+ src={logoImage}
+ />
+ <div className='signup__content'>
+ <h1>{global.window.mm_config.SiteName}</h1>
+ <h4 className='color--light'>
+ <FormattedMessage
+ id='web.root.signup_info'
+ />
+ </h4>
+ <div className='margin--extra'>
+ <h5><strong>
+ <FormattedMessage
+ id='signup.title'
+ defaultMessage='Create an account with:'
+ />
+ </strong></h5>
+ </div>
+ {signupControls}
+ {serverError}
+ </div>
+ </div>
+ </div>
+ </div>
+ );
+ }
+}
+
+SignupController.propTypes = {
+ location: React.PropTypes.object
+}; \ No newline at end of file