summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author=Corey Hulen <corey@hulen.com>2015-09-21 15:11:56 -0700
committer=Corey Hulen <corey@hulen.com>2015-09-21 15:11:56 -0700
commited9a2da83b3b77e7dd0314eaa92082ac8a2a9a9c (patch)
tree3c890327d884b33ad149196ddf9879313b2b000b
parentee5a77ec56ee13f5eb96fce6065b4b7a1845de89 (diff)
downloadchat-ed9a2da83b3b77e7dd0314eaa92082ac8a2a9a9c.tar.gz
chat-ed9a2da83b3b77e7dd0314eaa92082ac8a2a9a9c.tar.bz2
chat-ed9a2da83b3b77e7dd0314eaa92082ac8a2a9a9c.zip
Adding email to admin console
-rw-r--r--api/admin.go27
-rw-r--r--api/admin_test.go28
-rw-r--r--api/team.go11
-rw-r--r--api/user.go4
-rw-r--r--config/config.json13
-rw-r--r--model/client.go9
-rw-r--r--model/config.go21
-rw-r--r--utils/config.go29
-rw-r--r--utils/mail.go60
-rw-r--r--web/react/components/admin_console/email_settings.jsx528
-rw-r--r--web/react/components/admin_console/log_settings.jsx50
-rw-r--r--web/react/components/invite_member_modal.jsx2
-rw-r--r--web/react/components/login.jsx8
-rw-r--r--web/react/components/signup_team.jsx48
-rw-r--r--web/react/components/signup_user_complete.jsx9
-rw-r--r--web/react/components/team_signup_choose_auth.jsx20
-rw-r--r--web/react/components/team_signup_send_invites_page.jsx2
-rw-r--r--web/react/components/user_settings_general.jsx2
-rw-r--r--web/react/pages/login.jsx1
-rw-r--r--web/react/pages/signup_team.jsx6
-rw-r--r--web/react/pages/signup_user_complete.jsx1
-rw-r--r--web/react/utils/client.jsx15
-rw-r--r--web/web.go4
23 files changed, 554 insertions, 344 deletions
diff --git a/api/admin.go b/api/admin.go
index 646597755..ca66b7cb4 100644
--- a/api/admin.go
+++ b/api/admin.go
@@ -24,6 +24,7 @@ func InitAdmin(r *mux.Router) {
sr.Handle("/config", ApiUserRequired(getConfig)).Methods("GET")
sr.Handle("/save_config", ApiUserRequired(saveConfig)).Methods("POST")
sr.Handle("/client_props", ApiAppHandler(getClientProperties)).Methods("GET")
+ sr.Handle("/test_email", ApiUserRequired(testEmail)).Methods("POST")
}
func getLogs(c *Context, w http.ResponseWriter, r *http.Request) {
@@ -98,3 +99,29 @@ func saveConfig(c *Context, w http.ResponseWriter, r *http.Request) {
json := utils.Cfg.ToJson()
w.Write([]byte(json))
}
+
+func testEmail(c *Context, w http.ResponseWriter, r *http.Request) {
+ if !c.HasSystemAdminPermissions("testEmail") {
+ return
+ }
+
+ cfg := model.ConfigFromJson(r.Body)
+ if cfg == nil {
+ c.SetInvalidParam("testEmail", "config")
+ return
+ }
+
+ if result := <-Srv.Store.User().Get(c.Session.UserId); result.Err != nil {
+ c.Err = result.Err
+ return
+ } else {
+ if err := utils.SendMailUsingConfig(result.Data.(*model.User).Email, "Mattermost - Testing Email Settings", "<br/><br/><br/>It appears your Mattermost email is setup correctly!", cfg); err != nil {
+ c.Err = err
+ return
+ }
+ }
+
+ m := make(map[string]string)
+ m["SUCCESS"] = "true"
+ w.Write([]byte(model.MapToJson(m)))
+}
diff --git a/api/admin_test.go b/api/admin_test.go
index e1778b5ac..c74fbf6e5 100644
--- a/api/admin_test.go
+++ b/api/admin_test.go
@@ -122,3 +122,31 @@ func TestSaveConfig(t *testing.T) {
}
}
}
+
+func TestEmailTest(t *testing.T) {
+ Setup()
+
+ team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
+ team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
+
+ user := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
+ user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
+ store.Must(Srv.Store.User().VerifyEmail(user.Id))
+
+ Client.LoginByEmail(team.Name, user.Email, "pwd")
+
+ if _, err := Client.TestEmail(utils.Cfg); err == nil {
+ t.Fatal("Shouldn't have permissions")
+ }
+
+ c := &Context{}
+ c.RequestId = model.NewId()
+ c.IpAddress = "cmd_line"
+ UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
+
+ Client.LoginByEmail(team.Name, user.Email, "pwd")
+
+ if _, err := Client.TestEmail(utils.Cfg); err != nil {
+ t.Fatal(err)
+ }
+}
diff --git a/api/team.go b/api/team.go
index 92fcbff93..f0025fdbd 100644
--- a/api/team.go
+++ b/api/team.go
@@ -38,7 +38,7 @@ func InitTeam(r *mux.Router) {
}
func signupTeam(c *Context, w http.ResponseWriter, r *http.Request) {
- if utils.Cfg.ServiceSettings.DisableEmailSignUp {
+ if !utils.Cfg.EmailSettings.AllowSignUpWithEmail {
c.Err = model.NewAppError("signupTeam", "Team sign-up with email is disabled.", "")
c.Err.StatusCode = http.StatusNotImplemented
return
@@ -76,10 +76,7 @@ func signupTeam(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
- if utils.Cfg.ServiceSettings.Mode == utils.MODE_DEV || utils.Cfg.EmailSettings.ByPassEmail {
- m["follow_link"] = bodyPage.Props["Link"]
- }
-
+ m["follow_link"] = bodyPage.Props["Link"]
w.Header().Set("Access-Control-Allow-Origin", " *")
w.Write([]byte(model.MapToJson(m)))
}
@@ -147,7 +144,7 @@ func createTeamFromSSO(c *Context, w http.ResponseWriter, r *http.Request) {
}
func createTeamFromSignup(c *Context, w http.ResponseWriter, r *http.Request) {
- if utils.Cfg.ServiceSettings.DisableEmailSignUp {
+ if !utils.Cfg.EmailSettings.AllowSignUpWithEmail {
c.Err = model.NewAppError("createTeamFromSignup", "Team sign-up with email is disabled.", "")
c.Err.StatusCode = http.StatusNotImplemented
return
@@ -257,7 +254,7 @@ func createTeam(c *Context, w http.ResponseWriter, r *http.Request) {
}
func CreateTeam(c *Context, team *model.Team) *model.Team {
- if utils.Cfg.ServiceSettings.DisableEmailSignUp {
+ if !utils.Cfg.EmailSettings.AllowSignUpWithEmail {
c.Err = model.NewAppError("createTeam", "Team sign-up with email is disabled.", "")
c.Err.StatusCode = http.StatusNotImplemented
return nil
diff --git a/api/user.go b/api/user.go
index 0a54b6a5d..352e1f0e1 100644
--- a/api/user.go
+++ b/api/user.go
@@ -58,7 +58,7 @@ func InitUser(r *mux.Router) {
}
func createUser(c *Context, w http.ResponseWriter, r *http.Request) {
- if utils.Cfg.ServiceSettings.DisableEmailSignUp {
+ if !utils.Cfg.EmailSettings.AllowSignUpWithEmail {
c.Err = model.NewAppError("signupTeam", "User sign-up with email is disabled.", "")
c.Err.StatusCode = http.StatusNotImplemented
return
@@ -324,7 +324,7 @@ func checkUserPassword(c *Context, user *model.User, password string) bool {
func Login(c *Context, w http.ResponseWriter, r *http.Request, user *model.User, deviceId string) {
c.LogAuditWithUserId(user.Id, "attempt")
- if !user.EmailVerified && !utils.Cfg.EmailSettings.ByPassEmail {
+ if !user.EmailVerified && utils.Cfg.EmailSettings.RequireEmailVerification {
c.Err = model.NewAppError("Login", "Login failed because email address has not been verified", "user_id="+user.Id)
c.Err.StatusCode = http.StatusForbidden
return
diff --git a/config/config.json b/config/config.json
index 38948641c..4b0c0fe51 100644
--- a/config/config.json
+++ b/config/config.json
@@ -21,7 +21,6 @@
"UseLocalStorage": true,
"StorageDirectory": "./data/",
"AllowedLoginAttempts": 10,
- "DisableEmailSignUp": false,
"EnableOAuthServiceProvider": false
},
"SqlSettings": {
@@ -51,14 +50,16 @@
"InitialFont": "luximbi.ttf"
},
"EmailSettings": {
- "ByPassEmail": true,
+ "AllowSignUpWithEmail": true,
+ "SendEmailNotifications": false,
+ "RequireEmailVerification": false,
+ "FeedbackName": "",
+ "FeedbackEmail": "",
"SMTPUsername": "",
"SMTPPassword": "",
"SMTPServer": "",
- "UseTLS": false,
- "UseStartTLS": false,
- "FeedbackEmail": "",
- "FeedbackName": "",
+ "SMTPPort": "",
+ "ConnectionSecurity": "",
"ApplePushServer": "",
"ApplePushCertPublic": "",
"ApplePushCertPrivate": ""
diff --git a/model/client.go b/model/client.go
index f9127719f..823e859cf 100644
--- a/model/client.go
+++ b/model/client.go
@@ -403,6 +403,15 @@ func (c *Client) SaveConfig(config *Config) (*Result, *AppError) {
}
}
+func (c *Client) TestEmail(config *Config) (*Result, *AppError) {
+ if r, err := c.DoApiPost("/admin/test_email", config.ToJson()); err != nil {
+ return nil, err
+ } else {
+ return &Result{r.Header.Get(HEADER_REQUEST_ID),
+ r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil
+ }
+}
+
func (c *Client) CreateChannel(channel *Channel) (*Result, *AppError) {
if r, err := c.DoApiPost("/channels/create", channel.ToJson()); err != nil {
return nil, err
diff --git a/model/config.go b/model/config.go
index 3b333dbe1..5240caf55 100644
--- a/model/config.go
+++ b/model/config.go
@@ -22,7 +22,6 @@ type ServiceSettings struct {
UseLocalStorage bool
StorageDirectory string
AllowedLoginAttempts int
- DisableEmailSignUp bool
EnableOAuthServiceProvider bool
}
@@ -73,14 +72,18 @@ type ImageSettings struct {
}
type EmailSettings struct {
- ByPassEmail bool
- SMTPUsername string
- SMTPPassword string
- SMTPServer string
- UseTLS bool
- UseStartTLS bool
- FeedbackEmail string
- FeedbackName string
+ AllowSignUpWithEmail bool
+ SendEmailNotifications bool
+ RequireEmailVerification bool
+ FeedbackName string
+ FeedbackEmail string
+ SMTPUsername string
+ SMTPPassword string
+ SMTPServer string
+ SMTPPort string
+ ConnectionSecurity string
+
+ // For Future Use
ApplePushServer string
ApplePushCertPublic string
ApplePushCertPrivate string
diff --git a/utils/config.go b/utils/config.go
index dd2c17977..f3e93ef11 100644
--- a/utils/config.go
+++ b/utils/config.go
@@ -176,18 +176,24 @@ func getClientProperties(c *model.Config) map[string]string {
props["BuildHash"] = model.BuildHash
props["SiteName"] = c.ServiceSettings.SiteName
- props["ByPassEmail"] = strconv.FormatBool(c.EmailSettings.ByPassEmail)
+ props["AnalyticsUrl"] = c.ServiceSettings.AnalyticsUrl
+ props["EnableOAuthServiceProvider"] = strconv.FormatBool(c.ServiceSettings.EnableOAuthServiceProvider)
+
+ props["SendEmailNotifications"] = strconv.FormatBool(c.EmailSettings.SendEmailNotifications)
+ props["AllowSignUpWithEmail"] = strconv.FormatBool(c.EmailSettings.AllowSignUpWithEmail)
props["FeedbackEmail"] = c.EmailSettings.FeedbackEmail
+
+ props["AllowSignUpWithGitLab"] = strconv.FormatBool(false)
+
props["ShowEmailAddress"] = strconv.FormatBool(c.PrivacySettings.ShowEmailAddress)
props["AllowPublicLink"] = strconv.FormatBool(c.TeamSettings.AllowPublicLink)
+
props["SegmentDeveloperKey"] = c.ClientSettings.SegmentDeveloperKey
props["GoogleDeveloperKey"] = c.ClientSettings.GoogleDeveloperKey
- props["AnalyticsUrl"] = c.ServiceSettings.AnalyticsUrl
- props["ByPassEmail"] = strconv.FormatBool(c.EmailSettings.ByPassEmail)
+
props["ProfileHeight"] = fmt.Sprintf("%v", c.ImageSettings.ProfileHeight)
props["ProfileWidth"] = fmt.Sprintf("%v", c.ImageSettings.ProfileWidth)
props["ProfileWidth"] = fmt.Sprintf("%v", c.ImageSettings.ProfileWidth)
- props["EnableOAuthServiceProvider"] = strconv.FormatBool(c.ServiceSettings.EnableOAuthServiceProvider)
return props
}
@@ -200,21 +206,6 @@ func IsS3Configured() bool {
return true
}
-func GetAllowedAuthServices() []string {
- authServices := []string{}
- for name, service := range Cfg.SSOSettings {
- if service.Allow {
- authServices = append(authServices, name)
- }
- }
-
- if !Cfg.ServiceSettings.DisableEmailSignUp {
- authServices = append(authServices, "email")
- }
-
- return authServices
-}
-
func IsServiceAllowed(s string) bool {
if len(s) == 0 {
return false
diff --git a/utils/mail.go b/utils/mail.go
index 7cb178626..9d3db9640 100644
--- a/utils/mail.go
+++ b/utils/mail.go
@@ -15,43 +15,28 @@ import (
"time"
)
-func CheckMailSettings() *model.AppError {
- if len(Cfg.EmailSettings.SMTPServer) == 0 || Cfg.EmailSettings.ByPassEmail {
- return model.NewAppError("CheckMailSettings", "No email settings present, mail will not be sent", "")
- }
- conn, err := connectToSMTPServer()
- if err != nil {
- return err
- }
- defer conn.Close()
- c, err2 := newSMTPClient(conn)
- if err2 != nil {
- return err
- }
- defer c.Quit()
- defer c.Close()
-
- return nil
-}
-
-func connectToSMTPServer() (net.Conn, *model.AppError) {
- host, _, _ := net.SplitHostPort(Cfg.EmailSettings.SMTPServer)
+const (
+ CONN_SECURITY_NONE = ""
+ CONN_SECURITY_TLS = "TLS"
+ CONN_SECURITY_STARTTLS = "STARTTLS"
+)
+func connectToSMTPServer(config *model.Config) (net.Conn, *model.AppError) {
var conn net.Conn
var err error
- if Cfg.EmailSettings.UseTLS {
+ if config.EmailSettings.ConnectionSecurity == CONN_SECURITY_TLS {
tlsconfig := &tls.Config{
InsecureSkipVerify: true,
- ServerName: host,
+ ServerName: config.EmailSettings.SMTPServer,
}
- conn, err = tls.Dial("tcp", Cfg.EmailSettings.SMTPServer, tlsconfig)
+ conn, err = tls.Dial("tcp", config.EmailSettings.SMTPServer+":"+config.EmailSettings.SMTPPort, tlsconfig)
if err != nil {
return nil, model.NewAppError("SendMail", "Failed to open TLS connection", err.Error())
}
} else {
- conn, err = net.Dial("tcp", Cfg.EmailSettings.SMTPServer)
+ conn, err = net.Dial("tcp", config.EmailSettings.SMTPServer+":"+config.EmailSettings.SMTPPort)
if err != nil {
return nil, model.NewAppError("SendMail", "Failed to open connection", err.Error())
}
@@ -60,24 +45,23 @@ func connectToSMTPServer() (net.Conn, *model.AppError) {
return conn, nil
}
-func newSMTPClient(conn net.Conn) (*smtp.Client, *model.AppError) {
- host, _, _ := net.SplitHostPort(Cfg.EmailSettings.SMTPServer)
- c, err := smtp.NewClient(conn, host)
+func newSMTPClient(conn net.Conn, config *model.Config) (*smtp.Client, *model.AppError) {
+ c, err := smtp.NewClient(conn, config.EmailSettings.SMTPServer+":"+config.EmailSettings.SMTPPort)
if err != nil {
l4g.Error("Failed to open a connection to SMTP server %v", err)
return nil, model.NewAppError("SendMail", "Failed to open TLS connection", err.Error())
}
// GO does not support plain auth over a non encrypted connection.
// so if not tls then no auth
- auth := smtp.PlainAuth("", Cfg.EmailSettings.SMTPUsername, Cfg.EmailSettings.SMTPPassword, host)
- if Cfg.EmailSettings.UseTLS {
+ auth := smtp.PlainAuth("", config.EmailSettings.SMTPUsername, config.EmailSettings.SMTPPassword, config.EmailSettings.SMTPServer+":"+config.EmailSettings.SMTPPort)
+ if config.EmailSettings.ConnectionSecurity == CONN_SECURITY_TLS {
if err = c.Auth(auth); err != nil {
return nil, model.NewAppError("SendMail", "Failed to authenticate on SMTP server", err.Error())
}
- } else if Cfg.EmailSettings.UseStartTLS {
+ } else if config.EmailSettings.ConnectionSecurity == CONN_SECURITY_TLS {
tlsconfig := &tls.Config{
InsecureSkipVerify: true,
- ServerName: host,
+ ServerName: config.EmailSettings.SMTPServer,
}
c.StartTLS(tlsconfig)
if err = c.Auth(auth); err != nil {
@@ -88,12 +72,16 @@ func newSMTPClient(conn net.Conn) (*smtp.Client, *model.AppError) {
}
func SendMail(to, subject, body string) *model.AppError {
+ return SendMailUsingConfig(to, subject, body, Cfg)
+}
+
+func SendMailUsingConfig(to, subject, body string, config *model.Config) *model.AppError {
- if len(Cfg.EmailSettings.SMTPServer) == 0 || Cfg.EmailSettings.ByPassEmail {
+ if !config.EmailSettings.SendEmailNotifications {
return nil
}
- fromMail := mail.Address{Cfg.EmailSettings.FeedbackName, Cfg.EmailSettings.FeedbackEmail}
+ fromMail := mail.Address{config.EmailSettings.FeedbackName, config.EmailSettings.FeedbackEmail}
toMail := mail.Address{"", to}
headers := make(map[string]string)
@@ -110,13 +98,13 @@ func SendMail(to, subject, body string) *model.AppError {
}
message += "\r\n<html><body>" + body + "</body></html>"
- conn, err1 := connectToSMTPServer()
+ conn, err1 := connectToSMTPServer(config)
if err1 != nil {
return err1
}
defer conn.Close()
- c, err2 := newSMTPClient(conn)
+ c, err2 := newSMTPClient(conn, config)
if err2 != nil {
return err2
}
diff --git a/web/react/components/admin_console/email_settings.jsx b/web/react/components/admin_console/email_settings.jsx
index e8fb25858..2e107f1ba 100644
--- a/web/react/components/admin_console/email_settings.jsx
+++ b/web/react/components/admin_console/email_settings.jsx
@@ -1,15 +1,148 @@
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
// See License.txt for license information.
+var Client = require('../../utils/client.jsx');
+var AsyncClient = require('../../utils/async_client.jsx');
+
export default 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.state = {
+ sendEmailNotifications: this.props.config.EmailSettings.SendEmailNotifications,
+ saveNeeded: false,
+ serverError: null,
+ emailSuccess: null,
+ emailFail: null
};
}
+ handleChange(action) {
+ var s = {saveNeeded: true, serverError: this.state.serverError};
+
+ if (action === 'sendEmailNotifications_true') {
+ s.sendEmailNotifications = true;
+ }
+
+ if (action === 'sendEmailNotifications_false') {
+ s.sendEmailNotifications = false;
+ }
+
+ this.setState(s);
+ }
+
+ buildConfig() {
+ var config = this.props.config;
+ config.EmailSettings.AllowSignUpWithEmail = React.findDOMNode(this.refs.allowSignUpWithEmail).checked;
+ config.EmailSettings.SendEmailNotifications = React.findDOMNode(this.refs.sendEmailNotifications).checked;
+ config.EmailSettings.RequireEmailVerification = React.findDOMNode(this.refs.requireEmailVerification).checked;
+ config.EmailSettings.SendEmailNotifications = React.findDOMNode(this.refs.sendEmailNotifications).checked;
+ config.EmailSettings.FeedbackName = React.findDOMNode(this.refs.feedbackName).value.trim();
+ config.EmailSettings.FeedbackEmail = React.findDOMNode(this.refs.feedbackEmail).value.trim();
+ config.EmailSettings.SMTPServer = React.findDOMNode(this.refs.SMTPServer).value.trim();
+ config.EmailSettings.SMTPPort = React.findDOMNode(this.refs.SMTPPort).value.trim();
+ config.EmailSettings.SMTPUsername = React.findDOMNode(this.refs.SMTPUsername).value.trim();
+ config.EmailSettings.SMTPPassword = React.findDOMNode(this.refs.SMTPPassword).value.trim();
+ config.EmailSettings.ConnectionSecurity = React.findDOMNode(this.refs.ConnectionSecurity).value.trim();
+ return config;
+ }
+
+ 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
+ });
+ },
+ (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() {
+ 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>{'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>{'Connection unsuccessful: ' + this.state.emailFail}
+ </div>
+ );
+ }
+
return (
<div className='wrapper--fixed'>
<h3>{'Email Settings'}</h3>
@@ -17,295 +150,308 @@ export default class EmailSettings extends React.Component {
className='form-horizontal'
role='form'
>
+
<div className='form-group'>
<label
className='control-label col-sm-4'
- htmlFor='email'
+ htmlFor='allowSignUpWithEmail'
>
- {'Bypass Email: '}
- <a
- href='#'
- data-trigger='hover click'
- data-toggle='popover'
- data-position='bottom'
- data-content={'Here\'s some more help text inside a popover for the Bypass Email field just to show how popovers look.'}
- >
- {'(?)'}
- </a>
+ {'Allow Sign Up With Email: '}
</label>
<div className='col-sm-8'>
<label className='radio-inline'>
<input
type='radio'
- name='byPassEmail'
- value='option1'
+ name='allowSignUpWithEmail'
+ value='true'
+ ref='allowSignUpWithEmail'
+ defaultChecked={this.props.config.EmailSettings.AllowSignUpWithEmail}
+ onChange={this.handleChange.bind(this, 'allowSignUpWithEmail_true')}
/>
- {'True'}
+ {'true'}
</label>
<label className='radio-inline'>
<input
type='radio'
- name='byPassEmail'
- value='option2'
+ name='allowSignUpWithEmail'
+ value='false'
+ defaultChecked={!this.props.config.EmailSettings.AllowSignUpWithEmail}
+ onChange={this.handleChange.bind(this, 'allowSignUpWithEmail_false')}
/>
- {'False'}
+ {'false'}
</label>
- <p className='help-text'>{'This is some sample help text for the Bypass Email field'}</p>
+ <p className='help-text'>{'Typically set to true in production. When true Mattermost will allow team creation and account signup utilizing email and password. You would set this to false if you only wanted to allow signup from a service like OAuth or LDAP.'}</p>
</div>
</div>
+
<div className='form-group'>
<label
className='control-label col-sm-4'
- htmlFor='smtpUsername'
+ htmlFor='sendEmailNotifications'
>
- {'SMTP Username:'}
+ {'Send Email Notifications: '}
</label>
<div className='col-sm-8'>
- <input
- type='email'
- className='form-control'
- id='smtpUsername'
- placeholder='Enter your SMTP username'
- value=''
- />
- <div className='help-text'>
- <div className='alert alert-warning'><i className='fa fa-warning'></i>{' This is some error text for the Bypass Email field'}</div>
- </div>
- <p className='help-text'>{'This is some sample help text for the SMTP username field'}</p>
+ <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')}
+ />
+ {'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')}
+ />
+ {'false'}
+ </label>
+ <p className='help-text'>{'Typically set to true in production. When true Mattermost will attempt to send email notifications. Developers may set this field to false skipping sending emails for faster development.'}</p>
</div>
</div>
+
<div className='form-group'>
<label
className='control-label col-sm-4'
- htmlFor='smtpPassword'
+ htmlFor='requireEmailVerification'
>
- {'SMTP Password:'}
+ {'Require Email Verification: '}
</label>
<div className='col-sm-8'>
- <input
- type='password'
- className='form-control'
- id='smtpPassword'
- placeholder='Enter your SMTP password'
- value=''
- />
+ <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}
+ />
+ {'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}
+ />
+ {'false'}
+ </label>
+ <p className='help-text'>{'Typically set to true in production. When true Mattermost will not allow a user to login without first having recieved an email with a verification link. 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='smtpServer'
+ htmlFor='feedbackName'
>
- {'SMTP Server:'}
+ {'Feedback Name:'}
</label>
<div className='col-sm-8'>
<input
type='text'
className='form-control'
- id='smtpServer'
- placeholder='Enter your SMTP server'
- value=''
+ id='feedbackName'
+ ref='feedbackName'
+ placeholder='Ex: "Mattermost", "System", "John Smith"'
+ defaultValue={this.props.config.EmailSettings.FeedbackName}
+ onChange={this.handleChange}
+ disabled={!this.state.sendEmailNotifications}
/>
- <div className='help-text'>
- <a
- href='#'
- className='help-link'
- >
- {'Test Connection'}
- </a>
- <div className='alert alert-success'><i className='fa fa-check'></i>{' Connection successful'}</div>
- <div className='alert alert-warning hide'><i className='fa fa-warning'></i>{' Connection unsuccessful'}</div>
- </div>
+ <p className='help-text'>{'Name 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'>{'Use TLS:'}</label>
+ <label
+ className='control-label col-sm-4'
+ htmlFor='feedbackEmail'
+ >
+ {'Feedback Email:'}
+ </label>
<div className='col-sm-8'>
- <label className='radio-inline'>
- <input
- type='radio'
- name='tls'
- value='option1'
- />
- {'True'}
- </label>
- <label className='radio-inline'>
- <input
- type='radio'
- name='tls'
- value='option2'
- />
- {'False'}
- </label>
+ <input
+ type='email'
+ className='form-control'
+ id='feedbackEmail'
+ ref='feedbackEmail'
+ placeholder='Ex: "mattermost@yourcompany.com", "admin@yourcompany.com"'
+ defaultValue={this.props.config.EmailSettings.FeedbackEmail}
+ onChange={this.handleChange}
+ disabled={!this.state.sendEmailNotifications}
+ />
+ <p className='help-text'>{'Email 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'>{'Use Start TLS:'}</label>
+ <label
+ className='control-label col-sm-4'
+ htmlFor='SMTPUsername'
+ >
+ {'SMTP Username:'}
+ </label>
<div className='col-sm-8'>
- <label className='radio-inline'>
- <input
- type='radio'
- name='starttls'
- value='option1'
- />
- {'True'}
- </label>
- <label className='radio-inline'>
- <input
- type='radio'
- name='starttls'
- value='option2'
- />
- {'False'}
- </label>
+ <input
+ type='text'
+ className='form-control'
+ id='SMTPUsername'
+ ref='SMTPUsername'
+ placeholder='Ex: "admin@yourcompany.com", "AKIADTOVBGERKLCBV"'
+ defaultValue={this.props.config.EmailSettings.SMTPUsername}
+ onChange={this.handleChange}
+ disabled={!this.state.sendEmailNotifications}
+ />
+ <p className='help-text'>{' 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='feedbackEmail'
+ htmlFor='SMTPPassword'
>
- {'Feedback Email:'}
+ {'SMTP Password:'}
</label>
<div className='col-sm-8'>
<input
type='text'
className='form-control'
- id='feedbackEmail'
- placeholder='Enter your feedback email'
- value=''
+ id='SMTPPassword'
+ ref='SMTPPassword'
+ placeholder='Ex: "yourpassword", "jcuS8PuvcpGhpgHhlcpT1Mx42pnqMxQY"'
+ defaultValue={this.props.config.EmailSettings.SMTPPassword}
+ onChange={this.handleChange}
+ disabled={!this.state.sendEmailNotifications}
/>
+ <p className='help-text'>{' 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='feedbackUsername'
+ htmlFor='SMTPServer'
>
- {'Feedback Username:'}
+ {'SMTP Server:'}
</label>
<div className='col-sm-8'>
<input
type='text'
className='form-control'
- id='feedbackUsername'
- placeholder='Enter your feedback username'
- value=''
+ id='SMTPServer'
+ ref='SMTPServer'
+ placeholder='Ex: "smtp.yourcompany.com", "email-smtp.us-east-1.amazonaws.com"'
+ defaultValue={this.props.config.EmailSettings.SMTPServer}
+ onChange={this.handleChange}
+ disabled={!this.state.sendEmailNotifications}
/>
+ <p className='help-text'>{'Location of SMTP email server.'}</p>
</div>
</div>
+
<div className='form-group'>
- <div className='col-sm-offset-4 col-sm-8'>
- <div className='checkbox'>
- <label><input type='checkbox' />{'Remember me'}</label>
- </div>
+ <label
+ className='control-label col-sm-4'
+ htmlFor='SMTPPort'
+ >
+ {'SMTP Port:'}
+ </label>
+ <div className='col-sm-8'>
+ <input
+ type='text'
+ className='form-control'
+ id='SMTPPort'
+ ref='SMTPPort'
+ placeholder='Ex: "25", "465"'
+ defaultValue={this.props.config.EmailSettings.SMTPPort}
+ onChange={this.handleChange}
+ disabled={!this.state.sendEmailNotifications}
+ />
+ <p className='help-text'>{'Port of SMTP email server.'}</p>
</div>
</div>
- <div
- className='panel-group'
- id='accordion'
- role='tablist'
- aria-multiselectable='true'
- >
- <div className='panel panel-default'>
- <div
- className='panel-heading'
- role='tab'
- id='headingOne'
+ <div className='form-group'>
+ <label
+ className='control-label col-sm-4'
+ htmlFor='ConnectionSecurity'
+ >
+ {'Connection Security:'}
+ </label>
+ <div className='col-sm-8'>
+ <select
+ className='form-control'
+ id='ConnectionSecurity'
+ ref='ConnectionSecurity'
+ defaultValue={this.props.config.EmailSettings.ConnectionSecurity}
+ onChange={this.handleChange}
+ disabled={!this.state.sendEmailNotifications}
>
- <h3 className='panel-title'>
- <a
- className='collapsed'
- role='button'
- data-toggle='collapse'
- data-parent='#accordion'
- href='#collapseOne'
- aria-expanded='true'
- aria-controls='collapseOne'
- >
- {'Advanced Settings '}
- <i className='fa fa-plus'></i>
- <i className='fa fa-minus'></i>
- </a>
- </h3>
+ <option value=''>{'None'}</option>
+ <option value='TLS'>{'TLS (Recommended)'}</option>
+ <option value='STARTTLS'>{'STARTTLS'}</option>
+ </select>
+ <div className='help-text'>
+ <table
+ className='table-bordered'
+ cellPadding='5'
+ >
+ <tr><td className='help-text'>{'None'}</td><td className='help-text'>{'Mattermost will send email over an unsecure connection.'}</td></tr>
+ <tr><td className='help-text'>{'TLS'}</td><td className='help-text'>{'Encrypts the communication between Mattermost and your email server.'}</td></tr>
+ <tr><td className='help-text'>{'STARTTLS'}</td><td className='help-text'>{'Takes an existing insecure connection and attempts to upgrade it to a secure connection using TLS.'}</td></tr>
+ </table>
</div>
- <div
- id='collapseOne'
- className='panel-collapse collapse'
- role='tabpanel'
- aria-labelledby='headingOne'
- >
- <div className='panel-body'>
- <div className='form-group'>
- <label
- className='control-label col-sm-4'
- htmlFor='feedbackUsername'
- >
- {'Apple push server:'}
- </label>
- <div className='col-sm-8'>
- <input
- type='text'
- className='form-control'
- id='feedbackUsername'
- placeholder='Enter your Apple push server'
- value=''
- />
- <p className='help-text'>{'This is some sample help text for the Apple push server field'}</p>
- </div>
- </div>
- <div className='form-group'>
- <label
- className='control-label col-sm-4'
- htmlFor='feedbackUsername'
- >
- {'Apple push certificate public:'}
- </label>
- <div className='col-sm-8'>
- <input
- type='text'
- className='form-control'
- id='feedbackUsername'
- placeholder='Enter your public apple push certificate'
- value=''
- />
- </div>
- </div>
- <div className='form-group'>
- <label
- className='control-label col-sm-4'
- htmlFor='feedbackUsername'
- >
- {'Apple push certificate private:'}
- </label>
- <div className='col-sm-8'>
- <input
- type='text'
- className='form-control'
- id='feedbackUsername'
- placeholder='Enter your private apple push certificate'
- value=''
- />
- </div>
- </div>
- </div>
+ <div className='help-text'>
+ <button
+ className='help-link'
+ onClick={this.handleTestConnection}
+ disabled={!this.state.sendEmailNotifications}
+ id='connection-button'
+ data-loading-text={'<span class=\'glyphicon glyphicon-refresh glyphicon-refresh-animate\'></span> Testing...'}
+ >
+ {'Test Connection'}
+ </button>
+ {emailSuccess}
+ {emailFail}
</div>
</div>
</div>
<div className='form-group'>
<div className='col-sm-12'>
+ {serverError}
<button
+ disabled={!this.state.saveNeeded}
type='submit'
- className='btn btn-primary'
+ className={saveClass}
+ onClick={this.handleSubmit}
+ id='save-button'
+ data-loading-text={'<span class=\'glyphicon glyphicon-refresh glyphicon-refresh-animate\'></span> Saving Config...'}
>
{'Save'}
</button>
</div>
</div>
+
</form>
</div>
);
}
-} \ No newline at end of file
+}
+
+EmailSettings.propTypes = {
+ config: React.PropTypes.object
+}; \ No newline at end of file
diff --git a/web/react/components/admin_console/log_settings.jsx b/web/react/components/admin_console/log_settings.jsx
index 4e3db8f68..2707ce6b6 100644
--- a/web/react/components/admin_console/log_settings.jsx
+++ b/web/react/components/admin_console/log_settings.jsx
@@ -12,13 +12,33 @@ export default class LogSettings extends React.Component {
this.handleSubmit = this.handleSubmit.bind(this);
this.state = {
+ consoleEnable: this.props.config.LogSettings.ConsoleEnable,
+ fileEnable: this.props.config.LogSettings.FileEnable,
saveNeeded: false,
serverError: null
};
}
- handleChange() {
- this.setState({saveNeeded: true, serverError: this.state.serverError});
+ handleChange(action) {
+ var s = {saveNeeded: true, serverError: this.state.serverError};
+
+ if (action === 'console_true') {
+ s.consoleEnable = true;
+ }
+
+ if (action === 'console_false') {
+ s.consoleEnable = false;
+ }
+
+ if (action === 'file_true') {
+ s.fileEnable = true;
+ }
+
+ if (action === 'file_false') {
+ s.fileEnable = false;
+ }
+
+ this.setState(s);
}
handleSubmit(e) {
@@ -37,11 +57,21 @@ export default class LogSettings extends React.Component {
config,
() => {
AsyncClient.getConfig();
- this.setState({serverError: null, saveNeeded: false});
+ this.setState({
+ consoleEnable: config.LogSettings.ConsoleEnable,
+ fileEnable: config.LogSettings.FileEnable,
+ serverError: null,
+ saveNeeded: false
+ });
$('#save-button').button('reset');
},
(err) => {
- this.setState({serverError: err.message, saveNeeded: true});
+ this.setState({
+ consoleEnable: config.LogSettings.ConsoleEnable,
+ fileEnable: config.LogSettings.FileEnable,
+ serverError: err.message,
+ saveNeeded: true
+ });
$('#save-button').button('reset');
}
);
@@ -81,7 +111,7 @@ export default class LogSettings extends React.Component {
value='true'
ref='consoleEnable'
defaultChecked={this.props.config.LogSettings.ConsoleEnable}
- onChange={this.handleChange}
+ onChange={this.handleChange.bind(this, 'console_true')}
/>
{'true'}
</label>
@@ -91,7 +121,7 @@ export default class LogSettings extends React.Component {
name='consoleEnable'
value='false'
defaultChecked={!this.props.config.LogSettings.ConsoleEnable}
- onChange={this.handleChange}
+ onChange={this.handleChange.bind(this, 'console_false')}
/>
{'false'}
</label>
@@ -113,6 +143,7 @@ export default class LogSettings extends React.Component {
ref='consoleLevel'
defaultValue={this.props.config.LogSettings.consoleLevel}
onChange={this.handleChange}
+ disabled={!this.state.consoleEnable}
>
<option value='DEBUG'>{'DEBUG'}</option>
<option value='INFO'>{'INFO'}</option>
@@ -136,7 +167,7 @@ export default class LogSettings extends React.Component {
ref='fileEnable'
value='true'
defaultChecked={this.props.config.LogSettings.FileEnable}
- onChange={this.handleChange}
+ onChange={this.handleChange.bind(this, 'file_true')}
/>
{'true'}
</label>
@@ -146,7 +177,7 @@ export default class LogSettings extends React.Component {
name='fileEnable'
value='false'
defaultChecked={!this.props.config.LogSettings.FileEnable}
- onChange={this.handleChange}
+ onChange={this.handleChange.bind(this, 'file_false')}
/>
{'false'}
</label>
@@ -168,6 +199,7 @@ export default class LogSettings extends React.Component {
ref='fileLevel'
defaultValue={this.props.config.LogSettings.FileLevel}
onChange={this.handleChange}
+ disabled={!this.state.fileEnable}
>
<option value='DEBUG'>{'DEBUG'}</option>
<option value='INFO'>{'INFO'}</option>
@@ -193,6 +225,7 @@ export default class LogSettings extends React.Component {
placeholder='Enter your file location'
defaultValue={this.props.config.LogSettings.FileLocation}
onChange={this.handleChange}
+ disabled={!this.state.fileEnable}
/>
<p className='help-text'>{'File to which log files are written. If blank, will be set to ./logs/mattermost.log. Log rotation is enabled and new files may be created in the same directory.'}</p>
</div>
@@ -214,6 +247,7 @@ export default class LogSettings extends React.Component {
placeholder='Enter your file format'
defaultValue={this.props.config.LogSettings.FileFormat}
onChange={this.handleChange}
+ disabled={!this.state.fileEnable}
/>
<p className='help-text'>
{'Format of log message output. If blank will be set to "[%D %T] [%L] %M", where:'}
diff --git a/web/react/components/invite_member_modal.jsx b/web/react/components/invite_member_modal.jsx
index 650a72516..acf6db9dc 100644
--- a/web/react/components/invite_member_modal.jsx
+++ b/web/react/components/invite_member_modal.jsx
@@ -21,7 +21,7 @@ export default class InviteMemberModal extends React.Component {
emailErrors: {},
firstNameErrors: {},
lastNameErrors: {},
- emailEnabled: !global.window.config.ByPassEmail
+ emailEnabled: !global.window.config.SendEmailNotifications
};
}
diff --git a/web/react/components/login.jsx b/web/react/components/login.jsx
index ffc07a4dd..cb7bc8835 100644
--- a/web/react/components/login.jsx
+++ b/web/react/components/login.jsx
@@ -95,10 +95,8 @@ export default class Login extends React.Component {
focusEmail = true;
}
- const authServices = JSON.parse(this.props.authServices);
-
let loginMessage = [];
- if (authServices.indexOf(Constants.GITLAB_SERVICE) !== -1) {
+ if (global.window.config.AllowSignUpWithGitLab) {
loginMessage.push(
<a
className='btn btn-custom-login gitlab'
@@ -116,7 +114,7 @@ export default class Login extends React.Component {
}
let emailSignup;
- if (authServices.indexOf(Constants.EMAIL_SERVICE) !== -1) {
+ if (global.window.config.AllowSignUpWithEmail) {
emailSignup = (
<div>
<div className={'form-group' + errorClass}>
@@ -206,10 +204,8 @@ export default class Login extends React.Component {
Login.defaultProps = {
teamName: '',
teamDisplayName: '',
- authServices: ''
};
Login.propTypes = {
teamName: React.PropTypes.string,
teamDisplayName: React.PropTypes.string,
- authServices: React.PropTypes.string
};
diff --git a/web/react/components/signup_team.jsx b/web/react/components/signup_team.jsx
index bf08e6508..91d79b919 100644
--- a/web/react/components/signup_team.jsx
+++ b/web/react/components/signup_team.jsx
@@ -4,7 +4,7 @@
const ChoosePage = require('./team_signup_choose_auth.jsx');
const EmailSignUpPage = require('./team_signup_with_email.jsx');
const SSOSignupPage = require('./team_signup_with_sso.jsx');
-const Constants = require('../utils/constants.jsx');
+var Constants = require('../utils/constants.jsx');
export default class TeamSignUp extends React.Component {
constructor(props) {
@@ -12,38 +12,32 @@ export default class TeamSignUp extends React.Component {
this.updatePage = this.updatePage.bind(this);
- if (props.services.length === 1) {
- if (props.services[0] === Constants.EMAIL_SERVICE) {
- this.state = {page: 'email', service: ''};
- } else {
- this.state = {page: 'service', service: props.services[0]};
- }
- } else {
- this.state = {page: 'choose', service: ''};
+ if (global.window.config.AllowSignUpWithEmail && global.window.config.AllowSignUpWithGitLab) {
+ this.state = {page: 'choose'};
+ } else if (global.window.config.AllowSignUpWithEmail) {
+ this.state = {page: 'email'};
+ } else if (global.window.config.AllowSignUpWithGitLab) {
+ this.state = {page: 'gitlab'};
}
}
- updatePage(page, service) {
- this.setState({page: page, service: service});
+
+ updatePage(page) {
+ this.setState({page});
}
+
render() {
+ if (this.state.page === 'choose') {
+ return (
+ <ChoosePage
+ updatePage={this.updatePage}
+ />
+ );
+ }
+
if (this.state.page === 'email') {
return <EmailSignUpPage />;
- } else if (this.state.page === 'service' && this.state.service !== '') {
- return <SSOSignupPage service={this.state.service} />;
+ } else if (this.state.page === 'gitlab') {
+ return <SSOSignupPage service={Constants.GITLAB_SERVICE} />;
}
-
- return (
- <ChoosePage
- services={this.props.services}
- updatePage={this.updatePage}
- />
- );
}
}
-
-TeamSignUp.defaultProps = {
- services: []
-};
-TeamSignUp.propTypes = {
- services: React.PropTypes.array
-};
diff --git a/web/react/components/signup_user_complete.jsx b/web/react/components/signup_user_complete.jsx
index 19c3b2d22..08d5e2f48 100644
--- a/web/react/components/signup_user_complete.jsx
+++ b/web/react/components/signup_user_complete.jsx
@@ -161,11 +161,8 @@ export default class SignupUserComplete extends React.Component {
</div>
);
- // add options to log in using another service
- var authServices = JSON.parse(this.props.authServices);
-
var signupMessage = [];
- if (authServices.indexOf(Constants.GITLAB_SERVICE) >= 0) {
+ if (global.window.config.AllowSignUpWithGitLab) {
signupMessage.push(
<a
className='btn btn-custom-login gitlab'
@@ -178,7 +175,7 @@ export default class SignupUserComplete extends React.Component {
}
var emailSignup;
- if (authServices.indexOf(Constants.EMAIL_SERVICE) !== -1) {
+ if (global.window.config.AllowSignUpWithEmail) {
emailSignup = (
<div>
<div className='inner__content'>
@@ -262,7 +259,6 @@ SignupUserComplete.defaultProps = {
teamId: '',
email: '',
data: null,
- authServices: '',
teamDisplayName: ''
};
SignupUserComplete.propTypes = {
@@ -271,6 +267,5 @@ SignupUserComplete.propTypes = {
teamId: React.PropTypes.string,
email: React.PropTypes.string,
data: React.PropTypes.string,
- authServices: React.PropTypes.string,
teamDisplayName: React.PropTypes.string
};
diff --git a/web/react/components/team_signup_choose_auth.jsx b/web/react/components/team_signup_choose_auth.jsx
index d3107c5c7..cfd45edb3 100644
--- a/web/react/components/team_signup_choose_auth.jsx
+++ b/web/react/components/team_signup_choose_auth.jsx
@@ -1,8 +1,6 @@
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
// See License.txt for license information.
-var Constants = require('../utils/constants.jsx');
-
export default class ChooseAuthPage extends React.Component {
constructor(props) {
super(props);
@@ -10,7 +8,7 @@ export default class ChooseAuthPage extends React.Component {
}
render() {
var buttons = [];
- if (this.props.services.indexOf(Constants.GITLAB_SERVICE) !== -1) {
+ if (global.window.config.AllowSignUpWithGitLab) {
buttons.push(
<a
className='btn btn-custom-login gitlab btn-full'
@@ -18,17 +16,17 @@ export default class ChooseAuthPage extends React.Component {
onClick={
function clickGit(e) {
e.preventDefault();
- this.props.updatePage('service', Constants.GITLAB_SERVICE);
+ this.props.updatePage('gitlab');
}.bind(this)
}
>
<span className='icon' />
- <span>Create new team with GitLab Account</span>
+ <span>{'Create new team with GitLab Account'}</span>
</a>
);
}
- if (this.props.services.indexOf(Constants.EMAIL_SERVICE) !== -1) {
+ if (global.window.config.AllowSignUpWithEmail) {
buttons.push(
<a
className='btn btn-custom-login email btn-full'
@@ -36,18 +34,18 @@ export default class ChooseAuthPage extends React.Component {
onClick={
function clickEmail(e) {
e.preventDefault();
- this.props.updatePage('email', '');
+ this.props.updatePage('email');
}.bind(this)
}
>
<span className='fa fa-envelope' />
- <span>Create new team with email address</span>
+ <span>{'Create new team with email address'}</span>
</a>
);
}
if (buttons.length === 0) {
- buttons = <span>No sign-up methods configured, please contact your system administrator.</span>;
+ buttons = <span>{'No sign-up methods configured, please contact your system administrator.'}</span>;
}
return (
@@ -61,10 +59,6 @@ export default class ChooseAuthPage extends React.Component {
}
}
-ChooseAuthPage.defaultProps = {
- services: []
-};
ChooseAuthPage.propTypes = {
- services: React.PropTypes.array,
updatePage: React.PropTypes.func
};
diff --git a/web/react/components/team_signup_send_invites_page.jsx b/web/react/components/team_signup_send_invites_page.jsx
index 41ac98303..ee51debb7 100644
--- a/web/react/components/team_signup_send_invites_page.jsx
+++ b/web/react/components/team_signup_send_invites_page.jsx
@@ -13,7 +13,7 @@ export default class TeamSignupSendInvitesPage extends React.Component {
this.submitSkip = this.submitSkip.bind(this);
this.keySubmit = this.keySubmit.bind(this);
this.state = {
- emailEnabled: !global.window.config.ByPassEmail
+ emailEnabled: !global.window.config.SendEmailNotifications
};
if (!this.state.emailEnabled) {
diff --git a/web/react/components/user_settings_general.jsx b/web/react/components/user_settings_general.jsx
index 66cde6ca2..895601bd2 100644
--- a/web/react/components/user_settings_general.jsx
+++ b/web/react/components/user_settings_general.jsx
@@ -208,7 +208,7 @@ export default class UserSettingsGeneralTab extends React.Component {
}
setupInitialState(props) {
var user = props.user;
- var emailEnabled = !global.window.config.ByPassEmail;
+ var emailEnabled = !global.window.config.SendEmailNotifications;
return {username: user.username, firstName: user.first_name, lastName: user.last_name, nickname: user.nickname,
email: user.email, picture: null, loadingPicture: false, emailEnabled: emailEnabled};
}
diff --git a/web/react/pages/login.jsx b/web/react/pages/login.jsx
index 830f622fa..f78e0f37a 100644
--- a/web/react/pages/login.jsx
+++ b/web/react/pages/login.jsx
@@ -8,7 +8,6 @@ function setupLoginPage(props) {
<Login
teamDisplayName={props.TeamDisplayName}
teamName={props.TeamName}
- authServices={props.AuthServices}
/>,
document.getElementById('login')
);
diff --git a/web/react/pages/signup_team.jsx b/web/react/pages/signup_team.jsx
index 427daf577..d0e08f446 100644
--- a/web/react/pages/signup_team.jsx
+++ b/web/react/pages/signup_team.jsx
@@ -3,11 +3,9 @@
var SignupTeam = require('../components/signup_team.jsx');
-function setupSignupTeamPage(props) {
- var services = JSON.parse(props.AuthServices);
-
+function setupSignupTeamPage() {
React.render(
- <SignupTeam services={services} />,
+ <SignupTeam />,
document.getElementById('signup-team')
);
}
diff --git a/web/react/pages/signup_user_complete.jsx b/web/react/pages/signup_user_complete.jsx
index 112aaa3f2..cc7607187 100644
--- a/web/react/pages/signup_user_complete.jsx
+++ b/web/react/pages/signup_user_complete.jsx
@@ -12,7 +12,6 @@ function setupSignupUserCompletePage(props) {
email={props.Email}
hash={props.Hash}
data={props.Data}
- authServices={props.AuthServices}
/>,
document.getElementById('signup-user-complete')
);
diff --git a/web/react/utils/client.jsx b/web/react/utils/client.jsx
index c9eb09c00..b3fb28e99 100644
--- a/web/react/utils/client.jsx
+++ b/web/react/utils/client.jsx
@@ -334,6 +334,21 @@ export function saveConfig(config, success, error) {
});
}
+export function testEmail(config, success, error) {
+ $.ajax({
+ url: '/api/v1/admin/test_email',
+ dataType: 'json',
+ contentType: 'application/json',
+ type: 'POST',
+ data: JSON.stringify(config),
+ success,
+ error: function onError(xhr, status, err) {
+ var e = handleError('testEmail', xhr, status, err);
+ error(e);
+ }
+ });
+}
+
export function getMeSynchronous(success, error) {
var currentUser = null;
$.ajax({
diff --git a/web/web.go b/web/web.go
index 305e4f199..2264d5053 100644
--- a/web/web.go
+++ b/web/web.go
@@ -143,7 +143,6 @@ func root(c *api.Context, w http.ResponseWriter, r *http.Request) {
if len(c.Session.UserId) == 0 {
page := NewHtmlTemplatePage("signup_team", "Signup")
- page.Props["AuthServices"] = model.ArrayToJson(utils.GetAllowedAuthServices())
page.Render(c, w)
} else {
page := NewHtmlTemplatePage("home", "Home")
@@ -159,7 +158,6 @@ func signup(c *api.Context, w http.ResponseWriter, r *http.Request) {
}
page := NewHtmlTemplatePage("signup_team", "Signup")
- page.Props["AuthServices"] = model.ArrayToJson(utils.GetAllowedAuthServices())
page.Render(c, w)
}
@@ -191,7 +189,6 @@ func login(c *api.Context, w http.ResponseWriter, r *http.Request) {
page := NewHtmlTemplatePage("login", "Login")
page.Props["TeamDisplayName"] = team.DisplayName
page.Props["TeamName"] = teamName
- page.Props["AuthServices"] = model.ArrayToJson(utils.GetAllowedAuthServices())
page.Render(c, w)
}
@@ -277,7 +274,6 @@ func signupUserComplete(c *api.Context, w http.ResponseWriter, r *http.Request)
page.Props["TeamId"] = props["id"]
page.Props["Data"] = data
page.Props["Hash"] = hash
- page.Props["AuthServices"] = model.ArrayToJson(utils.GetAllowedAuthServices())
page.Render(c, w)
}