diff --git a/docs/develop/integrate/plugins/example-plugins.md b/docs/develop/integrate/plugins/example-plugins.md
index 13953c635d9..7dbbf2f6248 100644
--- a/docs/develop/integrate/plugins/example-plugins.md
+++ b/docs/develop/integrate/plugins/example-plugins.md
@@ -2,6 +2,7 @@
title: "Example plugins"
sidebar_position: 90
---
+import useBaseUrl from '@docusaurus/useBaseUrl';
## Server "Hello, world!"
@@ -23,7 +24,7 @@ To see a stripped down version of the demo plugin with just the build scripts an
The [Zoom plugin for Mattermost](https://github.com/mattermost/mattermost-plugin-zoom) adds UI elements that allow users to easily create and join Zoom meetings:
-
+
Topics demonstrated:
@@ -37,7 +38,7 @@ Topics demonstrated:
The [JIRA plugin for Mattermost](https://github.com/mattermost/mattermost-plugin-jira) creates a webhook that your JIRA server can use to post messages to Mattermost when issues are created:
-
+
Topics demonstrated:
@@ -59,7 +60,7 @@ Topics demonstrated:
The [Memes plugin for Mattermost](https://github.com/mattermost/mattermost-plugin-memes) creates a slash command that can be used to create dank memes:
-
+
Topics demonstrated:
diff --git a/docs/main/administration-guide/comply/embedded-json-audit-log-schema.mdx b/docs/main/administration-guide/comply/embedded-json-audit-log-schema.mdx
index 4a2e7a97b8c..99e6839bc3a 100644
--- a/docs/main/administration-guide/comply/embedded-json-audit-log-schema.mdx
+++ b/docs/main/administration-guide/comply/embedded-json-audit-log-schema.mdx
@@ -1,6 +1,8 @@
---
title: "Audit log JSON schema"
---
+import useBaseUrl from '@docusaurus/useBaseUrl';
+
Mattermost currently supports three log formats: plain, JSON, and | GELF. | | - Plain log format uses RFC3339 by default. | See the plain log format configuration documentation for supported options. | - JSON log format uses RFC3339 by default. | See the JSON log format configuration documentation for supported options. | | - GELF log format uses unixtime. | See the GELF log format configuration documentation for supported options. |
Mattermost currently supports three log formats: plain, JSON, and | GELF. | | - Plain log format uses RFC3339 by default. | See the plain log format configuration documentation for supported options. | - JSON log format uses RFC3339 by default. | See the JSON log format configuration documentation for supported options. | | - GELF log format uses unixtime. | See the GELF log format configuration documentation for supported options. |
config.json setting: TeamSettings > RestrictCreationToDomains to true for the restriction to function. This setting only affects email login. | - Environment variable: MM_TEAMSETTINGS_RESTRICTCREATIONTODOMAINS |config.json setting: TeamSettings > RestrictCreationToDomains to true for the restriction to function. This setting only affects email login. | - Environment variable: MM_TEAMSETTINGS_RESTRICTCREATIONTODOMAINS |config.json setting: ServiceSettings > EnableMultifactorAuthentication > falseMM_SERVICESETTINGS_ENABLEMULTIFACTORAUTHENTICATION |config.json setting: ServiceSettings > EnableMultifactorAuthentication > falseMM_SERVICESETTINGS_ENABLEMULTIFACTORAUTHENTICATION |config.json setting: ServiceSettings > EnforceMultifactorAuthentication > falsefor users who sign-in with AD/LDAP or an email address. | - Environment variable: MM_SERVICESETTINGS_ENFORCEMULTIFACTORAUTHENTICATION | New users must set up MFA. Logged in users are redirected to the MFA | | setup page until configuration is complete. | |
config.json setting: ServiceSettings > EnforceMultifactorAuthentication > falsefor users who sign-in with AD/LDAP or an email address. | - Environment variable: MM_SERVICESETTINGS_ENFORCEMULTIFACTORAUTHENTICATION | New users must set up MFA. Logged in users are redirected to the MFA | | setup page until configuration is complete. | |
config.json setting: LdapSettings > GuestFilter |MM_LDAPSETTINGS_GUESTFILTERString input. | |
config.json setting: LdapSettings > GuestFilter |MM_LDAPSETTINGS_GUESTFILTERString input. | |
config.json setting: LdapSettings > FirstNameAttribute |MM_LDAPSETTINGS_FIRSTNAMEATTRIBUTE |When not set, users can edit their first name in their | | profile settings. | | | String input. | |
config.json setting: LdapSettings > FirstNameAttribute |MM_LDAPSETTINGS_FIRSTNAMEATTRIBUTE |When not set, users can edit their first name in their | | profile settings. | | | String input. | |
config.json setting: LdapSettings > LastNameAttribute |MM_LDAPSETTINGS_LASTNAMEATTRIBUTE |When not set, users can edit their last name as part of their | | profile settings. | | | | String input. | |
config.json setting: LdapSettings > LastNameAttribute |MM_LDAPSETTINGS_LASTNAMEATTRIBUTE |When not set, users can edit their last name as part of their | | profile settings. | | | | String input. | |
config.json setting: LdapSettings > NicknameAttribute |MM_LDAPSETTINGS_NICKNAMEATTRIBUTE |When not set, users can edit their nickname as part of their | | profile settings. | | | String input. | |
config.json setting: LdapSettings > NicknameAttribute |MM_LDAPSETTINGS_NICKNAMEATTRIBUTE |When not set, users can edit their nickname as part of their | | profile settings. | | | String input. | |
config.json setting: LdapSettings > PositionAttribute |MM_LDAPSETTINGS_POSITIONATTRIBUTE |When not set, users can edit their position as part of their | | profile settings. | | | String input. | |
config.json setting: LdapSettings > PositionAttribute |MM_LDAPSETTINGS_POSITIONATTRIBUTE |When not set, users can edit their position as part of their | | profile settings. | | | String input. | |
config.json setting: SamlSettings > Enable > false |MM_SAMLSETTINGS_ENABLE |config.json setting: SamlSettings > Enable > false |MM_SAMLSETTINGS_ENABLE |config.json setting: SamlSettings > GuestAttribute|MM_SAMLSETTINGS_GUESTATTRIBUTEString input. | |
config.json setting: SamlSettings > GuestAttribute|MM_SAMLSETTINGS_GUESTATTRIBUTEString input. | |
config.json setting: GoogleSettings > Enable > false|MM_GOOGLESETTINGS_ENABLE |See Google Single Sign-On implementation instructions. |
config.json setting: GoogleSettings > Enable > false|MM_GOOGLESETTINGS_ENABLE |See Google Single Sign-On implementation instructions. |
config.json setting: GoogleSettings > Id|MM_GOOGLESETTINGS_IDString input. | |
config.json setting: GoogleSettings > Id|MM_GOOGLESETTINGS_IDString input. | |
config.json setting: GoogleSettings > Enable > false |MM_GOOGLESETTINGS_ENABLE |See Google Single Sign-On implementation instructions. |
config.json setting: GoogleSettings > Enable > false |MM_GOOGLESETTINGS_ENABLE |See Google Single Sign-On implementation instructions. |
config.json setting: GoogleSettings > DiscoveryEndpoint |MM_GOOGLESETTINGS_DISCOVERYENDPOINTString input. Default is https://accounts.google.com/.well-known/openid-configuration | |
config.json setting: GoogleSettings > DiscoveryEndpoint |MM_GOOGLESETTINGS_DISCOVERYENDPOINTString input. Default is https://accounts.google.com/.well-known/openid-configuration | |
config.json setting: GoogleSettings > Id |MM_GOOGLESETTINGS_IDString input. | |
config.json setting: GoogleSettings > Id |MM_GOOGLESETTINGS_IDString input. | |
config.json setting: GoogleSettings > Secret|MM_GOOGLESETTINGS_SECRETString input. | |
config.json setting: GoogleSettings > Secret|MM_GOOGLESETTINGS_SECRETString input. | |
config.json setting: Office365Settings > Enable > false |MM_OFFICE365SETTINGS_ENABLE |See Entra ID Single Sign-On implementation instructions. |
config.json setting: Office365Settings > Enable > false |MM_OFFICE365SETTINGS_ENABLE |See Entra ID Single Sign-On implementation instructions. |
config.json setting: Office365Settings > DirectoryId |MM_OFFICE365SETTINGS_DIRECTORYIDString input. | |
config.json setting: Office365Settings > DirectoryId |MM_OFFICE365SETTINGS_DIRECTORYIDString input. | |
config.json setting: Office365Settings > DiscoveryEndpoint |MM_OFFICE365SETTINGS_DISCOVERYENDPOINTString input. Default is https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration | |
config.json setting: Office365Settings > DiscoveryEndpoint |MM_OFFICE365SETTINGS_DISCOVERYENDPOINTString input. Default is https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration | |
config.json setting: Office365Settings > Id |MM_OFFICE365SETTINGS_IDString input. | |
config.json setting: Office365Settings > Id |MM_OFFICE365SETTINGS_IDString input. | |
config.json setting: Office365Settings > Secret |MM_OFFICE365SETTINGS_SECRETString input. | |
config.json setting: Office365Settings > Secret |MM_OFFICE365SETTINGS_SECRETString input. | |
config.json setting: OpenIdSettings > Enable > false |MM_OPENIDSETTINGS_ENABLE |See OpenID Connect Single Sign-On implementation instructions. |
config.json setting: OpenIdSettings > Enable > false |MM_OPENIDSETTINGS_ENABLE |See OpenID Connect Single Sign-On implementation instructions. |
https://myopenid.provider.com/{my_organization}/ | -config.jsonsetting:OpenIdSettings>DiscoveryEndpoint| .well-known/openid-configuration. | - Environment variable: MM_OPENIDSETTINGS_DISCOVERYENDPOINT | | | See OpenID Connect Single Sign-On | implementation instructions. | | | | String input. | |https://myopenid.provider.com/{my_organization}/ | -config.jsonsetting:OpenIdSettings>DiscoveryEndpoint| .well-known/openid-configuration. | - Environment variable: MM_OPENIDSETTINGS_DISCOVERYENDPOINT | | | See OpenID Connect Single Sign-On | implementation instructions. | | | | String input. | |config.json setting: OpenIdSettings > Id |MM_OPENIDSETTINGS_IDString input. | |
config.json setting: OpenIdSettings > Id |MM_OPENIDSETTINGS_IDString input. | |
config.json setting: OpenIdSettings > Secret|MM_OPENIDSETTINGS_SECRETString input. | |
config.json setting: OpenIdSettings > Secret|MM_OPENIDSETTINGS_SECRETString input. | |
config.json setting: SqlSettings > DisableDatabaseSearch > false | | - Environment variable: MM_SQLSETTINGS_DISABLEDATABASESEARCH | - true: Disables the use of the database to perform | | searches. If another search engine isn't configured, | | setting this value to true will result in empty search | | results. | | - false: (Default) Database search isn't disabled. | |config.json setting: SqlSettings > DisableDatabaseSearch > false | | - Environment variable: MM_SQLSETTINGS_DISABLEDATABASESEARCH | - true: Disables the use of the database to perform | | searches. If another search engine isn't configured, | | setting this value to true will result in empty search | | results. | | - false: (Default) Database search isn't disabled. | |config.json setting: FileSettings > MobileEnableSecureFilePreview > false | Allow file downloads on mobile | - Environment variable: MM_FILESETTINGS_MOBILEENABLESECUREFILEPREVIEW configuration setting is enabled. Allows in-app previews for PDFs, | | videos, and images only. Files are stored temporarily in the app's cache and cannot be exported or shared. | |config.json setting: FileSettings > MobileEnableSecureFilePreview > false | Allow file downloads on mobile | - Environment variable: MM_FILESETTINGS_MOBILEENABLESECUREFILEPREVIEW configuration setting is enabled. Allows in-app previews for PDFs, | | videos, and images only. Files are stored temporarily in the app's cache and cannot be exported or shared. | |Enables the ability to specify an alternate filestore target for Mattermost bulk exports and compliance exports.
ExportFileBackend() is generated under FileSettings using new configuration values for the following configuration settings:ExportDriverNameExportDirectoryExportAmazonS3AccessKeyIdExportAmazonS3SecretAccessKeyExportAmazonS3BucketExportAmazonS3PathPrefixExportAmazonS3RegionExportAmazonS3EndpointExportAmazonS3SSLExportAmazonS3SignV2ExportAmazonS3SSEExportAmazonS3TraceExportAmazonS3RequestTimeoutMillisecondsExportAmazonS3PresignExpiresSecondsExportAzureStorageAccountExportAzureAuthModeExportAzureAccessKeyExportAzureContainerExportAzurePathPrefixExportAzureCloudExportAzureEndpointExportAzureSSLExportAzureRequestTimeoutMillisecondsExportAzurePresignExpiresSecondsEnables the ability to specify an alternate filestore target for Mattermost bulk exports and compliance exports.
ExportFileBackend() is generated under FileSettings using new configuration values for the following configuration settings:ExportDriverNameExportDirectoryExportAmazonS3AccessKeyIdExportAmazonS3SecretAccessKeyExportAmazonS3BucketExportAmazonS3PathPrefixExportAmazonS3RegionExportAmazonS3EndpointExportAmazonS3SSLExportAmazonS3SignV2ExportAmazonS3SSEExportAmazonS3TraceExportAmazonS3RequestTimeoutMillisecondsExportAmazonS3PresignExpiresSecondsExportAzureStorageAccountExportAzureAuthModeExportAzureAccessKeyExportAzureContainerExportAzurePathPrefixExportAzureCloudExportAzureEndpointExportAzureSSLExportAzureRequestTimeoutMillisecondsExportAzurePresignExpiresSecondsconfig.json setting: FileSettings > DedicatedExportStoreMM_FILESETTINGS_DEDICATEDEXPORTSTOREYou're notified when updates are available.
See the Upgrade Mattermost product documentation for details on upgrading your workspace.
You're notified when updates are available.
See the Upgrade Mattermost product documentation for details on upgrading your workspace.
See the product documentation to learn more:
See the product documentation to learn more:
See the product documentation to learn more:
See the product documentation to learn more:
See the product documentation to learn more:
See the product documentation to learn more:
config.json setting: TeamSettings > CustomBrandText as in Mattermost messages. | - Environment variable: MM_TEAMSETTINGS_CUSTOMBRANDTEXT | | | String input. Maximum 500 characters. Enable custom branding | | must be set to true to display the text. | |config.json setting: TeamSettings > CustomBrandText as in Mattermost messages. | - Environment variable: MM_TEAMSETTINGS_CUSTOMBRANDTEXT | | | String input. Maximum 500 characters. Enable custom branding | | must be set to true to display the text. | |5.10.0). Users connecting with a Desktop App version below this minimum are shown | - config.json setting: ServiceSettings > MinimumDesktopAppVersion | an update required screen and cannot use the application until they update. | - Environment variable: MM_SERVICESETTINGS_MINIMUMDESKTOPAPPVERSION | | | The update screen includes a download link configured via the | | Mattermost apps download page link setting. | | | Must be a valid semantic version (e.g., 5.0.0). Leave blank to allow all Desktop App | | versions to connect. | | | | String input. Default is empty (no minimum enforced). | |5.10.0). Users connecting with a Desktop App version below this minimum are shown | - config.json setting: ServiceSettings > MinimumDesktopAppVersion | an update required screen and cannot use the application until they update. | - Environment variable: MM_SERVICESETTINGS_MINIMUMDESKTOPAPPVERSION | | | The update screen includes a download link configured via the | | Mattermost apps download page link setting. | | | Must be a valid semantic version (e.g., 5.0.0). Leave blank to allow all Desktop App | | versions to connect. | | | | String input. Default is empty (no minimum enforced). | |config.json setting: TeamSettings > MaxUsersPerTeam > 50 | | - Environment variable: MM_TEAMSETTINGS_MAXUSERSPERTEAM | In Mattermost, a team of people should be a small organization with a | | specific goal. In the physical world, a team could sit around a single | | table. The default maximum (50) should be enough for most teams, but | | with appropriate hardware, this limit can be increased to | | thousands of users. | | | | Channels | are another way of organizing communications within teams on various topics. | | | | Numerical input. Default is 50 self-hosted deployments, and 10000 | | for Cloud deployments. | |config.json setting: TeamSettings > MaxUsersPerTeam > 50 | | - Environment variable: MM_TEAMSETTINGS_MAXUSERSPERTEAM | In Mattermost, a team of people should be a small organization with a | | specific goal. In the physical world, a team could sit around a single | | table. The default maximum (50) should be enough for most teams, but | | with appropriate hardware, this limit can be increased to | | thousands of users. | | | | Channels | are another way of organizing communications within teams on various topics. | | | | Numerical input. Default is 50 self-hosted deployments, and 10000 | | for Cloud deployments. | |This setting determines how names appear in posts and under the Direct Messages list. Users can change this setting in their interface under Settings > Display > Teammate Name Display, unless this setting is locked by a system admin via the Lock teammate name display for all users configuration setting.
config.json option: "username".config.json option: "nickname_full_name".config.json option: "full_name".This setting determines how names appear in posts and under the Direct Messages list. Users can change this setting in their interface under Settings > Display > Teammate Name Display, unless this setting is locked by a system admin via the Lock teammate name display for all users configuration setting.
config.json option: "username".config.json option: "nickname_full_name".config.json option: "full_name".config.json setting: TeamSettings > TeammateNameDisplay > usernameMM_TEAMSETTINGS_TEAMMATENAMEDISPLAYThis setting controls whether users who sign in with email and password can change their own profile fields under Settings > Profile. System admins are always exempt and can edit any user's profile through the System Console or the API. Users authenticating through an external provider (AD/LDAP, SAML, or OAuth) aren't affected; their fields remain governed by the provider's attribute settings.
config.json option: "none".config.json option: "name_and_username".config.json option: "all".Empty first and last names can be filled in once by the user, so people who join through a team invite link or open server signup aren't left without a name. Once set, the name is locked.
When this setting is enabled, anyone with the Invite Users permission can pre-set the first name, last name, and username for each email invitation they send. The invited person sees the pre-set username on the account creation page and cannot change it. We recommend restricting the Invite Users permission through advanced permissions to people trusted to enter this information correctly.
For a display name convention of "First Last" across the workspace, combine this setting with Teammate Name Display set to Show first and last name and Lock Teammate Name Display set to true.
This setting controls whether users who sign in with email and password can change their own profile fields under Settings > Profile. System admins are always exempt and can edit any user's profile through the System Console or the API. Users authenticating through an external provider (AD/LDAP, SAML, or OAuth) aren't affected; their fields remain governed by the provider's attribute settings.
config.json option: "none".config.json option: "name_and_username".config.json option: "all".Empty first and last names can be filled in once by the user, so people who join through a team invite link or open server signup aren't left without a name. Once set, the name is locked.
When this setting is enabled, anyone with the Invite Users permission can pre-set the first name, last name, and username for each email invitation they send. The invited person sees the pre-set username on the account creation page and cannot change it. We recommend restricting the Invite Users permission through advanced permissions to people trusted to enter this information correctly.
For a display name convention of "First Last" across the workspace, combine this setting with Teammate Name Display set to Show first and last name and Lock Teammate Name Display set to true.
config.json setting: TeamSettings > LockProfileFieldsForEmailUsers > noneMM_TEAMSETTINGS_LOCKPROFILEFIELDSFOREMAILUSERSconfig.json setting: ServiceSettings > CollapsedThreadson the server and for all users. This is the recommended configuration for optimal user experience | - Environment variable: MM_SERVICESETTINGS_COLLAPSEDTHREADS | and to ensure consistency in how users read and respond to threaded conversations. | | config.json setting: "always_on" | |
config.json setting: "disabled" | |config.json setting: ServiceSettings > CollapsedThreadson the server and for all users. This is the recommended configuration for optimal user experience | - Environment variable: MM_SERVICESETTINGS_COLLAPSEDTHREADS | and to ensure consistency in how users read and respond to threaded conversations. | | config.json setting: "always_on" | |
config.json setting: "disabled" | |config.json setting: ServiceSettings > EnablePermalinkPreviews > true |MM_SERVICESETTINGS_ENABLEPERMALINKPREVIEWS |config.json setting: ServiceSettings > EnablePermalinkPreviews > true |MM_SERVICESETTINGS_ENABLEPERMALINKPREVIEWS |config.json setting: ServiceSettings > EnableLatex > false|MM_SERVICESETTINGS_ENABLELATEX |config.json setting: ServiceSettings > EnableLatex > false|MM_SERVICESETTINGS_ENABLELATEX |config.json setting: ServiceSettings > EnableInlineLatex > falseMM_SERVICESETTINGS_ENABLEINLINELATEX | LaTeX can also be rendered in a code block, if that feature is enabled. See Enable LaTeX code block rendering. | |config.json setting: ServiceSettings > EnableInlineLatex > falseMM_SERVICESETTINGS_ENABLEINLINELATEX | LaTeX can also be rendered in a code block, if that feature is enabled. See Enable LaTeX code block rendering. | |config.json setting: FileSettings > MobileEnableSecureFilePreview > false | Allow file downloads on mobile | - Environment variable: MM_FILESETTINGS_MOBILEENABLESECUREFILEPREVIEW configuration setting is enabled. Allows in-app previews for PDFs, | | videos, and images only. Files are stored temporarily in the app's cache and cannot be exported or shared. | |config.json setting: FileSettings > MobileEnableSecureFilePreview > false | Allow file downloads on mobile | - Environment variable: MM_FILESETTINGS_MOBILEENABLESECUREFILEPREVIEW configuration setting is enabled. Allows in-app previews for PDFs, | | videos, and images only. Files are stored temporarily in the app's cache and cannot be exported or shared. | |config.json setting: FileSettings > EnablePublicLink > false |MM_FILESETTINGS_ENABLEPUBLICLINK |config.json setting: FileSettings > EnablePublicLink > false |MM_FILESETTINGS_ENABLEPUBLICLINK |config.json setting: AnnouncementSettings > AdminNoticesEnabled > true |MM_ANNOUNCEMENTSETTINGS_ADMINNOTICESENABLED |config.json setting: AnnouncementSettings > AdminNoticesEnabled > true |MM_ANNOUNCEMENTSETTINGS_ADMINNOTICESENABLED |config.json setting: AnnouncementSettings > UserNoticesEnabled > true |MM_ANNOUNCEMENTSETTINGS_USERNOTICESENABLED |config.json setting: AnnouncementSettings > UserNoticesEnabled > true |MM_ANNOUNCEMENTSETTINGS_USERNOTICESENABLED |role_updated WebSocket events are scoped to the affected team/channel instead of broadcasting globally, improving performance and reducing unnecessary network traffic. No manual action is required from administrators as the migration runs automatically during the upgrade. No downtime is expected, and no special planning is needed for the upgrade as the migration can run during normal operations. All installations are affected by this change, but the impact is minimal since the roles table is small with well under 10k rows even on large installations. The upgrade includes automatic database migrations to add a schemeid column to the roles table for efficient role-scheme lookups. The migrations use PostgreSQL's non-blocking techniques: first adding the column with a brief ACCESS EXCLUSIVE lock (catalog-only operation), then backfilling existing data with a ROW EXCLUSIVE lock, and finally creating an index concurrently with a SHARE UPDATE EXCLUSIVE lock that doesn't block other operations. The roles table size is bounded and unaffected by posts, reactions, or other high-volume data. The migrations are fully backwards-compatible.
v11.7.6 migration removes orphaned rows from the threadmemberships table — specifically, rows where the associated user is no longer a member of the channel that the thread belongs to. The cleanup is performed via a filtered DELETE using a three-way join across threadmemberships, threads, and channelmembers. No schema objects (tables, columns, or indexes) are added or removed; only data rows are affected. Note for large instances: this migration issues a single unbatched delete that scans the entirety of threadmemberships with a join against threads and channelmembers. On databases with tens of millions of rows or significant historical channel-membership churn, this query may run for an extended period, block autovacuum on threadmemberships, increase WAL pressure, and contribute to replication lag. Administrators of large deployments should test execution time on a representative dataset before upgrading and consider scheduling the upgrade during a low-traffic window. The down migration contains no rollback SQL because the deleted rows cannot be recovered; this migration is irreversible. The migrations are fully backwards-compatible and no database downtime is expected for this upgrade. The SQL queries included are:
-- Drop ThreadMembership rows whose user is no longer a member of the thread's channel.
@@ -683,7 +685,7 @@ DELETE FROM threadmemberships WHERE (postid, userid) IN (
System Console statistics now perform faster on PostgreSQL. The MaxUsersForStatistics configuration setting now only disables the User counts with posts chart, while all other stats remain unaffected. The other stats remain unaffected because that configuration value is no longer needed to disable the other queries since they are always fast now. Post and file counts update daily, so they may not always reflect real-time data. Advanced stats, such as line charts and plugin data, are now hidden until clicked, reducing load time. No performance improvements apply to MySQL since it's scheduled for full deprecation in v11. We recommend migrating to PostgreSQL for better performance and long-term support. Migration times: On a system with 12M posts, and 1M fileinfo entries, the migration takes 15s, but could take several minutes depending on the server's table sizes and database specs. This migration is non-locking. Note that there is no migration for MySQL deployments because this optimization is only applicable for PostgreSQL. Below are the SQL queries included in the schema changes:
CREATE MATERIALIZED VIEW IF NOT EXISTS posts_by_team_day asSELECT to_timestamp(p.createat/1000)::date as day, COUNT(*) as num, teamidFROM posts p JOIN channels c on p.channelid=c.idGROUP BY day, c.teamid;CREATE MATERIALIZED VIEW IF NOT EXISTS bot_posts_by_team_day asSELECT to_timestamp(p.createat/1000)::date as day, COUNT(*) as num, teamidFROM posts pJOIN Bots b ON p.UserId = b.UseridJOIN channels c on p.channelid=c.idGROUP BY day, c.teamid;CREATE MATERIALIZED VIEW IF NOT EXISTS file_stats asSELECT COUNT(*) as num, COALESCE(SUM(Size), 0) as usageFROM fileinfoWHERE DeleteAt = 0;As part of the Property System Architecture feature, Mattermost v10.5 is going to run a set of migrations to add new tables to the schema. This migration only creates new tables and indexes, so there is no impact on preexisting data.
New tables PropertyGroups, PropertyFields and PropertyValues are going to be created.
In the case of PostgreSQL, a new enum type property_field_type is going to be created, to be used in the Type column of the PropertyFields table.
The PropertyFields and PropertyValues tables have a unique constraint that will generate an index in MySQL, and in the case of PostgreSQL, they directly use a UNIQUE INDEX to enforce this constraint.
A new index idx_propertyvalues_targetid_groupid will be created for the PropertyValues table.
The migration is only creating new tables with no data. The migration is backwards-compatible, and a previous version of Mattermost can run with the new schema changes. No table locks or existing operations on the table are impacted by this upgrade. Zero downtime is possible when upgrading to this release.
Below are the SQL queries included in the schema changes:
MySQL:
CREATE TABLE IF NOT EXISTS PropertyGroups ( ID varchar(26) PRIMARY KEY, Name varchar(64) NOT NULL, UNIQUE(Name));CREATE TABLE IF NOT EXISTS PropertyFields ( ID varchar(26) PRIMARY KEY, GroupID varchar(26) NOT NULL, Name varchar(255) NOT NULL, Type enum('text', 'select', 'multiselect', 'date', 'user', 'multiuser'), Attrs json, TargetID varchar(255), TargetType varchar(255), CreateAt bigint(20), UpdateAt bigint(20), DeleteAt bigint(20), UNIQUE(GroupID, TargetID, Name, DeleteAt));CREATE TABLE IF NOT EXISTS PropertyValues ( ID varchar(26) PRIMARY KEY, TargetID varchar(255) NOT NULL, TargetType varchar(255) NOT NULL, GroupID varchar(26) NOT NULL, FieldID varchar(26) NOT NULL, Value json, CreateAt bigint(20), UpdateAt bigint(20), DeleteAt bigint(20), UNIQUE(GroupID, TargetID, FieldID, DeleteAt));SET @preparedStatement = (SELECT IF( ( SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS WHERE table_name = 'PropertyValues' AND table_schema = DATABASE() AND index_name = 'idx_propertyvalues_targetid_groupid' ) > 0, 'SELECT 1', 'CREATE INDEX idx_propertyvalues_targetid_groupid ON PropertyValues (TargetID, GroupID);'));PREPARE createIndexIfNotExists FROM @preparedStatement;EXECUTE createIndexIfNotExists;DEALLOCATE PREPARE createIndexIfNotExists;PostgreSQL:
CREATE TABLE IF NOT EXISTS PropertyGroups ( ID varchar(26) PRIMARY KEY, Name varchar(64) NOT NULL, UNIQUE(Name));DOBEGIN IF NOT EXISTS (SELECT * FROM pg_type typ INNER JOIN pg_namespace nsp ON nsp.oid = typ.typnamespace WHERE nsp.nspname = current_schema() AND typ.typname = 'property_field_type') THEN CREATE TYPE property_field_type AS ENUM ( 'text', 'select', 'multiselect', 'date', 'user', 'multiuser' ); END IF;END;LANGUAGE plpgsql;CREATE TABLE IF NOT EXISTS PropertyFields ( ID varchar(26) PRIMARY KEY, GroupID varchar(26) NOT NULL, Name varchar(255) NOT NULL, Type property_field_type, Attrs jsonb, TargetID varchar(255), TargetType varchar(255), CreateAt bigint NOT NULL, UpdateAt bigint NOT NULL, DeleteAt bigint NOT NULL);CREATE UNIQUE INDEX IF NOT EXISTS idx_propertyfields_unique ON PropertyFields (GroupID, TargetID, Name) WHERE DeleteAt = 0;CREATE TABLE IF NOT EXISTS PropertyValues ( ID varchar(26) PRIMARY KEY, TargetID varchar(255) NOT NULL, TargetType varchar(255) NOT NULL, GroupID varchar(26) NOT NULL, FieldID varchar(26) NOT NULL, Value jsonb NOT NULL, CreateAt bigint NOT NULL, UpdateAt bigint NOT NULL, DeleteAt bigint NOT NULL);CREATE UNIQUE INDEX IF NOT EXISTS idx_propertyvalues_unique ON PropertyValues (GroupID, TargetID, FieldID) WHERE DeleteAt = 0;CREATE INDEX IF NOT EXISTS idx_propertyvalues_targetid_groupid ON PropertyValues (TargetID, GroupID); ``ElasticsearchSettings.Backend has been | added to differentiate between Elasticsearch and OpenSearch. The default value is elasticsearch which breaks support for AWS Elasticsearch v7.10.x | since the official v8 client only works from Elasticsearch v7.11+ versions. | | .. note:: | | - For AWS customers on OpenSearch, you must modify Mattermost configuration from elasticsearch to opensearch and disable compatibility mode. | See the OpenSearch documentation for details on upgrading. | - After upgrading the Mattermost server, use mmctl or edit the config manually, | then restart the Mattermost server. | - If you are using OpenSearch, you must set the backend to opensearch. Otherwise Mattermost will not work. | | If you are using Elasticsearch v8, be sure to set action.destructive_requires_name to false in elasticsearch.yml to allow for wildcard operations to | work. |ElasticsearchSettings.Backend has been | added to differentiate between Elasticsearch and OpenSearch. The default value is elasticsearch which breaks support for AWS Elasticsearch v7.10.x | since the official v8 client only works from Elasticsearch v7.11+ versions. | | .. note:: | | - For AWS customers on OpenSearch, you must modify Mattermost configuration from elasticsearch to opensearch and disable compatibility mode. | See the OpenSearch documentation for details on upgrading. | - After upgrading the Mattermost server, use mmctl or edit the config manually, | then restart the Mattermost server. | - If you are using OpenSearch, you must set the backend to opensearch. Otherwise Mattermost will not work. | | If you are using Elasticsearch v8, be sure to set action.destructive_requires_name to false in elasticsearch.yml to allow for wildcard operations to | work. |model.CommandArgs.Session.ServiceSettings.AllowCorsFrom | configuration setting. Also ensure that | the siteURL is set correctly. |ServiceSettings.AllowCorsFrom | configuration setting. Also ensure that | the siteURL is set correctly. |mattermost-server, mattermost-webapp and mmctl. Developers should read the updated Developer Guide for details.ServiceSettings.AllowCorsFrom | configuration setting. Also ensure that | the siteURL is set correctly. |ServiceSettings.AllowCorsFrom | configuration setting. Also ensure that | the siteURL is set correctly. |In v7.9.4, backported a fix related Oauth 2. Query times depend on if you have rows to delete or not.
With no rows to delete:
4 rows:
Those times are based off the following table sizes:
oauthaccessdata and sessions: 10 recordsYou can assess the number of impacted rows by running the following:
PostgreSQL:
SELECT count(o.*)FROM oauthaccessdata o WHERE NOT EXISTS ( SELECT p.* FROM preferences p WHERE o.clientid = p.name AND o.userid = p. userid AND p.category = 'oauth_app' );MySQL:
SELECT COUNT(o.`Token`)FROM OAuthAccessData oLEFT JOIN Preferences p ON o. clientid = p.name AND o.userid = p.userid AND p.category = 'oauth_app'INNER JOIN Sessions s ON o.token = s .tokenWHERE p.name IS NULL;Locks on the oauthaccessdata and sessions table will only be acquired if there are rows to delete.
ServiceSettings.AllowCorsFrom | configuration setting. Also ensure that | the siteURL is set correctly. |ServiceSettings.AllowCorsFrom | configuration setting. Also ensure that | the siteURL is set correctly. |PostPriority setting. |PostPriority setting. |In v7.8.5, backported a fix related Oauth 2. Query times depend on if you have rows to delete or not.
With no rows to delete:
4 rows:
Those times are based off the following table sizes:
oauthaccessdata and sessions: 10 recordsYou can assess the number of impacted rows by running the following:
PostgreSQL:
SELECT count(o.*) FROM oauthaccessdata o WHERE NOT EXISTS ( SELECT p.* FROM preferences p WHERE o.clientid = p.name AND o.userid = p. userid AND p.category = 'oauth_app' );MySQL:
SELECT COUNT(o.`Token`)FROM OAuthAccessData oLEFT JOIN Preferences p ON o. clientid = p.name AND o.userid = p.userid AND p.category = 'oauth_app'INNER JOIN Sessions s ON o.token = s .tokenWHERE p.name IS NULL;Locks on the oauthaccessdata and sessions table will only be acquired if there are rows to delete.
ServiceSettings.AllowCorsFrom | configuration setting. Also ensure that | the siteURL is set correctly. |ServiceSettings.AllowCorsFrom | configuration setting. Also ensure that | the siteURL is set correctly. |In v7.8.11, improved performance on data retention DeleteOrphanedRows queries.
New migration for a new table:
MySQL:
CREATE TABLEIF NOT EXISTS RetentionIdsForDeletion(Id VARCHAR(26) NOT NULL, TableName VARCHAR(64), Ids json, PRIMARY KEY (Id ), KEY idx_retentionidsfordeletion_tablename (TableName)) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4; ``PostgreSQL:
CREATE TABLEIF NOT EXISTS retentionidsfordeletion(id VARCHAR(26) PRIMARY KEY, tablename VARCHAR(64), ids VARCHAR(26) []); CREATE INDEXIF NOT EXISTS idx_retentionidsfordeletion_tablename ON retentionidsfordeletion( tablename); ``Hard deleting a user or a channel will now also clean up associated reactions.
Removed feature flag DataRetentionConcurrencyEnabled. Data retention now runs without concurrency in order to avoid any performance degradation.
Added a new configuration setting DataRetentionSettings.RetentionIdsBatchSize, which allows admins to configure how many batches of IDs will be fetched at a time when deleting orphaned reactions. The default value is 100.
PostPriority | setting. |PostPriority | setting. |false for self-hosted deployments.ServiceSettings.TrustedProxyIPHeader defaults to empty from now on. A previous bug prevented this from happening in certain conditions. | Customers are requested to check for these values in their config and set them to nil if necessary. See more details | here. |ServiceSettings.TrustedProxyIPHeader defaults to empty from now on. A previous bug prevented this from happening in certain conditions. | Customers are requested to check for these values in their config and set them to nil if necessary. See more details | here. |New schema changes were introduced in the form of a new index. The following summarizes the test results measuring how long it took for the database queries to run with these schema changes:
MySQL 7M Posts - ~17s (Instance: db.r5.xlarge)
MySQL 9M Posts - 2min 12s (Instance: db.r5.large)
Postgres 7M Posts - ~9s (Instance: db.r5.xlarge)
For customers wanting a zero downtime upgrade, they are encouraged to apply this index prior to doing the upgrade. This is fully backwards compatible and will not acquire any table lock or affect any existing operations on the table when run manually. Else, the queries will run during the upgrade process and will lock the table in non-MySQL environments. Run the following to apply this index:
For MySQL: CREATE INDEX idx_posts_create_at_id on Posts(CreateAt, Id) LOCK=NONE;
For Postgres: CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_posts_create_at_id on posts(createat, id);
ServiceSettings.TrustedProxyIPHeader defaults to empty from now on. A previous bug prevented this from happening in certain | conditions. Customers are requested to check for these values in their config and set them to nil if necessary. See more details | here. |ServiceSettings.TrustedProxyIPHeader defaults to empty from now on. A previous bug prevented this from happening in certain | conditions. Customers are requested to check for these values in their config and set them to nil if necessary. See more details | here. |call into separate submit, form, refresh and lookup calls. If any users have created their own Apps, they have to be updated to the new system.ServiceSettings.TrustedProxyIPHeader defaults to empty from now on. A previous bug prevented this from happening in certain | conditions. Customers are requested to check for these values in their config and set them to nil if necessary. See more details | here. |ServiceSettings.TrustedProxyIPHeader defaults to empty from now on. A previous bug prevented this from happening in certain | conditions. Customers are requested to check for these values in their config and set them to nil if necessary. See more details | here. |mattermost version CLI command does not interact with the database anymore. Therefore the database version is not going to be | printed. Also, the database migrations are not going to be applied with the version sub command. | A new db migrate sub command is added to enable administrators | to trigger migrations. |mattermost version CLI command does not interact with the database anymore. Therefore the database version is not going to be | printed. Also, the database migrations are not going to be applied with the version sub command. | A new db migrate sub command is added to enable administrators | to trigger migrations. |ServiceSettings.TrustedProxyIPHeader defaults to empty from now on. A previous bug prevented this from happening in certain | conditions. Customers are requested to check for these values in their config and set them to nil if necessary. See more details | here. |ServiceSettings.TrustedProxyIPHeader defaults to empty from now on. A previous bug prevented this from happening in certain | conditions. Customers are requested to check for these values in their config and set them to nil if necessary. See more details | here. |ThreadAutoFollow has been changed to false. This does not affect existing configurations where this value is already set to true.ServiceSettings.TrustedProxyIPHeader defaults to empty from now on. A previous bug prevented this from happening in certain | conditions. Customers are requested to check for these values in their config and set them to nil if necessary. See more details | here. |ServiceSettings.TrustedProxyIPHeader defaults to empty from now on. A previous bug prevented this from happening in certain | conditions. Customers are requested to check for these values in their config and set them to nil if necessary. See more details | here. |ThreadAutoFollow has been changed to false. This does not affect existing configurations where this value is already set to true.While trying to upgrade to a Mattermost version >= 6.0.x, you might encounter the following error: Failed to alter column type. It is likely you have invalid JSON values in the column. Please fix the values manually and run the migration again.
This means that the particular column has some invalid JSON values which need to be fixed manually. A common fix that is known to work is to wipe out all \u0000 characters.
Please follow these steps:
SELECT COUNT(*) FROM <table> WHERE <column> LIKE '%\u0000%';UPDATE <table> SET <column> = regexp_replace(<column>, '\\u0000', '', 'g') where <column> like '%\u0000%';Then try to start Mattermost again.
Some breaking changes to plugins are included:
platform binary and “--platform” flag have been removed. If you are using the “--platform” flag or are using the platform binary directly to run the Mattermost server application via a systemd file or custom script, you will be required to use only the mattermost binary.ThreadAutoFollow has been added to support Collapsed Reply Threads releasing in beta in Q1 2021. | This setting is enabled by default and may affect server performance. It is recommended to review our documentation on hardware requirements | to ensure your servers are appropriately scaled for the size of your user base. |ThreadAutoFollow has been added to support Collapsed Reply Threads releasing in beta in Q1 2021. | This setting is enabled by default and may affect server performance. It is recommended to review our documentation on hardware requirements | to ensure your servers are appropriately scaled for the size of your user base. |Now when the service crashes, it will generate a coredump instead of just dumping the stack trace to the console. This allows us to preserve the full information of the crash to help with debugging it.
For more information about coredumps, please see: https://man7.org/linux/man-pages/man5/core.5.html.
http://. Organizations using non-secure Mattermost Servers http:// will need to update to Mattermost Server versions 5.16.0+, 5.15.1, 5.14.4 or 5.9.5 (ESR) to continue receiving desktop notifications when using Mattermost Desktop v4.3.0 or later.GoogleSettings.Scope config.json setting is set to profile email and | UserAPIEndpoint setting should be set to https://people.googleapis.com/v1/people/me?personFields=names,emailAddresses,nicknames,metadata per | updated documentation. |GoogleSettings.Scope config.json setting is set to profile email and | UserAPIEndpoint setting should be set to https://people.googleapis.com/v1/people/me?personFields=names,emailAddresses,nicknames,metadata per | updated documentation. |SupportedTimezonesPath setting in config.json and changes to timezones in the UI based on the timezones.json file was removed. This was made to support | storing configurations in the database. |SupportedTimezonesPath setting in config.json and changes to timezones in the UI based on the timezones.json file was removed. This was made to support | storing configurations in the database. |DisableLegacyMfa setting in config.json is set to true and | multi-factor authentication is enabled, ensure your users have upgraded to mobile app | version 1.17 or later. Otherwise, users who have MFA enabled may not be able to log in successfully. | | If the setting is not defined in the config.json file, the DisableLegacyMfa setting is set to false by default to ensure no breaking changes. | | We recommend setting DisableLegacyMfa to true for additional security hardening. |DisableLegacyMfa setting in config.json is set to true and | multi-factor authentication is enabled, ensure your users have upgraded to mobile app | version 1.17 or later. Otherwise, users who have MFA enabled may not be able to log in successfully. | | If the setting is not defined in the config.json file, the DisableLegacyMfa setting is set to false by default to ensure no breaking changes. | | We recommend setting DisableLegacyMfa to true for additional security hardening. |AllowUntrustedInternalConnections setting. | See documentation for more details if you have trouble loading images. |AllowUntrustedInternalConnections setting. | See documentation for more details if you have trouble loading images. |This release includes support for post messages longer than the default of 4000 characters, but may require a manual database migration. This migration is entirely optional, and need only be done if you want to enable post messages up to 16383 characters. For many installations, no migration will be required, or the old limit remains sufficient.
To check your current post limit after upgrading to 5.0.0, look for a log message on startup:
[2018/03/27 09:08:00 EDT] [INFO] Post.Message supports at most 16383 characters (65535 bytes)
As of 5.0.0, the maximum post message size is 16383 (multi-byte) characters. If your logs show a number less than this limit and you want to enable longer post messages, you will need to manually migrate your database as described below. This migration can be slow for larger Posts tables, so it's best to schedule this upgrade during off-peak hours.
To migrate a MySQL database, connect to your database and run the following:
ALTER TABLE Posts MODIFY COLUMN Message TEXT;
To migrate a PostgreSQL database, connect to your database and run the following:
ALTER TABLE Posts ALTER COLUMN Message TYPE VARCHAR(65535);
Restart your Mattermost instances.
RunJobs in the config.json and allow the permissions migration to complete before using Team | Override Schemes. |RunJobs in the config.json and allow the permissions migration to complete before using Team | Override Schemes. |config.json setting PostEditTimeLimit has been updated to accommodate the migration to a roles based permission system. When post editing is permitted, set "PostEditTimeLimit": -1 to allow editing anytime, or set "PostEditTimeLimit" to a positive integer to restrict editing time in seconds. If post editing is disabled, this setting does not apply.config.json setting is set to true.If forwarding port 80 to 443, the server will fail to start with an error message unless the ListenAddress | config.json setting is set to listen on port 443. |
config.json setting is set to true.If forwarding port 80 to 443, the server will fail to start with an error message unless the ListenAddress | config.json setting is set to listen on port 443. |
config.json setting set to true to complete the Let's Encrypt certification. |config.json setting set to true to complete the Let's Encrypt certification. |application/json content-type to retain previous behavior./data/<date-of-upload-as-YYYYMMDD>/teams/... of your file storage system.You need to verify settings in the System Console due to a security-related change.
rtcd servicertcd service to discover their instance public IP. Only needed if configuring STUN/TURN servers. This requirement does not apply when manually setting an IP or hostname through the ICE Host Override config option.rtcd service to discover their instance public IP. Only needed if configuring STUN/TURN servers. This requirement does not apply when manually setting an IP or hostname through the ICE Host Override config option.Icon badge (dot)
})
Icon badge (number)
})
If your system admin has enabled multi-factor authentication (MFA), you can require a passcode in addition to your password to log-in to your Mattermost account.
You'll need to download a MFA passcode generation app, such as Google Authenticator or a similar app, and then set-up MFA in your Mattermost account.
Download a passcode generation app
Enable MFA in Mattermost
})
})
If your system admin has enabled multi-factor authentication (MFA), you can require a passcode in addition to your password to log-in to your Mattermost account.
You'll need to download a MFA passcode generation app, such as Google Authenticator or a similar app, and then set-up MFA in your Mattermost account.
Download a passcode generation app
Enable MFA in Mattermost
})
})
This option allows you to switch your login method between using email/username and password and single sign-on credentials.
You can configure this setting using Mattermost in a web browser or using the desktop app.
While you can choose to log in with either set of credentials, you can only enable one login method at a time. For example, if AD/LDAP single sign-on is enabled, you can select Switch to using AD/LDAP, and enter your AD/LDAP credentials to switch login over to AD/LDAP. You'll need to enter the password for your email account to verify your existing credentials. Following the change, you'll receive an email to confirm the action.
This option allows you to switch your login method between using email/username and password and single sign-on credentials.
You can configure this setting using Mattermost in a web browser or using the desktop app.
While you can choose to log in with either set of credentials, you can only enable one login method at a time. For example, if AD/LDAP single sign-on is enabled, you can select Switch to using AD/LDAP, and enter your AD/LDAP credentials to switch login over to AD/LDAP. You'll need to enter the password for your email account to verify your existing credentials. Following the change, you'll receive an email to confirm the action.
textprops.mm_blocks is not set)@<username>, @channel, and @here for notifications.@<username>, @channel, and @here for notifications.channelusernameicon_urlicon_emojiicon_url with an emoji. Use the emoji name (e.g., :tada:). The Enable integrations to override profile picture icons setting must be enabled.icon_url with an emoji. Use the emoji name (e.g., :tada:). The Enable integrations to override profile picture icons setting must be enabled.typetextattachments or props.mm_blocks is set) Markdown-formatted message.attachments or props.mm_blocks is set) Markdown-formatted message.response_typeusernameicon_urlattachmentsGroups in the database are retained but cannot be used. Memberships are frozen in state for group synced teams/channels.
Mentions for AD/LDAP groups are not shown in the autocomplete menu.
Group mentions are no longer highlighted in text and do not trigger new notifications.