diff --git a/webapp/components/login/login_controller.jsx b/webapp/components/login/login_controller.jsx index f62464f37a..5a5d0388af 100644 --- a/webapp/components/login/login_controller.jsx +++ b/webapp/components/login/login_controller.jsx @@ -520,6 +520,7 @@ export default class LoginController extends React.Component { key='saml' href={'/login/sso/saml' + this.props.location.search} > + {window.mm_config.SamlLoginButtonText} diff --git a/webapp/components/signup/components/signup_email.jsx b/webapp/components/signup/components/signup_email.jsx new file mode 100644 index 0000000000..2d4b3f2774 --- /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 = ( + + ); + } + ); + + 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: (), + passwordError: '', + serverError: '' + }); + return false; + } + + if (!Utils.isEmail(providedEmail)) { + this.setState({ + nameError: '', + emailError: (), + passwordError: '', + serverError: '' + }); + return false; + } + + const providedUsername = this.refs.name.value.trim().toLowerCase(); + if (!providedUsername) { + this.setState({ + nameError: (), + emailError: '', + passwordError: '', + serverError: '' + }); + return false; + } + + const usernameError = Utils.isValidUsername(providedUsername); + if (usernameError === 'Cannot use a reserved word as a username.') { + this.setState({ + nameError: (), + emailError: '', + passwordError: '', + serverError: '' + }); + return false; + } else if (usernameError) { + this.setState({ + nameError: ( + + ), + 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 = ( + + + + ); + let emailDivStyle = 'form-group'; + if (this.state.emailError) { + emailError = (); + emailHelpText = ''; + emailDivStyle += ' has-error'; + } + + let nameError = null; + let nameHelpText = ( + + + + ); + let nameDivStyle = 'form-group'; + if (this.state.nameError) { + nameError = ; + nameHelpText = ''; + nameDivStyle += ' has-error'; + } + + let passwordError = null; + let passwordDivStyle = 'form-group'; + if (this.state.passwordError) { + passwordError = ; + passwordDivStyle += ' has-error'; + } + + let yourEmailIs = null; + if (this.state.email) { + yourEmailIs = ( + + ); + } + + let emailContainerStyle = 'margin--extra'; + if (this.state.email) { + emailContainerStyle = 'hidden'; + } + + return ( +
+
+
+
+ +
+
+ + {emailError} + {emailHelpText} +
+
+ {yourEmailIs} +
+
+ +
+
+ + {nameError} + {nameHelpText} +
+
+
+
+ +
+
+ + {passwordError} +
+
+

+ +

+
+
+ ); + } + + render() { + track('signup', 'signup_user_01_welcome'); + + let serverError = null; + if (this.state.serverError) { + serverError = ( +
+ +
+ ); + } + + if (this.state.loading) { + return (); + } + + let emailSignup; + if (global.window.mm_config.EnableSignUpWithEmail === 'true') { + emailSignup = this.renderEmailSignup(); + } else { + return null; + } + + let terms = null; + if (!this.state.noOpenServerError && emailSignup) { + terms = ( +

+ +

+ ); + } + + 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 = ( + + ); + } + + return ( +
+
+ + + + +
+
+
+ +

{global.window.mm_config.SiteName}

+

+ {description} +

+

+ +

+ + + {' '} + + + + + {emailSignup} + {serverError} + {terms} +
+
+
+ ); + } +} diff --git a/webapp/components/signup/components/signup_ldap.jsx b/webapp/components/signup/components/signup_ldap.jsx new file mode 100644 index 0000000000..92089f2f7b --- /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 = ( +
+
+ + + +
+
+
+ +
+ +
+
+ +
+
+ +
+
+
+
+ ); + } else { + return null; + } + + let terms = null; + if (ldapSignup) { + terms = ( +

+ +

+ ); + } + + 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 = ( + + ); + } + + return ( +
+
+ + + + +
+
+
+ +

{global.window.mm_config.SiteName}

+

+ {description} +

+

+ +

+ + + {' '} + + + + + {ldapSignup} + {terms} +
+
+
+ ); + } +} diff --git a/webapp/components/signup/signup_controller.jsx b/webapp/components/signup/signup_controller.jsx new file mode 100644 index 0000000000..a0587bba92 --- /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 = ( + + ); + } + } + + 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: ( + + ) + }); + } + ); + } + } 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( + + + + + + + + ); + } + + if (global.window.mm_config.EnableSignUpWithGitLab === 'true') { + signupControls.push( + + + + + + + ); + } + + if (global.window.mm_config.EnableSignUpWithGoogle === 'true') { + signupControls.push( + + + + + + + ); + } + + if (global.window.mm_config.EnableSignUpWithOffice365 === 'true') { + signupControls.push( + + + + + + + ); + } + + if (global.window.mm_license.IsLicensed === 'true' && global.window.mm_config.EnableLdap === 'true') { + signupControls.push( + + + + + + + ); + } + + 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( + + + + {global.window.mm_config.SamlLoginButtonText} + + + ); + } + + if (signupControls.length === 0) { + const signupDisabledError = ( + + ); + signupControls = ( + + ); + } + + return signupControls; + } + + render() { + if (this.state.loading) { + return (); + } + + if (this.state.usedBefore) { + return ( +
+ +
+ ); + } + + let signupControls = this.renderSignupControls(); + + let serverError = null; + if (this.state.serverError) { + serverError = ( +
+ +
+ ); + } + + if (this.state.noOpenServerError || this.state.usedBefore) { + signupControls = null; + } + + return ( +
+ +
+ + + + +
+
+
+ +
+

{global.window.mm_config.SiteName}

+

+ +

+
+
+ +
+
+ {signupControls} + {serverError} +
+
+
+
+ ); + } +} + +SignupController.propTypes = { + location: React.PropTypes.object +}; \ No newline at end of file diff --git a/webapp/components/signup_user_complete.jsx b/webapp/components/signup_user_complete.jsx deleted file mode 100644 index 9bb208c843..0000000000 --- a/webapp/components/signup_user_complete.jsx +++ /dev/null @@ -1,840 +0,0 @@ -// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import FormError from 'components/form_error.jsx'; -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 UserStore from 'stores/user_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 ReactDOM from 'react-dom'; -import {FormattedMessage, FormattedHTMLMessage} from 'react-intl'; -import {browserHistory, Link} from 'react-router/es6'; - -import logoImage from 'images/logo.png'; - -export default class SignupUserComplete extends React.Component { - static get propTypes() { - return { - location: React.PropTypes.object - }; - } - - constructor(props) { - super(props); - - this.handleSubmit = this.handleSubmit.bind(this); - this.handleLdapSignup = this.handleLdapSignup.bind(this); - - this.handleLdapIdChange = this.handleLdapIdChange.bind(this); - this.handleLdapPasswordChange = this.handleLdapPasswordChange.bind(this); - - this.state = { - data: '', - hash: '', - usedBefore: false, - email: '', - teamDisplayName: '', - signupDisabledError: '', - teamName: '', - teamId: '', - openServer: false, - loading: true, - inviteId: '', - ldapId: '', - ldapPassword: '' - }; - } - - componentWillMount() { - let data = this.props.location.query.d; - let hash = this.props.location.query.h; - const inviteId = this.props.location.query.id; - let usedBefore = false; - let email = ''; - let teamDisplayName = ''; - let teamName = ''; - let teamId = ''; - let openServer = false; - let loading = true; - - if ((inviteId && inviteId.length > 0) || (hash && hash.length > 0)) { - // if we are already logged in then attempt to just join the team - if (UserStore.getCurrentUser()) { - Client.addUserToTeamFromInvite( - data, - hash, - inviteId, - (team) => { - loading = true; - GlobalActions.emitInitialLoad( - () => { - browserHistory.push('/' + team.name + '/channels/town-square'); - } - ); - }, - (err) => { - this.setState({ - noOpenServerError: true, - serverError: err.message, - loading: false - }); - } - ); - } else if (hash) { - // If we have a hash in the url then we are attempting to access a private team - const parsedData = JSON.parse(data); - usedBefore = BrowserStore.getGlobalItem(hash); - email = parsedData.email; - teamDisplayName = parsedData.display_name; - teamName = parsedData.name; - teamId = parsedData.id; - loading = false; - } else { - loading = true; - Client.getInviteInfo( - inviteId, - (inviteData) => { - if (!inviteData) { - return; - } - - this.setState({ - serverError: null, - teamDisplayName: inviteData.display_name, - teamName: inviteData.name, - teamId: inviteData.id - }); - }, - () => { - this.setState({ - noOpenServerError: true, - serverError: - - }); - } - ); - - loading = false; - data = ''; - hash = ''; - } - } else if (global.window.mm_config.EnableOpenServer === 'true' || UserStore.getNoAccounts()) { - // If this is the first account then let them create an account anyway. - // The server will verify it's the first account before allowing creation. - // Of if the server is open then we don't care. - openServer = true; - loading = false; - } else { - loading = false; - this.setState({ - noOpenServerError: true, - serverError: - - }); - } - - this.setState({ - data, - hash, - usedBefore, - email, - teamDisplayName, - teamName, - teamId, - openServer, - inviteId, - loading - }); - - this.setState({ - signupDisabledError: ( - - ) - }); - } - - handleLdapSignup(e) { - e.preventDefault(); - - this.setState({ldapError: ''}); - - Client.webLoginByLdap( - this.state.ldapId, - this.state.ldapPassword, - null, - () => { - 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(); - } - ); - - return; - } - - this.finishSignup(); - }, - (err) => { - if (err.id === 'ent.ldap.do_login.user_not_registered.app_error' || err.id === 'ent.ldap.do_login.user_filtered.app_error') { - this.setState({ - ldapError: ( - - ) - }); - } else if (err.id === 'ent.ldap.do_login.invalid_password.app_error') { - this.setState({ - ldapError: ( - - ) - }); - } else { - this.setState({ldapError: err.message}); - } - } - ); - } - - 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'); - } - } - ); - } - - handleUserCreated(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}); - } - } - ); - } - - handleSubmit(e) { - e.preventDefault(); - - const providedEmail = ReactDOM.findDOMNode(this.refs.email).value.trim(); - if (!providedEmail) { - this.setState({ - nameError: '', - emailError: (), - passwordError: '', - serverError: '' - }); - return; - } - - if (!Utils.isEmail(providedEmail)) { - this.setState({ - nameError: '', - emailError: (), - passwordError: '', - serverError: '' - }); - return; - } - - const providedUsername = ReactDOM.findDOMNode(this.refs.name).value.trim().toLowerCase(); - if (!providedUsername) { - this.setState({ - nameError: (), - emailError: '', - passwordError: '', - serverError: '' - }); - return; - } - - const usernameError = Utils.isValidUsername(providedUsername); - if (usernameError === 'Cannot use a reserved word as a username.') { - this.setState({ - nameError: (), - emailError: '', - passwordError: '', - serverError: '' - }); - return; - } else if (usernameError) { - this.setState({ - nameError: ( - - ), - emailError: '', - passwordError: '', - serverError: '' - }); - return; - } - - const providedPassword = ReactDOM.findDOMNode(this.refs.password).value; - const pwdError = Utils.isValidPassword(providedPassword); - if (pwdError != null) { - this.setState({ - nameError: '', - emailError: '', - passwordError: pwdError, - serverError: '' - }); - } - - this.setState({ - nameError: '', - emailError: '', - passwordError: '', - serverError: '' - }); - - const user = { - email: providedEmail, - username: providedUsername, - password: providedPassword, - allow_marketing: true - }; - - Client.createUserWithInvite(user, - this.state.data, - this.state.hash, - this.state.inviteId, - this.handleUserCreated.bind(this, user), - (err) => { - this.setState({serverError: err.message}); - } - ); - } - - handleLdapIdChange(e) { - e.preventDefault(); - - this.setState({ - ldapId: e.target.value - }); - } - - handleLdapPasswordChange(e) { - e.preventDefault(); - - this.setState({ - ldapPassword: e.target.value - }); - } - - renderLdapLogin() { - 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'; - } - - return ( -
-
- -
- -
-
- -
-
- -
-
-
- ); - } - - render() { - track('signup', 'signup_user_01_welcome'); - - // If we have been used then just display a message - if (this.state.usedBefore) { - return ( -
- -
- ); - } - - if (this.state.loading) { - return (); - } - - // set up error labels - var emailError = null; - var emailHelpText = ( - - - - ); - var emailDivStyle = 'form-group'; - if (this.state.emailError) { - emailError = (); - emailHelpText = ''; - emailDivStyle += ' has-error'; - } - - var nameError = null; - var nameHelpText = ( - - - - ); - var nameDivStyle = 'form-group'; - if (this.state.nameError) { - nameError = ; - nameHelpText = ''; - nameDivStyle += ' has-error'; - } - - var passwordError = null; - var passwordDivStyle = 'form-group'; - if (this.state.passwordError) { - passwordError = ; - passwordDivStyle += ' has-error'; - } - - var serverError = null; - if (this.state.serverError) { - serverError = ( -
- -
- ); - } - - // set up the email entry and hide it if an email was provided - var yourEmailIs = ''; - if (this.state.email) { - yourEmailIs = ( - - ); - } - - var emailContainerStyle = 'margin--extra'; - if (this.state.email) { - emailContainerStyle = 'hidden'; - } - - var email = ( -
-
- -
-
- - {emailError} - {emailHelpText} -
-
- ); - - let signupMessage = []; - if (global.window.mm_config.EnableSignUpWithGitLab === 'true') { - signupMessage.push( - - - - - - - ); - } - - if (global.window.mm_config.EnableSignUpWithGoogle === 'true') { - signupMessage.push( - - - - - - - ); - } - - if (global.window.mm_config.EnableSignUpWithOffice365 === 'true') { - signupMessage.push( - - - - - - - ); - } - - if (global.window.mm_config.EnableSaml === 'true' && global.window.mm_license.IsLicensed === 'true' && global.window.mm_license.SAML === 'true') { - signupMessage.push( - - - {global.window.mm_config.SamlLoginButtonText} - - - ); - } - - let ldapSignup; - if (global.window.mm_config.EnableLdap === 'true' && global.window.mm_license.IsLicensed === 'true' && global.window.mm_license.LDAP) { - ldapSignup = ( -
-
- - - -
- {this.renderLdapLogin()} -
- ); - } - - let emailSignup; - if (global.window.mm_config.EnableSignUpWithEmail === 'true') { - emailSignup = ( -
-
- {email} - {yourEmailIs} -
-
- -
-
- - {nameError} - {nameHelpText} -
-
-
-
- -
-
- - {passwordError} -
-
-

- -

-
-
- ); - } - - if (signupMessage.length > 0 && (emailSignup || ldapSignup)) { - signupMessage = ( -
- {signupMessage} -
- -
-
- ); - } - - if (ldapSignup && emailSignup) { - ldapSignup = ( -
- {ldapSignup} -
- -
-
- ); - } - - let terms = null; - if (!this.state.noOpenServerError && (emailSignup || ldapSignup)) { - terms = ( -

- -

- ); - } - - if (signupMessage.length === 0 && !emailSignup && !ldapSignup) { - emailSignup = ( - - ); - } - - if (this.state.noOpenServerError) { - signupMessage = null; - emailSignup = null; - ldapSignup = 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 = ( - - ); - } - - return ( -
-
- - - - -
-
-
- -

{global.window.mm_config.SiteName}

-

- {description} -

-

- -

- - - {' '} - - - - - {signupMessage} - {ldapSignup} - {emailSignup} - {serverError} - {terms} -
-
-
- ); - } -} diff --git a/webapp/i18n/en.json b/webapp/i18n/en.json index b26e33cd63..5c636716b6 100644 --- a/webapp/i18n/en.json +++ b/webapp/i18n/en.json @@ -1597,6 +1597,12 @@ "sidebar_right_menu.switch_team": "Team Selection", "sidebar_right_menu.teamLink": "Get Team Invite Link", "sidebar_right_menu.teamSettings": "Team Settings", + "signup.title": "Create an account with:", + "signup.ldap": "LDAP Credentials", + "signup.google": "Google Account", + "signup.office365": "Office 365", + "signup.gitlab": "GitLab Single-Sign-On", + "signup.email": "Email and Password", "signup_team.choose": "Your teams: ", "signup_team.createTeam": "Or Create a Team", "signup_team.disabled": "Team creation has been disabled. Please contact an administrator for access.", diff --git a/webapp/routes/route_root.jsx b/webapp/routes/route_root.jsx index 52eb5c7574..9d64c60125 100644 --- a/webapp/routes/route_root.jsx +++ b/webapp/routes/route_root.jsx @@ -66,7 +66,19 @@ export default { { path: 'signup_user_complete', getComponents: (location, callback) => { - System.import('components/signup_user_complete.jsx').then(RouteUtils.importComponentSuccess(callback)); + System.import('components/signup/signup_controller.jsx').then(RouteUtils.importComponentSuccess(callback)); + } + }, + { + path: 'signup_email', + getComponents: (location, callback) => { + System.import('components/signup/components/signup_email.jsx').then(RouteUtils.importComponentSuccess(callback)); + } + }, + { + path: 'signup_ldap', + getComponents: (location, callback) => { + System.import('components/signup/components/signup_ldap.jsx').then(RouteUtils.importComponentSuccess(callback)); } }, { diff --git a/webapp/sass/routes/_signup.scss b/webapp/sass/routes/_signup.scss index 8315f88901..106cdc3728 100644 --- a/webapp/sass/routes/_signup.scss +++ b/webapp/sass/routes/_signup.scss @@ -203,6 +203,11 @@ .fa { font-size: 17px; margin-right: 8px; + + &.fa--margin-top { + position: relative; + top: 2px; + } } .icon { @@ -210,6 +215,7 @@ display: inline-block; height: 18px; margin-right: 8px; + text-align: center; width: 18px; } @@ -218,10 +224,11 @@ color: $white; display: block; height: 40px; - line-height: 34px; + line-height: 36px; margin: 1em 0; min-width: 200px; - padding: 0 1em; + padding: 0 1em 0 2em; + text-align: left; width: 200px; &.gitlab { @@ -268,16 +275,15 @@ } .icon { - margin-left:-10px; background-image: url('../images/office365Logo.png'); } } &.ldap { - background: #dd4b39; + background: #3AA1CF; &:hover { - background: darken(#dd4b39, 10%); + background: darken(#3AA1CF, 10%); } span { @@ -298,10 +304,10 @@ } &.saml { - background: #dd4b39; + background: #34a28b; &:hover { - background: darken(#dd4b39, 10%); + background: darken(#34a28b, 10%); } span { @@ -309,11 +315,16 @@ } } - &.btn-full { + &.btn--full { + max-width: 350px; padding-left: 35px; text-align: left; width: 100%; } + + &.btn--large { + width: 300px; + } } &.btn-default { @@ -502,4 +513,4 @@ .verify_panel { margin: 60px auto auto; max-width: 380px; -} +} \ No newline at end of file