summaryrefslogtreecommitdiffstats
path: root/webapp
diff options
context:
space:
mode:
Diffstat (limited to 'webapp')
-rw-r--r--webapp/client/client.jsx51
-rw-r--r--webapp/components/login/components/login_email.jsx121
-rw-r--r--webapp/components/login/components/login_ldap.jsx115
-rw-r--r--webapp/components/login/components/login_mfa.jsx3
-rw-r--r--webapp/components/login/components/login_username.jsx121
-rw-r--r--webapp/components/login/login.jsx320
-rw-r--r--webapp/components/signup_user_complete.jsx65
-rw-r--r--webapp/i18n/en.json28
-rw-r--r--webapp/i18n/es.json26
-rw-r--r--webapp/i18n/fr.json26
-rw-r--r--webapp/i18n/ja.json26
-rw-r--r--webapp/i18n/pt.json26
-rw-r--r--webapp/stores/user_store.jsx17
-rw-r--r--webapp/tests/client_user.test.jsx19
-rw-r--r--webapp/tests/test_helper.jsx1
-rw-r--r--webapp/utils/web_client.jsx9
16 files changed, 236 insertions, 738 deletions
diff --git a/webapp/client/client.jsx b/webapp/client/client.jsx
index 6a7c5de40..69f573eff 100644
--- a/webapp/client/client.jsx
+++ b/webapp/client/client.jsx
@@ -746,49 +746,30 @@ export default class Client {
end(this.handleResponse.bind(this, 'getMe', success, error));
}
- login = (email, username, password, mfaToken, success, error) => {
- var outer = this; // eslint-disable-line consistent-this
+ login = (loginId, password, mfaToken, success, error) => {
+ this.doLogin({login_id: loginId, password, token: mfaToken}, success, error);
- request.
- post(`${this.getUsersRoute()}/login`).
- set(this.defaultHeaders).
- type('application/json').
- accept('application/json').
- send({email, password, username, token: mfaToken}).
- end(this.handleResponse.bind(
- this,
- 'login',
- (data, res) => {
- if (res && res.header) {
- outer.token = res.header[HEADER_TOKEN];
-
- if (outer.useToken) {
- outer.defaultHeaders[HEADER_AUTH] = `${HEADER_BEARER} ${outer.token}`;
- }
- }
+ this.track('api', 'api_users_login', '', 'login_id', loginId);
+ }
- if (success) {
- success(data, res);
- }
- },
- error
- ));
+ loginById = (id, password, mfaToken, success, error) => {
+ this.doLogin({id, password, token: mfaToken}, success, error);
- this.track('api', 'api_users_login', '', 'email', email);
+ this.track('api', 'api_users_login', '', 'id', id);
}
- loginByLdap = (ldapId, password, mfaToken, success, error) => {
+ doLogin = (outgoingData, success, error) => {
var outer = this; // eslint-disable-line consistent-this
request.
- post(`${this.getUsersRoute()}/login_ldap`).
+ post(`${this.getUsersRoute()}/login`).
set(this.defaultHeaders).
type('application/json').
accept('application/json').
- send({id: ldapId, password, token: mfaToken}).
+ send(outgoingData).
end(this.handleResponse.bind(
this,
- 'loginByLdap',
+ 'login',
(data, res) => {
if (res && res.header) {
outer.token = res.header[HEADER_TOKEN];
@@ -804,8 +785,6 @@ export default class Client {
},
error
));
-
- this.track('api', 'api_users_loginLdap', '', 'email', ldapId);
}
logout = (success, error) => {
@@ -819,10 +798,10 @@ export default class Client {
this.track('api', 'api_users_logout');
}
- checkMfa = (method, loginId, success, error) => {
- var data = {};
- data.method = method;
- data.login_id = loginId;
+ checkMfa = (loginId, success, error) => {
+ const data = {
+ login_id: loginId
+ };
request.
post(`${this.getUsersRoute()}/mfa`).
diff --git a/webapp/components/login/components/login_email.jsx b/webapp/components/login/components/login_email.jsx
deleted file mode 100644
index b1f484c08..000000000
--- a/webapp/components/login/components/login_email.jsx
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
-// See License.txt for license information.
-
-import * as Utils from 'utils/utils.jsx';
-import UserStore from 'stores/user_store.jsx';
-import Constants from 'utils/constants.jsx';
-
-import {FormattedMessage} from 'react-intl';
-
-import React from 'react';
-
-export default class LoginEmail extends React.Component {
- constructor(props) {
- super(props);
-
- this.handleSubmit = this.handleSubmit.bind(this);
-
- this.state = {
- serverError: props.serverError
- };
- }
- componentWillReceiveProps(nextProps) {
- this.setState({serverError: nextProps.serverError});
- }
- handleSubmit(e) {
- e.preventDefault();
- var state = {};
-
- const email = this.refs.email.value.trim();
- if (!email) {
- state.serverError = Utils.localizeMessage('login_email.emailReq', 'An email is required');
- this.setState(state);
- return;
- }
-
- const password = this.refs.password.value.trim();
- if (!password) {
- state.serverError = Utils.localizeMessage('login_email.pwdReq', 'A password is required');
- this.setState(state);
- return;
- }
-
- state.serverError = '';
- this.setState(state);
-
- this.props.submit(Constants.EMAIL_SERVICE, email, password);
- }
- render() {
- let serverError;
- let errorClass = '';
- if (this.state.serverError) {
- serverError = <label className='control-label'>{this.state.serverError}</label>;
- errorClass = ' has-error';
- }
-
- let priorEmail = UserStore.getLastEmail();
- let focusEmail = false;
- let focusPassword = false;
- if (priorEmail === '') {
- focusEmail = true;
- } else {
- focusPassword = true;
- }
-
- const emailParam = Utils.getUrlParameter('email');
- if (emailParam) {
- priorEmail = decodeURIComponent(emailParam);
- }
-
- return (
- <form onSubmit={this.handleSubmit}>
- <div className='signup__email-container'>
- <div className={'form-group' + errorClass}>
- {serverError}
- </div>
- <div className={'form-group' + errorClass}>
- <input
- autoFocus={focusEmail}
- type='email'
- className='form-control'
- name='email'
- defaultValue={priorEmail}
- ref='email'
- placeholder={Utils.localizeMessage('login_email.email', 'Email')}
- spellCheck='false'
- />
- </div>
- <div className={'form-group' + errorClass}>
- <input
- autoFocus={focusPassword}
- type='password'
- className='form-control'
- name='password'
- ref='password'
- placeholder={Utils.localizeMessage('login_email.pwd', 'Password')}
- spellCheck='false'
- />
- </div>
- <div className='form-group'>
- <button
- type='submit'
- className='btn btn-primary'
- >
- <FormattedMessage
- id='login_email.signin'
- defaultMessage='Sign in'
- />
- </button>
- </div>
- </div>
- </form>
- );
- }
-}
-LoginEmail.defaultProps = {
-};
-
-LoginEmail.propTypes = {
- submit: React.PropTypes.func.isRequired,
- serverError: React.PropTypes.string
-};
diff --git a/webapp/components/login/components/login_ldap.jsx b/webapp/components/login/components/login_ldap.jsx
deleted file mode 100644
index 36b8a406c..000000000
--- a/webapp/components/login/components/login_ldap.jsx
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
-// See License.txt for license information.
-
-import * as Utils from 'utils/utils.jsx';
-import Constants from 'utils/constants.jsx';
-
-import {FormattedMessage} from 'react-intl';
-
-import React from 'react';
-
-export default class LoginLdap extends React.Component {
- constructor(props) {
- super(props);
-
- this.handleSubmit = this.handleSubmit.bind(this);
-
- this.state = {
- serverError: props.serverError
- };
- }
- componentWillReceiveProps(nextProps) {
- this.setState({serverError: nextProps.serverError});
- }
- handleSubmit(e) {
- e.preventDefault();
- const state = {};
-
- const id = this.refs.id.value.trim();
- if (!id) {
- state.serverError = Utils.localizeMessage('login_ldap.idlReq', 'An LDAP ID is required');
- this.setState(state);
- return;
- }
-
- const password = this.refs.password.value.trim();
- if (!password) {
- state.serverError = Utils.localizeMessage('login_ldap.pwdReq', 'An LDAP password is required');
- this.setState(state);
- return;
- }
-
- state.serverError = '';
- this.setState(state);
-
- this.props.submit(Constants.LDAP_SERVICE, id, password);
- }
- render() {
- let serverError;
- let errorClass = '';
- if (this.state.serverError) {
- serverError = <label className='control-label'>{this.state.serverError}</label>;
- errorClass = ' has-error';
- }
-
- let loginPlaceholder;
- if (global.window.mm_config.LdapLoginFieldName) {
- loginPlaceholder = global.window.mm_config.LdapLoginFieldName;
- } else {
- loginPlaceholder = Utils.localizeMessage('login_ldap.username', 'LDAP Username');
- }
-
- let passwordPlaceholder;
- if (global.window.mm_config.LdapPasswordFieldName) {
- passwordPlaceholder = global.window.mm_config.LdapPasswordFieldName;
- } else {
- passwordPlaceholder = Utils.localizeMessage('login_ldap.pwd', 'LDAP Password');
- }
-
- return (
- <form onSubmit={this.handleSubmit}>
- <div className='signup__email-container'>
- <div className={'form-group' + errorClass}>
- {serverError}
- </div>
- <div className={'form-group' + errorClass}>
- <input
- autoFocus={true}
- className='form-control'
- ref='id'
- placeholder={loginPlaceholder}
- spellCheck='false'
- />
- </div>
- <div className={'form-group' + errorClass}>
- <input
- type='password'
- className='form-control'
- ref='password'
- placeholder={passwordPlaceholder}
- spellCheck='false'
- />
- </div>
- <div className='form-group'>
- <button
- type='submit'
- className='btn btn-primary'
- >
- <FormattedMessage
- id='login_ldap.signin'
- defaultMessage='Sign in'
- />
- </button>
- </div>
- </div>
- </form>
- );
- }
-}
-LoginLdap.defaultProps = {
-};
-
-LoginLdap.propTypes = {
- serverError: React.PropTypes.string,
- submit: React.PropTypes.func.isRequired
-};
diff --git a/webapp/components/login/components/login_mfa.jsx b/webapp/components/login/components/login_mfa.jsx
index f8ebf1e82..f8d42012c 100644
--- a/webapp/components/login/components/login_mfa.jsx
+++ b/webapp/components/login/components/login_mfa.jsx
@@ -31,7 +31,7 @@ export default class LoginMfa extends React.Component {
state.serverError = '';
this.setState(state);
- this.props.submit(this.props.method, this.props.loginId, this.props.password, token);
+ this.props.submit(this.props.loginId, this.props.password, token);
}
render() {
let serverError;
@@ -85,7 +85,6 @@ LoginMfa.defaultProps = {
};
LoginMfa.propTypes = {
- method: React.PropTypes.string.isRequired,
loginId: React.PropTypes.string.isRequired,
password: React.PropTypes.string.isRequired,
submit: React.PropTypes.func.isRequired
diff --git a/webapp/components/login/components/login_username.jsx b/webapp/components/login/components/login_username.jsx
deleted file mode 100644
index 3cb213994..000000000
--- a/webapp/components/login/components/login_username.jsx
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
-// See License.txt for license information.
-
-import * as Utils from 'utils/utils.jsx';
-import UserStore from 'stores/user_store.jsx';
-import Constants from 'utils/constants.jsx';
-
-import {FormattedMessage} from 'react-intl';
-
-import React from 'react';
-
-export default class LoginUsername extends React.Component {
- constructor(props) {
- super(props);
-
- this.handleSubmit = this.handleSubmit.bind(this);
-
- this.state = {
- serverError: props.serverError
- };
- }
- componentWillReceiveProps(nextProps) {
- this.setState({serverError: nextProps.serverError});
- }
- handleSubmit(e) {
- e.preventDefault();
- const state = {};
-
- const username = this.refs.username.value.trim();
- if (!username) {
- state.serverError = Utils.localizeMessage('login_username.usernameReq', 'A username is required');
- this.setState(state);
- return;
- }
-
- const password = this.refs.password.value.trim();
- if (!password) {
- state.serverError = Utils.localizeMessage('login_username.pwdReq', 'A password is required');
- this.setState(state);
- return;
- }
-
- state.serverError = '';
- this.setState(state);
-
- this.props.submit(Constants.USERNAME_SERVICE, username, password);
- }
- render() {
- let serverError;
- let errorClass = '';
- if (this.state.serverError) {
- serverError = <label className='control-label'>{this.state.serverError}</label>;
- errorClass = ' has-error';
- }
-
- let priorUsername = UserStore.getLastUsername();
- let focusUsername = false;
- let focusPassword = false;
- if (priorUsername === '') {
- focusUsername = true;
- } else {
- focusPassword = true;
- }
-
- const emailParam = Utils.getUrlParameter('email');
- if (emailParam) {
- priorUsername = decodeURIComponent(emailParam);
- }
-
- return (
- <form onSubmit={this.handleSubmit}>
- <div className='signup__email-container'>
- <div className={'form-group' + errorClass}>
- {serverError}
- </div>
- <div className={'form-group' + errorClass}>
- <input
- autoFocus={focusUsername}
- type='username'
- className='form-control'
- name='username'
- defaultValue={priorUsername}
- ref='username'
- placeholder={Utils.localizeMessage('login_username.username', 'Username')}
- spellCheck='false'
- />
- </div>
- <div className={'form-group' + errorClass}>
- <input
- autoFocus={focusPassword}
- type='password'
- className='form-control'
- name='password'
- ref='password'
- placeholder={Utils.localizeMessage('login_username.pwd', 'Password')}
- spellCheck='false'
- />
- </div>
- <div className='form-group'>
- <button
- type='submit'
- className='btn btn-primary'
- >
- <FormattedMessage
- id='login_username.signin'
- defaultMessage='Sign in'
- />
- </button>
- </div>
- </div>
- </form>
- );
- }
-}
-LoginUsername.defaultProps = {
-};
-
-LoginUsername.propTypes = {
- serverError: React.PropTypes.string,
- submit: React.PropTypes.func.isRequired
-};
diff --git a/webapp/components/login/login.jsx b/webapp/components/login/login.jsx
index f6c02f6a3..64ef72995 100644
--- a/webapp/components/login/login.jsx
+++ b/webapp/components/login/login.jsx
@@ -1,13 +1,11 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
-import LoginEmail from './components/login_email.jsx';
-import LoginUsername from './components/login_username.jsx';
-import LoginLdap from './components/login_ldap.jsx';
import LoginMfa from './components/login_mfa.jsx';
import ErrorBar from 'components/error_bar.jsx';
+import FormError from 'components/form_error.jsx';
-import * as GlobalActions from '../../action_creators/global_actions.jsx';
+import * as GlobalActions from 'action_creators/global_actions.jsx';
import UserStore from 'stores/user_store.jsx';
import Client from 'utils/web_client.jsx';
@@ -30,10 +28,16 @@ export default class Login extends React.Component {
this.submit = this.submit.bind(this);
this.finishSignin = this.finishSignin.bind(this);
- const state = {};
- state.showMfa = false;
- this.state = state;
+ this.handleLoginIdChange = this.handleLoginIdChange.bind(this);
+ this.handlePasswordChange = this.handlePasswordChange.bind(this);
+
+ this.state = {
+ loginId: '', // the browser will set a default for this
+ password: '',
+ showMfa: false
+ };
}
+
componentDidMount() {
document.title = global.window.mm_config.SiteName;
@@ -41,31 +45,97 @@ export default class Login extends React.Component {
browserHistory.push('/select_team');
}
}
- preSubmit(method, loginId, password) {
+
+ preSubmit(e) {
+ e.preventDefault();
+
+ const loginId = this.state.loginId.trim();
+ if (!loginId) {
+ const ldapEnabled = global.window.mm_config.EnableLdap === 'true';
+ const usernameSigninEnabled = global.window.mm_config.EnableSignInWithUsername === 'true';
+ const emailSigninEnabled = global.window.mm_config.EnableSignInWithEmail === 'true';
+
+ this.setState({
+ serverError: (
+ <FormattedMessage
+ id='login.loginIdRequired'
+ defaultMessage='A {type} is required'
+ values={{
+ type: this.createLoginPlaceholder(emailSigninEnabled, usernameSigninEnabled, ldapEnabled)
+ }}
+ />
+ )
+ });
+
+ return;
+ }
+
+ const password = this.state.password.trim();
+ if (!password) {
+ this.setState({
+ serverError: (
+ <FormattedMessage
+ id='login.passwordRequired'
+ defaultMessage='A password is required'
+ />
+ )
+ });
+
+ return;
+ }
+
if (global.window.mm_config.EnableMultifactorAuthentication !== 'true') {
- this.submit(method, loginId, password, '');
+ this.submit(loginId, password, '');
return;
}
- Client.checkMfa(method, loginId,
+ Client.checkMfa(
+ loginId,
(data) => {
if (data.mfa_required === 'true') {
- this.setState({showMfa: true, method, loginId, password});
+ this.setState({showMfa: true});
} else {
- this.submit(method, loginId, password, '');
+ this.submit(loginId, password, '');
}
},
(err) => {
- if (method === Constants.EMAIL_SERVICE) {
- this.setState({serverEmailError: err.message});
- } else if (method === Constants.USERNAME_SERVICE) {
- this.setState({serverUsernameError: err.message});
- } else if (method === Constants.LDAP_SERVICE) {
- this.setState({serverLdapError: err.message});
+ this.setState({serverError: err.message});
+ }
+ );
+ }
+
+ submit(loginId, password, token) {
+ this.setState({showMfa: false, serverError: null});
+
+ Client.webLogin(
+ loginId,
+ password,
+ token,
+ () => {
+ this.finishSignin();
+ },
+ (err) => {
+ if (err.id === 'api.user.login.not_verified.app_error') {
+ browserHistory.push('/should_verify_email?&email=' + encodeURIComponent(loginId));
+ return;
+ } else if (err.id === 'store.sql_user.get_for_login.app_error' ||
+ err.id === 'ent.ldap.do_login.user_not_registered.app_error' ||
+ err.id === 'ent.ldap.do_login.user_filtered.app_error') {
+ this.setState({
+ serverError: (
+ <FormattedMessage
+ id='login.userNotFound'
+ defaultMessage="We couldn't find an existing account matching your login credentials."
+ />
+ )
+ });
+ } else {
+ this.setState({serverError: err.message});
}
}
);
}
+
finishSignin() {
GlobalActions.emitInitialLoad(
() => {
@@ -74,72 +144,18 @@ export default class Login extends React.Component {
);
}
- submit(method, loginId, password, token) {
- this.setState({showMfa: false, serverEmailError: null, serverUsernameError: null, serverLdapError: null});
-
- if (method === Constants.EMAIL_SERVICE) {
- Client.webLogin(
- loginId,
- null,
- password,
- token,
- () => {
- UserStore.setLastEmail(loginId);
- this.finishSignin();
- },
- (err) => {
- if (err.id === 'api.user.login.not_verified.app_error') {
- browserHistory.push('/should_verify_email?&email=' + encodeURIComponent(loginId));
- return;
- }
- this.setState({serverEmailError: err.message});
- }
- );
- } else if (method === Constants.USERNAME_SERVICE) {
- Client.webLogin(
- null,
- loginId,
- password,
- token,
- () => {
- UserStore.setLastUsername(loginId);
-
- const redirect = Utils.getUrlParameter('redirect');
- if (redirect) {
- browserHistory.push(decodeURIComponent(redirect));
- } else {
- this.finishSignin();
- }
- },
- (err) => {
- if (err.id === 'api.user.login.not_verified.app_error') {
- this.setState({serverUsernameError: Utils.localizeMessage('login_username.verifyEmailError', 'Please verify your email address. Check your inbox for an email.')});
- } else if (err.id === 'store.sql_user.get_by_username.app_error') {
- this.setState({serverUsernameError: Utils.localizeMessage('login_username.userNotFoundError', 'We couldn\'t find an existing account matching your username for this team.')});
- } else {
- this.setState({serverUsernameError: err.message});
- }
- }
- );
- } else if (method === Constants.LDAP_SERVICE) {
- Client.loginByLdap(
- loginId,
- password,
- token,
- () => {
- const redirect = Utils.getUrlParameter('redirect');
- if (redirect) {
- browserHistory.push(decodeURIComponent(redirect));
- } else {
- this.finishSignin();
- }
- },
- (err) => {
- this.setState({serverLdapError: err.message});
- }
- );
- }
+ handleLoginIdChange(e) {
+ this.setState({
+ loginId: e.target.value
+ });
+ }
+
+ handlePasswordChange(e) {
+ this.setState({
+ password: e.target.value
+ });
}
+
createCustomLogin() {
if (global.window.mm_license.IsLicensed === 'true' &&
global.window.mm_license.CustomBrand === 'true' &&
@@ -158,6 +174,36 @@ export default class Login extends React.Component {
return null;
}
+
+ createLoginPlaceholder(emailSigninEnabled, usernameSigninEnabled, ldapEnabled) {
+ const loginPlaceholders = [];
+ if (emailSigninEnabled) {
+ loginPlaceholders.push(Utils.localizeMessage('login.email', 'Email'));
+ }
+
+ if (usernameSigninEnabled) {
+ loginPlaceholders.push(Utils.localizeMessage('login.username', 'Username'));
+ }
+
+ if (ldapEnabled) {
+ if (global.window.mm_config.LdapLoginFieldName) {
+ loginPlaceholders.push(global.window.mm_config.LdapLoginFieldName);
+ } else {
+ loginPlaceholders.push(Utils.localizeMessage('login.ldap_username', 'LDAP Username'));
+ }
+ }
+
+ if (loginPlaceholders.length >= 2) {
+ return loginPlaceholders.slice(0, loginPlaceholders.length - 1).join(', ') +
+ Utils.localizeMessage('login.placeholderOr', ' or ') +
+ loginPlaceholders[loginPlaceholders.length - 1];
+ } else if (loginPlaceholders.length === 1) {
+ return loginPlaceholders[0];
+ }
+
+ return '';
+ }
+
createLoginOptions() {
const extraParam = Utils.getUrlParameter('extra');
let extraBox = '';
@@ -248,76 +294,52 @@ export default class Login extends React.Component {
);
}
- let emailLogin;
- if (emailSigninEnabled) {
- emailLogin = (
- <LoginEmail
- serverError={this.state.serverEmailError}
- submit={this.preSubmit}
- />
- );
-
- if (oauthLogins.length > 0) {
- emailLogin = (
- <div>
- <div className='or__container'>
- <FormattedMessage
- id='login.or'
- defaultMessage='or'
- />
- </div>
- {emailLogin}
- </div>
- );
+ let login = null;
+ if (emailSigninEnabled || usernameSigninEnabled || ldapEnabled) {
+ let errorClass = '';
+ if (this.state.serverError) {
+ errorClass = ' has-error';
}
- }
-
- let usernameLogin;
- if (usernameSigninEnabled) {
- usernameLogin = (
- <LoginUsername
- serverError={this.state.serverUsernameError}
- submit={this.preSubmit}
- />
- );
- if (emailSigninEnabled || oauthLogins.length > 0) {
- usernameLogin = (
- <div>
- <div className='or__container'>
- <FormattedMessage
- id='login.or'
- defaultMessage='or'
+ login = (
+ <form onSubmit={this.preSubmit}>
+ <div className='signup__email-container'>
+ <FormError error={this.state.serverError}/>
+ <div className={'form-group' + errorClass}>
+ <input
+ className='form-control'
+ name='loginId'
+ value={this.state.loginId}
+ onChange={this.handleLoginIdChange}
+ placeholder={this.createLoginPlaceholder(emailSigninEnabled, usernameSigninEnabled, ldapEnabled)}
+ spellCheck='false'
/>
</div>
- {usernameLogin}
- </div>
- );
- }
- }
-
- let ldapLogin;
- if (ldapEnabled) {
- ldapLogin = (
- <LoginLdap
- serverError={this.state.serverLdapError}
- submit={this.preSubmit}
- />
- );
-
- if (emailSigninEnabled || usernameSigninEnabled || oauthLogins.length > 0) {
- ldapLogin = (
- <div>
- <div className='or__container'>
- <FormattedMessage
- id='login.or'
- defaultMessage='or'
+ <div className={'form-group' + errorClass}>
+ <input
+ type='password'
+ className='form-control'
+ name='password'
+ value={this.state.password}
+ onChange={this.handlePasswordChange}
+ placeholder={Utils.localizeMessage('login.password', 'Password')}
+ spellCheck='false'
/>
</div>
- {ldapLogin}
+ <div className='form-group'>
+ <button
+ type='submit'
+ className='btn btn-primary'
+ >
+ <FormattedMessage
+ id='login.signIn'
+ defaultMessage='Sign in'
+ />
+ </button>
+ </div>
</div>
- );
- }
+ </form>
+ );
}
const userSignUp = (
@@ -358,14 +380,13 @@ export default class Login extends React.Component {
<div>
{extraBox}
{oauthLogins}
- {emailLogin}
- {usernameLogin}
- {ldapLogin}
+ {login}
{userSignUp}
{forgotPassword}
</div>
);
}
+
render() {
let content;
let customContent;
@@ -373,7 +394,6 @@ export default class Login extends React.Component {
if (this.state.showMfa) {
content = (
<LoginMfa
- method={this.state.method}
loginId={this.state.loginId}
password={this.state.password}
submit={this.submit}
diff --git a/webapp/components/signup_user_complete.jsx b/webapp/components/signup_user_complete.jsx
index 666e72e13..6dd26f391 100644
--- a/webapp/components/signup_user_complete.jsx
+++ b/webapp/components/signup_user_complete.jsx
@@ -2,7 +2,6 @@
// See License.txt for license information.
import LoadingScreen from 'components/loading_screen.jsx';
-import LoginLdap from 'components/login/components/login_ldap.jsx';
import * as GlobalActions from 'action_creators/global_actions.jsx';
import BrowserStore from 'stores/browser_store.jsx';
@@ -25,7 +24,6 @@ class SignupUserComplete extends React.Component {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
- this.handleLdapSignup = this.handleLdapSignup.bind(this);
this.state = {
data: '',
@@ -150,26 +148,6 @@ class SignupUserComplete extends React.Component {
});
}
- handleLdapSignup(method, loginId, password, token) {
- Client.loginByLdap(loginId, password, token,
- () => {
- const redirect = Utils.getUrlParameter('redirect');
- if (redirect) {
- browserHistory.push(decodeURIComponent(redirect));
- } else {
- GlobalActions.emitInitialLoad(
- () => {
- browserHistory.push('/select_team');
- }
- );
- }
- },
- (err) => {
- this.setState({serverError: err.message});
- }
- );
- }
-
handleSubmit(e) {
e.preventDefault();
@@ -268,15 +246,13 @@ class SignupUserComplete extends React.Component {
this.state.data,
this.state.hash,
this.state.inviteId,
- () => {
+ (data) => {
Client.track('signup', 'signup_user_02_complete');
- Client.login(
- user.email,
- null,
+ Client.loginById(
+ data.id,
user.password,
'',
() => {
- UserStore.setLastEmail(user.email);
if (this.state.hash > 0) {
BrowserStore.setGlobalItem(this.state.hash, JSON.stringify({usedBefore: true}));
}
@@ -455,21 +431,6 @@ class SignupUserComplete extends React.Component {
);
}
- 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_user_completed.withLdap'
- defaultMessage='With your LDAP credentials'
- />
- </strong></h5>
- <LoginLdap submit={this.handleLdapSignup}/>
- </div>
- );
- }
-
let emailSignup;
if (global.window.mm_config.EnableSignUpWithEmail === 'true') {
emailSignup = (
@@ -533,7 +494,7 @@ class SignupUserComplete extends React.Component {
);
}
- if (signupMessage.length > 0 && (emailSignup || ldapSignup)) {
+ if (signupMessage.length > 0 && emailSignup) {
signupMessage = (
<div>
{signupMessage}
@@ -547,21 +508,7 @@ class SignupUserComplete extends React.Component {
);
}
- if (ldapSignup && emailSignup) {
- ldapSignup = (
- <div>
- {ldapSignup}
- <div className='or__container'>
- <FormattedMessage
- id='signup_user_completed.or'
- defaultMessage='or'
- />
- </div>
- </div>
- );
- }
-
- if (signupMessage.length === 0 && !emailSignup && !ldapSignup) {
+ if (signupMessage.length === 0 && !emailSignup) {
emailSignup = (
<div>
<FormattedMessage
@@ -586,7 +533,6 @@ class SignupUserComplete extends React.Component {
if (this.state.noOpenServerError) {
signupMessage = null;
- ldapSignup = null;
emailSignup = null;
terms = null;
}
@@ -620,7 +566,6 @@ class SignupUserComplete extends React.Component {
/>
</h4>
{signupMessage}
- {ldapSignup}
{emailSignup}
{serverError}
{terms}
diff --git a/webapp/i18n/en.json b/webapp/i18n/en.json
index 3bceb978c..fbbf66fbd 100644
--- a/webapp/i18n/en.json
+++ b/webapp/i18n/en.json
@@ -953,41 +953,29 @@
"login.changed": " Sign-in method changed successfully",
"login.create": "Create one now",
"login.createTeam": "Create a new team",
+ "login.email": "Email",
"login.find": "Find your other teams",
"login.forgot": "I forgot my password",
+ "login.loginIdRequired": "A {type} is required",
"login.gitlab": "with GitLab",
"login.google": "with Google Apps",
+ "login.ldapUsername": "LDAP Username",
"login.noAccount": "Don't have an account? ",
"login.on": "on {siteName}",
"login.or": "or",
+ "login.password": "Password",
"login.passwordChanged": " Password updated successfully",
+ "login.passwordRequired": "A password is required",
"login.session_expired": " Your session has expired. Please login again.",
+ "login.signIn": "Sign in",
"login.signTo": "Sign in to:",
+ "login.username": "Username",
+ "login.userNotFound": "We couldn't find an existing account matching your login credentials.",
"login.verified": " Email Verified",
- "login_email.badTeam": "Bad team name",
- "login_email.email": "Email",
- "login_email.emailReq": "An email is required",
- "login_email.pwd": "Password",
- "login_email.pwdReq": "A password is required",
- "login_email.signin": "Sign in",
- "login_ldap.badTeam": "Bad team name",
- "login_ldap.idlReq": "An LDAP ID is required",
- "login_ldap.pwd": "LDAP Password",
- "login_ldap.pwdReq": "An LDAP password is required",
- "login_ldap.signin": "Sign in",
- "login_ldap.username": "LDAP Username",
"login_mfa.enterToken": "To complete the sign in process, please enter a token from your smartphone's authenticator",
"login_mfa.submit": "Submit",
"login_mfa.token": "MFA Token",
"login_mfa.tokenReq": "Please enter an MFA token",
- "login_username.badTeam": "Bad team name",
- "login_username.pwd": "Password",
- "login_username.pwdReq": "A password is required",
- "login_username.signin": "Sign in",
- "login_username.userNotFoundError": "We couldn't find an existing account matching your username for this team.",
- "login_username.username": "Username",
- "login_username.usernameReq": "A username is required",
- "login_username.verifyEmailError": "Please verify your email address. Check your inbox for an email.",
"member_item.makeAdmin": "Make Admin",
"member_item.member": "Member",
"member_list.noUsersAdd": "No users to add.",
diff --git a/webapp/i18n/es.json b/webapp/i18n/es.json
index 78645b769..34e4360b5 100644
--- a/webapp/i18n/es.json
+++ b/webapp/i18n/es.json
@@ -953,41 +953,27 @@
"login.changed": " Cambiado el método de inicio de sesión satisfactoriamente",
"login.create": "Crea una ahora",
"login.createTeam": "Crear un nuevo equipo",
+ "login.email": "Correo electrónico",
"login.find": "Encuentra tus otros equipos",
"login.forgot": "Olvide mi contraseña",
"login.gitlab": "con GitLab",
"login.google": "con Google Apps",
+ "login.ldapUsername": "Usuario LDAP",
"login.noAccount": "¿No tienes una cuenta? ",
"login.on": "en {siteName}",
"login.or": "o",
+ "login.password": "Contraseña",
"login.passwordChanged": " La contraseña ha sido actualizada",
+ "login.passwordRequired": "La contraseña es obligatoria",
"login.session_expired": " Tu sesión ha expirado. Por favor inicia sesión nuevamente.",
+ "login.signIn": "Entrar",
"login.signTo": "Ingresar a:",
+ "login.username": "Nombre de usuario",
"login.verified": " Correo electrónico Verificado",
- "login_email.badTeam": "Nombre de Equipo inválido",
- "login_email.email": "Correo electrónico",
- "login_email.emailReq": "El correo electrónico es obligatorio",
- "login_email.pwd": "Contraseña",
- "login_email.pwdReq": "La contraseña es obligatoria",
- "login_email.signin": "Entrar",
- "login_ldap.badTeam": "Nombre de Equipo inválido",
- "login_ldap.idlReq": "El ID de LDAP es obligatorio",
- "login_ldap.pwd": "Contraseña LDAP",
- "login_ldap.pwdReq": "La contraseña LDAP es obligatoria",
- "login_ldap.signin": "Entrar",
- "login_ldap.username": "Usuario LDAP",
"login_mfa.enterToken": "Para completar el proceso de inicio de sesión, por favor ingresa el token provisto por el autenticador de tu teléfono inteligente",
"login_mfa.submit": "Enviar",
"login_mfa.token": "Token AMF",
"login_mfa.tokenReq": "Por favor ingresa un token AMF",
- "login_username.badTeam": "Mal nombre de equipo",
- "login_username.pwd": "Contraseña",
- "login_username.pwdReq": "La contraseña es obligatoria",
- "login_username.signin": "Ingresar",
- "login_username.userNotFoundError": "No encontramos una cuenta existente que coincida con tu nombre de usuario en este equipo.",
- "login_username.username": "Nombre de usuario",
- "login_username.usernameReq": "El nombre de usuario es obligatorio",
- "login_username.verifyEmailError": "Por favor válida tu dirección de correo electrónico. Te hemos enviado un correo, revisa tu bandeja de entrada.",
"member_item.makeAdmin": "Convertir en Admin de Equipo",
"member_item.member": "Miembro",
"member_list.noUsersAdd": "No hay usuarios que agregar.",
diff --git a/webapp/i18n/fr.json b/webapp/i18n/fr.json
index 39267f8b9..c92dff181 100644
--- a/webapp/i18n/fr.json
+++ b/webapp/i18n/fr.json
@@ -818,36 +818,22 @@
"login.changed": "Méthode de connexion changée",
"login.create": "Créer maintenant",
"login.createTeam": "Créer une nouvelle équipe",
+ "login.email": "Adresse électronique",
"login.find": "Trouver vos autres équipes",
"login.forgot": "Mot de passe perdu",
"login.gitlab": "avec GitLab",
"login.google": "avec Google Apps",
+ "login.ldapUsername": "Utilisateur LDAP",
"login.noAccount": "Pas de compte utilisateur ?",
"login.on": "sur {siteName}",
"login.or": "ou",
+ "login.password": "Mot de passe",
+ "login.passwordRequired": "Le mot de passe est obligatoire",
"login.session_expired": "Votre session a expiré. Merci de vous reconnecter.",
+ "login.signIn": "Connexion",
"login.signTo": "Se connecter à :",
+ "login.username": "Nom d'utilisateur",
"login.verified": "Adresse électronique vérifiée",
- "login_email.badTeam": "Erreur dans le nom de l'équipe",
- "login_email.email": "Adresse électronique",
- "login_email.emailReq": "Une adresse électronique est obligatoire",
- "login_email.pwd": "Mot de passe",
- "login_email.pwdReq": "Le mot de passe est obligatoire",
- "login_email.signin": "Connexion",
- "login_ldap.badTeam": "Erreur dans le nom de l'équipe",
- "login_ldap.idlReq": "Un identifiant LDAP est obligatoire",
- "login_ldap.pwd": "Mot de passe LDAP",
- "login_ldap.pwdReq": "Un mot de passe LDAP est obligatoire",
- "login_ldap.signin": "Connexion",
- "login_ldap.username": "Utilisateur LDAP",
- "login_username.badTeam": "Erreur dans le nom de l'équipe",
- "login_username.pwd": "Mot de passe",
- "login_username.pwdReq": "Mot de passe obligatoire",
- "login_username.signin": "Connexion",
- "login_username.userNotFoundError": "Impossible de trouver un compte utilisateur à ce nom dans cette équipe.",
- "login_username.username": "Nom d'utilisateur",
- "login_username.usernameReq": "Le nom d'utilisateur est obligatoire",
- "login_username.verifyEmailError": "Vérifiez votre adresse électronique. Cherchez le courriel dans votre boîte de réception.",
"member_item.makeAdmin": "Passer Administrateur",
"member_item.member": "Membre",
"member_list.noUsersAdd": "Aucun utilisateur à ajouter.",
diff --git a/webapp/i18n/ja.json b/webapp/i18n/ja.json
index 290c6b5d5..88e10498e 100644
--- a/webapp/i18n/ja.json
+++ b/webapp/i18n/ja.json
@@ -915,40 +915,26 @@
"login.changed": "サインイン方法が変更されました",
"login.create": "ただいま作成しています",
"login.createTeam": "新しいチームを作成する",
+ "login.email": "電子メールアドレス",
"login.find": "参加している他のチームを探す",
"login.forgot": "パスワードを忘れました",
"login.gitlab": "GitLabでログインする",
"login.google": "Google Appsでログインする",
+ "login.ldapUsername": "LDAPユーザー名",
"login.noAccount": "アカウントを持っていますか? ",
"login.on": "{siteName}にて",
"login.or": "または",
+ "login.password": "パスワード",
+ "login.passwordRequired": "パスワードは必須です",
"login.session_expired": " あなたのセッションは有効期限が切れました。再度ログインしてください。",
+ "login.signIn": "利用登録",
"login.signTo": "利用登録先: ",
+ "login.username": "LDAPユーザー名",
"login.verified": " 電子メールアドレスが確認されました",
- "login_email.badTeam": "無効なチーム名です",
- "login_email.email": "電子メールアドレス",
- "login_email.emailReq": "電子メールアドレスは必須です",
- "login_email.pwd": "パスワード",
- "login_email.pwdReq": "パスワードは必須です",
- "login_email.signin": "利用登録",
- "login_ldap.badTeam": "無効なチーム名です",
- "login_ldap.idlReq": "LDAP IDは必須です",
- "login_ldap.pwd": "LDAPパスワード",
- "login_ldap.pwdReq": "LDAPパスワードは必須です",
- "login_ldap.signin": "利用登録",
- "login_ldap.username": "LDAPユーザー名",
"login_mfa.enterToken": "利用登録を完了するには、スマートフォンのauthenticatorからのトークンを入力してください。",
"login_mfa.submit": "送信する",
"login_mfa.token": "MFAトークン",
"login_mfa.tokenReq": "MFAトークンを入力してください",
- "login_username.badTeam": "無効なチーム名です",
- "login_username.pwd": "パスワード",
- "login_username.pwdReq": "パスワードは必須です",
- "login_username.signin": "利用登録",
- "login_username.userNotFoundError": "このチームにはあなたのユーザー名に合致するアカウントはありません。",
- "login_username.username": "ユーザー名",
- "login_username.usernameReq": "ユーザー名は必須です",
- "login_username.verifyEmailError": "電子メールアドレスを確認します。電子メールの受信ボックスを見てみてください。",
"member_item.makeAdmin": "管理者にする",
"member_item.member": "メンバー",
"member_list.noUsersAdd": "ユーザーは追加されません。",
diff --git a/webapp/i18n/pt.json b/webapp/i18n/pt.json
index 8daf1fe70..2edbc40e9 100644
--- a/webapp/i18n/pt.json
+++ b/webapp/i18n/pt.json
@@ -911,40 +911,26 @@
"login.changed": " Método de login alterada com sucesso",
"login.create": "Crie um agora",
"login.createTeam": "Criar uma nova equipe",
+ "login.email": "E-mail",
"login.find": "Encontre suas outras equipes",
"login.forgot": "Eu esqueci a minha senha",
"login.gitlab": "com GitLab",
"login.google": "com Google Apps",
+ "login.ldapUsername": "Usuário LDAP",
"login.noAccount": "Não tem uma conta? ",
"login.on": "no {siteName}",
"login.or": "ou",
+ "login.password": "Senha",
+ "login.passwordRequired": "É necessário uma senha",
"login.session_expired": " Sua sessão expirou. Por favor faça login novamente.",
+ "login.signIn": "Login",
"login.signTo": "Login em:",
+ "login.username": "Usuário",
"login.verified": " Email Verificado",
- "login_email.badTeam": "Nome ruim de equipe",
- "login_email.email": "E-mail",
- "login_email.emailReq": "Um email é necessário",
- "login_email.pwd": "Senha",
- "login_email.pwdReq": "É necessário uma senha",
- "login_email.signin": "Login",
- "login_ldap.badTeam": "Nome de equipe ruim",
- "login_ldap.idlReq": "Um ID LDAP é necessário",
- "login_ldap.pwd": "Senha LDAP",
- "login_ldap.pwdReq": "É necessário uma senha do LDAP",
- "login_ldap.signin": "Login",
- "login_ldap.username": "Usuário LDAP",
"login_mfa.enterToken": "Para completar o login em processo, por favor entre um token do seu autenticador no smartphone",
"login_mfa.submit": "Enviar",
"login_mfa.token": "Token MFA",
"login_mfa.tokenReq": "Por favor entre um token MFA",
- "login_username.badTeam": "Nome de equipe ruim",
- "login_username.pwd": "Senha",
- "login_username.pwdReq": "É necessário uma senha",
- "login_username.signin": "Login",
- "login_username.userNotFoundError": "Não foi possível encontrar uma conta existente que corresponda ao seu usuário para esta equipe.",
- "login_username.username": "Usuário",
- "login_username.usernameReq": "Um nome de usuário é necessário",
- "login_username.verifyEmailError": "Por favor verifique seu endereço de email. Verifique por um email na sua caixa de entrada.",
"member_item.makeAdmin": "Tornar Admin",
"member_item.member": "Membro",
"member_list.noUsersAdd": "Nenhum usuário para adicionar.",
diff --git a/webapp/stores/user_store.jsx b/webapp/stores/user_store.jsx
index 2c6bfade3..8d685aea3 100644
--- a/webapp/stores/user_store.jsx
+++ b/webapp/stores/user_store.jsx
@@ -6,7 +6,6 @@ import EventEmitter from 'events';
import Constants from 'utils/constants.jsx';
const ActionTypes = Constants.ActionTypes;
-import BrowserStore from './browser_store.jsx';
const CHANGE_EVENT = 'change';
const CHANGE_EVENT_SESSIONS = 'change_sessions';
@@ -97,22 +96,6 @@ class UserStoreClass extends EventEmitter {
return null;
}
- getLastEmail() {
- return BrowserStore.getGlobalItem('last_email', '');
- }
-
- setLastEmail(email) {
- BrowserStore.setGlobalItem('last_email', email);
- }
-
- getLastUsername() {
- return BrowserStore.getGlobalItem('last_username', '');
- }
-
- setLastUsername(username) {
- BrowserStore.setGlobalItem('last_username', username);
- }
-
hasProfile(userId) {
return this.getProfiles()[userId] != null;
}
diff --git a/webapp/tests/client_user.test.jsx b/webapp/tests/client_user.test.jsx
index e0ead2de9..7835a38bf 100644
--- a/webapp/tests/client_user.test.jsx
+++ b/webapp/tests/client_user.test.jsx
@@ -66,7 +66,6 @@ describe('Client.User', function() {
function() {
client.login(
user.email,
- null,
user.password,
null,
function(data) {
@@ -85,15 +84,15 @@ describe('Client.User', function() {
);
});
- it('loginByUsername', function(done) {
+ it('loginById', function(done) {
var client = TestHelper.createClient();
var user = TestHelper.fakeUser();
client.createUser(
user,
- function() {
- client.login(
- null,
- user.username,
+ function(newUser) {
+ assert.equal(user.email, newUser.email);
+ client.loginById(
+ newUser.id,
user.password,
null,
function(data) {
@@ -112,14 +111,14 @@ describe('Client.User', function() {
);
});
- it('loginByLdap', function(done) {
+ it('loginByUsername', function(done) {
var client = TestHelper.createClient();
client.enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
var user = TestHelper.fakeUser();
client.createUser(
user,
function() {
- client.loginByLdap(
+ client.login(
user.username,
user.password,
null,
@@ -127,7 +126,8 @@ describe('Client.User', function() {
done(new Error());
},
function(err) {
- assert.equal(err.id, 'api.user.login_ldap.disabled.app_error');
+ // should error out because logging in by username is disabled by default
+ assert.equal(err.id, 'store.sql_user.get_for_login.app_error');
done();
}
);
@@ -372,7 +372,6 @@ describe('Client.User', function() {
it('checkMfa', function(done) {
TestHelper.initBasic(() => {
TestHelper.basicClient().checkMfa(
- 'email',
TestHelper.generateId(),
function(data) {
assert.equal(data.mfa_required, 'false');
diff --git a/webapp/tests/test_helper.jsx b/webapp/tests/test_helper.jsx
index 385279360..f19d96433 100644
--- a/webapp/tests/test_helper.jsx
+++ b/webapp/tests/test_helper.jsx
@@ -128,7 +128,6 @@ class TestHelperClass {
outer.basicClient().setTeamId(outer.basict.id);
outer.basicClient().login(
rteamSignup.user.email,
- null,
password,
null,
function() {
diff --git a/webapp/utils/web_client.jsx b/webapp/utils/web_client.jsx
index a9851442b..3efb32806 100644
--- a/webapp/utils/web_client.jsx
+++ b/webapp/utils/web_client.jsx
@@ -39,14 +39,13 @@ class WebClientClass extends Client {
// not sure why but super.login doesn't work if using an () => arrow functions.
// I think this might be a webpack issue.
- webLogin(email, username, password, token, success, error) {
+ webLogin(loginId, password, token, success, error) {
this.login(
- email,
- username,
+ loginId,
password,
token,
(data) => {
- this.track('api', 'api_users_login_success', '', 'email', data.email);
+ this.track('api', 'api_users_login_success', '', 'login_id', loginId);
BrowserStore.signalLogin();
if (success) {
@@ -54,7 +53,7 @@ class WebClientClass extends Client {
}
},
(err) => {
- this.track('api', 'api_users_login_fail', name, 'email', email);
+ this.track('api', 'api_users_login_fail', name, 'login_id', loginId);
if (error) {
error(err);
}