summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md4
-rw-r--r--api/team.go21
-rw-r--r--store/sql_user_store.go8
-rw-r--r--web/react/components/setting_picture.jsx30
-rw-r--r--web/react/components/user_settings.jsx25
5 files changed, 58 insertions, 30 deletions
diff --git a/README.md b/README.md
index f0857e99d..4ba3de128 100644
--- a/README.md
+++ b/README.md
@@ -19,8 +19,8 @@ Learn More
<li/>Make a pull request: http://www.mattermost.org/contribute-to-mattermost/</li>
</ul>
-Installing the Mattermost
-=========================
+Installing Mattermost
+=====================
You're installing "Mattermost Alpha", a pre-released version intended for an early look at what we're building. While SpinPunch runs this version internally, it's not recommended for production deployments since we can't guarantee API stability or backwards compatibility until our production release.
diff --git a/api/team.go b/api/team.go
index c9fe42ecc..01c8e50b6 100644
--- a/api/team.go
+++ b/api/team.go
@@ -275,11 +275,24 @@ func emailTeams(c *Context, w http.ResponseWriter, r *http.Request) {
subjectPage := NewServerTemplatePage("find_teams_subject", c.GetSiteURL())
bodyPage := NewServerTemplatePage("find_teams_body", c.GetSiteURL())
- if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil {
- l4g.Error("An error occured while sending an email in emailTeams err=%v", err)
- }
+ if result := <-Srv.Store.Team().GetTeamsForEmail(email); result.Err != nil {
+ c.Err = result.Err
+ } else {
+ teams := result.Data.([]*model.Team)
- w.Write([]byte(model.MapToJson(m)))
+ // the template expects Props to be a map with team names as the keys
+ props := make(map[string]string)
+ for _, team := range teams {
+ props[team.Name] = team.Name
+ }
+ bodyPage.Props = props
+
+ if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil {
+ l4g.Error("An error occured while sending an email in emailTeams err=%v", err)
+ }
+
+ w.Write([]byte(model.MapToJson(m)))
+ }
}
func inviteMembers(c *Context, w http.ResponseWriter, r *http.Request) {
diff --git a/store/sql_user_store.go b/store/sql_user_store.go
index cd63e95b8..552d12843 100644
--- a/store/sql_user_store.go
+++ b/store/sql_user_store.go
@@ -161,7 +161,13 @@ func (us SqlUserStore) Update(user *model.User, allowActiveUpdate bool) StoreCha
}
if count, err := us.GetMaster().Update(user); err != nil {
- result.Err = model.NewAppError("SqlUserStore.Update", "We encounted an error updating the account", "user_id="+user.Id+", "+err.Error())
+ if IsUniqueConstraintError(err.Error(), "Email", "users_email_teamid_key") {
+ result.Err = model.NewAppError("SqlUserStore.Update", "This email is already taken. Please choose another", "user_id="+user.Id+", "+err.Error())
+ } else if IsUniqueConstraintError(err.Error(), "Username", "users_username_teamid_key") {
+ result.Err = model.NewAppError("SqlUserStore.Update", "This username is already taken. Please choose another.", "user_id="+user.Id+", "+err.Error())
+ } else {
+ result.Err = model.NewAppError("SqlUserStore.Update", "We encounted an error updating the account", "user_id="+user.Id+", "+err.Error())
+ }
} else if count != 1 {
result.Err = model.NewAppError("SqlUserStore.Update", "We couldn't update the account", fmt.Sprintf("user_id=%v, count=%v", user.Id, count))
} else {
diff --git a/web/react/components/setting_picture.jsx b/web/react/components/setting_picture.jsx
index 6cfb74d60..fa4c8bb62 100644
--- a/web/react/components/setting_picture.jsx
+++ b/web/react/components/setting_picture.jsx
@@ -7,8 +7,8 @@ module.exports = React.createClass({
var reader = new FileReader();
var img = this.refs.image.getDOMNode();
- reader.onload = function (e) {
- $(img).attr('src', e.target.result)
+ reader.onload = function(e) {
+ $(img).attr('src', e.target.result);
};
reader.readAsDataURL(file);
@@ -25,27 +25,27 @@ module.exports = React.createClass({
var img = null;
if (this.props.picture) {
- img = (<img ref="image" className="profile-img" src=""/>);
+ img = (<img ref='image' className='profile-img' src=''/>);
} else {
- img = (<img ref="image" className="profile-img" src={this.props.src}/>);
+ img = (<img ref='image' className='profile-img' src={this.props.src}/>);
}
var self = this;
return (
- <ul className="section-max">
- <li className="col-xs-12 section-title">{this.props.title}</li>
- <li className="col-xs-offset-3 col-xs-8">
- <ul className="setting-list">
- <li className="setting-list-item">
+ <ul className='section-max'>
+ <li className='col-xs-12 section-title'>{this.props.title}</li>
+ <li className='col-xs-offset-3 col-xs-8'>
+ <ul className='setting-list'>
+ <li className='setting-list-item'>
{img}
</li>
- <li className="setting-list-item">
- { server_error }
- { client_error }
- <span className="btn btn-sm btn-primary btn-file sel-btn">Upload<input ref="input" accept=".jpg,.png,.bmp" type="file" onChange={this.props.pictureChange}/></span>
- <a className={this.props.submitActive ? "btn btn-sm btn-primary" : "btn btn-sm btn-inactive disabled"} onClick={this.props.submit}>Save</a>
- <a className="btn btn-sm theme" href="#" onClick={self.props.updateSection}>Cancel</a>
+ <li className='setting-list-item'>
+ {server_error}
+ {client_error}
+ <span className='btn btn-sm btn-primary btn-file sel-btn'>Select<input ref='input' accept='.jpg,.png,.bmp' type='file' onChange={this.props.pictureChange}/></span>
+ <a className={this.props.submitActive ? 'btn btn-sm btn-primary' : 'btn btn-sm btn-inactive disabled'} onClick={this.props.submit}>Save</a>
+ <a className='btn btn-sm theme' href='#' onClick={self.props.updateSection}>Cancel</a>
</li>
</ul>
</li>
diff --git a/web/react/components/user_settings.jsx b/web/react/components/user_settings.jsx
index e1ae6da52..902989b7b 100644
--- a/web/react/components/user_settings.jsx
+++ b/web/react/components/user_settings.jsx
@@ -465,17 +465,17 @@ var SecurityTab = React.createClass({
var confirmPassword = this.state.confirm_password;
if (currentPassword === '') {
- this.setState({ password_error: "Please enter your current password" });
+ this.setState({password_error: 'Please enter your current password', server_error: ''});
return;
}
if (newPassword.length < 5) {
- this.setState({ password_error: "New passwords must be at least 5 characters" });
+ this.setState({password_error: 'New passwords must be at least 5 characters', server_error: ''});
return;
}
- if (newPassword != confirmPassword) {
- this.setState({ password_error: "The new passwords you entered do not match" });
+ if (newPassword !== confirmPassword) {
+ this.setState({password_error: 'The new passwords you entered do not match', server_error: ''});
return;
}
@@ -488,11 +488,16 @@ var SecurityTab = React.createClass({
function(data) {
this.props.updateSection("");
AsyncClient.getMe();
- this.setState({ current_password: '', new_password: '', confirm_password: '' });
+ this.setState({current_password: '', new_password: '', confirm_password: ''});
}.bind(this),
function(err) {
- state = this.getInitialState();
- state.server_error = err;
+ var state = this.getInitialState();
+ if (err.message) {
+ state.server_error = err.message;
+ } else {
+ state.server_error = err;
+ }
+ state.password_error = '';
this.setState(state);
}.bind(this)
);
@@ -709,7 +714,11 @@ var GeneralTab = React.createClass({
}.bind(this),
function(err) {
state = this.getInitialState();
- state.server_error = err;
+ if(err.message) {
+ state.server_error = err.message;
+ } else {
+ state.server_error = err
+ }
this.setState(state);
}.bind(this)
);