diff options
-rw-r--r-- | utils/config.go | 2 | ||||
-rw-r--r-- | utils/mail.go | 3 | ||||
-rw-r--r-- | web/react/components/edit_channel_modal.jsx | 7 | ||||
-rw-r--r-- | web/react/components/edit_post_modal.jsx | 7 | ||||
-rw-r--r-- | web/react/components/new_channel.jsx | 4 | ||||
-rw-r--r-- | web/react/components/post.jsx | 5 | ||||
-rw-r--r-- | web/react/components/post_info.jsx | 1 | ||||
-rw-r--r-- | web/react/components/post_right.jsx | 4 | ||||
-rw-r--r-- | web/react/components/team_signup_send_invites_page.jsx | 17 | ||||
-rw-r--r-- | web/react/utils/client.jsx | 17 | ||||
-rw-r--r-- | web/templates/signup_team.html | 2 | ||||
-rw-r--r-- | web/web.go | 13 |
12 files changed, 60 insertions, 22 deletions
diff --git a/utils/config.go b/utils/config.go index 536d0d802..46daf203c 100644 --- a/utils/config.go +++ b/utils/config.go @@ -234,8 +234,8 @@ func LoadConfig(fileName string) { // Check for a valid email for feedback, if not then do feedback@domain if _, err := mail.ParseAddress(config.EmailSettings.FeedbackEmail); err != nil { - config.EmailSettings.FeedbackEmail = "feedback@localhost" l4g.Error("Misconfigured feedback email setting: %s", config.EmailSettings.FeedbackEmail) + config.EmailSettings.FeedbackEmail = "feedback@localhost" } configureLog(config.LogSettings) diff --git a/utils/mail.go b/utils/mail.go index f02e21253..783a2de8c 100644 --- a/utils/mail.go +++ b/utils/mail.go @@ -79,6 +79,9 @@ func newSMTPClient(conn net.Conn) (*smtp.Client, *model.AppError) { ServerName: host, } c.StartTLS(tlsconfig) + if err = c.Auth(auth); err != nil { + return nil, model.NewAppError("SendMail", "Failed to authenticate on SMTP server", err.Error()) + } } return c, nil } diff --git a/web/react/components/edit_channel_modal.jsx b/web/react/components/edit_channel_modal.jsx index fc303bbc2..76f0c2c4d 100644 --- a/web/react/components/edit_channel_modal.jsx +++ b/web/react/components/edit_channel_modal.jsx @@ -50,13 +50,18 @@ module.exports = React.createClass({ render: function() { var server_error = this.state.server_error ? <div className='form-group has-error'><br/><label className='control-label'>{ this.state.server_error }</label></div> : null; + var editTitle = <h4 className='modal-title' ref='title'>Edit Description</h4>; + if (this.state.title) { + editTitle = <h4 className='modal-title' ref='title'>Edit Description for <span className='name'>{this.state.title}</span></h4>; + } + return ( <div className="modal fade" ref="modal" id="edit_channel" role="dialog" tabIndex="-1" aria-hidden="true"> <div className="modal-dialog"> <div className="modal-content"> <div className="modal-header"> <button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> - <h4 className="modal-title" ref="title">Edit Description for <span className='name'>{this.state.title}</span></h4> + {editTitle} </div> <div className="modal-body"> <textarea className="form-control no-resize" rows="6" ref="channelDesc" maxLength="1024" value={this.state.description} onChange={this.handleUserInput}></textarea> diff --git a/web/react/components/edit_post_modal.jsx b/web/react/components/edit_post_modal.jsx index 064d3fa94..2d865a45d 100644 --- a/web/react/components/edit_post_modal.jsx +++ b/web/react/components/edit_post_modal.jsx @@ -34,6 +34,7 @@ module.exports = React.createClass({ ); $("#edit_post").modal('hide'); + $(this.state.refocusId).focus(); }, handleEditInput: function(editText) { this.setState({ editText: editText }); @@ -52,12 +53,12 @@ module.exports = React.createClass({ var self = this; $(this.refs.modal.getDOMNode()).on('hidden.bs.modal', function(e) { - self.setState({ editText: "", title: "", channel_id: "", post_id: "", comments: 0 }); + self.setState({ editText: "", title: "", channel_id: "", post_id: "", comments: 0, refocusId: "" }); }); $(this.refs.modal.getDOMNode()).on('show.bs.modal', function(e) { var button = e.relatedTarget; - self.setState({ editText: $(button).attr('data-message'), title: $(button).attr('data-title'), channel_id: $(button).attr('data-channelid'), post_id: $(button).attr('data-postid'), comments: $(button).attr('data-comments') }); + self.setState({ editText: $(button).attr('data-message'), title: $(button).attr('data-title'), channel_id: $(button).attr('data-channelid'), post_id: $(button).attr('data-postid'), comments: $(button).attr('data-comments'), refocusId: $(button).attr('data-refoucsid') }); }); $(this.refs.modal.getDOMNode()).on('shown.bs.modal', function(e) { @@ -65,7 +66,7 @@ module.exports = React.createClass({ }); }, getInitialState: function() { - return { editText: "", title: "", post_id: "", channel_id: "", comments: 0 }; + return { editText: "", title: "", post_id: "", channel_id: "", comments: 0, refocusId: "" }; }, render: function() { var error = this.state.error ? <div className='form-group has-error'><label className='control-label'>{ this.state.error }</label></div> : null; diff --git a/web/react/components/new_channel.jsx b/web/react/components/new_channel.jsx index b00376758..38c9ea76d 100644 --- a/web/react/components/new_channel.jsx +++ b/web/react/components/new_channel.jsx @@ -127,12 +127,12 @@ module.exports = React.createClass({ <div className='modal-body'> <div className={displayNameClass}> <label className='control-label'>Display Name</label> - <input onKeyUp={this.displayNameKeyUp} type='text' ref='display_name' className='form-control' placeholder='Enter display name' maxLength='64' /> + <input onKeyUp={this.displayNameKeyUp} type='text' ref='display_name' className='form-control' placeholder='Enter display name' maxLength='22' /> {displayNameError} </div> <div className={nameClass}> <label className='control-label'>Handle</label> - <input type='text' className='form-control' ref='channel_name' placeholder="lowercase alphanumeric's only" maxLength='64' /> + <input type='text' className='form-control' ref='channel_name' placeholder="lowercase alphanumeric's only" maxLength='22' /> {nameError} </div> <div className='form-group'> diff --git a/web/react/components/post.jsx b/web/react/components/post.jsx index 7bc6a8c01..cc2e37fa8 100644 --- a/web/react/components/post.jsx +++ b/web/react/components/post.jsx @@ -102,7 +102,12 @@ module.exports = React.createClass({ currentUserCss = "current--user"; } + var userProfile = UserStore.getProfile(post.user_id); + var timestamp = UserStore.getCurrentUser().update_at; + if (userProfile) { + timestamp = userProfile.update_at; + } return ( <div> diff --git a/web/react/components/post_info.jsx b/web/react/components/post_info.jsx index c96a04c7c..73e897f62 100644 --- a/web/react/components/post_info.jsx +++ b/web/react/components/post_info.jsx @@ -49,6 +49,7 @@ export default class PostInfo extends React.Component { role='menuitem' data-toggle='modal' data-target='#edit_post' + data-refoucsid="#post_textbox" data-title={type} data-message={post.message} data-postid={post.id} diff --git a/web/react/components/post_right.jsx b/web/react/components/post_right.jsx index c8c51b0c3..ac4c8a6d7 100644 --- a/web/react/components/post_right.jsx +++ b/web/react/components/post_right.jsx @@ -93,7 +93,7 @@ RootPost = React.createClass({ <div> <a href='#' className='dropdown-toggle theme' type='button' data-toggle='dropdown' aria-expanded='false' /> <ul className='dropdown-menu' role='menu'> - <li role='presentation'><a href='#' role='menuitem' data-toggle='modal' data-target='#edit_post' data-title={type} data-message={post.message} data-postid={post.id} data-channelid={post.channel_id}>Edit</a></li> + <li role='presentation'><a href='#' role='menuitem' data-toggle='modal' data-target='#edit_post' data-refoucsid='#reply_textbox' data-title={type} data-message={post.message} data-postid={post.id} data-channelid={post.channel_id}>Edit</a></li> <li role='presentation'><a href='#' role='menuitem' data-toggle='modal' data-target='#delete_post' data-title={type} data-postid={post.id} data-channelid={post.channel_id} data-comments={this.props.commentCount}>Delete</a></li> </ul> </div> @@ -203,7 +203,7 @@ CommentPost = React.createClass({ <div className='dropdown' onClick={function(e){$('.post-list-holder-by-time').scrollTop($('.post-list-holder-by-time').scrollTop() + 50);}}> <a href='#' className='dropdown-toggle theme' type='button' data-toggle='dropdown' aria-expanded='false' /> <ul className='dropdown-menu' role='menu'> - <li role='presentation'><a href='#' role='menuitem' data-toggle='modal' data-target='#edit_post' data-title={type} data-message={post.message} data-postid={post.id} data-channelid={post.channel_id}>Edit</a></li> + <li role='presentation'><a href='#' role='menuitem' data-toggle='modal' data-target='#edit_post' data-refoucsid='#reply_textbox' data-title={type} data-message={post.message} data-postid={post.id} data-channelid={post.channel_id}>Edit</a></li> <li role='presentation'><a href='#' role='menuitem' data-toggle='modal' data-target='#delete_post' data-title={type} data-postid={post.id} data-channelid={post.channel_id} data-comments={0}>Delete</a></li> </ul> </div> diff --git a/web/react/components/team_signup_send_invites_page.jsx b/web/react/components/team_signup_send_invites_page.jsx index a1e12661e..646a742ba 100644 --- a/web/react/components/team_signup_send_invites_page.jsx +++ b/web/react/components/team_signup_send_invites_page.jsx @@ -13,6 +13,7 @@ export default class TeamSignupSendInvitesPage extends React.Component { this.submitNext = this.submitNext.bind(this); this.submitAddInvite = this.submitAddInvite.bind(this); this.submitSkip = this.submitSkip.bind(this); + this.keySubmit = this.keySubmit.bind(this); this.state = { emailEnabled: !ConfigStore.getSettingAsBoolean('ByPassEmail', false) }; @@ -68,12 +69,28 @@ export default class TeamSignupSendInvitesPage extends React.Component { this.props.state.wizard = 'username'; this.props.updateParent(this.props.state); } + keySubmit(e) { + if (e && e.keyCode === 13) { + this.submitNext(e) + } + } componentWillMount() { if (!this.state.emailEnabled) { this.props.state.wizard = 'username'; this.props.updateParent(this.props.state); } } + componentDidMount() { + if (!this.state.emailEnabled) { + // Must use keypress not keyup due to event chain of pressing enter + $('body').keypress(this.keySubmit); + } + } + componentWillUnmount() { + if (!this.state.emailEnabled) { + $('body').off('keypress', this.keySubmit); + } + } render() { client.track('signup', 'signup_team_05_send_invites'); diff --git a/web/react/utils/client.jsx b/web/react/utils/client.jsx index 103292abf..754843697 100644 --- a/web/react/utils/client.jsx +++ b/web/react/utils/client.jsx @@ -252,6 +252,7 @@ module.exports.revokeSession = function(altId, success, error) { module.exports.getSessions = function(userId, success, error) { $.ajax({ + cache: false, url: '/api/v1/users/' + userId + '/sessions', dataType: 'json', contentType: 'application/json', @@ -282,6 +283,7 @@ module.exports.getMeSynchronous = function(success, error) { var currentUser = null; $.ajax({ async: false, + cache: false, url: '/api/v1/users/me', dataType: 'json', contentType: 'application/json', @@ -293,12 +295,9 @@ module.exports.getMeSynchronous = function(success, error) { } }, error: function onError(xhr, status, err) { - var ieChecker = window.navigator.userAgent; // This and the condition below is used to check specifically for browsers IE10 & 11 to suppress a 200 'OK' error from appearing on login - if (xhr.status !== 200 || !(ieChecker.indexOf('Trident/7.0') > 0 || ieChecker.indexOf('Trident/6.0') > 0)) { - if (error) { - var e = handleError('getMeSynchronous', xhr, status, err); - error(e); - } + if (error) { + var e = handleError('getMeSynchronous', xhr, status, err); + error(e); } } }); @@ -566,6 +565,7 @@ module.exports.updateLastViewedAt = function(channelId, success, error) { function getChannels(success, error) { $.ajax({ + cache: false, url: '/api/v1/channels/', dataType: 'json', type: 'GET', @@ -581,6 +581,7 @@ module.exports.getChannels = getChannels; module.exports.getChannel = function(id, success, error) { $.ajax({ + cache: false, url: '/api/v1/channels/' + id + '/', dataType: 'json', type: 'GET', @@ -610,6 +611,7 @@ module.exports.getMoreChannels = function(success, error) { function getChannelCounts(success, error) { $.ajax({ + cache: false, url: '/api/v1/channels/counts', dataType: 'json', type: 'GET', @@ -653,6 +655,7 @@ module.exports.executeCommand = function(channelId, command, suggest, success, e module.exports.getPosts = function(channelId, offset, limit, success, error, complete) { $.ajax({ + cache: false, url: '/api/v1/channels/' + channelId + '/posts/' + offset + '/' + limit, dataType: 'json', type: 'GET', @@ -668,6 +671,7 @@ module.exports.getPosts = function(channelId, offset, limit, success, error, com module.exports.getPost = function(channelId, postId, success, error) { $.ajax({ + cache: false, url: '/api/v1/channels/' + channelId + '/post/' + postId, dataType: 'json', type: 'GET', @@ -791,6 +795,7 @@ module.exports.removeChannelMember = function(id, data, success, error) { module.exports.getProfiles = function(success, error) { $.ajax({ + cache: false, url: '/api/v1/users/profiles', dataType: 'json', contentType: 'application/json', diff --git a/web/templates/signup_team.html b/web/templates/signup_team.html index 313ed9d5f..b896dedf5 100644 --- a/web/templates/signup_team.html +++ b/web/templates/signup_team.html @@ -9,7 +9,7 @@ <div class="col-sm-12"> <div class="signup-team__container"> <img class="signup-team-logo" src="/static/images/logo.png" /> - <h1>Mattermost</h1> + <h1>{{ .SiteName }}</h1> <h4 class="color--light">All team communication in one place, searchable and accessible anywhere</h4> <div id="signup-team"></div> </div> diff --git a/web/web.go b/web/web.go index e449d2d3a..dc2b5dced 100644 --- a/web/web.go +++ b/web/web.go @@ -4,18 +4,19 @@ package web import ( - l4g "code.google.com/p/log4go" "fmt" + "html/template" + "net/http" + "strconv" + "strings" + + l4g "code.google.com/p/log4go" "github.com/gorilla/mux" "github.com/mattermost/platform/api" "github.com/mattermost/platform/model" "github.com/mattermost/platform/utils" "github.com/mssola/user_agent" "gopkg.in/fsnotify.v1" - "html/template" - "net/http" - "strconv" - "strings" ) var Templates *template.Template @@ -214,7 +215,7 @@ func signupTeamComplete(c *api.Context, w http.ResponseWriter, r *http.Request) props := model.MapFromJson(strings.NewReader(data)) t, err := strconv.ParseInt(props["time"], 10, 64) - if err != nil || model.GetMillis()-t > 1000*60*60 { // one hour + if err != nil || model.GetMillis()-t > 1000*60*60*24*30 { // 30 days c.Err = model.NewAppError("signupTeamComplete", "The signup link has expired", "") return } |