// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
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 'actions/global_actions.jsx';
import {addUserToTeamFromInvite} from 'actions/team_actions.jsx';
import {checkMfa, webLogin} from 'actions/user_actions.jsx';
import BrowserStore from 'stores/browser_store.jsx';
import UserStore from 'stores/user_store.jsx';
import Client from 'client/web_client.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import * as TextFormatting from 'utils/text_formatting.jsx';
import * as Utils from 'utils/utils.jsx';
import Constants from 'utils/constants.jsx';
import {FormattedMessage} from 'react-intl';
import {browserHistory, Link} from 'react-router/es6';
import React from 'react';
import logoImage from 'images/logo.png';
export default class LoginController extends React.Component {
static get propTypes() {
return {
location: React.PropTypes.object.isRequired,
params: React.PropTypes.object.isRequired
};
}
constructor(props) {
super(props);
this.preSubmit = this.preSubmit.bind(this);
this.submit = this.submit.bind(this);
this.finishSignin = this.finishSignin.bind(this);
this.handleLoginIdChange = this.handleLoginIdChange.bind(this);
this.handlePasswordChange = this.handlePasswordChange.bind(this);
let loginId = '';
if (this.props.location.query.extra === Constants.SIGNIN_VERIFIED && this.props.location.query.email) {
loginId = this.props.location.query.email;
}
this.state = {
ldapEnabled: global.window.mm_license.IsLicensed === 'true' && global.window.mm_config.EnableLdap === 'true',
usernameSigninEnabled: global.window.mm_config.EnableSignInWithUsername === 'true',
emailSigninEnabled: global.window.mm_config.EnableSignInWithEmail === 'true',
samlEnabled: global.window.mm_license.IsLicensed === 'true' && global.window.mm_config.EnableSaml === 'true',
loginId,
password: '',
showMfa: false,
loading: false
};
}
componentDidMount() {
document.title = global.window.mm_config.SiteName;
BrowserStore.removeGlobalItem('team');
if (UserStore.getCurrentUser()) {
GlobalActions.redirectUserToDefaultTeam();
}
if (this.props.location.query.extra === Constants.SIGNIN_VERIFIED && this.props.location.query.email) {
this.refs.password.focus();
}
AsyncClient.checkVersion();
}
preSubmit(e) {
e.preventDefault();
// password managers don't always call onInput handlers for form fields so it's possible
// for the state to get out of sync with what the user sees in the browser
let loginId = this.refs.loginId.value;
if (loginId !== this.state.loginId) {
this.setState({loginId});
}
const password = this.refs.password.value;
if (password !== this.state.password) {
this.setState({password});
}
// don't trim the password since we support spaces in passwords
loginId = loginId.trim().toLowerCase();
if (!loginId) {
// it's slightly weird to be constructing the message ID, but it's a bit nicer than triply nested if statements
let msgId = 'login.no';
if (this.state.emailSigninEnabled) {
msgId += 'Email';
}
if (this.state.usernameSigninEnabled) {
msgId += 'Username';
}
if (this.state.ldapEnabled) {
msgId += 'LdapUsername';
}
this.setState({
serverError: (
)
});
return;
}
if (!password) {
this.setState({
serverError: (
)
});
return;
}
checkMfa(
loginId,
(requiresMfa) => {
if (requiresMfa) {
this.setState({showMfa: true});
} else {
this.submit(loginId, password, '');
}
},
(err) => {
this.setState({serverError: err.message});
}
);
}
submit(loginId, password, token) {
this.setState({serverError: null, loading: true});
webLogin(
loginId,
password,
token,
() => {
// check for query params brought over from signup_user_complete
const hash = this.props.location.query.h;
const data = this.props.location.query.d;
const inviteId = this.props.location.query.id;
if (inviteId || hash) {
addUserToTeamFromInvite(
data,
hash,
inviteId,
(team) => {
this.finishSignin(team);
},
() => {
// there's not really a good way to deal with this, so just let the user log in like normal
this.finishSignin();
}
);
return;
}
this.finishSignin();
},
(err) => {
if (err.id === 'api.user.login.not_verified.app_error') {
browserHistory.push('/should_verify_email?&email=' + encodeURIComponent(loginId));
} else if (err.id === 'store.sql_user.get_for_login.app_error' ||
err.id === 'ent.ldap.do_login.user_not_registered.app_error') {
this.setState({
showMfa: false,
loading: false,
serverError: (
)
});
} else if (err.id === 'api.user.check_user_password.invalid.app_error' || err.id === 'ent.ldap.do_login.invalid_password.app_error') {
this.setState({
showMfa: false,
loading: false,
serverError: (
)
});
} else {
this.setState({showMfa: false, serverError: err.message, loading: false});
}
}
);
}
finishSignin(team) {
const query = this.props.location.query;
GlobalActions.loadDefaultLocale();
if (query.redirect_to) {
browserHistory.push(query.redirect_to);
} else if (team) {
browserHistory.push(`/${team.name}`);
} else {
GlobalActions.redirectUserToDefaultTeam();
}
}
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' &&
global.window.mm_config.EnableCustomBrand === 'true') {
const text = global.window.mm_config.CustomBrandText || '';
return (
);
}
return null;
}
createLoginPlaceholder() {
const ldapEnabled = this.state.ldapEnabled;
const usernameSigninEnabled = this.state.usernameSigninEnabled;
const emailSigninEnabled = this.state.emailSigninEnabled;
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.ldapUsername', 'AD/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 '';
}
checkSignUpEnabled() {
return global.window.mm_config.EnableSignUpWithEmail === 'true' ||
global.window.mm_config.EnableSignUpWithGitLab === 'true' ||
global.window.mm_config.EnableSignUpWithOffice365 === 'true' ||
global.window.mm_config.EnableSignUpWithGoogle === 'true' ||
global.window.mm_config.EnableLdap === 'true' ||
global.window.mm_config.EnableSaml === 'true';
}
createLoginOptions() {
const extraParam = this.props.location.query.extra;
let extraBox = '';
if (extraParam) {
if (extraParam === Constants.SIGNIN_CHANGE) {
extraBox = (
);
} else if (extraParam === Constants.SIGNIN_VERIFIED) {
extraBox = (
);
} else if (extraParam === Constants.SESSION_EXPIRED) {
extraBox = (
);
} else if (extraParam === Constants.PASSWORD_CHANGE) {
extraBox = (
);
}
}
const loginControls = [];
const ldapEnabled = this.state.ldapEnabled;
const gitlabSigninEnabled = global.window.mm_config.EnableSignUpWithGitLab === 'true';
const googleSigninEnabled = global.window.mm_config.EnableSignUpWithGoogle === 'true';
const office365SigninEnabled = global.window.mm_config.EnableSignUpWithOffice365 === 'true';
const samlSigninEnabled = this.state.samlEnabled;
const usernameSigninEnabled = this.state.usernameSigninEnabled;
const emailSigninEnabled = this.state.emailSigninEnabled;
if (emailSigninEnabled || usernameSigninEnabled || ldapEnabled) {
let errorClass = '';
if (this.state.serverError) {
errorClass = ' has-error';
}
let loginButton =
();
if (this.state.loading) {
loginButton =
(
);
}
loginControls.push(
);
}
if (global.window.mm_config.EnableOpenServer === 'true' && this.checkSignUpEnabled()) {
loginControls.push(
);
}
if (usernameSigninEnabled || emailSigninEnabled) {
loginControls.push(
);
}
if ((emailSigninEnabled || usernameSigninEnabled || ldapEnabled) && (gitlabSigninEnabled || googleSigninEnabled || samlSigninEnabled || office365SigninEnabled)) {
loginControls.push(
);
loginControls.push(
);
}
if (gitlabSigninEnabled) {
loginControls.push(
);
}
if (googleSigninEnabled) {
loginControls.push(
);
}
if (office365SigninEnabled) {
loginControls.push(
);
}
if (samlSigninEnabled) {
loginControls.push(
{global.window.mm_config.SamlLoginButtonText}
);
}
if (loginControls.length === 0) {
loginControls.push(
}
margin={true}
/>
);
}
return (
{extraBox}
{loginControls}
);
}
render() {
let content;
let customContent;
let customClass;
if (this.state.showMfa) {
content = (
);
} else {
content = this.createLoginOptions();
customContent = this.createCustomLogin();
if (customContent) {
customClass = 'branded';
}
}
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 (
{customContent}
{global.window.mm_config.SiteName}
{description}
{content}
);
}
}