Guest accounts feature (#11428)
* MM-14139: Creating permissions for invite/promote/demote guests (#10778) * MM-14139: Creating permissions for invite/promote/demote guests * Fixing tests * Adding invite guest api endpoint (#10792) * Adding invite guest api endpoint * Adding i18n * Adding some tests * WIP * Migrating Token.Extra info to bigger size (2048) * Fixing tests * Adding client function for invite guests * Adding send guests invites tests * Renaming file from guest to guest_invite * Adding Promote/Demote users from/to guest endpoints (#10791) * Adding Promote/Demote users from/to guest endpoints * Adding i18n translations * Adding the client functions * Using getQueryBuilder function * Addressing PR review comments * Adding default channels to users on promte from guest (#10851) * Adding default channels to users on promte from guest * Addressing PR review comments * Fixing merge problems * Sending websockets events on promote/demote (#11403) * Sending websockets events on promote/demote * Fixing merge problems * Fixing govet shadowing problem * Fixing feature branch tests * Avoiding leaking users data through websockets for guest accounts (#11489) * Avoiding leaking users data through websockets for guest accounts * Adding tests and fixing code error * Fixing i18n * Allow to enable/disable guests and other extra config settings (#11481) * Allow to enable/disable guests and other extra config settings * Fixing tests and moving license and config validation to api level * Update api4/role_test.go Co-Authored-By: George Goldberg <george@gberg.me> * Update api4/role_test.go Co-Authored-By: George Goldberg <george@gberg.me> * Fixing typo * fixing tests * Managing correctly the guest channel leave behavior (#11578) * MM-15134: Removing guests from teams or system on leave channels if needed * WIP * No deactivating the guest user when leave the last team * Adding a couple of tests * Fixing shadow variables * Fixing tests * fixing tests * fixing shadow variables * Adding guest counts for channel stats (#11646) * Adding guest counts for channel stats * Adding tests * Fixing tests * Fixing guest domain restrictions (#11660) * Adding needed migration for the database * Fixing migration
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
fdde7c8287
Коммит
fe8a0f6485
82
app/email.go
82
app/email.go
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"net/http"
|
||||
|
||||
@@ -357,6 +358,87 @@ func (a *App) SendInviteEmails(team *model.Team, senderName string, senderUserId
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) SendGuestInviteEmails(team *model.Team, channels []*model.Channel, senderName string, senderUserId string, invites []string, siteURL string, message string) {
|
||||
if a.Srv.EmailRateLimiter == nil {
|
||||
a.Log.Error("Email invite not sent, rate limiting could not be setup.", mlog.String("user_id", senderUserId), mlog.String("team_id", team.Id))
|
||||
return
|
||||
}
|
||||
rateLimited, result, err := a.Srv.EmailRateLimiter.RateLimit(senderUserId, len(invites))
|
||||
if err != nil {
|
||||
a.Log.Error("Error rate limiting invite email.", mlog.String("user_id", senderUserId), mlog.String("team_id", team.Id), mlog.Err(err))
|
||||
return
|
||||
}
|
||||
|
||||
if rateLimited {
|
||||
a.Log.Error("Invite emails rate limited.",
|
||||
mlog.String("user_id", senderUserId),
|
||||
mlog.String("team_id", team.Id),
|
||||
mlog.String("retry_after", result.RetryAfter.String()),
|
||||
mlog.Err(err))
|
||||
return
|
||||
}
|
||||
|
||||
for _, invite := range invites {
|
||||
if len(invite) > 0 {
|
||||
senderRole := utils.T("api.team.invite_members.member")
|
||||
|
||||
subject := utils.T("api.templates.invite_guest_subject",
|
||||
map[string]interface{}{"SenderName": senderName,
|
||||
"TeamDisplayName": team.DisplayName,
|
||||
"SiteName": a.ClientConfig()["SiteName"]})
|
||||
|
||||
bodyPage := a.NewEmailTemplate("invite_body", model.DEFAULT_LOCALE)
|
||||
bodyPage.Props["SiteURL"] = siteURL
|
||||
bodyPage.Props["Title"] = utils.T("api.templates.invite_body.title")
|
||||
bodyPage.Html["Info"] = utils.TranslateAsHtml(utils.T, "api.templates.invite_body_guest.info",
|
||||
map[string]interface{}{"SenderStatus": senderRole, "SenderName": senderName, "TeamDisplayName": team.DisplayName})
|
||||
bodyPage.Props["Button"] = utils.T("api.templates.invite_body.button")
|
||||
bodyPage.Props["Message"] = ""
|
||||
if message != "" {
|
||||
bodyPage.Props["Message"] = message
|
||||
}
|
||||
bodyPage.Html["ExtraInfo"] = utils.TranslateAsHtml(utils.T, "api.templates.invite_body.extra_info",
|
||||
map[string]interface{}{"TeamDisplayName": team.DisplayName})
|
||||
bodyPage.Props["TeamURL"] = siteURL + "/" + team.Name
|
||||
|
||||
channelIds := []string{}
|
||||
for _, channel := range channels {
|
||||
channelIds = append(channelIds, channel.Id)
|
||||
}
|
||||
|
||||
token := model.NewToken(
|
||||
TOKEN_TYPE_GUEST_INVITATION,
|
||||
model.MapToJson(map[string]string{
|
||||
"teamId": team.Id,
|
||||
"channels": strings.Join(channelIds, " "),
|
||||
"email": invite,
|
||||
"guest": "true",
|
||||
}),
|
||||
)
|
||||
|
||||
props := make(map[string]string)
|
||||
props["email"] = invite
|
||||
props["display_name"] = team.DisplayName
|
||||
props["name"] = team.Name
|
||||
data := model.MapToJson(props)
|
||||
|
||||
if err := a.Srv.Store.Token().Save(token); err != nil {
|
||||
mlog.Error(fmt.Sprintf("Failed to send invite email successfully err=%v", err))
|
||||
continue
|
||||
}
|
||||
bodyPage.Props["Link"] = fmt.Sprintf("%s/signup_user_complete/?d=%s&t=%s", siteURL, url.QueryEscape(data), url.QueryEscape(token.Token))
|
||||
|
||||
if !*a.Config().EmailSettings.SendEmailNotifications {
|
||||
mlog.Info(fmt.Sprintf("sending invitation to %v %v", invite, bodyPage.Props["Link"]))
|
||||
}
|
||||
|
||||
if err := a.SendMail(invite, subject, bodyPage.Render()); err != nil {
|
||||
mlog.Error(fmt.Sprintf("Failed to send invite email successfully err=%v", err))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) NewEmailTemplate(name, locale string) *utils.HTMLTemplate {
|
||||
t := utils.NewHTMLTemplate(a.HTMLTemplates(), name)
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user