Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ Review and manage the following [experimental](/administration-guide/manage/feat

<Tip>

System admins managing a self-hosted Mattermost deployment can edit the `config.json` file as described in the following tables. Each configuration value below includes a JSON path to access the value programmatically in the `config.json` file using a JSON-aware tool. For example, one `LoginButtonColor` value is under `EmailSettings`.
System admins managing a self-hosted Mattermost deployment can edit the `config.json` file as described in the following tables. Each configuration value below includes a JSON path to access the value programmatically in the `config.json` file using a JSON-aware tool. For example, the `EmailBatchingBufferSize` value is under `EmailSettings`.

- If using a tool such as [jq](https://stedolan.github.io/jq/), you'd enter: `cat config/config.json | jq '.EmailSettings.LoginButtonColor'`
- When working with the `config.json` file manually, look for an object such as `EmailSettings`, then within that object, find the key `LoginButtonColor`.
- If using a tool such as [jq](https://stedolan.github.io/jq/), you'd enter: `cat config/config.json | jq '.EmailSettings.EmailBatchingBufferSize'`
- When working with the `config.json` file manually, look for an object such as `EmailSettings`, then within that object, find the key `EmailBatchingBufferSize`.

</Tip>

Expand Down Expand Up @@ -101,51 +101,6 @@ Specify the maximum frequency, in seconds, which the batching job checks for new
</tbody>
</table>

### Email login button color

Specify the color of the email login button for white labeling purposes. Use a hex code with a \#-sign before the code. This setting only applies to the mobile app.

<table>
<colgroup>
<col style={{width: '100%'}} />
</colgroup>
<tbody>
<tr>
<td>This feature's <code>config.json</code> setting is <code>"LoginButtonColor": ""</code> with string input.</td>
</tr>
</tbody>
</table>

### Email login button border color

Specify the color of the email login button border for white labeling purposes. Use a hex code with a \#-sign before the code. This setting only applies to the mobile app.

<table>
<colgroup>
<col style={{width: '100%'}} />
</colgroup>
<tbody>
<tr>
<td>This feature's <code>config.json</code> setting is <code>"LoginButtonBorderColor": ""</code> with string input.</td>
</tr>
</tbody>
</table>

### Email login button text color

Specify the color of the email login button text for white labeling purposes. Use a hex code with a \#-sign before the code. This setting only applies to the mobile app.

<table>
<colgroup>
<col style={{width: '100%'}} />
</colgroup>
<tbody>
<tr>
<td>This feature's <code>config.json</code> setting is <code>"LoginButtonTextColor": ""</code> with string input.</td>
</tr>
</tbody>
</table>

### Enable account deactivation

**True**: Ability for users to deactivate their own account from **Settings \> Advanced \> Deactivate Account**. If a user deactivates their own account, they will get an email notification confirming they were deactivated. Available only when authentication is set to use email/password. Not available when authentication uses SAML or AD/LDAP.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,7 @@
"EmailBatchingInterval": 30,
"EnablePreviewModeBanner": true,
"SkipServerCertificateVerification": false,
"EmailNotificationContentsType": "full",
"LoginButtonColor": "#0000",
"LoginButtonBorderColor": "#2389D7",
"LoginButtonTextColor": "#2389D7"
"EmailNotificationContentsType": "full"
},
"PrivacySettings": {
"ShowEmailAddress": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,10 +257,7 @@
"EmailBatchingInterval": 30,
"EnablePreviewModeBanner": true,
"SkipServerCertificateVerification": false,
"EmailNotificationContentsType": "full",
"LoginButtonColor": "#0000",
"LoginButtonBorderColor": "#2389D7",
"LoginButtonTextColor": "#2389D7"
"EmailNotificationContentsType": "full"
},
"RateLimitSettings": {
"Enable": false,
Expand Down
3 changes: 0 additions & 3 deletions e2e-tests/playwright/lib/src/server/default_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,9 +405,6 @@
EnablePreviewModeBanner: true,
SkipServerCertificateVerification: false,
EmailNotificationContentsType: 'full',
LoginButtonColor: '#0000',
LoginButtonBorderColor: '#2389D7',
LoginButtonTextColor: '#2389D7',
},
RateLimitSettings: {
Enable: false,
Expand Down Expand Up @@ -818,7 +815,7 @@
MobileEphemeralMode: false,
PropertyFieldRank: false,
TeamMembershipAccessControl: true,
MmBlocksEnabled: true,

Check warning on line 818 in e2e-tests/playwright/lib/src/server/default_config.ts

View workflow job for this annotation

GitHub Actions / check

File has too many lines (903). Maximum allowed is 800
},
ImportSettings: {
Directory: './import',
Expand Down
13 changes: 12 additions & 1 deletion server/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,7 @@ vet: setup-go-work ## Run mattermost go vet specific checks
cd ../tools/mattermost-govet && $(GO) install .
$(GO) vet -vettool=$(GOBIN)/mattermost-govet \
-structuredLogging \
-mlogFieldNaming \
-inconsistentReceiverName \
-emptyStrCmp \
-tFatal \
Expand All @@ -957,7 +958,17 @@ vet: setup-go-work ## Run mattermost go vet specific checks
./...
ifeq ($(BUILD_ENTERPRISE_READY),true)
ifneq ($(MM_NO_ENTERPRISE_LINT),true)
$(GO) vet -vettool=$(GOBIN)/mattermost-govet -structuredLogging -inconsistentReceiverName -emptyStrCmp -tFatal -configtelemetry -errorAssertions -requestCtxNaming -enterpriseLicense $(BUILD_ENTERPRISE_DIR)/...
$(GO) vet -vettool=$(GOBIN)/mattermost-govet -structuredLogging -mlogFieldNaming -inconsistentReceiverName -emptyStrCmp -tFatal -configtelemetry -errorAssertions -requestCtxNaming -enterpriseLicense $(BUILD_ENTERPRISE_DIR)/...
endif
endif

.PHONY: vet-fix
vet-fix: setup-go-work ## Apply the suggested fixes from mattermost go vet checks
cd ../tools/mattermost-govet && $(GO) install .
$(GO) fix -fixtool=$(GOBIN)/mattermost-govet -mlogFieldNaming ./...
ifeq ($(BUILD_ENTERPRISE_READY),true)
ifneq ($(MM_NO_ENTERPRISE_LINT),true)
$(GO) fix -fixtool=$(GOBIN)/mattermost-govet -mlogFieldNaming $(BUILD_ENTERPRISE_DIR)/...
endif
endif

Expand Down
14 changes: 7 additions & 7 deletions server/channels/api4/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -2469,7 +2469,7 @@ func addChannelMember(c *Context, w http.ResponseWriter, r *http.Request) {
var newChannelMembers []model.ChannelMember
for _, userId := range userIds {
if !model.IsValidId(userId) {
c.Logger.Warn("Error adding channel member, invalid UserId", mlog.String("UserId", userId), mlog.String("ChannelId", channel.Id))
c.Logger.Warn("Error adding channel member, invalid UserId", mlog.String("user_id", userId), mlog.String("channel_id", channel.Id))
c.SetInvalidParam("user_id")
lastError = c.Err
continue
Expand All @@ -2489,7 +2489,7 @@ func addChannelMember(c *Context, w http.ResponseWriter, r *http.Request) {
existingMember, err := c.App.GetChannelMember(c.AppContext, member.ChannelId, member.UserId)
if err != nil {
if err.Id != app.MissingChannelMemberError {
c.Logger.Warn("Error adding channel member, error getting channel member", mlog.String("UserId", userId), mlog.String("ChannelId", channel.Id), mlog.Err(err))
c.Logger.Warn("Error adding channel member, error getting channel member", mlog.String("user_id", userId), mlog.String("channel_id", channel.Id), mlog.Err(err))
lastError = err
continue
}
Expand All @@ -2502,12 +2502,12 @@ func addChannelMember(c *Context, w http.ResponseWriter, r *http.Request) {
newChannelMembers = append(newChannelMembers, *existingMember)
continue
} else if isSelfAdd && !canAddSelf {
c.Logger.Warn("Error adding channel member, Invalid Permission to add self", mlog.String("UserId", userId), mlog.String("ChannelId", channel.Id))
c.Logger.Warn("Error adding channel member, Invalid Permission to add self", mlog.String("user_id", userId), mlog.String("channel_id", channel.Id))
c.SetPermissionError(model.PermissionJoinPublicChannels)
lastError = c.Err
continue
} else if !isSelfAdd && !canAddOthers {
c.Logger.Warn("Error adding channel member, Invalid Permission to add others", mlog.String("UserId", userId), mlog.String("ChannelId", channel.Id))
c.Logger.Warn("Error adding channel member, Invalid Permission to add others", mlog.String("user_id", userId), mlog.String("channel_id", channel.Id))
c.SetPermissionError(model.PermissionManagePublicChannelMembers)
lastError = c.Err
continue
Expand All @@ -2516,7 +2516,7 @@ func addChannelMember(c *Context, w http.ResponseWriter, r *http.Request) {

if existingMember != nil {
// user is already a member, go to next
c.Logger.Warn("User is already a channel member, skipping", mlog.String("UserId", userId), mlog.String("ChannelId", channel.Id))
c.Logger.Warn("User is already a channel member, skipping", mlog.String("user_id", userId), mlog.String("channel_id", channel.Id))
newChannelMembers = append(newChannelMembers, *existingMember)
continue
}
Expand All @@ -2526,7 +2526,7 @@ func addChannelMember(c *Context, w http.ResponseWriter, r *http.Request) {
PostRootID: postRootId,
})
if err != nil {
c.Logger.Warn("Error adding channel member", mlog.String("UserId", userId), mlog.String("ChannelId", channel.Id), mlog.Err(err))
c.Logger.Warn("Error adding channel member", mlog.String("user_id", userId), mlog.String("channel_id", channel.Id), mlog.Err(err))
lastError = err
continue
}
Expand All @@ -2535,7 +2535,7 @@ func addChannelMember(c *Context, w http.ResponseWriter, r *http.Request) {
if postRootId != "" {
err := c.App.UpdateThreadFollowForUserFromChannelAdd(c.AppContext, cm.UserId, channel.TeamId, postRootId)
if err != nil {
c.Logger.Warn("Error adding channel member, error updating thread", mlog.String("UserId", userId), mlog.String("ChannelId", channel.Id), mlog.Err(err))
c.Logger.Warn("Error adding channel member, error updating thread", mlog.String("user_id", userId), mlog.String("channel_id", channel.Id), mlog.Err(err))
lastError = err
continue
}
Expand Down
2 changes: 1 addition & 1 deletion server/channels/api4/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ func getJobs(c *Context, w http.ResponseWriter, r *http.Request) {
for _, jType := range model.AllJobTypes {
hasPermission, permissionRequired := c.App.SessionHasPermissionToReadJob(*c.AppContext.Session(), jType)
if permissionRequired == nil {
c.Logger.Warn("The job types of a job you are trying to retrieve does not contain permissions", mlog.String("jobType", jType))
c.Logger.Warn("The job types of a job you are trying to retrieve does not contain permissions", mlog.String("job_type", jType))
continue
}
if hasPermission {
Expand Down
2 changes: 1 addition & 1 deletion server/channels/app/audit.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ func (s *Server) configureAudit(adt *audit.Audit, bAllowAdvancedLogging bool) er
}

func (s *Server) onAuditTargetQueueFull(qname string, maxQSize int) bool {
s.Log().Error("Audit queue full, dropping record.", mlog.String("qname", qname), mlog.Int("queueSize", maxQSize))
s.Log().Error("Audit queue full, dropping record.", mlog.String("qname", qname), mlog.Int("queue_size", maxQSize))
return true // drop it
}

Expand Down
4 changes: 2 additions & 2 deletions server/channels/app/brand.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ func (a *App) SaveBrandImage(rctx request.CTX, imageData *multipart.FileHeader)
rctx.Logger().Warn(
"Failed to backup old brand image",
mlog.Err(err),
mlog.String("oldPath", oldPath),
mlog.String("newPath", newPath),
mlog.String("old_path", oldPath),
mlog.String("new_path", newPath),
)
}
}
Expand Down
8 changes: 4 additions & 4 deletions server/channels/app/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (a *App) JoinDefaultChannels(rctx request.CTX, teamID string, user *model.U
for _, channelName := range a.DefaultChannelNames(rctx) {
channel, channelErr := a.Srv().Store().Channel().GetByName(teamID, channelName, true)
if channelErr != nil {
rctx.Logger().Warn("No default channel with this name", mlog.String("channelName", channelName), mlog.String("teamID", teamID), mlog.Err(channelErr))
rctx.Logger().Warn("No default channel with this name", mlog.String("channel_name", channelName), mlog.String("team_id", teamID), mlog.Err(channelErr))
continue
}

Expand Down Expand Up @@ -3848,7 +3848,7 @@ func (a *App) MoveChannel(rctx request.CTX, team *model.Team, channel *model.Cha
}
for _, channelMember := range channelMembers {
if _, ok := teamMembersMap[channelMember.UserId]; !ok {
rctx.Logger().Warn("Not member of the target team", mlog.String("userId", channelMember.UserId))
rctx.Logger().Warn("Not member of the target team", mlog.String("user_id", channelMember.UserId))
}
}
return model.NewAppError("MoveChannel", "app.channel.move_channel.members_do_not_match.error", nil, "", http.StatusInternalServerError)
Expand Down Expand Up @@ -3895,7 +3895,7 @@ func (a *App) MoveChannel(rctx request.CTX, team *model.Team, channel *model.Cha
if webhook.ChannelId == channel.Id {
webhook.TeamId = team.Id
if _, err := a.Srv().Store().Webhook().UpdateIncoming(webhook); err != nil {
rctx.Logger().Warn("Failed to move incoming webhook to new team", mlog.String("webhook id", webhook.Id))
rctx.Logger().Warn("Failed to move incoming webhook to new team", mlog.String("webhook_id", webhook.Id))
}
}
}
Expand All @@ -3908,7 +3908,7 @@ func (a *App) MoveChannel(rctx request.CTX, team *model.Team, channel *model.Cha
if webhook.ChannelId == channel.Id {
webhook.TeamId = team.Id
if _, err := a.Srv().Store().Webhook().UpdateOutgoing(webhook); err != nil {
rctx.Logger().Warn("Failed to move outgoing webhook to new team.", mlog.String("webhook id", webhook.Id))
rctx.Logger().Warn("Failed to move outgoing webhook to new team.", mlog.String("webhook_id", webhook.Id))
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions server/channels/app/email/email.go
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ func (es *Service) SendInviteEmails(rctx request.CTX, inviteData InviteEmailData
}

if rateLimited {
mlog.Error("rate limit exceeded", mlog.Duration("RetryAfter", result.RetryAfter), mlog.Duration("ResetAfter", result.ResetAfter), mlog.String("user_id", inviteData.SenderUserID),
mlog.Error("rate limit exceeded", mlog.Duration("retry_after", result.RetryAfter), mlog.Duration("reset_after", result.ResetAfter), mlog.String("user_id", inviteData.SenderUserID),
mlog.String("team_id", inviteData.Team.Id), mlog.String("retry_after_secs", fmt.Sprintf("%f", result.RetryAfter.Seconds())), mlog.String("reset_after_secs", fmt.Sprintf("%f", result.ResetAfter.Seconds())))
return RateLimitExceededError
}
Expand Down Expand Up @@ -547,7 +547,7 @@ func (es *Service) SendGuestInviteEmails(
}

if rateLimited {
mlog.Error("rate limit exceeded", mlog.Duration("RetryAfter", result.RetryAfter), mlog.Duration("ResetAfter", result.ResetAfter), mlog.String("user_id", senderUserId),
mlog.Error("rate limit exceeded", mlog.Duration("retry_after", result.RetryAfter), mlog.Duration("reset_after", result.ResetAfter), mlog.String("user_id", senderUserId),
mlog.String("team_id", team.Id), mlog.String("retry_after_secs", fmt.Sprintf("%f", result.RetryAfter.Seconds())), mlog.String("reset_after_secs", fmt.Sprintf("%f", result.ResetAfter.Seconds())))
return RateLimitExceededError
}
Expand Down Expand Up @@ -670,7 +670,7 @@ func (es *Service) SendMagicLinkEmailSelfService(
}

if rateLimited {
mlog.Error("rate limit exceeded", mlog.Duration("RetryAfter", result.RetryAfter), mlog.Duration("ResetAfter", result.ResetAfter), mlog.String("email", invite),
mlog.Error("rate limit exceeded", mlog.Duration("retry_after", result.RetryAfter), mlog.Duration("reset_after", result.ResetAfter), mlog.String("email", invite),
mlog.String("retry_after_secs", fmt.Sprintf("%f", result.RetryAfter.Seconds())), mlog.String("reset_after_secs", fmt.Sprintf("%f", result.ResetAfter.Seconds())))
return RateLimitExceededError
}
Expand Down Expand Up @@ -736,7 +736,7 @@ func (es *Service) SendInviteEmailsToTeamAndChannels(rctx request.CTX, inviteDat
}

if rateLimited {
mlog.Error("rate limit exceeded", mlog.Duration("RetryAfter", result.RetryAfter), mlog.Duration("ResetAfter", result.ResetAfter), mlog.String("user_id", inviteData.SenderUserID),
mlog.Error("rate limit exceeded", mlog.Duration("retry_after", result.RetryAfter), mlog.Duration("reset_after", result.ResetAfter), mlog.String("user_id", inviteData.SenderUserID),
mlog.String("team_id", inviteData.Team.Id), mlog.String("retry_after_secs", fmt.Sprintf("%f", result.RetryAfter.Seconds())), mlog.String("reset_after_secs", fmt.Sprintf("%f", result.ResetAfter.Seconds())))
return nil, RateLimitExceededError
}
Expand Down
3 changes: 0 additions & 3 deletions server/channels/app/email/email_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -469,9 +469,6 @@ func TestMailServiceConfig(t *testing.T) {
EnablePreviewModeBanner: new(bool),
SkipServerCertificateVerification: new(bool),
EmailNotificationContentsType: new(string),
LoginButtonColor: new(string),
LoginButtonBorderColor: new(string),
LoginButtonTextColor: new(string),
},
}
},
Expand Down
4 changes: 2 additions & 2 deletions server/channels/app/expirynotify.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (a *App) NotifySessionsExpired() error {
mlog.String("push_type", tmpMessage.Type),
mlog.String("user_id", session.UserId),
mlog.String("session_id", session.Id),
mlog.String("deviceId", model.RedactDeviceId(tmpMessage.DeviceId)),
mlog.String("device_id", model.RedactDeviceId(tmpMessage.DeviceId)),
mlog.String("post_id", msg.PostId),
))

Expand Down Expand Up @@ -83,7 +83,7 @@ func (a *App) NotifySessionsExpired() error {
if err != nil {
mlog.Error("Failed to update ExpiredNotify flag",
mlog.String("sessionid", session.Id),
mlog.String("deviceId", model.RedactDeviceId(tmpMessage.DeviceId)),
mlog.String("device_id", model.RedactDeviceId(tmpMessage.DeviceId)),
mlog.Err(err),
)
}
Expand Down
8 changes: 4 additions & 4 deletions server/channels/app/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -879,10 +879,10 @@ func (a *App) UploadFileX(rctx request.CTX, channelID, name string, input io.Rea
if !a.Srv().GoExtraction(func() {
err := a.ExtractContentFromFileInfo(rctx, &infoCopy)
if err != nil {
rctx.Logger().Error("Failed to extract file content", mlog.Err(err), mlog.String("fileInfoId", infoCopy.Id))
rctx.Logger().Error("Failed to extract file content", mlog.Err(err), mlog.String("file_info_id", infoCopy.Id))
}
}) {
rctx.Logger().Warn("Content extraction queue is full, skipping inline extraction; this file's content will not be searchable until the scheduled content extraction catch-up job runs or an admin runs a content extraction job (e.g. mmctl extract)", mlog.String("fileInfoId", infoCopy.Id))
rctx.Logger().Warn("Content extraction queue is full, skipping inline extraction; this file's content will not be searchable until the scheduled content extraction catch-up job runs or an admin runs a content extraction job (e.g. mmctl extract)", mlog.String("file_info_id", infoCopy.Id))
}
}

Expand Down Expand Up @@ -1148,10 +1148,10 @@ func (a *App) DoUploadFileExpectModification(rctx request.CTX, now time.Time, ra
if !a.Srv().GoExtraction(func() {
err := a.ExtractContentFromFileInfo(rctx, &infoCopy)
if err != nil {
rctx.Logger().Error("Failed to extract file content", mlog.Err(err), mlog.String("fileInfoId", infoCopy.Id))
rctx.Logger().Error("Failed to extract file content", mlog.Err(err), mlog.String("file_info_id", infoCopy.Id))
}
}) {
rctx.Logger().Warn("Content extraction queue is full, skipping inline extraction; this file's content will not be searchable until the scheduled content extraction catch-up job runs or an admin runs a content extraction job (e.g. mmctl extract)", mlog.String("fileInfoId", infoCopy.Id))
rctx.Logger().Warn("Content extraction queue is full, skipping inline extraction; this file's content will not be searchable until the scheduled content extraction catch-up job runs or an admin runs a content extraction job (e.g. mmctl extract)", mlog.String("file_info_id", infoCopy.Id))
}
}

Expand Down
Loading
Loading