* Adding TeamMember to system * Fixing all unit tests on the backend * Fixing merge conflicts * Fixing merge conflict * Adding javascript unit tests * Adding TeamMember to system * Fixing all unit tests on the backend * Fixing merge conflicts * Fixing merge conflict * Adding javascript unit tests * Adding client side unit test * Cleaning up the clint side tests * Fixing msg * Adding more client side unit tests * Adding more using tests * Adding last bit of client side unit tests and adding make cmd * Fixing bad merge * Fixing libraries * Updating to new client side API * Fixing borken unit test * Fixing unit tests * ugg...trying to beat gofmt * ugg...trying to beat gofmt * Cleaning up remainder of the server side routes * Adding inital load api * Increased coverage of webhook unit tests (#2660) * Adding loading ... to root html * Fixing bad merge * Removing explicit content type so superagent will guess corectly (#2685) * Fixing merge and unit tests * Adding create team UI * Fixing signup flows * Adding LDAP unit tests and enterprise unit test helper (#2702) * Add the ability to reset MFA from the commandline (#2706) * Fixing compliance unit tests * Fixing client side tests * Adding open server to system console * Moving websocket connection * Fixing unit test * Fixing unit tests * Fixing unit tests * Adding nickname and more LDAP unit tests (#2717) * Adding join open teams * Cleaning up all TODOs in the code * Fixing web sockets * Removing unused webockets file * PLT-2533 Add the ability to reset a user's MFA from the system console (#2715) * Add the ability to reset a user's MFA from the system console * Add client side unit test for adminResetMfa * Reorganizing authentication to fix LDAP error message (#2723) * Fixing failing unit test * Initial upgrade db code * Adding upgrade script * Fixing upgrade script after running on core * Update OAuth and Claim routes to work with user model changes (#2739) * Fixing perminant deletion. Adding ability to delete all user and the entire database (#2740) * Fixing team invite ldap login call (#2741) * Fixing bluebar and some img stuff * Fix all the different file upload web utils (#2743) * Fixing invalid session redirect (#2744) * Redirect on bad channel name (#2746) * Fixing a bunch of issue and removing dead code * Patch to fix error message on leave channel (#2747) * Setting EnableOpenServer to false by default * Fixing config * Fixing upgrade * Fixing reported bugs * Bug fixes for PLT-2057 * PLT-2563 Redo password recovery to use a database table (#2745) * Redo password recovery to use a database table * Update reset password audits * Split out admin and user reset password APIs to be separate * Delete password recovery when user is permanently deleted * Consolidate password resetting into a single function * Removed private channels as an option for outgoing webhooks (#2752) * PLT-2577/PLT-2552 Fixes for backstage (#2753) * Added URL to incoming webhook list * Fixed client functions for adding/removing integrations * Disallowed slash commands without trigger words * Fixed clientside handling of errors on AddCommand page * Minor auth cleanup (#2758) * Changed EditPostModal to just close if you save without making any changes (#2759) * Renamed client -> Client in async_client.jsx and fixed eslint warnings (#2756) * Fixed url in channel info modal (#2755) * Fixing reported issues * Moving to version 3 of the apis * Fixing command unit tests (#2760) * Adding team admins * Fixing DM issue * Fixing eslint error * Properly set EditPostModal's originalText state in all cases (#2762) * Update client config check to assume features is defined if server is licensed (#2772) * Fixing url link * Fixing issue with websocket crashing when sending messages to different teams
946 строки
46 KiB
JavaScript
946 строки
46 KiB
JavaScript
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
|
// See License.txt for license information.
|
|
|
|
import $ from 'jquery';
|
|
import ReactDOM from 'react-dom';
|
|
import Client from 'utils/web_client.jsx';
|
|
import * as AsyncClient from 'utils/async_client.jsx';
|
|
import crypto from 'crypto';
|
|
import ConnectionSecurityDropdownSetting from './connection_security_dropdown_setting.jsx';
|
|
|
|
import {injectIntl, intlShape, defineMessages, FormattedMessage, FormattedHTMLMessage} from 'react-intl';
|
|
|
|
var holders = defineMessages({
|
|
notificationDisplayExample: {
|
|
id: 'admin.email.notificationDisplayExample',
|
|
defaultMessage: 'Ex: "Mattermost Notification", "System", "No-Reply"'
|
|
},
|
|
notificationEmailExample: {
|
|
id: 'admin.email.notificationEmailExample',
|
|
defaultMessage: 'Ex: "mattermost@yourcompany.com", "admin@yourcompany.com"'
|
|
},
|
|
smtpUsernameExample: {
|
|
id: 'admin.email.smtpUsernameExample',
|
|
defaultMessage: 'Ex: "admin@yourcompany.com", "AKIADTOVBGERKLCBV"'
|
|
},
|
|
smtpPasswordExample: {
|
|
id: 'admin.email.smtpPasswordExample',
|
|
defaultMessage: 'Ex: "yourpassword", "jcuS8PuvcpGhpgHhlcpT1Mx42pnqMxQY"'
|
|
},
|
|
smtpServerExample: {
|
|
id: 'admin.email.smtpServerExample',
|
|
defaultMessage: 'Ex: "smtp.yourcompany.com", "email-smtp.us-east-1.amazonaws.com"'
|
|
},
|
|
smtpPortExample: {
|
|
id: 'admin.email.smtpPortExample',
|
|
defaultMessage: 'Ex: "25", "465"'
|
|
},
|
|
inviteSaltExample: {
|
|
id: 'admin.email.inviteSaltExample',
|
|
defaultMessage: 'Ex "bjlSR4QqkXFBr7TP4oDzlfZmcNuH9Yo"'
|
|
},
|
|
passwordSaltExample: {
|
|
id: 'admin.email.passwordSaltExample',
|
|
defaultMessage: 'Ex "bjlSR4QqkXFBr7TP4oDzlfZmcNuH9Yo"'
|
|
},
|
|
pushServerEx: {
|
|
id: 'admin.email.pushServerEx',
|
|
defaultMessage: 'E.g.: "http://push-test.mattermost.com"'
|
|
},
|
|
genericPush: {
|
|
id: 'admin.email.genericPushNotification',
|
|
defaultMessage: 'Send generic description with user and channel names'
|
|
},
|
|
fullPush: {
|
|
id: 'admin.email.fullPushNotification',
|
|
defaultMessage: 'Send full message snippet'
|
|
},
|
|
testing: {
|
|
id: 'admin.email.testing',
|
|
defaultMessage: 'Testing...'
|
|
},
|
|
saving: {
|
|
id: 'admin.email.saving',
|
|
defaultMessage: 'Saving Config...'
|
|
}
|
|
});
|
|
|
|
import React from 'react';
|
|
|
|
class EmailSettings extends React.Component {
|
|
constructor(props) {
|
|
super(props);
|
|
|
|
this.handleChange = this.handleChange.bind(this);
|
|
this.handleTestConnection = this.handleTestConnection.bind(this);
|
|
this.handleSubmit = this.handleSubmit.bind(this);
|
|
this.buildConfig = this.buildConfig.bind(this);
|
|
this.handleGenerateInvite = this.handleGenerateInvite.bind(this);
|
|
this.handleGenerateReset = this.handleGenerateReset.bind(this);
|
|
|
|
this.state = {
|
|
sendEmailNotifications: this.props.config.EmailSettings.SendEmailNotifications,
|
|
sendPushNotifications: this.props.config.EmailSettings.SendPushNotifications,
|
|
saveNeeded: false,
|
|
serverError: null,
|
|
emailSuccess: null,
|
|
emailFail: null,
|
|
pushNotificationContents: this.props.config.EmailSettings.PushNotificationContents,
|
|
connectionSecurity: this.props.config.EmailSettings.ConnectionSecurity
|
|
};
|
|
}
|
|
|
|
handleChange(action) {
|
|
var s = {saveNeeded: true, serverError: this.state.serverError};
|
|
|
|
if (action === 'sendEmailNotifications_true') {
|
|
s.sendEmailNotifications = true;
|
|
}
|
|
|
|
if (action === 'sendEmailNotifications_false') {
|
|
s.sendEmailNotifications = false;
|
|
}
|
|
|
|
if (action === 'sendPushNotifications_true') {
|
|
s.sendPushNotifications = true;
|
|
}
|
|
|
|
if (action === 'sendPushNotifications_false') {
|
|
s.sendPushNotifications = false;
|
|
}
|
|
|
|
this.setState(s);
|
|
}
|
|
|
|
buildConfig() {
|
|
var config = this.props.config;
|
|
config.EmailSettings.EnableSignUpWithEmail = ReactDOM.findDOMNode(this.refs.allowSignUpWithEmail).checked;
|
|
config.EmailSettings.EnableSignInWithEmail = ReactDOM.findDOMNode(this.refs.allowSignInWithEmail).checked;
|
|
config.EmailSettings.EnableSignInWithUsername = ReactDOM.findDOMNode(this.refs.allowSignInWithUsername).checked;
|
|
config.EmailSettings.SendEmailNotifications = ReactDOM.findDOMNode(this.refs.sendEmailNotifications).checked;
|
|
config.EmailSettings.SendPushNotifications = ReactDOM.findDOMNode(this.refs.sendPushNotifications).checked;
|
|
config.EmailSettings.RequireEmailVerification = ReactDOM.findDOMNode(this.refs.requireEmailVerification).checked;
|
|
config.EmailSettings.FeedbackName = ReactDOM.findDOMNode(this.refs.feedbackName).value.trim();
|
|
config.EmailSettings.FeedbackEmail = ReactDOM.findDOMNode(this.refs.feedbackEmail).value.trim();
|
|
config.EmailSettings.SMTPServer = ReactDOM.findDOMNode(this.refs.SMTPServer).value.trim();
|
|
config.EmailSettings.PushNotificationServer = ReactDOM.findDOMNode(this.refs.PushNotificationServer).value.trim();
|
|
config.EmailSettings.PushNotificationContents = ReactDOM.findDOMNode(this.refs.PushNotificationContents).value;
|
|
config.EmailSettings.SMTPPort = ReactDOM.findDOMNode(this.refs.SMTPPort).value.trim();
|
|
config.EmailSettings.SMTPUsername = ReactDOM.findDOMNode(this.refs.SMTPUsername).value.trim();
|
|
config.EmailSettings.SMTPPassword = ReactDOM.findDOMNode(this.refs.SMTPPassword).value.trim();
|
|
config.EmailSettings.ConnectionSecurity = this.state.connectionSecurity.trim();
|
|
|
|
config.EmailSettings.InviteSalt = ReactDOM.findDOMNode(this.refs.InviteSalt).value.trim();
|
|
if (config.EmailSettings.InviteSalt === '') {
|
|
config.EmailSettings.InviteSalt = crypto.randomBytes(256).toString('base64').substring(0, 32);
|
|
ReactDOM.findDOMNode(this.refs.InviteSalt).value = config.EmailSettings.InviteSalt;
|
|
}
|
|
|
|
config.EmailSettings.PasswordResetSalt = ReactDOM.findDOMNode(this.refs.PasswordResetSalt).value.trim();
|
|
if (config.EmailSettings.PasswordResetSalt === '') {
|
|
config.EmailSettings.PasswordResetSalt = crypto.randomBytes(256).toString('base64').substring(0, 32);
|
|
ReactDOM.findDOMNode(this.refs.PasswordResetSalt).value = config.EmailSettings.PasswordResetSalt;
|
|
}
|
|
|
|
return config;
|
|
}
|
|
|
|
handleGenerateInvite(e) {
|
|
e.preventDefault();
|
|
ReactDOM.findDOMNode(this.refs.InviteSalt).value = crypto.randomBytes(256).toString('base64').substring(0, 32);
|
|
var s = {saveNeeded: true, serverError: this.state.serverError};
|
|
this.setState(s);
|
|
}
|
|
|
|
handleGenerateReset(e) {
|
|
e.preventDefault();
|
|
ReactDOM.findDOMNode(this.refs.PasswordResetSalt).value = crypto.randomBytes(256).toString('base64').substring(0, 32);
|
|
var s = {saveNeeded: true, serverError: this.state.serverError};
|
|
this.setState(s);
|
|
}
|
|
|
|
handleTestConnection(e) {
|
|
e.preventDefault();
|
|
$('#connection-button').button('loading');
|
|
|
|
var config = this.buildConfig();
|
|
|
|
Client.testEmail(
|
|
config,
|
|
() => {
|
|
this.setState({
|
|
sendEmailNotifications: config.EmailSettings.SendEmailNotifications,
|
|
serverError: null,
|
|
saveNeeded: true,
|
|
emailSuccess: true,
|
|
emailFail: null
|
|
});
|
|
$('#connection-button').button('reset');
|
|
},
|
|
(err) => {
|
|
this.setState({
|
|
sendEmailNotifications: config.EmailSettings.SendEmailNotifications,
|
|
serverError: null,
|
|
saveNeeded: true,
|
|
emailSuccess: null,
|
|
emailFail: err.message + ' - ' + err.detailed_error
|
|
});
|
|
$('#connection-button').button('reset');
|
|
}
|
|
);
|
|
}
|
|
|
|
handleSubmit(e) {
|
|
e.preventDefault();
|
|
$('#save-button').button('loading');
|
|
|
|
var config = this.buildConfig();
|
|
|
|
Client.saveConfig(
|
|
config,
|
|
() => {
|
|
AsyncClient.getConfig();
|
|
this.setState({
|
|
sendEmailNotifications: config.EmailSettings.SendEmailNotifications,
|
|
serverError: null,
|
|
saveNeeded: false,
|
|
emailSuccess: null,
|
|
emailFail: null
|
|
});
|
|
$('#save-button').button('reset');
|
|
},
|
|
(err) => {
|
|
this.setState({
|
|
sendEmailNotifications: config.EmailSettings.SendEmailNotifications,
|
|
serverError: err.message,
|
|
saveNeeded: true,
|
|
emailSuccess: null,
|
|
emailFail: null
|
|
});
|
|
$('#save-button').button('reset');
|
|
}
|
|
);
|
|
}
|
|
|
|
render() {
|
|
const {formatMessage} = this.props.intl;
|
|
var serverError = '';
|
|
if (this.state.serverError) {
|
|
serverError = <div className='form-group has-error'><label className='control-label'>{this.state.serverError}</label></div>;
|
|
}
|
|
|
|
var saveClass = 'btn';
|
|
if (this.state.saveNeeded) {
|
|
saveClass = 'btn btn-primary';
|
|
}
|
|
|
|
var emailSuccess = '';
|
|
if (this.state.emailSuccess) {
|
|
emailSuccess = (
|
|
<div className='alert alert-success'>
|
|
<i className='fa fa-check'></i>
|
|
<FormattedMessage
|
|
id='admin.email.emailSuccess'
|
|
defaultMessage='No errors were reported while sending an email. Please check your inbox to make sure.'
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
var emailFail = '';
|
|
if (this.state.emailFail) {
|
|
emailSuccess = (
|
|
<div className='alert alert-warning'>
|
|
<i className='fa fa-warning'></i>
|
|
<FormattedMessage
|
|
id='admin.email.emailFail'
|
|
defaultMessage='Connection unsuccessful: {error}'
|
|
values={{
|
|
error: this.state.emailFail
|
|
}}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className='wrapper--fixed'>
|
|
<h3>
|
|
<FormattedMessage
|
|
id='admin.email.emailSettings'
|
|
defaultMessage='Email Settings'
|
|
/>
|
|
</h3>
|
|
<form
|
|
className='form-horizontal'
|
|
role='form'
|
|
>
|
|
|
|
<div className='form-group'>
|
|
<label
|
|
className='control-label col-sm-4'
|
|
htmlFor='allowSignUpWithEmail'
|
|
>
|
|
<FormattedMessage
|
|
id='admin.email.allowSignupTitle'
|
|
defaultMessage='Allow Sign Up With Email: '
|
|
/>
|
|
</label>
|
|
<div className='col-sm-8'>
|
|
<label className='radio-inline'>
|
|
<input
|
|
type='radio'
|
|
name='allowSignUpWithEmail'
|
|
value='true'
|
|
ref='allowSignUpWithEmail'
|
|
defaultChecked={this.props.config.EmailSettings.EnableSignUpWithEmail}
|
|
onChange={this.handleChange.bind(this, 'allowSignUpWithEmail_true')}
|
|
/>
|
|
<FormattedMessage
|
|
id='admin.email.true'
|
|
defaultMessage='true'
|
|
/>
|
|
</label>
|
|
<label className='radio-inline'>
|
|
<input
|
|
type='radio'
|
|
name='allowSignUpWithEmail'
|
|
value='false'
|
|
defaultChecked={!this.props.config.EmailSettings.EnableSignUpWithEmail}
|
|
onChange={this.handleChange.bind(this, 'allowSignUpWithEmail_false')}
|
|
/>
|
|
<FormattedMessage
|
|
id='admin.email.false'
|
|
defaultMessage='false'
|
|
/>
|
|
</label>
|
|
<p className='help-text'>
|
|
<FormattedMessage
|
|
id='admin.email.allowSignupDescription'
|
|
defaultMessage='When true, Mattermost allows team creation and account signup using email and password. This value should be false only when you want to limit signup to a single-sign-on service like OAuth or LDAP.'
|
|
/>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className='form-group'>
|
|
<label
|
|
className='control-label col-sm-4'
|
|
htmlFor='allowSignInWithEmail'
|
|
>
|
|
<FormattedMessage
|
|
id='admin.email.allowEmailSignInTitle'
|
|
defaultMessage='Allow Sign In With Email: '
|
|
/>
|
|
</label>
|
|
<div className='col-sm-8'>
|
|
<label className='radio-inline'>
|
|
<input
|
|
type='radio'
|
|
name='allowSignInWithEmail'
|
|
value='true'
|
|
ref='allowSignInWithEmail'
|
|
defaultChecked={this.props.config.EmailSettings.EnableSignInWithEmail}
|
|
onChange={this.handleChange.bind(this, 'allowSignInWithEmail_true')}
|
|
/>
|
|
<FormattedMessage
|
|
id='admin.email.true'
|
|
defaultMessage='true'
|
|
/>
|
|
</label>
|
|
<label className='radio-inline'>
|
|
<input
|
|
type='radio'
|
|
name='allowSignInWithEmail'
|
|
value='false'
|
|
defaultChecked={!this.props.config.EmailSettings.EnableSignInWithEmail}
|
|
onChange={this.handleChange.bind(this, 'allowSignInWithEmail_false')}
|
|
/>
|
|
<FormattedMessage
|
|
id='admin.email.false'
|
|
defaultMessage='false'
|
|
/>
|
|
</label>
|
|
<p className='help-text'>
|
|
<FormattedMessage
|
|
id='admin.email.allowEmailSignInDescription'
|
|
defaultMessage='When true, Mattermost allows users to sign in using their email and password.'
|
|
/>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className='form-group'>
|
|
<label
|
|
className='control-label col-sm-4'
|
|
htmlFor='allowSignInWithUsername'
|
|
>
|
|
<FormattedMessage
|
|
id='admin.email.allowUsernameSignInTitle'
|
|
defaultMessage='Allow Sign In With Username: '
|
|
/>
|
|
</label>
|
|
<div className='col-sm-8'>
|
|
<label className='radio-inline'>
|
|
<input
|
|
type='radio'
|
|
name='allowSignInWithUsername'
|
|
value='true'
|
|
ref='allowSignInWithUsername'
|
|
defaultChecked={this.props.config.EmailSettings.EnableSignInWithUsername}
|
|
onChange={this.handleChange.bind(this, 'allowSignInWithUsername_true')}
|
|
/>
|
|
<FormattedMessage
|
|
id='admin.email.true'
|
|
defaultMessage='true'
|
|
/>
|
|
</label>
|
|
<label className='radio-inline'>
|
|
<input
|
|
type='radio'
|
|
name='allowSignInWithUsername'
|
|
value='false'
|
|
defaultChecked={!this.props.config.EmailSettings.EnableSignInWithUsername}
|
|
onChange={this.handleChange.bind(this, 'allowSignInWithUsername_false')}
|
|
/>
|
|
<FormattedMessage
|
|
id='admin.email.false'
|
|
defaultMessage='false'
|
|
/>
|
|
</label>
|
|
<p className='help-text'>
|
|
<FormattedMessage
|
|
id='admin.email.allowUsernameSignInDescription'
|
|
defaultMessage='When true, Mattermost allows users to sign in using their username and password. This setting is typically only used when email verification is disabled.'
|
|
/>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className='form-group'>
|
|
<label
|
|
className='control-label col-sm-4'
|
|
htmlFor='sendEmailNotifications'
|
|
>
|
|
<FormattedMessage
|
|
id='admin.email.notificationsTitle'
|
|
defaultMessage='Send Email Notifications: '
|
|
/>
|
|
</label>
|
|
<div className='col-sm-8'>
|
|
<label className='radio-inline'>
|
|
<input
|
|
type='radio'
|
|
name='sendEmailNotifications'
|
|
value='true'
|
|
ref='sendEmailNotifications'
|
|
defaultChecked={this.props.config.EmailSettings.SendEmailNotifications}
|
|
onChange={this.handleChange.bind(this, 'sendEmailNotifications_true')}
|
|
/>
|
|
<FormattedMessage
|
|
id='admin.email.true'
|
|
defaultMessage='true'
|
|
/>
|
|
</label>
|
|
<label className='radio-inline'>
|
|
<input
|
|
type='radio'
|
|
name='sendEmailNotifications'
|
|
value='false'
|
|
defaultChecked={!this.props.config.EmailSettings.SendEmailNotifications}
|
|
onChange={this.handleChange.bind(this, 'sendEmailNotifications_false')}
|
|
/>
|
|
<FormattedMessage
|
|
id='admin.email.false'
|
|
defaultMessage='false'
|
|
/>
|
|
</label>
|
|
<p className='help-text'>
|
|
<FormattedHTMLMessage
|
|
id='admin.email.notificationsDescription'
|
|
defaultMessage='Typically set to true in production. When true, Mattermost attempts to send email notifications. Developers may set this field to false to skip email setup for faster development.<br />Setting this to true removes the Preview Mode banner (requires logging out and logging back in after setting is changed).'
|
|
/>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className='form-group'>
|
|
<label
|
|
className='control-label col-sm-4'
|
|
htmlFor='requireEmailVerification'
|
|
>
|
|
<FormattedMessage
|
|
id='admin.email.requireVerificationTitle'
|
|
defaultMessage='Require Email Verification: '
|
|
/>
|
|
</label>
|
|
<div className='col-sm-8'>
|
|
<label className='radio-inline'>
|
|
<input
|
|
type='radio'
|
|
name='requireEmailVerification'
|
|
value='true'
|
|
ref='requireEmailVerification'
|
|
defaultChecked={this.props.config.EmailSettings.RequireEmailVerification}
|
|
onChange={this.handleChange.bind(this, 'requireEmailVerification_true')}
|
|
disabled={!this.state.sendEmailNotifications}
|
|
/>
|
|
<FormattedMessage
|
|
id='admin.email.true'
|
|
defaultMessage='true'
|
|
/>
|
|
</label>
|
|
<label className='radio-inline'>
|
|
<input
|
|
type='radio'
|
|
name='requireEmailVerification'
|
|
value='false'
|
|
defaultChecked={!this.props.config.EmailSettings.RequireEmailVerification}
|
|
onChange={this.handleChange.bind(this, 'requireEmailVerification_false')}
|
|
disabled={!this.state.sendEmailNotifications}
|
|
/>
|
|
<FormattedMessage
|
|
id='admin.email.false'
|
|
defaultMessage='false'
|
|
/>
|
|
</label>
|
|
<p className='help-text'>
|
|
<FormattedMessage
|
|
id='admin.email.requireVerificationDescription'
|
|
defaultMessage='Typically set to true in production. When true, Mattermost requires email verification after account creation prior to allowing login. Developers may set this field to false so skip sending verification emails for faster development.'
|
|
/>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className='form-group'>
|
|
<label
|
|
className='control-label col-sm-4'
|
|
htmlFor='feedbackName'
|
|
>
|
|
<FormattedMessage
|
|
id='admin.email.notificationDisplayTitle'
|
|
defaultMessage='Notification Display Name:'
|
|
/>
|
|
</label>
|
|
<div className='col-sm-8'>
|
|
<input
|
|
type='text'
|
|
className='form-control'
|
|
id='feedbackName'
|
|
ref='feedbackName'
|
|
placeholder={formatMessage(holders.notificationDisplayExample)}
|
|
defaultValue={this.props.config.EmailSettings.FeedbackName}
|
|
onChange={this.handleChange}
|
|
disabled={!this.state.sendEmailNotifications}
|
|
/>
|
|
<p className='help-text'>
|
|
<FormattedMessage
|
|
id='admin.email.notificationDisplayDescription'
|
|
defaultMessage='Display name on email account used when sending notification emails from Mattermost.'
|
|
/>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className='form-group'>
|
|
<label
|
|
className='control-label col-sm-4'
|
|
htmlFor='feedbackEmail'
|
|
>
|
|
<FormattedMessage
|
|
id='admin.email.notificationEmailTitle'
|
|
defaultMessage='Notification Email Address:'
|
|
/>
|
|
</label>
|
|
<div className='col-sm-8'>
|
|
<input
|
|
type='email'
|
|
className='form-control'
|
|
id='feedbackEmail'
|
|
ref='feedbackEmail'
|
|
placeholder={formatMessage(holders.notificationEmailExample)}
|
|
defaultValue={this.props.config.EmailSettings.FeedbackEmail}
|
|
onChange={this.handleChange}
|
|
disabled={!this.state.sendEmailNotifications}
|
|
/>
|
|
<p className='help-text'>
|
|
<FormattedMessage
|
|
id='admin.email.notificationEmailDescription'
|
|
defaultMessage='Email address displayed on email account used when sending notification emails from Mattermost.'
|
|
/>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className='form-group'>
|
|
<label
|
|
className='control-label col-sm-4'
|
|
htmlFor='SMTPUsername'
|
|
>
|
|
<FormattedMessage
|
|
id='admin.email.smtpUsernameTitle'
|
|
defaultMessage='SMTP Username:'
|
|
/>
|
|
</label>
|
|
<div className='col-sm-8'>
|
|
<input
|
|
type='text'
|
|
className='form-control'
|
|
id='SMTPUsername'
|
|
ref='SMTPUsername'
|
|
placeholder={formatMessage(holders.smtpUsernameExample)}
|
|
defaultValue={this.props.config.EmailSettings.SMTPUsername}
|
|
onChange={this.handleChange}
|
|
disabled={!this.state.sendEmailNotifications}
|
|
/>
|
|
<p className='help-text'>
|
|
<FormattedMessage
|
|
id='admin.email.smtpUsernameDescription'
|
|
defaultMessage=' Obtain this credential from administrator setting up your email server.'
|
|
/>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className='form-group'>
|
|
<label
|
|
className='control-label col-sm-4'
|
|
htmlFor='SMTPPassword'
|
|
>
|
|
<FormattedMessage
|
|
id='admin.email.smtpPasswordTitle'
|
|
defaultMessage='SMTP Password:'
|
|
/>
|
|
</label>
|
|
<div className='col-sm-8'>
|
|
<input
|
|
type='text'
|
|
className='form-control'
|
|
id='SMTPPassword'
|
|
ref='SMTPPassword'
|
|
placeholder={formatMessage(holders.smtpPasswordExample)}
|
|
defaultValue={this.props.config.EmailSettings.SMTPPassword}
|
|
onChange={this.handleChange}
|
|
disabled={!this.state.sendEmailNotifications}
|
|
/>
|
|
<p className='help-text'>
|
|
<FormattedMessage
|
|
id='admin.email.smtpPasswordDescription'
|
|
defaultMessage=' Obtain this credential from administrator setting up your email server.'
|
|
/>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className='form-group'>
|
|
<label
|
|
className='control-label col-sm-4'
|
|
htmlFor='SMTPServer'
|
|
>
|
|
<FormattedMessage
|
|
id='admin.email.smtpServerTitle'
|
|
defaultMessage='SMTP Server:'
|
|
/>
|
|
</label>
|
|
<div className='col-sm-8'>
|
|
<input
|
|
type='text'
|
|
className='form-control'
|
|
id='SMTPServer'
|
|
ref='SMTPServer'
|
|
placeholder={formatMessage(holders.smtpServerExample)}
|
|
defaultValue={this.props.config.EmailSettings.SMTPServer}
|
|
onChange={this.handleChange}
|
|
disabled={!this.state.sendEmailNotifications}
|
|
/>
|
|
<p className='help-text'>
|
|
<FormattedMessage
|
|
id='admin.email.smtpServerDescription'
|
|
defaultMessage='Location of SMTP email server.'
|
|
/>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className='form-group'>
|
|
<label
|
|
className='control-label col-sm-4'
|
|
htmlFor='SMTPPort'
|
|
>
|
|
<FormattedMessage
|
|
id='admin.email.smtpPortTitle'
|
|
defaultMessage='SMTP Port:'
|
|
/>
|
|
</label>
|
|
<div className='col-sm-8'>
|
|
<input
|
|
type='text'
|
|
className='form-control'
|
|
id='SMTPPort'
|
|
ref='SMTPPort'
|
|
placeholder={formatMessage(holders.smtpPortExample)}
|
|
defaultValue={this.props.config.EmailSettings.SMTPPort}
|
|
onChange={this.handleChange}
|
|
disabled={!this.state.sendEmailNotifications}
|
|
/>
|
|
<p className='help-text'>
|
|
<FormattedMessage
|
|
id='admin.email.smtpPortDescription'
|
|
defaultMessage='Port of SMTP email server.'
|
|
/>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<ConnectionSecurityDropdownSetting
|
|
currentValue={this.state.connectionSecurity}
|
|
handleChange={(e) => this.setState({connectionSecurity: e.target.value, saveNeeded: true})}
|
|
isDisabled={!this.state.sendEmailNotifications}
|
|
/>
|
|
<div className='form-group'>
|
|
<div className='col-sm-8'>
|
|
<div className='help-text'>
|
|
<button
|
|
className='btn btn-default'
|
|
onClick={this.handleTestConnection}
|
|
disabled={!this.state.sendEmailNotifications}
|
|
id='connection-button'
|
|
data-loading-text={'<span class=\'glyphicon glyphicon-refresh glyphicon-refresh-animate\'></span> ' + formatMessage(holders.testing)}
|
|
>
|
|
<FormattedMessage
|
|
id='admin.email.connectionSecurityTest'
|
|
defaultMessage='Test Connection'
|
|
/>
|
|
</button>
|
|
{emailSuccess}
|
|
{emailFail}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className='form-group'>
|
|
<label
|
|
className='control-label col-sm-4'
|
|
htmlFor='InviteSalt'
|
|
>
|
|
<FormattedMessage
|
|
id='admin.email.inviteSaltTitle'
|
|
defaultMessage='Invite Salt:'
|
|
/>
|
|
</label>
|
|
<div className='col-sm-8'>
|
|
<input
|
|
type='text'
|
|
className='form-control'
|
|
id='InviteSalt'
|
|
ref='InviteSalt'
|
|
placeholder={formatMessage(holders.inviteSaltExample)}
|
|
defaultValue={this.props.config.EmailSettings.InviteSalt}
|
|
onChange={this.handleChange}
|
|
disabled={!this.state.sendEmailNotifications}
|
|
/>
|
|
<p className='help-text'>
|
|
<FormattedMessage
|
|
id='admin.email.inviteSaltDescription'
|
|
defaultMessage='32-character salt added to signing of email invites. Randomly generated on install. Click "Re-Generate" to create new salt.'
|
|
/>
|
|
</p>
|
|
<div className='help-text'>
|
|
<button
|
|
className='btn btn-default'
|
|
onClick={this.handleGenerateInvite}
|
|
disabled={!this.state.sendEmailNotifications}
|
|
>
|
|
<FormattedMessage
|
|
id='admin.email.regenerate'
|
|
defaultMessage='Re-Generate'
|
|
/>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className='form-group'>
|
|
<label
|
|
className='control-label col-sm-4'
|
|
htmlFor='PasswordResetSalt'
|
|
>
|
|
<FormattedMessage
|
|
id='admin.email.passwordSaltTitle'
|
|
defaultMessage='Password Reset Salt:'
|
|
/>
|
|
</label>
|
|
<div className='col-sm-8'>
|
|
<input
|
|
type='text'
|
|
className='form-control'
|
|
id='PasswordResetSalt'
|
|
ref='PasswordResetSalt'
|
|
placeholder={formatMessage(holders.passwordSaltExample)}
|
|
defaultValue={this.props.config.EmailSettings.PasswordResetSalt}
|
|
onChange={this.handleChange}
|
|
disabled={!this.state.sendEmailNotifications}
|
|
/>
|
|
<p className='help-text'>
|
|
<FormattedMessage
|
|
id='admin.email.passwordSaltDescription'
|
|
defaultMessage='32-character salt added to signing of password reset emails. Randomly generated on install. Click "Re-Generate" to create new salt.'
|
|
/>
|
|
</p>
|
|
<div className='help-text'>
|
|
<button
|
|
className='btn btn-default'
|
|
onClick={this.handleGenerateReset}
|
|
disabled={!this.state.sendEmailNotifications}
|
|
>
|
|
<FormattedMessage
|
|
id='admin.email.regenerate'
|
|
defaultMessage='Re-Generate'
|
|
/>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className='form-group'>
|
|
<label
|
|
className='control-label col-sm-4'
|
|
htmlFor='sendPushNotifications'
|
|
>
|
|
<FormattedMessage
|
|
id='admin.email.pushTitle'
|
|
defaultMessage='Send Push Notifications: '
|
|
/>
|
|
</label>
|
|
<div className='col-sm-8'>
|
|
<label className='radio-inline'>
|
|
<input
|
|
type='radio'
|
|
name='sendPushNotifications'
|
|
value='true'
|
|
ref='sendPushNotifications'
|
|
defaultChecked={this.props.config.EmailSettings.SendPushNotifications}
|
|
onChange={this.handleChange.bind(this, 'sendPushNotifications_true')}
|
|
/>
|
|
<FormattedMessage
|
|
id='admin.email.true'
|
|
defaultMessage='true'
|
|
/>
|
|
</label>
|
|
<label className='radio-inline'>
|
|
<input
|
|
type='radio'
|
|
name='sendPushNotifications'
|
|
value='false'
|
|
defaultChecked={!this.props.config.EmailSettings.SendPushNotifications}
|
|
onChange={this.handleChange.bind(this, 'sendPushNotifications_false')}
|
|
/>
|
|
<FormattedMessage
|
|
id='admin.email.false'
|
|
defaultMessage='false'
|
|
/>
|
|
</label>
|
|
<p className='help-text'>
|
|
<FormattedMessage
|
|
id='admin.email.pushDesc'
|
|
defaultMessage='Typically set to true in production. When true, Mattermost attempts to send iOS and Android push notifications through the push notification server.'
|
|
/>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className='form-group'>
|
|
<label
|
|
className='control-label col-sm-4'
|
|
htmlFor='PushNotificationServer'
|
|
>
|
|
<FormattedMessage
|
|
id='admin.email.pushServerTitle'
|
|
defaultMessage='Push Notification Server:'
|
|
/>
|
|
</label>
|
|
<div className='col-sm-8'>
|
|
<input
|
|
type='text'
|
|
className='form-control'
|
|
id='PushNotificationServer'
|
|
ref='PushNotificationServer'
|
|
placeholder={formatMessage(holders.pushServerEx)}
|
|
defaultValue={this.props.config.EmailSettings.PushNotificationServer}
|
|
onChange={this.handleChange}
|
|
disabled={!this.state.sendPushNotifications}
|
|
/>
|
|
<p className='help-text'>
|
|
<FormattedMessage
|
|
id='admin.email.pushServerDesc'
|
|
defaultMessage='Location of Mattermost push notification service you can set up behind your firewall using https://github.com/mattermost/push-proxy. For testing you can use http://push-test.mattermost.com, which connects to the sample Mattermost iOS app in the public Apple AppStore. Please do not use test service for production deployments.'
|
|
/>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className='form-group'>
|
|
<label
|
|
className='control-label col-sm-4'
|
|
htmlFor='pushNotificationContents'
|
|
>
|
|
<FormattedMessage
|
|
id='admin.email.pushContentTitle'
|
|
defaultMessage='Push Notification Contents:'
|
|
/>
|
|
</label>
|
|
<div className='col-sm-8'>
|
|
<select
|
|
className='form-control'
|
|
id='pushNotificationContents'
|
|
ref='PushNotificationContents'
|
|
defaultValue={this.props.config.EmailSettings.PushNotificationContents}
|
|
onChange={this.handleChange.bind(this, 'pushNotificationContents')}
|
|
disabled={!this.state.sendPushNotifications}
|
|
>
|
|
<option value='generic'>{formatMessage(holders.genericPush)}</option>
|
|
<option value='full'>{formatMessage(holders.fullPush)}</option>
|
|
</select>
|
|
<p className='help-text'>
|
|
<FormattedHTMLMessage
|
|
id='admin.email.pushContentDesc'
|
|
defaultMessage='Selecting "Send generic description with user and channel names" provides push notifications with generic messages, including names of users and channels but no specific details from the message text.<br /><br />
|
|
Selecting "Send full message snippet" sends excerpts from messages triggering notifications with specifics and may include confidential information sent in messages. If your Push Notification Service is outside your firewall, it is HIGHLY RECOMMENDED this option only be used with an "https" protocol to encrypt the connection.'
|
|
/>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className='form-group'>
|
|
<div className='col-sm-12'>
|
|
{serverError}
|
|
<button
|
|
disabled={!this.state.saveNeeded}
|
|
type='submit'
|
|
className={saveClass}
|
|
onClick={this.handleSubmit}
|
|
id='save-button'
|
|
data-loading-text={'<span class=\'glyphicon glyphicon-refresh glyphicon-refresh-animate\'></span> ' + formatMessage(holders.saving)}
|
|
>
|
|
<FormattedMessage
|
|
id='admin.email.save'
|
|
defaultMessage='Save'
|
|
/>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
</form>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
EmailSettings.propTypes = {
|
|
intl: intlShape.isRequired,
|
|
config: React.PropTypes.object
|
|
};
|
|
|
|
export default injectIntl(EmailSettings);
|