From 0140e94d77b1c7ee646a857ae1958b29bbea318e Mon Sep 17 00:00:00 2001 From: Allan Guwatudde Date: Mon, 27 Mar 2023 22:38:19 +0300 Subject: [PATCH] [MM-49751] - Turn off Inactive Server Email (#22648) * [MM-49751] - Turn off Inactive Server Email * remove unused var --------- Co-authored-by: Mattermost Build --- model/config.go | 5 - model/feature_flags.go | 3 - server/channels/app/email/email.go | 46 -- server/channels/app/email/email_test.go | 1 - .../app/email/mocks/ServiceInterface.go | 14 - server/channels/app/email/service.go | 1 - server/channels/app/server.go | 7 - server/channels/app/server_inactivity.go | 119 ---- .../opentracinglayer/opentracinglayer.go | 36 -- .../channels/store/retrylayer/retrylayer.go | 42 -- server/channels/store/sqlstore/post_store.go | 11 - .../channels/store/sqlstore/session_store.go | 11 - server/channels/store/store.go | 2 - .../store/storetest/mocks/PostStore.go | 21 - .../store/storetest/mocks/SessionStore.go | 21 - server/channels/store/storetest/post_store.go | 35 -- .../channels/store/storetest/session_store.go | 18 - .../channels/store/timerlayer/timerlayer.go | 32 - server/i18n/en.json | 48 -- .../platform/services/telemetry/telemetry.go | 1 - server/templates/inactivity_body.html | 548 ------------------ server/templates/inactivity_body.mjml | 65 --- server/tests/test-config.json | 1 - 23 files changed, 1088 deletions(-) delete mode 100644 server/channels/app/server_inactivity.go delete mode 100644 server/templates/inactivity_body.html delete mode 100644 server/templates/inactivity_body.mjml diff --git a/model/config.go b/model/config.go index b5272d5f1f..3e0f60c8c7 100644 --- a/model/config.go +++ b/model/config.go @@ -1624,7 +1624,6 @@ type EmailSettings struct { LoginButtonColor *string `access:"experimental_features"` LoginButtonBorderColor *string `access:"experimental_features"` LoginButtonTextColor *string `access:"experimental_features"` - EnableInactivityEmail *bool } func (s *EmailSettings) SetDefaults(isUpdate bool) { @@ -1767,10 +1766,6 @@ func (s *EmailSettings) SetDefaults(isUpdate bool) { if s.LoginButtonTextColor == nil { s.LoginButtonTextColor = NewString("#2389D7") } - - if s.EnableInactivityEmail == nil { - s.EnableInactivityEmail = NewBool(true) - } } type RateLimitSettings struct { diff --git a/model/feature_flags.go b/model/feature_flags.go index 86bb298e5b..ebe357d3d9 100644 --- a/model/feature_flags.go +++ b/model/feature_flags.go @@ -41,8 +41,6 @@ type FeatureFlags struct { NormalizeLdapDNs bool - EnableInactivityCheckJob bool - // Enable special onboarding flow for first admin UseCaseOnboarding bool @@ -92,7 +90,6 @@ func (f *FeatureFlags) SetDefaults() { f.BoardsFeatureFlags = "" f.BoardsDataRetention = false f.NormalizeLdapDNs = false - f.EnableInactivityCheckJob = true f.UseCaseOnboarding = true f.GraphQL = false f.InsightsEnabled = true diff --git a/server/channels/app/email/email.go b/server/channels/app/email/email.go index 4444f42e5d..bb64e6efd0 100644 --- a/server/channels/app/email/email.go +++ b/server/channels/app/email/email.go @@ -11,8 +11,6 @@ import ( "io" "net/http" "net/url" - "os" - "strconv" "strings" "github.com/pkg/errors" @@ -26,8 +24,6 @@ import ( "github.com/microcosm-cc/bluemonday" ) -const serverInactivityHours = 100 - // Returns category if enabled is true (default false) // If "" is returned when enabled is false, the category headers aren't attached to the email func getSendGridCategory(category string, enabled bool) string { @@ -948,48 +944,6 @@ func (es *Service) CreateVerifyEmailToken(userID string, newEmail string) (*mode return token, nil } -func (es *Service) SendLicenseInactivityEmail(email, name, locale, siteURL string) error { - T := i18n.GetUserTranslations(locale) - subject := T("api.templates.server_inactivity_subject") - data := es.NewEmailTemplateData(locale) - data.Props["SiteURL"] = siteURL - data.Props["Title"] = T("api.templates.server_inactivity_title") - data.Props["SubTitle"] = T("api.templates.server_inactivity_subtitle", map[string]any{"Name": name}) - data.Props["InfoBullet"] = T("api.templates.server_inactivity_info_bullet") - data.Props["InfoBullet1"] = T("api.templates.server_inactivity_info_bullet1") - data.Props["InfoBullet2"] = T("api.templates.server_inactivity_info_bullet2") - data.Props["Info"] = T("api.templates.server_inactivity_info") - data.Props["EmailUs"] = T("api.templates.email_us_anytime_at") - data.Props["QuestionTitle"] = T("api.templates.questions_footer.title") - data.Props["QuestionInfo"] = T("api.templates.questions_footer.info") - data.Props["Button"] = T("api.templates.server_inactivity_button") - data.Props["SupportEmail"] = "feedback@mattermost.com" - data.Props["ButtonURL"] = siteURL - data.Props["Channels"] = T("Channels") - data.Props["Playbooks"] = T("Playbooks") - data.Props["Boards"] = T("Boards") - - inactivityDurationHoursEnv := os.Getenv("MM_INACTIVITY_DURATION") - inactivityDurationHours, parseError := strconv.ParseFloat(inactivityDurationHoursEnv, 64) - if parseError != nil { - // default to 100 hours - inactivityDurationHours = serverInactivityHours - } - - data.Props["FooterDisclaimer"] = T("api.templates.server_inactivity_footer_disclaimer", map[string]any{"Hours": inactivityDurationHours}) - - body, err := es.templatesContainer.RenderToString("inactivity_body", data) - if err != nil { - return err - } - - if err := es.sendMail(email, subject, body, "LicenseInactivityEmail"); err != nil { - return err - } - - return nil -} - func (es *Service) SendLicenseUpForRenewalEmail(email, name, locale, siteURL, ctaTitle, ctaLink, ctaText string, daysToExpiration int) error { T := i18n.GetUserTranslations(locale) subject := T("api.templates.license_up_for_renewal_subject") diff --git a/server/channels/app/email/email_test.go b/server/channels/app/email/email_test.go index d8b22431fc..3fb2e09a7a 100644 --- a/server/channels/app/email/email_test.go +++ b/server/channels/app/email/email_test.go @@ -408,7 +408,6 @@ func TestMailServiceConfig(t *testing.T) { LoginButtonColor: new(string), LoginButtonBorderColor: new(string), LoginButtonTextColor: new(string), - EnableInactivityEmail: new(bool), }, } }, diff --git a/server/channels/app/email/mocks/ServiceInterface.go b/server/channels/app/email/mocks/ServiceInterface.go index b86365846a..e4d4011f45 100644 --- a/server/channels/app/email/mocks/ServiceInterface.go +++ b/server/channels/app/email/mocks/ServiceInterface.go @@ -344,20 +344,6 @@ func (_m *ServiceInterface) SendInviteEmailsToTeamAndChannels(team *model.Team, return r0, r1 } -// SendLicenseInactivityEmail provides a mock function with given fields: _a0, name, locale, siteURL -func (_m *ServiceInterface) SendLicenseInactivityEmail(_a0 string, name string, locale string, siteURL string) error { - ret := _m.Called(_a0, name, locale, siteURL) - - var r0 error - if rf, ok := ret.Get(0).(func(string, string, string, string) error); ok { - r0 = rf(_a0, name, locale, siteURL) - } else { - r0 = ret.Error(0) - } - - return r0 -} - // SendLicenseUpForRenewalEmail provides a mock function with given fields: _a0, name, locale, siteURL, ctaTitle, ctaLink, ctaText, daysToExpiration func (_m *ServiceInterface) SendLicenseUpForRenewalEmail(_a0 string, name string, locale string, siteURL string, ctaTitle string, ctaLink string, ctaText string, daysToExpiration int) error { ret := _m.Called(_a0, name, locale, siteURL, ctaTitle, ctaLink, ctaText, daysToExpiration) diff --git a/server/channels/app/email/service.go b/server/channels/app/email/service.go index f5f186c168..3aa0b658f4 100644 --- a/server/channels/app/email/service.go +++ b/server/channels/app/email/service.go @@ -163,7 +163,6 @@ type ServiceInterface interface { InitEmailBatching() SendChangeUsernameEmail(newUsername, email, locale, siteURL string) error CreateVerifyEmailToken(userID string, newEmail string) (*model.Token, error) - SendLicenseInactivityEmail(email, name, locale, siteURL string) error Stop() } diff --git a/server/channels/app/server.go b/server/channels/app/server.go index c416089792..6197c6c55b 100644 --- a/server/channels/app/server.go +++ b/server/channels/app/server.go @@ -484,7 +484,6 @@ func NewServer(options ...Option) (*Server, error) { s.Go(func() { appInstance := New(ServerConnector(s.Channels())) s.runLicenseExpirationCheckJob() - s.runInactivityCheckJob() runDNDStatusExpireJob(appInstance) runPostReminderJob(appInstance) }) @@ -1198,12 +1197,6 @@ func runConfigCleanupJob(s *Server) { }, time.Hour*24) } -func (s *Server) runInactivityCheckJob() { - model.CreateRecurringTask("Server inactivity Check", func() { - s.doInactivityCheck() - }, time.Hour*24) -} - func (s *Server) runLicenseExpirationCheckJob() { s.doLicenseExpirationCheck() model.CreateRecurringTask("License Expiration Check", func() { diff --git a/server/channels/app/server_inactivity.go b/server/channels/app/server_inactivity.go deleted file mode 100644 index a1693069fb..0000000000 --- a/server/channels/app/server_inactivity.go +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -package app - -import ( - "os" - "strconv" - "time" - - "github.com/mattermost/mattermost-server/v6/model" - "github.com/mattermost/mattermost-server/v6/server/platform/shared/mlog" -) - -const serverInactivityHours = 100 -const inactivityEmailSent = "INACTIVITY" - -func (s *Server) doInactivityCheck() { - - if *s.platform.Config().ServiceSettings.EnableDeveloper { - mlog.Info("No activity check because developer mode is enabled") - return - } - - if !*s.platform.Config().EmailSettings.EnableInactivityEmail { - mlog.Info("No activity check because EnableInactivityEmail is false") - return - } - - if !s.platform.Config().FeatureFlags.EnableInactivityCheckJob { - mlog.Info("No activity check because EnableInactivityCheckJob feature flag is disabled") - return - } - - _, sysValErr := s.Store().System().GetByName(inactivityEmailSent) - // if there is no error which may include *store.ErrNotFound, it means this check was already flagged as done - if sysValErr == nil { - return - } - - inactivityDurationHoursEnv := os.Getenv("MM_INACTIVITY_DURATION") - inactivityDurationHours, parseError := strconv.ParseFloat(inactivityDurationHoursEnv, 64) - if parseError != nil { - // default to 100 hours - inactivityDurationHours = serverInactivityHours - } - - // The first time this job runs. We check if the user has not made any posts in last inactivityDurationHours - // and remind them to use the workspace. If no posts have been made. We check the last time - // they logged in (session) for the last inactivityDurationHours and send a reminder. - lastPostAt, _ := s.Store().Post().GetLastPostRowCreateAt() - if lastPostAt != 0 { - posT := time.Unix(lastPostAt/1000, 0) - timeForLastPost := time.Since(posT).Hours() - if timeForLastPost > inactivityDurationHours { - s.takeInactivityAction() - } - return - } - - lastSessionAt, _ := s.Store().Session().GetLastSessionRowCreateAt() - if lastSessionAt != 0 { - sesT := time.Unix(lastSessionAt/1000, 0) - timeForLastSession := time.Since(sesT).Hours() - if timeForLastSession > inactivityDurationHours { - s.takeInactivityAction() - } - return - } -} - -func (s *Server) takeInactivityAction() { - siteURL := *s.platform.Config().ServiceSettings.SiteURL - if siteURL == "" { - mlog.Warn("No SiteURL configured") - } - - properties := map[string]any{ - "SiteURL": siteURL, - } - s.GetTelemetryService().SendTelemetry("inactive_server", properties) - users, err := s.Store().User().GetSystemAdminProfiles() - if err != nil { - mlog.Error("Failed to get system admins for inactivity check from Mattermost.") - return - } - - for _, user := range users { - - // See https://go.dev/doc/faq#closures_and_goroutines for why we make this assignment - user := user - - if user.Email == "" { - mlog.Error("Invalid system admin email.", mlog.String("user_email", user.Email)) - continue - } - - name := user.FirstName - if name == "" { - name = user.Username - } - - mlog.Debug("Sending inactivity reminder email.", mlog.String("user_email", user.Email)) - s.Go(func() { - if err := s.EmailService.SendLicenseInactivityEmail(user.Email, name, user.Locale, siteURL); err != nil { - mlog.Error("Error while sending inactivity reminder email.", mlog.String("user_email", user.Email), mlog.Err(err)) - } - }) - } - - // Mark that we sent emails. - sysVar := &model.System{Name: inactivityEmailSent, Value: "true"} - if err := s.Store().System().SaveOrUpdate(sysVar); err != nil { - mlog.Error("Unable to save INACTIVITY", mlog.Err(err)) - } - - // do some telemetry about sending the email - s.GetTelemetryService().SendTelemetry("inactive_server_emails_sent", properties) -} diff --git a/server/channels/store/opentracinglayer/opentracinglayer.go b/server/channels/store/opentracinglayer/opentracinglayer.go index 1f7d408365..15d32a18e2 100644 --- a/server/channels/store/opentracinglayer/opentracinglayer.go +++ b/server/channels/store/opentracinglayer/opentracinglayer.go @@ -6057,24 +6057,6 @@ func (s *OpenTracingLayerPostStore) GetFlaggedPostsForTeam(userID string, teamID return result, err } -func (s *OpenTracingLayerPostStore) GetLastPostRowCreateAt() (int64, error) { - origCtx := s.Root.Store.Context() - span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "PostStore.GetLastPostRowCreateAt") - s.Root.Store.SetContext(newCtx) - defer func() { - s.Root.Store.SetContext(origCtx) - }() - - defer span.Finish() - result, err := s.PostStore.GetLastPostRowCreateAt() - if err != nil { - span.LogFields(spanlog.Error(err)) - ext.Error.Set(span, true) - } - - return result, err -} - func (s *OpenTracingLayerPostStore) GetMaxPostSize() int { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "PostStore.GetMaxPostSize") @@ -8171,24 +8153,6 @@ func (s *OpenTracingLayerSessionStore) Get(ctx context.Context, sessionIDOrToken return result, err } -func (s *OpenTracingLayerSessionStore) GetLastSessionRowCreateAt() (int64, error) { - origCtx := s.Root.Store.Context() - span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SessionStore.GetLastSessionRowCreateAt") - s.Root.Store.SetContext(newCtx) - defer func() { - s.Root.Store.SetContext(origCtx) - }() - - defer span.Finish() - result, err := s.SessionStore.GetLastSessionRowCreateAt() - if err != nil { - span.LogFields(spanlog.Error(err)) - ext.Error.Set(span, true) - } - - return result, err -} - func (s *OpenTracingLayerSessionStore) GetSessions(userID string) ([]*model.Session, error) { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SessionStore.GetSessions") diff --git a/server/channels/store/retrylayer/retrylayer.go b/server/channels/store/retrylayer/retrylayer.go index 121a769248..07997b61ac 100644 --- a/server/channels/store/retrylayer/retrylayer.go +++ b/server/channels/store/retrylayer/retrylayer.go @@ -6856,27 +6856,6 @@ func (s *RetryLayerPostStore) GetFlaggedPostsForTeam(userID string, teamID strin } -func (s *RetryLayerPostStore) GetLastPostRowCreateAt() (int64, error) { - - tries := 0 - for { - result, err := s.PostStore.GetLastPostRowCreateAt() - if err == nil { - return result, nil - } - if !isRepeatableError(err) { - return result, err - } - tries++ - if tries >= 3 { - err = errors.Wrap(err, "giving up after 3 consecutive repeatable transaction failures") - return result, err - } - timepkg.Sleep(100 * timepkg.Millisecond) - } - -} - func (s *RetryLayerPostStore) GetMaxPostSize() int { return s.PostStore.GetMaxPostSize() @@ -9304,27 +9283,6 @@ func (s *RetryLayerSessionStore) Get(ctx context.Context, sessionIDOrToken strin } -func (s *RetryLayerSessionStore) GetLastSessionRowCreateAt() (int64, error) { - - tries := 0 - for { - result, err := s.SessionStore.GetLastSessionRowCreateAt() - if err == nil { - return result, nil - } - if !isRepeatableError(err) { - return result, err - } - tries++ - if tries >= 3 { - err = errors.Wrap(err, "giving up after 3 consecutive repeatable transaction failures") - return result, err - } - timepkg.Sleep(100 * timepkg.Millisecond) - } - -} - func (s *RetryLayerSessionStore) GetSessions(userID string) ([]*model.Session, error) { tries := 0 diff --git a/server/channels/store/sqlstore/post_store.go b/server/channels/store/sqlstore/post_store.go index c07c51a3cd..85854fdb90 100644 --- a/server/channels/store/sqlstore/post_store.go +++ b/server/channels/store/sqlstore/post_store.go @@ -2300,17 +2300,6 @@ func (s *SqlPostStore) AnalyticsPostCount(options *model.PostCountOptions) (int6 return v, nil } -func (s *SqlPostStore) GetLastPostRowCreateAt() (int64, error) { - query := `SELECT CREATEAT FROM Posts ORDER BY CREATEAT DESC LIMIT 1` - var createAt int64 - err := s.GetReplicaX().Get(&createAt, query) - if err != nil { - return 0, errors.Wrapf(err, "failed to get last post createat") - } - - return createAt, nil -} - func (s *SqlPostStore) GetPostsCreatedAt(channelId string, time int64) ([]*model.Post, error) { query := `SELECT * FROM Posts WHERE CreateAt = ? AND ChannelId = ?` diff --git a/server/channels/store/sqlstore/session_store.go b/server/channels/store/sqlstore/session_store.go index afe15e183e..851336dbc6 100644 --- a/server/channels/store/sqlstore/session_store.go +++ b/server/channels/store/sqlstore/session_store.go @@ -221,17 +221,6 @@ func (me SqlSessionStore) UpdateExpiresAt(sessionId string, time int64) error { return nil } -func (me *SqlSessionStore) GetLastSessionRowCreateAt() (int64, error) { - query := `SELECT CREATEAT FROM Sessions ORDER BY CREATEAT DESC LIMIT 1` - var createAt int64 - err := me.GetReplicaX().Get(&createAt, query) - if err != nil { - return 0, errors.Wrapf(err, "failed to get last session createat") - } - - return createAt, nil -} - func (me SqlSessionStore) UpdateLastActivityAt(sessionId string, time int64) error { _, err := me.GetMasterX().Exec("UPDATE Sessions SET LastActivityAt = ? WHERE Id = ?", time, sessionId) if err != nil { diff --git a/server/channels/store/store.go b/server/channels/store/store.go index 1ac231cb06..dec4fa0f89 100644 --- a/server/channels/store/store.go +++ b/server/channels/store/store.go @@ -381,7 +381,6 @@ type PostStore interface { AnalyticsPostCount(options *model.PostCountOptions) (int64, error) ClearCaches() InvalidateLastPostTimeCache(channelID string) - GetLastPostRowCreateAt() (int64, error) GetPostsCreatedAt(channelID string, timestamp int64) ([]*model.Post, error) Overwrite(post *model.Post) (*model.Post, error) OverwriteMultiple(posts []*model.Post) ([]*model.Post, int, error) @@ -510,7 +509,6 @@ type SessionStore interface { Remove(sessionIDOrToken string) error RemoveAllSessions() error PermanentDeleteSessionsByUser(teamID string) error - GetLastSessionRowCreateAt() (int64, error) UpdateExpiresAt(sessionID string, timestamp int64) error UpdateLastActivityAt(sessionID string, timestamp int64) error UpdateRoles(userID string, roles string) (string, error) diff --git a/server/channels/store/storetest/mocks/PostStore.go b/server/channels/store/storetest/mocks/PostStore.go index 3a57536e0f..727b5944dd 100644 --- a/server/channels/store/storetest/mocks/PostStore.go +++ b/server/channels/store/storetest/mocks/PostStore.go @@ -277,27 +277,6 @@ func (_m *PostStore) GetFlaggedPostsForTeam(userID string, teamID string, offset return r0, r1 } -// GetLastPostRowCreateAt provides a mock function with given fields: -func (_m *PostStore) GetLastPostRowCreateAt() (int64, error) { - ret := _m.Called() - - var r0 int64 - if rf, ok := ret.Get(0).(func() int64); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(int64) - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - // GetMaxPostSize provides a mock function with given fields: func (_m *PostStore) GetMaxPostSize() int { ret := _m.Called() diff --git a/server/channels/store/storetest/mocks/SessionStore.go b/server/channels/store/storetest/mocks/SessionStore.go index 7d5be8a3fb..eea72a1d4e 100644 --- a/server/channels/store/storetest/mocks/SessionStore.go +++ b/server/channels/store/storetest/mocks/SessionStore.go @@ -74,27 +74,6 @@ func (_m *SessionStore) Get(ctx context.Context, sessionIDOrToken string) (*mode return r0, r1 } -// GetLastSessionRowCreateAt provides a mock function with given fields: -func (_m *SessionStore) GetLastSessionRowCreateAt() (int64, error) { - ret := _m.Called() - - var r0 int64 - if rf, ok := ret.Get(0).(func() int64); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(int64) - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - // GetSessions provides a mock function with given fields: userID func (_m *SessionStore) GetSessions(userID string) ([]*model.Session, error) { ret := _m.Called(userID) diff --git a/server/channels/store/storetest/post_store.go b/server/channels/store/storetest/post_store.go index a47e096386..a718eb76ac 100644 --- a/server/channels/store/storetest/post_store.go +++ b/server/channels/store/storetest/post_store.go @@ -43,7 +43,6 @@ func TestPostStore(t *testing.T, ss store.Store, s SqlStore) { t.Run("GetFlaggedPosts", func(t *testing.T) { testPostStoreGetFlaggedPosts(t, ss) }) t.Run("GetFlaggedPostsForChannel", func(t *testing.T) { testPostStoreGetFlaggedPostsForChannel(t, ss) }) t.Run("GetPostsCreatedAt", func(t *testing.T) { testPostStoreGetPostsCreatedAt(t, ss) }) - t.Run("GetLastPostRowCreateAt", func(t *testing.T) { testPostStoreGetLastPostRowCreateAt(t, ss) }) t.Run("Overwrite", func(t *testing.T) { testPostStoreOverwrite(t, ss) }) t.Run("OverwriteMultiple", func(t *testing.T) { testPostStoreOverwriteMultiple(t, ss) }) t.Run("GetPostsByIds", func(t *testing.T) { testPostStoreGetPostsByIds(t, ss) }) @@ -3361,40 +3360,6 @@ func testPostStoreGetFlaggedPostsForChannel(t *testing.T, ss store.Store) { require.Len(t, r.Order, 0, "should have 0 posts") } -func testPostStoreGetLastPostRowCreateAt(t *testing.T, ss store.Store) { - teamId := model.NewId() - channel1, err := ss.Channel().Save(&model.Channel{ - TeamId: teamId, - DisplayName: "DisplayName1", - Name: "channel" + model.NewId(), - Type: model.ChannelTypeOpen, - }, -1) - require.NoError(t, err) - - createTime1 := model.GetMillis() + 1 - o0 := &model.Post{} - o0.ChannelId = channel1.Id - o0.UserId = model.NewId() - o0.Message = NewTestId() - o0.CreateAt = createTime1 - o0, err = ss.Post().Save(o0) - require.NoError(t, err) - - createTime2 := model.GetMillis() + 2 - - o1 := &model.Post{} - o1.ChannelId = o0.ChannelId - o1.UserId = model.NewId() - o1.Message = "Latest message" - o1.CreateAt = createTime2 - _, err = ss.Post().Save(o1) - require.NoError(t, err) - - createAt, err := ss.Post().GetLastPostRowCreateAt() - require.NoError(t, err) - assert.Equal(t, createAt, createTime2) -} - func testPostStoreGetPostsCreatedAt(t *testing.T, ss store.Store) { teamId := model.NewId() channel1, err := ss.Channel().Save(&model.Channel{ diff --git a/server/channels/store/storetest/session_store.go b/server/channels/store/storetest/session_store.go index fa3156979a..3c8fba5504 100644 --- a/server/channels/store/storetest/session_store.go +++ b/server/channels/store/storetest/session_store.go @@ -33,7 +33,6 @@ func TestSessionStore(t *testing.T, ss store.Store) { t.Run("SessionUpdateDeviceId2", func(t *testing.T) { testSessionUpdateDeviceId2(t, ss) }) t.Run("UpdateExpiresAt", func(t *testing.T) { testSessionStoreUpdateExpiresAt(t, ss) }) t.Run("UpdateLastActivityAt", func(t *testing.T) { testSessionStoreUpdateLastActivityAt(t, ss) }) - t.Run("GetLastSessionRowCreateAt", func(t *testing.T) { testSessionStoreGetLastSessionRowCreateAt(t, ss) }) t.Run("SessionCount", func(t *testing.T) { testSessionCount(t, ss) }) t.Run("GetSessionsExpired", func(t *testing.T) { testGetSessionsExpired(t, ss) }) t.Run("UpdateExpiredNotify", func(t *testing.T) { testUpdateExpiredNotify(t, ss) }) @@ -47,23 +46,6 @@ func testSessionStoreSave(t *testing.T, ss store.Store) { require.NoError(t, err) } -func testSessionStoreGetLastSessionRowCreateAt(t *testing.T, ss store.Store) { - s1 := &model.Session{} - s1.UserId = model.NewId() - _, err := ss.Session().Save(s1) - require.NoError(t, err) - - latestSessionUserid := model.NewId() - s2 := &model.Session{} - s2.UserId = latestSessionUserid - latestSession, err := ss.Session().Save(s2) - require.NoError(t, err) - - createAt, err := ss.Session().GetLastSessionRowCreateAt() - require.NoError(t, err) - assert.Equal(t, latestSession.CreateAt, createAt) -} - func testSessionGet(t *testing.T, ss store.Store) { s1 := &model.Session{} s1.UserId = model.NewId() diff --git a/server/channels/store/timerlayer/timerlayer.go b/server/channels/store/timerlayer/timerlayer.go index 219154d479..8199138ac2 100644 --- a/server/channels/store/timerlayer/timerlayer.go +++ b/server/channels/store/timerlayer/timerlayer.go @@ -5483,22 +5483,6 @@ func (s *TimerLayerPostStore) GetFlaggedPostsForTeam(userID string, teamID strin return result, err } -func (s *TimerLayerPostStore) GetLastPostRowCreateAt() (int64, error) { - start := time.Now() - - result, err := s.PostStore.GetLastPostRowCreateAt() - - elapsed := float64(time.Since(start)) / float64(time.Second) - if s.Root.Metrics != nil { - success := "false" - if err == nil { - success = "true" - } - s.Root.Metrics.ObserveStoreMethodDuration("PostStore.GetLastPostRowCreateAt", success, elapsed) - } - return result, err -} - func (s *TimerLayerPostStore) GetMaxPostSize() int { start := time.Now() @@ -7370,22 +7354,6 @@ func (s *TimerLayerSessionStore) Get(ctx context.Context, sessionIDOrToken strin return result, err } -func (s *TimerLayerSessionStore) GetLastSessionRowCreateAt() (int64, error) { - start := time.Now() - - result, err := s.SessionStore.GetLastSessionRowCreateAt() - - elapsed := float64(time.Since(start)) / float64(time.Second) - if s.Root.Metrics != nil { - success := "false" - if err == nil { - success = "true" - } - s.Root.Metrics.ObserveStoreMethodDuration("SessionStore.GetLastSessionRowCreateAt", success, elapsed) - } - return result, err -} - func (s *TimerLayerSessionStore) GetSessions(userID string) ([]*model.Session, error) { start := time.Now() diff --git a/server/i18n/en.json b/server/i18n/en.json index 07b6d2219b..ded7d5c8a6 100644 --- a/server/i18n/en.json +++ b/server/i18n/en.json @@ -7,14 +7,6 @@ "id": "August", "translation": "August" }, - { - "id": "Boards", - "translation": "Boards" - }, - { - "id": "Channels", - "translation": "Channels" - }, { "id": "December", "translation": "December" @@ -51,10 +43,6 @@ "id": "October", "translation": "October" }, - { - "id": "Playbooks", - "translation": "Playbooks" - }, { "id": "September", "translation": "September" @@ -3763,42 +3751,6 @@ "id": "api.templates.reset_subject", "translation": "[{{ .SiteName }}] Reset your password" }, - { - "id": "api.templates.server_inactivity_button", - "translation": "Open Mattermost" - }, - { - "id": "api.templates.server_inactivity_footer_disclaimer", - "translation": "You received this one-time email because your Mattermost server was inactive for more than {{.Hours}} hours. This email was automatically generated by your Mattermost server." - }, - { - "id": "api.templates.server_inactivity_info", - "translation": "Come and check it out!" - }, - { - "id": "api.templates.server_inactivity_info_bullet", - "translation": "Guest Access to specified " - }, - { - "id": "api.templates.server_inactivity_info_bullet1", - "translation": "Workflow management with " - }, - { - "id": "api.templates.server_inactivity_info_bullet2", - "translation": "Manage tasks using " - }, - { - "id": "api.templates.server_inactivity_subject", - "translation": "Come open Mattermost to increase your team’s productivity!" - }, - { - "id": "api.templates.server_inactivity_subtitle", - "translation": "Hey {{.Name}}, we’ve noticed that your Mattermost server is collecting a bit of dust. Take a look at some features that can help lighten your team's workload." - }, - { - "id": "api.templates.server_inactivity_title", - "translation": "Unlock increased productivity with these awesome features" - }, { "id": "api.templates.signin_change_email.body.info", "translation": "You updated your sign-in method on {{ .SiteName }} to {{.Method}}." diff --git a/server/platform/services/telemetry/telemetry.go b/server/platform/services/telemetry/telemetry.go index cf3402a8c1..a214911f20 100644 --- a/server/platform/services/telemetry/telemetry.go +++ b/server/platform/services/telemetry/telemetry.go @@ -609,7 +609,6 @@ func (ts *TelemetryService) trackConfig() { "isdefault_login_button_border_color": isDefault(*cfg.EmailSettings.LoginButtonBorderColor, ""), "isdefault_login_button_text_color": isDefault(*cfg.EmailSettings.LoginButtonTextColor, ""), "smtp_server_timeout": *cfg.EmailSettings.SMTPServerTimeout, - "enable_inactivity_email": *cfg.EmailSettings.EnableInactivityEmail, }) ts.SendTelemetry(TrackConfigRate, map[string]any{ diff --git a/server/templates/inactivity_body.html b/server/templates/inactivity_body.html deleted file mode 100644 index 36bb7795cb..0000000000 --- a/server/templates/inactivity_body.html +++ /dev/null @@ -1,548 +0,0 @@ -{{define "inactivity_body"}} - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - -
- -
- - - - - - -
- -
- - - - - - -
- - - - - - -
- -
-
-
- -
-
- -
- - - - - - -
- -
- - - - - - - - - - - - - - - - - - -
-
{{.Props.Title}}
-
-
{{.Props.SubTitle}}
-
-
-
    -
  • {{.Props.InfoBullet}}{{.Props.Channels}}
  • -
  • {{.Props.InfoBullet1}}{{.Props.Playbooks}}
  • -
  • {{.Props.InfoBullet2}}{{.Props.Boards}}
  • -
-
-
-
{{.Props.Info}}
-
- - - - -
- - {{.Props.Button}} - -
-
-
- -
-
- -
- - - - - - -
- -
- - - - - - -
- - - - - - -
- -
-
-
- -
-
- -
- - - - - - -
- -
- - - - - - - - - -
-
{{.Props.QuestionTitle}}
-
-
{{.Props.QuestionInfo}} - - {{.Props.SupportEmail}} - -
-
-
- -
-
- -
- - - - - - -
- -
- - - - - - - - - -
-
{{.Props.FooterDisclaimer}}
-
-
{{.Props.Organization}} - {{.Props.FooterV2}} -
-
-
- -
-
- -
-
- -
- - - - -{{end}} diff --git a/server/templates/inactivity_body.mjml b/server/templates/inactivity_body.mjml deleted file mode 100644 index 47b17fe42c..0000000000 --- a/server/templates/inactivity_body.mjml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - {{.Props.Title}} - - - {{.Props.SubTitle}} - - -
    -
  • {{.Props.InfoBullet}}{{.Props.Channels}}
  • -
  • {{.Props.InfoBullet1}}{{.Props.Playbooks}}
  • -
  • {{.Props.InfoBullet2}}{{.Props.Boards}}
  • -
-
- - {{.Props.Info}} - - {{.Props.Button}} -
-
- - - - - - - - - - - {{.Props.QuestionTitle}} - - - {{.Props.QuestionInfo}} - - {{.Props.SupportEmail}} - - - - - - - - - {{.Props.FooterDisclaimer}} - - - {{.Props.Organization}} - {{.Props.FooterV2}} - - - - -
-
-
diff --git a/server/tests/test-config.json b/server/tests/test-config.json index 3604556889..d98cbd98ca 100644 --- a/server/tests/test-config.json +++ b/server/tests/test-config.json @@ -167,7 +167,6 @@ "LoginButtonColor": "", "LoginButtonBorderColor": "", "LoginButtonTextColor": "", - "EnableInactivityEmail": true }, "RateLimitSettings": { "Enable": false,