From 9677a9f71777d75f3def0b0cb238050a30ec6a67 Mon Sep 17 00:00:00 2001 From: =Corey Hulen Date: Wed, 29 Jul 2015 01:26:10 -0800 Subject: Fixes mm-1355 adds rate limiting apis --- api/server.go | 37 +++++++++++++++++++++++++++++++++++-- api/user.go | 14 ++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) (limited to 'api') diff --git a/api/server.go b/api/server.go index 3163f79f5..3273e766c 100644 --- a/api/server.go +++ b/api/server.go @@ -9,7 +9,10 @@ import ( "github.com/gorilla/mux" "github.com/mattermost/platform/store" "github.com/mattermost/platform/utils" + "github.com/throttled/throttled" + throttledStore "github.com/throttled/throttled/store" "net/http" + "strings" "time" ) @@ -35,10 +38,40 @@ func NewServer() { func StartServer() { l4g.Info("Starting Server...") - l4g.Info("Server is listening on " + utils.Cfg.ServiceSettings.Port) + + var handler http.Handler = Srv.Router + + if utils.Cfg.RateLimitSettings.UseRateLimiter { + l4g.Info("RateLimiter is enabled") + + vary := throttled.VaryBy{} + + if utils.Cfg.RateLimitSettings.VaryByRemoteAddr { + vary.RemoteAddr = true + } + + if len(utils.Cfg.RateLimitSettings.VaryByHeader) > 0 { + vary.Headers = strings.Fields(utils.Cfg.RateLimitSettings.VaryByHeader) + + if utils.Cfg.RateLimitSettings.VaryByRemoteAddr { + l4g.Warn("RateLimitSettings not configured properly using VaryByHeader and disabling VaryByRemoteAddr") + vary.RemoteAddr = false + } + } + + th := throttled.RateLimit(throttled.PerSec(utils.Cfg.RateLimitSettings.PerSec), &vary, throttledStore.NewMemStore(utils.Cfg.RateLimitSettings.MemoryStoreSize)) + + th.DeniedHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + l4g.Error("%v: code=429 ip=%v", r.URL.Path, GetIpAddress(r)) + throttled.DefaultDeniedHandler.ServeHTTP(w, r) + }) + + handler = th.Throttle(Srv.Router) + } + go func() { - err := Srv.Server.ListenAndServe(":"+utils.Cfg.ServiceSettings.Port, Srv.Router) + err := Srv.Server.ListenAndServe(":"+utils.Cfg.ServiceSettings.Port, handler) if err != nil { l4g.Critical("Error starting server, err:%v", err) time.Sleep(time.Second) diff --git a/api/user.go b/api/user.go index e1d5e83dd..94b4eca18 100644 --- a/api/user.go +++ b/api/user.go @@ -282,12 +282,26 @@ func LoginByEmail(c *Context, w http.ResponseWriter, r *http.Request, email, nam } func checkUserPassword(c *Context, user *model.User, password string) bool { + + if user.FailedAttempts >= utils.Cfg.ServiceSettings.AllowedLoginAttempts { + c.LogAuditWithUserId(user.Id, "fail") + c.Err = model.NewAppError("checkUserPassword", "Your account is locked because of too many failed password attempts. Please reset your password.", "user_id="+user.Id) + c.Err.StatusCode = http.StatusForbidden + return false + } + if !model.ComparePassword(user.Password, password) { c.LogAuditWithUserId(user.Id, "fail") c.Err = model.NewAppError("checkUserPassword", "Login failed because of invalid password", "user_id="+user.Id) c.Err.StatusCode = http.StatusForbidden + + if result := <-Srv.Store.User().UpdateFailedPasswordAttempts(user.Id, user.FailedAttempts+1); result.Err != nil { + c.LogError(result.Err) + } + return false } + return true } -- cgit v1.2.3-1-g7c22 From 1af7cbe7fe5d015ba46b003f61afc3f606ba896a Mon Sep 17 00:00:00 2001 From: hmhealey Date: Wed, 22 Jul 2015 17:17:55 -0400 Subject: Allow file access apis to respond to HEAD requests --- api/file.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'api') diff --git a/api/file.go b/api/file.go index 3ef50fbbd..123cab457 100644 --- a/api/file.go +++ b/api/file.go @@ -33,7 +33,7 @@ func InitFile(r *mux.Router) { sr := r.PathPrefix("/files").Subrouter() sr.Handle("/upload", ApiUserRequired(uploadFile)).Methods("POST") - sr.Handle("/get/{channel_id:[A-Za-z0-9]+}/{user_id:[A-Za-z0-9]+}/{filename:([A-Za-z0-9]+/)?.+(\\.[A-Za-z0-9]{3,})?}", ApiAppHandler(getFile)).Methods("GET") + sr.Handle("/get/{channel_id:[A-Za-z0-9]+}/{user_id:[A-Za-z0-9]+}/{filename:([A-Za-z0-9]+/)?.+(\\.[A-Za-z0-9]{3,})?}", ApiAppHandler(getFile)).Methods("GET", "HEAD") sr.Handle("/get_public_link", ApiUserRequired(getPublicLink)).Methods("POST") } -- cgit v1.2.3-1-g7c22 From 2e5528542d532adb81b038cf14c0bae696fec03a Mon Sep 17 00:00:00 2001 From: hmhealey Date: Wed, 29 Jul 2015 10:21:31 -0400 Subject: Changed file API to not write response data on a HEAD request --- api/file.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'api') diff --git a/api/file.go b/api/file.go index 123cab457..219cf6103 100644 --- a/api/file.go +++ b/api/file.go @@ -261,7 +261,10 @@ func getFile(c *Context, w http.ResponseWriter, r *http.Request) { w.Header().Set("Cache-Control", "max-age=2592000, public") w.Header().Set("Content-Length", strconv.Itoa(len(f))) - w.Write(f) + + if r.Method != "HEAD" { + w.Write(f) + } } func asyncGetFile(path string, fileData chan []byte) { -- cgit v1.2.3-1-g7c22 From 3f97e06bf80c789ce8e2d572afdac65a73d417c8 Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Wed, 29 Jul 2015 11:30:56 -0400 Subject: Adding etag to channel extra_info api call. --- api/channel.go | 8 ++++- api/channel_benchmark_test.go | 2 +- api/channel_test.go | 68 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 74 insertions(+), 4 deletions(-) (limited to 'api') diff --git a/api/channel.go b/api/channel.go index 123fd8a35..9216dbb09 100644 --- a/api/channel.go +++ b/api/channel.go @@ -570,6 +570,11 @@ func getChannelExtraInfo(c *Context, w http.ResponseWriter, r *http.Request) { channel := cresult.Data.(*model.Channel) member := cmresult.Data.(model.ChannelMember) extraMembers := ecmresult.Data.([]model.ExtraMember) + extraEtag := channel.ExtraEtag() + + if HandleEtag(extraEtag, w, r) { + return + } if !c.HasPermissionsToTeam(channel.TeamId, "getChannelExtraInfo") { return @@ -586,6 +591,7 @@ func getChannelExtraInfo(c *Context, w http.ResponseWriter, r *http.Request) { } data := model.ChannelExtra{Id: channel.Id, Members: extraMembers} + w.Header().Set(model.HEADER_ETAG_SERVER, extraEtag) w.Header().Set("Expires", "-1") w.Write([]byte(data.ToJson())) } @@ -711,7 +717,7 @@ func removeChannelMember(c *Context, w http.ResponseWriter, r *http.Request) { } message := model.NewMessage(c.Session.TeamId, "", userId, model.ACTION_USER_REMOVED) - message.Add("channel_id",id) + message.Add("channel_id", id) message.Add("remover", c.Session.UserId) PublishAndForget(message) diff --git a/api/channel_benchmark_test.go b/api/channel_benchmark_test.go index 881638176..77e679c14 100644 --- a/api/channel_benchmark_test.go +++ b/api/channel_benchmark_test.go @@ -189,7 +189,7 @@ func BenchmarkGetChannelExtraInfo(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { for j := range channels { - Client.Must(Client.GetChannelExtraInfo(channels[j].Id)) + Client.Must(Client.GetChannelExtraInfo(channels[j].Id, "")) } } } diff --git a/api/channel_test.go b/api/channel_test.go index a8d53c4b5..d4fb11bd8 100644 --- a/api/channel_test.go +++ b/api/channel_test.go @@ -6,6 +6,7 @@ package api import ( "github.com/mattermost/platform/model" "github.com/mattermost/platform/store" + "github.com/mattermost/platform/utils" "net/http" "testing" "time" @@ -543,10 +544,73 @@ func TestGetChannelExtraInfo(t *testing.T) { channel1 := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id} channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel) - rget := Client.Must(Client.GetChannelExtraInfo(channel1.Id)).Data.(*model.ChannelExtra) - if rget.Id != channel1.Id { + rget := Client.Must(Client.GetChannelExtraInfo(channel1.Id, "")) + data := rget.Data.(*model.ChannelExtra) + if data.Id != channel1.Id { t.Fatal("couldnt't get extra info") } + + // + // Testing etag caching + // + + currentEtag := rget.Etag + + if cache_result, err := Client.GetChannelExtraInfo(channel1.Id, currentEtag); err != nil { + t.Fatal(err) + } else if cache_result.Data.(*model.ChannelExtra) != nil { + t.Log(cache_result.Data) + t.Fatal("response should be empty") + } else { + currentEtag = cache_result.Etag + } + + Client2 := model.NewClient("http://localhost:" + utils.Cfg.ServiceSettings.Port + "/api/v1") + + user2 := &model.User{TeamId: team.Id, Email: model.NewId() + "tester2@test.com", Nickname: "Tester 2", Password: "pwd"} + user2 = Client2.Must(Client2.CreateUser(user2, "")).Data.(*model.User) + store.Must(Srv.Store.User().VerifyEmail(user2.Id)) + + Client2.LoginByEmail(team.Name, user2.Email, "pwd") + Client2.Must(Client2.JoinChannel(channel1.Id)) + + if cache_result, err := Client.GetChannelExtraInfo(channel1.Id, currentEtag); err != nil { + t.Fatal(err) + } else if cache_result.Data.(*model.ChannelExtra) == nil { + t.Log(cache_result.Data) + t.Fatal("response should not be empty") + } else { + currentEtag = cache_result.Etag + } + + if cache_result, err := Client.GetChannelExtraInfo(channel1.Id, currentEtag); err != nil { + t.Fatal(err) + } else if cache_result.Data.(*model.ChannelExtra) != nil { + t.Log(cache_result.Data) + t.Fatal("response should be empty") + } else { + currentEtag = cache_result.Etag + } + + Client2.Must(Client2.LeaveChannel(channel1.Id)) + + if cache_result, err := Client.GetChannelExtraInfo(channel1.Id, currentEtag); err != nil { + t.Fatal(err) + } else if cache_result.Data.(*model.ChannelExtra) == nil { + t.Log(cache_result.Data) + t.Fatal("response should not be empty") + } else { + currentEtag = cache_result.Etag + } + + if cache_result, err := Client.GetChannelExtraInfo(channel1.Id, currentEtag); err != nil { + t.Fatal(err) + } else if cache_result.Data.(*model.ChannelExtra) != nil { + t.Log(cache_result.Data) + t.Fatal("response should be empty") + } else { + currentEtag = cache_result.Etag + } } func TestAddChannelMember(t *testing.T) { -- cgit v1.2.3-1-g7c22 From 1055d8f4a116cdbdb3cf38ecf4781c7fa761d7bd Mon Sep 17 00:00:00 2001 From: hmhealey Date: Wed, 29 Jul 2015 18:35:33 -0400 Subject: Fixed team API to properly provide team names for the Find My Team email --- api/team.go | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'api') 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) { -- cgit v1.2.3-1-g7c22 From b4877c5d36569dae486a1e53f39c35d346e3d3d2 Mon Sep 17 00:00:00 2001 From: =Corey Hulen Date: Thu, 30 Jul 2015 00:46:17 -0800 Subject: Fixing code review feedback --- api/user.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'api') diff --git a/api/user.go b/api/user.go index 94b4eca18..3c9ae5718 100644 --- a/api/user.go +++ b/api/user.go @@ -300,9 +300,14 @@ func checkUserPassword(c *Context, user *model.User, password string) bool { } return false + } else { + if result := <-Srv.Store.User().UpdateFailedPasswordAttempts(user.Id, 0); result.Err != nil { + c.LogError(result.Err) + } + + return true } - return true } // User MUST be validated before calling Login -- cgit v1.2.3-1-g7c22 From c7a8112c172a55741e1dcbf366ed637543c301ce Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Thu, 30 Jul 2015 08:24:06 -0400 Subject: Moving the handing of extra_info etag before the extra info is retrieved from the database --- api/channel.go | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'api') diff --git a/api/channel.go b/api/channel.go index 9216dbb09..803274d32 100644 --- a/api/channel.go +++ b/api/channel.go @@ -554,27 +554,31 @@ func getChannelExtraInfo(c *Context, w http.ResponseWriter, r *http.Request) { id := params["id"] sc := Srv.Store.Channel().Get(id) - scm := Srv.Store.Channel().GetMember(id, c.Session.UserId) - ecm := Srv.Store.Channel().GetExtraMembers(id, 20) - + var channel *model.Channel if cresult := <-sc; cresult.Err != nil { c.Err = cresult.Err return - } else if cmresult := <-scm; cmresult.Err != nil { + } else { + channel = cresult.Data.(*model.Channel) + } + + extraEtag := channel.ExtraEtag() + if HandleEtag(extraEtag, w, r) { + return + } + + scm := Srv.Store.Channel().GetMember(id, c.Session.UserId) + ecm := Srv.Store.Channel().GetExtraMembers(id, 20) + + if cmresult := <-scm; cmresult.Err != nil { c.Err = cmresult.Err return } else if ecmresult := <-ecm; ecmresult.Err != nil { c.Err = ecmresult.Err return } else { - channel := cresult.Data.(*model.Channel) member := cmresult.Data.(model.ChannelMember) extraMembers := ecmresult.Data.([]model.ExtraMember) - extraEtag := channel.ExtraEtag() - - if HandleEtag(extraEtag, w, r) { - return - } if !c.HasPermissionsToTeam(channel.TeamId, "getChannelExtraInfo") { return -- cgit v1.2.3-1-g7c22 From 6222d2cb3040b5c64c7cdf6a2724e694351442d6 Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Wed, 29 Jul 2015 16:17:20 -0400 Subject: Fixing links for signup from team invite link. Enter now advances signup_user_complete screen. Signin now link now redirects properly. --- api/user.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'api') diff --git a/api/user.go b/api/user.go index e1d5e83dd..47464f5a1 100644 --- a/api/user.go +++ b/api/user.go @@ -193,7 +193,7 @@ func CreateUser(c *Context, team *model.Team, user *model.User) *model.User { l4g.Error("Failed to set email verified err=%v", cresult.Err) } } else { - FireAndForgetVerifyEmail(result.Data.(*model.User).Id, ruser.FirstName, ruser.Email, team.DisplayName, c.GetTeamURLFromTeam(team)) + FireAndForgetVerifyEmail(result.Data.(*model.User).Id, ruser.Nickname, ruser.Email, team.Name, team.DisplayName, c.GetSiteURL(), c.GetTeamURLFromTeam(team)) } ruser.Sanitize(map[string]bool{}) @@ -223,19 +223,19 @@ func fireAndForgetWelcomeEmail(name, email, teamDisplayName, link string) { }() } -func FireAndForgetVerifyEmail(userId, name, email, teamDisplayName, teamURL string) { +func FireAndForgetVerifyEmail(userId, userNickname, userEmail, teamName, teamDisplayName, siteURL, teamURL string) { go func() { - link := fmt.Sprintf("%s/verify_email?uid=%s&hid=%s", teamURL, userId, model.HashPassword(userId)) + link := fmt.Sprintf("%s/verify_email?uid=%s&hid=%s&teamname=%s&email=%s", siteURL, userId, model.HashPassword(userId), teamName, userEmail) subjectPage := NewServerTemplatePage("verify_subject", teamURL) subjectPage.Props["TeamDisplayName"] = teamDisplayName bodyPage := NewServerTemplatePage("verify_body", teamURL) - bodyPage.Props["Nickname"] = name + bodyPage.Props["Nickname"] = userNickname bodyPage.Props["TeamDisplayName"] = teamDisplayName bodyPage.Props["VerifyUrl"] = link - if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil { + if err := utils.SendMail(userEmail, subjectPage.Render(), bodyPage.Render()); err != nil { l4g.Error("Failed to send verification email successfully err=%v", err) } }() -- cgit v1.2.3-1-g7c22 From 9cc369b6b637139d7ae53eb2d834ff8a6eeb439c Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Thu, 30 Jul 2015 13:42:27 -0400 Subject: Removing nickname parameter from FireAndForgetVerifyEmail --- api/user.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'api') diff --git a/api/user.go b/api/user.go index 47464f5a1..5e40dcc88 100644 --- a/api/user.go +++ b/api/user.go @@ -193,7 +193,7 @@ func CreateUser(c *Context, team *model.Team, user *model.User) *model.User { l4g.Error("Failed to set email verified err=%v", cresult.Err) } } else { - FireAndForgetVerifyEmail(result.Data.(*model.User).Id, ruser.Nickname, ruser.Email, team.Name, team.DisplayName, c.GetSiteURL(), c.GetTeamURLFromTeam(team)) + FireAndForgetVerifyEmail(result.Data.(*model.User).Id, ruser.Email, team.Name, team.DisplayName, c.GetSiteURL(), c.GetTeamURLFromTeam(team)) } ruser.Sanitize(map[string]bool{}) @@ -223,7 +223,7 @@ func fireAndForgetWelcomeEmail(name, email, teamDisplayName, link string) { }() } -func FireAndForgetVerifyEmail(userId, userNickname, userEmail, teamName, teamDisplayName, siteURL, teamURL string) { +func FireAndForgetVerifyEmail(userId, userEmail, teamName, teamDisplayName, siteURL, teamURL string) { go func() { link := fmt.Sprintf("%s/verify_email?uid=%s&hid=%s&teamname=%s&email=%s", siteURL, userId, model.HashPassword(userId), teamName, userEmail) @@ -231,7 +231,6 @@ func FireAndForgetVerifyEmail(userId, userNickname, userEmail, teamName, teamDis subjectPage := NewServerTemplatePage("verify_subject", teamURL) subjectPage.Props["TeamDisplayName"] = teamDisplayName bodyPage := NewServerTemplatePage("verify_body", teamURL) - bodyPage.Props["Nickname"] = userNickname bodyPage.Props["TeamDisplayName"] = teamDisplayName bodyPage.Props["VerifyUrl"] = link -- cgit v1.2.3-1-g7c22 From a41c42c4d4d78cab6ff12a932675aee8bd4aab86 Mon Sep 17 00:00:00 2001 From: nickago Date: Thu, 30 Jul 2015 13:54:00 -0700 Subject: Updated error message for an incorrect password --- api/user.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'api') diff --git a/api/user.go b/api/user.go index e1d5e83dd..73bf2e6ef 100644 --- a/api/user.go +++ b/api/user.go @@ -835,7 +835,7 @@ func updatePassword(c *Context, w http.ResponseWriter, r *http.Request) { } if !model.ComparePassword(user.Password, currentPassword) { - c.Err = model.NewAppError("updatePassword", "Update password failed because of invalid password", "") + c.Err = model.NewAppError("updatePassword", "The \"Current Password\" you entered is incorrect. Please check that Caps Lock is off and try again.", "") c.Err.StatusCode = http.StatusForbidden return } -- cgit v1.2.3-1-g7c22 From a541f09380ab2adbe4d0ba7c80ff72015767bd81 Mon Sep 17 00:00:00 2001 From: JoramWilander Date: Wed, 29 Jul 2015 10:09:11 -0400 Subject: image thumbnails now scale appropriately so there is no whitespace, also generalized some thumbnail loading code --- api/file.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'api') diff --git a/api/file.go b/api/file.go index 219cf6103..4ec421eb9 100644 --- a/api/file.go +++ b/api/file.go @@ -140,11 +140,18 @@ func fireAndForgetHandleImages(filenames []string, fileData [][]byte, teamId, ch // Create thumbnail go func() { + thumbWidth := float64(utils.Cfg.ImageSettings.ThumbnailWidth) + thumbHeight := float64(utils.Cfg.ImageSettings.ThumbnailHeight) + imgWidth := float64(imgConfig.Width) + imgHeight := float64(imgConfig.Height) + var thumbnail image.Image - if imgConfig.Width > int(utils.Cfg.ImageSettings.ThumbnailWidth) { - thumbnail = resize.Resize(utils.Cfg.ImageSettings.ThumbnailWidth, utils.Cfg.ImageSettings.ThumbnailHeight, img, resize.Lanczos3) - } else { + if imgHeight < thumbHeight && imgWidth < thumbWidth { thumbnail = img + } else if imgHeight/imgWidth < thumbHeight/thumbWidth { + thumbnail = resize.Resize(0, utils.Cfg.ImageSettings.ThumbnailHeight, img, resize.Lanczos3) + } else { + thumbnail = resize.Resize(utils.Cfg.ImageSettings.ThumbnailWidth, 0, img, resize.Lanczos3) } buf := new(bytes.Buffer) -- cgit v1.2.3-1-g7c22 From bc48281f7aedabf5cb830a02b5e081b6554115cf Mon Sep 17 00:00:00 2001 From: nickago Date: Tue, 28 Jul 2015 13:28:18 -0700 Subject: Changed all templates to use site url instead of team url for finding the 'static' directory --- api/api.go | 4 ++-- api/context.go | 2 +- api/post.go | 4 ++-- api/team.go | 6 ++---- api/templates/email_change_body.html | 6 +++--- api/templates/find_teams_body.html | 4 ++-- api/templates/invite_body.html | 4 ++-- api/templates/password_change_body.html | 6 +++--- api/templates/post_body.html | 4 ++-- api/templates/reset_body.html | 4 ++-- api/templates/signup_team_body.html | 4 ++-- api/templates/verify_body.html | 4 ++-- api/templates/welcome_body.html | 6 +++--- api/user.go | 35 ++++++++++++++++++--------------- 14 files changed, 47 insertions(+), 46 deletions(-) (limited to 'api') diff --git a/api/api.go b/api/api.go index 25f3376c6..2ea27ed9f 100644 --- a/api/api.go +++ b/api/api.go @@ -16,10 +16,10 @@ var ServerTemplates *template.Template type ServerTemplatePage Page -func NewServerTemplatePage(templateName, teamURL string) *ServerTemplatePage { +func NewServerTemplatePage(templateName, siteURL string) *ServerTemplatePage { props := make(map[string]string) props["AnalyticsUrl"] = utils.Cfg.ServiceSettings.AnalyticsUrl - return &ServerTemplatePage{TemplateName: templateName, SiteName: utils.Cfg.ServiceSettings.SiteName, FeedbackEmail: utils.Cfg.EmailSettings.FeedbackEmail, TeamURL: teamURL, Props: props} + return &ServerTemplatePage{TemplateName: templateName, SiteName: utils.Cfg.ServiceSettings.SiteName, FeedbackEmail: utils.Cfg.EmailSettings.FeedbackEmail, SiteURL: siteURL, Props: props} } func (me *ServerTemplatePage) Render() string { diff --git a/api/context.go b/api/context.go index 16da0a6eb..e3f279e90 100644 --- a/api/context.go +++ b/api/context.go @@ -32,7 +32,7 @@ type Page struct { Title string SiteName string FeedbackEmail string - TeamURL string + SiteURL string Props map[string]string } diff --git a/api/post.go b/api/post.go index f96320639..f6699d181 100644 --- a/api/post.go +++ b/api/post.go @@ -377,7 +377,7 @@ func fireAndForgetNotifications(post *model.Post, teamId, siteURL string) { location, _ := time.LoadLocation("UTC") tm := time.Unix(post.CreateAt/1000, 0).In(location) - subjectPage := NewServerTemplatePage("post_subject", teamURL) + subjectPage := NewServerTemplatePage("post_subject", siteURL) subjectPage.Props["TeamDisplayName"] = teamDisplayName subjectPage.Props["SubjectText"] = subjectText subjectPage.Props["Month"] = tm.Month().String()[:3] @@ -395,7 +395,7 @@ func fireAndForgetNotifications(post *model.Post, teamId, siteURL string) { continue } - bodyPage := NewServerTemplatePage("post_body", teamURL) + bodyPage := NewServerTemplatePage("post_body", siteURL) bodyPage.Props["Nickname"] = profileMap[id].FirstName bodyPage.Props["TeamDisplayName"] = teamDisplayName bodyPage.Props["ChannelName"] = channelName diff --git a/api/team.go b/api/team.go index 01c8e50b6..e6b8f4e14 100644 --- a/api/team.go +++ b/api/team.go @@ -344,8 +344,6 @@ func inviteMembers(c *Context, w http.ResponseWriter, r *http.Request) { func InviteMembers(c *Context, team *model.Team, user *model.User, invites []string) { for _, invite := range invites { if len(invite) > 0 { - teamURL := "" - teamURL = c.GetTeamURLFromTeam(team) sender := user.GetDisplayName() @@ -356,10 +354,10 @@ func InviteMembers(c *Context, team *model.Team, user *model.User, invites []str senderRole = "member" } - subjectPage := NewServerTemplatePage("invite_subject", teamURL) + subjectPage := NewServerTemplatePage("invite_subject", c.GetSiteURL()) subjectPage.Props["SenderName"] = sender subjectPage.Props["TeamDisplayName"] = team.DisplayName - bodyPage := NewServerTemplatePage("invite_body", teamURL) + bodyPage := NewServerTemplatePage("invite_body", c.GetSiteURL()) bodyPage.Props["TeamDisplayName"] = team.DisplayName bodyPage.Props["SenderName"] = sender bodyPage.Props["SenderStatus"] = senderRole diff --git a/api/templates/email_change_body.html b/api/templates/email_change_body.html index 439fffd5b..c4e1cf39d 100644 --- a/api/templates/email_change_body.html +++ b/api/templates/email_change_body.html @@ -9,7 +9,7 @@ @@ -18,7 +18,7 @@ @@ -34,7 +34,7 @@
- +

You updated your email

-

You updated your email for {{.Props.TeamDisplayName}} on {{ .TeamURL }}
If this change wasn't initiated by you, please reply to this email and let us know.

+

You updated your email for {{.Props.TeamDisplayName}} on {{ .Props.TeamURL }}
If this change wasn't initiated by you, please reply to this email and let us know.

- +

(c) 2015 SpinPunch, Inc. 855 El Camino Real, 13A-168, Palo Alto, CA, 94301.
diff --git a/api/templates/find_teams_body.html b/api/templates/find_teams_body.html index a73ed0ad4..bd151a819 100644 --- a/api/templates/find_teams_body.html +++ b/api/templates/find_teams_body.html @@ -9,7 +9,7 @@ @@ -42,7 +42,7 @@
- +

- +

(c) 2015 SpinPunch, Inc. 855 El Camino Real, 13A-168, Palo Alto, CA, 94301.
diff --git a/api/templates/invite_body.html b/api/templates/invite_body.html index ad0658e3d..568a0d893 100644 --- a/api/templates/invite_body.html +++ b/api/templates/invite_body.html @@ -9,7 +9,7 @@ @@ -37,7 +37,7 @@
- +

- +

(c) 2015 SpinPunch, Inc. 855 El Camino Real, 13A-168, Palo Alto, CA, 94301.
diff --git a/api/templates/password_change_body.html b/api/templates/password_change_body.html index 1d4a6e1c8..6fc9f2822 100644 --- a/api/templates/password_change_body.html +++ b/api/templates/password_change_body.html @@ -9,7 +9,7 @@ @@ -18,7 +18,7 @@ @@ -34,7 +34,7 @@
- +

You updated your password

-

You updated your password for {{.Props.TeamDisplayName}} on {{ .TeamURL }} by {{.Props.Method}}.
If this change wasn't initiated by you, please reply to this email and let us know.

+

You updated your password for {{.Props.TeamDisplayName}} on {{ .Props.TeamURL }} by {{.Props.Method}}.
If this change wasn't initiated by you, please reply to this email and let us know.

- +

(c) 2015 SpinPunch, Inc. 855 El Camino Real, 13A-168, Palo Alto, CA, 94301.
diff --git a/api/templates/post_body.html b/api/templates/post_body.html index 0aa913db5..a1df5b4c9 100644 --- a/api/templates/post_body.html +++ b/api/templates/post_body.html @@ -9,7 +9,7 @@ @@ -37,7 +37,7 @@
- +

- +

(c) 2015 SpinPunch, Inc. 855 El Camino Real, 13A-168, Palo Alto, CA, 94301.
diff --git a/api/templates/reset_body.html b/api/templates/reset_body.html index 4c2fec1e7..a6e6269c0 100644 --- a/api/templates/reset_body.html +++ b/api/templates/reset_body.html @@ -9,7 +9,7 @@ @@ -37,7 +37,7 @@
- +

- +

(c) 2015 SpinPunch, Inc. 855 El Camino Real, 13A-168, Palo Alto, CA, 94301.
diff --git a/api/templates/signup_team_body.html b/api/templates/signup_team_body.html index 5e60a042b..71df0b9c8 100644 --- a/api/templates/signup_team_body.html +++ b/api/templates/signup_team_body.html @@ -9,7 +9,7 @@ @@ -40,7 +40,7 @@
- +

- +

(c) 2015 SpinPunch, Inc. 855 El Camino Real, 13A-168, Palo Alto, CA, 94301.
diff --git a/api/templates/verify_body.html b/api/templates/verify_body.html index 1a68c16f5..6ba11d845 100644 --- a/api/templates/verify_body.html +++ b/api/templates/verify_body.html @@ -9,7 +9,7 @@ @@ -37,7 +37,7 @@
- +

- +

(c) 2015 SpinPunch, Inc. 855 El Camino Real, 13A-168, Palo Alto, CA, 94301.
diff --git a/api/templates/welcome_body.html b/api/templates/welcome_body.html index cc4d95fb1..f16f50e14 100644 --- a/api/templates/welcome_body.html +++ b/api/templates/welcome_body.html @@ -9,7 +9,7 @@ @@ -18,7 +18,7 @@ @@ -34,7 +34,7 @@
- +

You joined the {{.Props.TeamDisplayName}} team at {{.SiteName}}!

-

Please let me know if you have any questions.
Enjoy your stay at {{.SiteName}}.

+

Please let me know if you have any questions.
Enjoy your stay at {{.SiteName}}.

- +

(c) 2015 SpinPunch, Inc. 855 El Camino Real, 13A-168, Palo Alto, CA, 94301.
diff --git a/api/user.go b/api/user.go index e2d80b366..ad5385695 100644 --- a/api/user.go +++ b/api/user.go @@ -209,14 +209,15 @@ func CreateUser(c *Context, team *model.Team, user *model.User) *model.User { } } -func fireAndForgetWelcomeEmail(name, email, teamDisplayName, link string) { +func fireAndForgetWelcomeEmail(name, email, teamDisplayName, link, siteURL string) { go func() { - subjectPage := NewServerTemplatePage("welcome_subject", link) - bodyPage := NewServerTemplatePage("welcome_body", link) + subjectPage := NewServerTemplatePage("welcome_subject", siteURL) + bodyPage := NewServerTemplatePage("welcome_body", siteURL) bodyPage.Props["Nickname"] = name bodyPage.Props["TeamDisplayName"] = teamDisplayName bodyPage.Props["FeedbackName"] = utils.Cfg.EmailSettings.FeedbackName + bodyPage.Props["TeamURL"] = link if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil { l4g.Error("Failed to send welcome email successfully err=%v", err) @@ -230,9 +231,9 @@ func FireAndForgetVerifyEmail(userId, userEmail, teamName, teamDisplayName, site link := fmt.Sprintf("%s/verify_email?uid=%s&hid=%s&teamname=%s&email=%s", siteURL, userId, model.HashPassword(userId), teamName, userEmail) - subjectPage := NewServerTemplatePage("verify_subject", teamURL) + subjectPage := NewServerTemplatePage("verify_subject", siteURL) subjectPage.Props["TeamDisplayName"] = teamDisplayName - bodyPage := NewServerTemplatePage("verify_body", teamURL) + bodyPage := NewServerTemplatePage("verify_body", siteURL) bodyPage.Props["TeamDisplayName"] = teamDisplayName bodyPage.Props["VerifyUrl"] = link @@ -800,7 +801,7 @@ func updateUser(c *Context, w http.ResponseWriter, r *http.Request) { l4g.Error(tresult.Err.Message) } else { team := tresult.Data.(*model.Team) - fireAndForgetEmailChangeEmail(rusers[1].Email, team.DisplayName, c.GetTeamURLFromTeam(team)) + fireAndForgetEmailChangeEmail(rusers[1].Email, team.DisplayName, c.GetTeamURLFromTeam(team), c.GetSiteURL()) } } @@ -879,7 +880,7 @@ func updatePassword(c *Context, w http.ResponseWriter, r *http.Request) { l4g.Error(tresult.Err.Message) } else { team := tresult.Data.(*model.Team) - fireAndForgetPasswordChangeEmail(user.Email, team.DisplayName, c.GetTeamURLFromTeam(team), "using the settings menu") + fireAndForgetPasswordChangeEmail(user.Email, team.DisplayName, c.GetTeamURLFromTeam(team), c.GetSiteURL(), "using the settings menu") } data := make(map[string]string) @@ -1069,8 +1070,8 @@ func sendPasswordReset(c *Context, w http.ResponseWriter, r *http.Request) { link := fmt.Sprintf("%s/reset_password?d=%s&h=%s", c.GetTeamURLFromTeam(team), url.QueryEscape(data), url.QueryEscape(hash)) - subjectPage := NewServerTemplatePage("reset_subject", c.GetTeamURLFromTeam(team)) - bodyPage := NewServerTemplatePage("reset_body", c.GetTeamURLFromTeam(team)) + subjectPage := NewServerTemplatePage("reset_subject", c.GetSiteURL()) + bodyPage := NewServerTemplatePage("reset_body", c.GetSiteURL()) bodyPage.Props["ResetUrl"] = link if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil { @@ -1160,19 +1161,20 @@ func resetPassword(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAuditWithUserId(userId, "success") } - fireAndForgetPasswordChangeEmail(user.Email, team.DisplayName, c.GetTeamURLFromTeam(team), "using a reset password link") + fireAndForgetPasswordChangeEmail(user.Email, team.DisplayName, c.GetTeamURLFromTeam(team), c.GetSiteURL(), "using a reset password link") props["new_password"] = "" w.Write([]byte(model.MapToJson(props))) } -func fireAndForgetPasswordChangeEmail(email, teamDisplayName, teamURL, method string) { +func fireAndForgetPasswordChangeEmail(email, teamDisplayName, teamURL, siteURL, method string) { go func() { - subjectPage := NewServerTemplatePage("password_change_subject", teamURL) + subjectPage := NewServerTemplatePage("password_change_subject", siteURL) subjectPage.Props["TeamDisplayName"] = teamDisplayName - bodyPage := NewServerTemplatePage("password_change_body", teamURL) + bodyPage := NewServerTemplatePage("password_change_body", siteURL) bodyPage.Props["TeamDisplayName"] = teamDisplayName + bodyPage.Props["TeamURL"] = teamURL bodyPage.Props["Method"] = method if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil { @@ -1182,13 +1184,14 @@ func fireAndForgetPasswordChangeEmail(email, teamDisplayName, teamURL, method st }() } -func fireAndForgetEmailChangeEmail(email, teamDisplayName, teamURL string) { +func fireAndForgetEmailChangeEmail(email, teamDisplayName, teamURL, siteURL string) { go func() { - subjectPage := NewServerTemplatePage("email_change_subject", teamURL) + subjectPage := NewServerTemplatePage("email_change_subject", siteURL) subjectPage.Props["TeamDisplayName"] = teamDisplayName - bodyPage := NewServerTemplatePage("email_change_body", teamURL) + bodyPage := NewServerTemplatePage("email_change_body", siteURL) bodyPage.Props["TeamDisplayName"] = teamDisplayName + bodyPage.Props["TeamURL"] = teamURL if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil { l4g.Error("Failed to send update password email successfully err=%v", err) -- cgit v1.2.3-1-g7c22