diff --git a/docs/develop/contribute/more-info/server/plugins.md b/docs/develop/contribute/more-info/server/plugins.md index e8c2d1d16326..91837a801c0c 100644 --- a/docs/develop/contribute/more-info/server/plugins.md +++ b/docs/develop/contribute/more-info/server/plugins.md @@ -17,9 +17,9 @@ Plugins are generally made of at least two parts: a manifest and a server binary The manifest tells Mattermost what the plugin is and provides a set of metadata used by the server to install and run the plugin. Please see the [manifest reference](/developers/integrate/plugins/manifest-reference) for more information. Manifests may be defined in JSON or YAML. -The server binary is a compiled Go program that extends the [MattermostPlugin](https://godoc.org/github.com/mattermost/mattermost/server/public/plugin#MattermostPlugin) struct of the [plugin](https://godoc.org/github.com/mattermost/mattermost/server/public/plugin) package. When enabled, the plugin's server binary is started as a process by the Mattermost server. Plugin developers then have access to interact with the Mattermost server over RPC through the plugin [API](/developers/integrate/reference/server/server-reference#API) and [Hooks](/developers/integrate/reference/server/server-reference#Hooks). The server-side of plugins is built using the [go-plugin](https://github.com/hashicorp/go-plugin) library from Hashicorp. More information is available in the [server side of the plugin author documentation](/developers/integrate/plugins/components/server). +The server binary is a compiled Go program that extends the [MattermostPlugin](https://godoc.org/github.com/mattermost/mattermost/server/public/plugin#MattermostPlugin) struct of the [plugin](https://godoc.org/github.com/mattermost/mattermost/server/public/plugin) package. When enabled, the plugin's server binary is started as a process by the Mattermost server. Plugin developers then have access to interact with the Mattermost server over RPC through the plugin [API](/developers/integrate/reference/server#API) and [Hooks](/developers/integrate/reference/server#Hooks). The server-side of plugins is built using the [go-plugin](https://github.com/hashicorp/go-plugin) library from Hashicorp. More information is available in the [server side of the plugin author documentation](/developers/integrate/plugins/components/server). -The JavaScript bundle is a webpack-built collection of JavaScript code that will be run on the Mattermost web/desktop apps. When a plugin is enabled, the client is notified and it makes a request to add the JS bundle to the document. The plugin's client code then registers itself and its components with the Mattermost client through the client's [plugin registry](/developers/integrate/reference/webapp/webapp-reference#registry). The registry contains many methods for registering different components and callbacks. These are all stored as part of the app's [plugin reducer](https://github.com/mattermost/mattermost/blob/master/webapp/channels/src/reducers/plugins/index.ts). The [Pluggable](https://github.com/mattermost/mattermost/tree/master/webapp/channels/src/plugins/pluggable) component is then inserted into various places in the app, allowing plugins to insert components into these locations in the UI. In some special cases, the Pluggable component is not used and we instead implement the plugs manually. More information is available in the [webapp side of the plugin author documentation](/developers/integrate/plugins/components/webapp). +The JavaScript bundle is a webpack-built collection of JavaScript code that will be run on the Mattermost web/desktop apps. When a plugin is enabled, the client is notified and it makes a request to add the JS bundle to the document. The plugin's client code then registers itself and its components with the Mattermost client through the client's [plugin registry](/developers/integrate/reference/webapp#registry). The registry contains many methods for registering different components and callbacks. These are all stored as part of the app's [plugin reducer](https://github.com/mattermost/mattermost/blob/master/webapp/channels/src/reducers/plugins/index.ts). The [Pluggable](https://github.com/mattermost/mattermost/tree/master/webapp/channels/src/plugins/pluggable) component is then inserted into various places in the app, allowing plugins to insert components into these locations in the UI. In some special cases, the Pluggable component is not used and we instead implement the plugs manually. More information is available in the [webapp side of the plugin author documentation](/developers/integrate/plugins/components/webapp). All these different components of a plugin are compressed into a .tar.gz bundle. Installing a plugin is the process of uploading this bundle to the Mattermost server (via the UI, REST API or CLI). The server then unpacks the bundle, performs some validation and extracts it into the configured directory for storing installed plugins. Installed plugins are not yet running. To start a plugin it must be enabled (again via the UI, REST API or CLI). Once it is enabled, the server will then start the server process and prepare the web app bundle for serving to the client. Plugin settings, configuration and enabled/disabled status are managed by the Mattermost `config.json` using a [PluginSettings](https://godoc.org/github.com/mattermost/mattermost/server/public/model#PluginSettings) struct. diff --git a/docs/develop/integrate/getting-started/index.md b/docs/develop/integrate/getting-started/index.md index 62111f125dab..3c330b5e8768 100644 --- a/docs/develop/integrate/getting-started/index.md +++ b/docs/develop/integrate/getting-started/index.md @@ -24,7 +24,7 @@ Plugins are the most comprehensive way to add new features and customization, bu -See the [Mattermost Server SDK Reference](/developers/integrate/reference/server/server-reference) and [Mattermost Client UI SDK Reference](/developers/integrate/reference/webapp/webapp-reference) documentation for details on available server API endpoints and client methods. +See the [Mattermost Server SDK Reference](/developers/integrate/reference/server) and [Mattermost Client UI SDK Reference](/developers/integrate/reference/webapp) documentation for details on available server API endpoints and client methods. diff --git a/docs/develop/integrate/plugins/best-practices.md b/docs/develop/integrate/plugins/best-practices.md index f5c4842cd81e..6067cdf235a6 100644 --- a/docs/develop/integrate/plugins/best-practices.md +++ b/docs/develop/integrate/plugins/best-practices.md @@ -9,7 +9,7 @@ See here for [server-specific best practices for plugins](/developers/integrate/ Once a plugin is installed, Administrators have access to the plugin's configuration page in the __System Console > Plugins__ section. The configurable settings must first be defined in the plugin's manifest [setting schema](/developers/integrate/plugins/manifest-reference#settings_schema). The web app supports several basic pre-defined settings type, e.g. `bool` and `dropdown`, for which the corresponding UI components are provided in order to complete configuration in the System Console. -These settings are stored within the server configuration under [`Plugins`] indexed by plugin ids. The plugin's server code can access their current configuration calling the [`getConfig`](/developers/integrate/reference/server/server-reference#API.GetConfig) API call and can also make changes as needed with [`saveConfig`](/developers/integrate/reference/server/server-reference#API.SaveConfig). +These settings are stored within the server configuration under [`Plugins`] indexed by plugin ids. The plugin's server code can access their current configuration calling the [`getConfig`](/developers/integrate/reference/server#API.GetConfig) API call and can also make changes as needed with [`saveConfig`](/developers/integrate/reference/server#API.SaveConfig). ## How can a plugin define its own setting type? @@ -29,7 +29,7 @@ A plugin could define its own type of setting with a corresponding custom user i } ``` -2. In the plugin's web app code, define a custom component to manage the plugin's custom setting and register it in the web app with [`registerAdminConsoleCustomSetting`](/developers/integrate/reference/webapp/webapp-reference#registerAdminConsoleCustomSetting). This component will be instantiated in the System Console with the following `props` passed in: +2. In the plugin's web app code, define a custom component to manage the plugin's custom setting and register it in the web app with [`registerAdminConsoleCustomSetting`](/developers/integrate/reference/webapp#registerAdminConsoleCustomSetting). This component will be instantiated in the System Console with the following `props` passed in: - `id`: The setting `key` as defined in the plugin manifest within `settings_schema.settings`. - `label`: The text for the component label based on the setting's `displayName` defined in the manifest. @@ -132,7 +132,7 @@ Old servers won't do anything with new, unrecognized fields, but also won't brea ## How to expose performance metrics for a plugin? -From Mattermost v9.4, a [`ServeMetrics`](/developers/integrate/reference/server/server-reference#API.ServeMetrics) hook can be used to expose performance metrics in the [open metrics format](https://openmetrics.io/) under the common HTTP listener controlled by the [`MetricsSettings.ListenAddress`](https://docs.mattermost.com/configure/environment-configuration-settings.html#listen-address-for-performance) config setting. +From Mattermost v9.4, a [`ServeMetrics`](/developers/integrate/reference/server#API.ServeMetrics) hook can be used to expose performance metrics in the [open metrics format](https://openmetrics.io/) under the common HTTP listener controlled by the [`MetricsSettings.ListenAddress`](https://docs.mattermost.com/configure/environment-configuration-settings.html#listen-address-for-performance) config setting. Data returned by the hook's implementation through the given `http.ResponseWriter` object will be served through the `http://SITE_URL:8067/plugins/PLUGIN_ID/metrics` URL. diff --git a/docs/develop/integrate/plugins/components/server/best-practices.md b/docs/develop/integrate/plugins/components/server/best-practices.md index b367879d91e8..826f9ccde0eb 100644 --- a/docs/develop/integrate/plugins/components/server/best-practices.md +++ b/docs/develop/integrate/plugins/components/server/best-practices.md @@ -9,7 +9,7 @@ Add all static files under a file directory named `public` within the plugin dir ## How do plugins make sure http requests are authentic? -Plugins can implement the [`ServeHTTP`](/developers/integrate/reference/server/server-reference#Hooks.ServeHTTP) to listen to http requests. This can be used to receive post action requests when [Interactive Messages Buttons and Menus](https://docs.mattermost.com/developer/interactive-messages.html) are triggered by users. +Plugins can implement the [`ServeHTTP`](/developers/integrate/reference/server#Hooks.ServeHTTP) to listen to http requests. This can be used to receive post action requests when [Interactive Messages Buttons and Menus](https://docs.mattermost.com/developer/interactive-messages.html) are triggered by users. When plugins act as an HTTP server, they serve requests from Mattermost clients (which are authenticated in a Mattermost sense), but may also serve HTTP requests from external services like webhooks. These requests from external services might use the Authorization header to authorize themselves against the plugin. diff --git a/docs/develop/integrate/plugins/components/server/ha.md b/docs/develop/integrate/plugins/components/server/ha.md index 9ed2505620e0..b3abb7f00b22 100644 --- a/docs/develop/integrate/plugins/components/server/ha.md +++ b/docs/develop/integrate/plugins/components/server/ha.md @@ -9,7 +9,7 @@ It is important that all plugins consider HA environments when being built. Plugins are started as subprocesses of the main Mattermost process on each app server. This means a Mattermost deployment that has three app servers will have three separate copies of the same plugin running. Each running copy of the plugin will be isolated from one another on different servers. Therefore, to run properly in HA the plugin's server-side code must be stateless. -To be stateless, the plugin must not retain any information or status in memory that may be needed across multiple events (e.g. HTTP requests or in other hooks). This data should instead be stored in a place that all running copies of the plugin have access to. For example, the [key-value store](/developers/integrate/reference/server/server-reference#API.KVSet) the plugin API provides. +To be stateless, the plugin must not retain any information or status in memory that may be needed across multiple events (e.g. HTTP requests or in other hooks). This data should instead be stored in a place that all running copies of the plugin have access to. For example, the [key-value store](/developers/integrate/reference/server#API.KVSet) the plugin API provides. To better explain the problem with having a plugin store data in-memory, consider this case: diff --git a/docs/develop/integrate/plugins/components/server/hello-world.md b/docs/develop/integrate/plugins/components/server/hello-world.md index 576e880a1a66..2e58e1126120 100644 --- a/docs/develop/integrate/plugins/components/server/hello-world.md +++ b/docs/develop/integrate/plugins/components/server/hello-world.md @@ -37,7 +37,7 @@ cd $GOPATH/src/my-plugin Create a file named `plugin.go` with the following contents: -\{/* TODO: unconverted Hugo shortcode \{\{<plugingoexamplecode name="_helloWorld">\}\} (sources/mattermost-developer-documentation/site/content/integrate/plugins/components/server/hello-world.md) */\} + This plugin will register an HTTP handler that will respond with "Hello, world!" when requested. diff --git a/docs/develop/integrate/plugins/components/server/index.md b/docs/develop/integrate/plugins/components/server/index.md index e4fa0dca585a..f6157cf3a160 100644 --- a/docs/develop/integrate/plugins/components/server/index.md +++ b/docs/develop/integrate/plugins/components/server/index.md @@ -7,21 +7,21 @@ Server plugins are subprocesses invoked by the server that communicate with Matt Looking for a quick start? [See our "Hello, world!" tutorial](/developers/integrate/plugins/components/server/hello-world). -Want the Server SDK reference doc? [Find it here](/developers/integrate/reference/server/server-reference). +Want the Server SDK reference doc? [Find it here](/developers/integrate/reference/server). ## Features #### RPC API -Use the [RPC API](/developers/integrate/reference/server/server-reference#API) to execute create, read, update and delete (CRUD) operations on server data models. +Use the [RPC API](/developers/integrate/reference/server#API) to execute create, read, update and delete (CRUD) operations on server data models. For example, your plugin can consume events from a third-party webhook and create corresponding posts in Mattermost, without having to host your code outside Mattermost. #### Hooks -Register for [hooks](/developers/integrate/reference/server/server-reference#Hooks) and get alerted when certain events occur. +Register for [hooks](/developers/integrate/reference/server#Hooks) and get alerted when certain events occur. -For example, consume the [OnConfigurationChange](/developers/integrate/reference/server/server-reference#Hooks.OnConfigurationChange) hook to respond to server configuration changes, or the [MessageHasBeenPosted](/developers/integrate/reference/server/server-reference#Hooks.MessageHasBeenPosted) hook to respond to posts. +For example, consume the [OnConfigurationChange](/developers/integrate/reference/server#Hooks.OnConfigurationChange) hook to respond to server configuration changes, or the [MessageHasBeenPosted](/developers/integrate/reference/server#Hooks.MessageHasBeenPosted) hook to respond to posts. #### REST API @@ -33,7 +33,7 @@ Plugins with both a web app and server component can leverage this REST API to e When starting a plugin, the server consults the [plugin's manifest](/developers/integrate/plugins/manifest-reference) to determine if a server component was included. If found, the server launches a new process using the executable included with the plugin. -The server will trigger the [OnActivate](/developers/integrate/reference/server/server-reference#Hooks.OnActivate) hook if the plugin is successfully started, allowing you to perform startup events. If the plugin is disabled, the server will trigger the [OnDeactivate](/developers/integrate/reference/server/server-reference#Hooks.OnDeactivate) hook. While running, the server plugin can consume hook events, make API calls, launch threads or subprocesses of its own, interact with third-party services or do anything else a regular program can do. +The server will trigger the [OnActivate](/developers/integrate/reference/server#Hooks.OnActivate) hook if the plugin is successfully started, allowing you to perform startup events. If the plugin is disabled, the server will trigger the [OnDeactivate](/developers/integrate/reference/server#Hooks.OnDeactivate) hook. While running, the server plugin can consume hook events, make API calls, launch threads or subprocesses of its own, interact with third-party services or do anything else a regular program can do. ## High availability diff --git a/docs/develop/integrate/plugins/components/webapp/actions.md b/docs/develop/integrate/plugins/components/webapp/actions.md index ea430d20ded2..45d02f6d6aed 100644 --- a/docs/develop/integrate/plugins/components/webapp/actions.md +++ b/docs/develop/integrate/plugins/components/webapp/actions.md @@ -169,7 +169,7 @@ Get the client options to make requests to the server. Use this to create your o Reducers in Redux are pure functions that describe how the data in the store changes after any given action. Reducers will always produce the same resulting state for a given state and action. You can register a custom reducer for your plugin against the Redux store with the `registerReducer` function. -### [registerReducer(reducer)](/developers/integrate/reference/webapp/webapp-reference#registerReducer) +### [registerReducer(reducer)](/developers/integrate/reference/webapp#registerReducer) Registers a reducer against the Redux store. It will be accessible in Redux state under `state['plugins-']`. It generally accepts a reducer and returns undefined. @@ -275,7 +275,7 @@ The container is doing two things. First, it's grabbing the current (logged in) Now we can use `this.props.patchUser()` to update a user. The example component we made uses it to patch the current user's first name. -To use our component in our plugin we would then use the registry in the initialization function of the plugin to register the component somewhere in the Mattermost UI. That is beyond the scope of this guide, but you can [read more about that here](/developers/integrate/reference/webapp/webapp-reference). +To use our component in our plugin we would then use the registry in the initialization function of the plugin to register the component somewhere in the Mattermost UI. That is beyond the scope of this guide, but you can [read more about that here](/developers/integrate/reference/webapp). ## Available actions diff --git a/docs/develop/integrate/plugins/components/webapp/best-practices.md b/docs/develop/integrate/plugins/components/webapp/best-practices.md index 827a7848281a..6cb096e9370a 100644 --- a/docs/develop/integrate/plugins/components/webapp/best-practices.md +++ b/docs/develop/integrate/plugins/components/webapp/best-practices.md @@ -6,55 +6,55 @@ sidebar_position: 0 ## Design best practices ### Actions that apply to specific Channels -- Recommendation: Have your plugin register the actions to [the channel header](/developers/integrate/reference/webapp/webapp-reference#registerChannelHeaderButtonAction). This makes it quickly accessible for users and the actions apply on the channel they're viewing. +- Recommendation: Have your plugin register the actions to [the channel header](/developers/integrate/reference/webapp#registerChannelHeaderButtonAction). This makes it quickly accessible for users and the actions apply on the channel they're viewing. - Example: Zoom meeting posts to a channel ![Custom Channel Header Button](/img/extend/bp-channel-header.png) -You can additionally [register a slash command](/developers/integrate/reference/server/server-reference#API.RegisterCommand) on the server-side to take channel-specific actions. +You can additionally [register a slash command](/developers/integrate/reference/server#API.RegisterCommand) on the server-side to take channel-specific actions. - Example: Jira project actions ![Slash Command](/img/extend/bp-slash-command.gif) ### Actions that apply to specific messages -- Recommendation: Have your plugin register a [post dropdown menu component](/developers/integrate/reference/webapp/webapp-reference#registerPostDropdownMenuComponent) with some text, icon and an action function. This adds your action to the "More Actions" post menu dropdown for easy discovery. +- Recommendation: Have your plugin register a [post dropdown menu component](/developers/integrate/reference/webapp#registerPostDropdownMenuComponent) with some text, icon and an action function. This adds your action to the "More Actions" post menu dropdown for easy discovery. - Examples: Create or attach to Jira issue from a message; copy a message to another channel; report an inappropriate message - Sample code: [mattermost/mattermost-plugin-todo/webapp/src/index.js](https://github.com/mattermost/mattermost-plugin-todo/blob/0c4dbfb58a72f8392ea66e101996afd06fdb2913/webapp/src/index.js#L30-L37) ![Post Dropdown Menu](/img/extend/bp-post-dropdown-menu.png) ### Actions related to files or images -- Recommendation: Have your plugin register a [file upload method](/developers/integrate/reference/webapp/webapp-reference#registerFileUploadMethod) with some text, icon and an action function. This adds your new action to the file upload menu. +- Recommendation: Have your plugin register a [file upload method](/developers/integrate/reference/webapp#registerFileUploadMethod) with some text, icon and an action function. This adds your new action to the file upload menu. - Examples: File sharing from OneDrive or GDrive; Draw plugin for sketches ![File Upload Action](/img/extend/bp-file-upload.png) ### Actions that apply to specific teams -- Recommendation: Have your plugin register [left sidebar header component](/developers/integrate/reference/webapp/webapp-reference#registerLeftSidebarHeaderComponent) with some text, icon and an action function. This adds your action above your team's channels in the sidebar. +- Recommendation: Have your plugin register [left sidebar header component](/developers/integrate/reference/webapp#registerLeftSidebarHeaderComponent) with some text, icon and an action function. This adds your action above your team's channels in the sidebar. - Examples: Trello kanban board plugin, GitHub Plugin ![left sidebar header](/img/extend/bp-left-sidebar-header.png) ### Quick links or status summaries of workflows -- Recommendation: Have your plugin register a [bottom team sidebar component](/developers/integrate/reference/webapp/webapp-reference#registerBottomTeamSidebarComponent). This adds icons to the lower left corner of the UI. +- Recommendation: Have your plugin register a [bottom team sidebar component](/developers/integrate/reference/webapp#registerBottomTeamSidebarComponent). This adds icons to the lower left corner of the UI. - Examples: GitHub sidebar links with summary of outstanding reviews or unread messages; ServiceNow incident status summary ![bottom team sidebar](/img/extend/bp-bottom-team-sidebar.png) ### Global actions that can be taken anywhere in the server and not directly related to teams, channels or users -- Recommendation: Have your plugin register [main menu action](/developers/integrate/reference/webapp/webapp-reference#registerMainMenuAction) with some text, icon for mobile, and an action function. This adds your action to the Main Menu. You can additionally [register a slash command](/developers/integrate/reference/server/server-reference#API.RegisterCommand) on the server-side. +- Recommendation: Have your plugin register [main menu action](/developers/integrate/reference/webapp#registerMainMenuAction) with some text, icon for mobile, and an action function. This adds your action to the Main Menu. You can additionally [register a slash command](/developers/integrate/reference/server#API.RegisterCommand) on the server-side. - Examples: Share feedback plugin in Main Menu; /jira slash commands for quick actions ![main menu action](/img/extend/bp-main-menu-action.png) ### Actions that apply to specific users -- Recommendation: Have your plugin register a [popover user actions component](/developers/integrate/reference/webapp/webapp-reference#registerPopoverUserActionsComponent). This adds your action button to the user profile popover. +- Recommendation: Have your plugin register a [popover user actions component](/developers/integrate/reference/webapp#registerPopoverUserActionsComponent). This adds your action button to the user profile popover. - Examples: Report User plugin; Display extra information about the user from an LDAP server ![popover user actions component](/img/extend/bp-user-popover.png) ### Extra information on a user profile -- Recommendation: Have your plugin register a [popover user attribute component](/developers/integrate/reference/webapp/webapp-reference#registerPopoverUserAttributesComponent). This adds your custom attributes to the user profile popover. +- Recommendation: Have your plugin register a [popover user attribute component](/developers/integrate/reference/webapp#registerPopoverUserAttributesComponent). This adds your custom attributes to the user profile popover. - Examples: Custom User Attributes plugin ![popover user attribute component](/img/extend/bp-user-attributes.png) diff --git a/docs/develop/integrate/plugins/components/webapp/index.md b/docs/develop/integrate/plugins/components/webapp/index.md index 461e48eae624..c4ad211e3c38 100644 --- a/docs/develop/integrate/plugins/components/webapp/index.md +++ b/docs/develop/integrate/plugins/components/webapp/index.md @@ -7,7 +7,7 @@ Web app plugins extend and modify the Mattermost web and desktop apps, without h Looking for a quick start? [See our "Hello, world!" tutorial](/developers/integrate/plugins/components/webapp/hello-world). -Want the web app SDK reference doc? [Find it here](/developers/integrate/reference/webapp/webapp-reference). +Want the web app SDK reference doc? [Find it here](/developers/integrate/reference/webapp). ## Features @@ -25,7 +25,7 @@ Register your own React components alongside other root components like the side Web app plugins can also render different post components based on the post's type. Any time the web app encounters a post with this post type, it replaces the default rendering of the post component with your own custom implementation. Only one plugin can own the rendering for a given custom post type at a time: the last plugin to register will own the rendering for that custom post type. -For example, you can register a custom post type `custom_poll` using [registerPostTypeComponent](/developers/integrate/reference/webapp/webapp-reference#registerPostTypeComponent). Then, any time the web app sees that post type, it replaces the regular rendering of the post component with your own custom implementation. +For example, you can register a custom post type `custom_poll` using [registerPostTypeComponent](/developers/integrate/reference/webapp#registerPostTypeComponent). Then, any time the web app sees that post type, it replaces the regular rendering of the post component with your own custom implementation. Use this in conjunction with setting the post type in webhooks or slash commands, through the REST API or with a server plugin, and you can deeply integrate or extend Mattermost posts to fit your needs. @@ -35,7 +35,7 @@ When a plugin is uploaded to a Mattermost server and activated, the server check On web app launch, a request is made to the server to get a list of plugins that contain web app components. The web app then proceeds to download and execute the JavaScript bundles for each plugin. A similar process happens if an already launched web app receives a WebSocket event for a newly activated plugin. -Once downloaded and executed, each plugin should have registered itself via the global [registerPlugin](/developers/integrate/reference/webapp/webapp-reference#registerPlugin). The web app then invokes the `initialize` function defined on the plugin class, passing a registry and store. The registry passed allows the plugin to register (and unregister) components, event callbacks and Redux reducers to track plugin state. The store passed is the same Redux store used by the web app, giving the plugin access to the full state of the web app. +Once downloaded and executed, each plugin should have registered itself via the global [registerPlugin](/developers/integrate/reference/webapp#registerPlugin). The web app then invokes the `initialize` function defined on the plugin class, passing a registry and store. The registry passed allows the plugin to register (and unregister) components, event callbacks and Redux reducers to track plugin state. The store passed is the same Redux store used by the web app, giving the plugin access to the full state of the web app. Components registered by the plugin via the registry are tracked in the Redux store and used by `Pluggable` components throughout the web app. `Pluggable` components with a `pluggableName` attribute can render multiple such components registered by plugins. diff --git a/docs/develop/integrate/plugins/index.md b/docs/develop/integrate/plugins/index.md index 08b226bc29fc..4ea39159a397 100644 --- a/docs/develop/integrate/plugins/index.md +++ b/docs/develop/integrate/plugins/index.md @@ -23,7 +23,7 @@ Extend the Mattermost REST API with custom endpoints for use by Web App plugins -See the [Mattermost Server SDK Reference](/developers/integrate/reference/server/server-reference) and [Mattermost Client UI SDK Reference](/developers/integrate/reference/webapp/webapp-reference) documentation for details on available server API endpoints and client methods. +See the [Mattermost Server SDK Reference](/developers/integrate/reference/server) and [Mattermost Client UI SDK Reference](/developers/integrate/reference/webapp) documentation for details on available server API endpoints and client methods. diff --git a/docs/develop/integrate/plugins/interactive-dialogs/index.md b/docs/develop/integrate/plugins/interactive-dialogs/index.md index 2a75f3472c96..4de8eb38c374 100644 --- a/docs/develop/integrate/plugins/interactive-dialogs/index.md +++ b/docs/develop/integrate/plugins/interactive-dialogs/index.md @@ -777,7 +777,7 @@ The integration may also return a generic error message to the user that is not Support for generic error messages was added in Mattermost v5.18. -Finally, once the request is submitted, we recommend that the integration responds with a system message or an ephemeral message confirming the submission. This should be a separate request back to Mattermost once the service has received and responded to a submission request from a dialog. This can be done either via [the REST API](https://api.mattermost.com/#tag/posts%2Fpaths%2F~1posts~1ephemeral%2Fpost), or via the [Plugin API](/developers/integrate/reference/server/server-reference#API.SendEphemeralPost) if you're developing a plugin. +Finally, once the request is submitted, we recommend that the integration responds with a system message or an ephemeral message confirming the submission. This should be a separate request back to Mattermost once the service has received and responded to a submission request from a dialog. This can be done either via [the REST API](https://api.mattermost.com/#tag/posts%2Fpaths%2F~1posts~1ephemeral%2Fpost), or via the [Plugin API](/developers/integrate/reference/server#API.SendEphemeralPost) if you're developing a plugin. ## Multi-step dialogs ##### Minimum Server Version: 11.1 diff --git a/docs/develop/integrate/plugins/interactive-messages/index.md b/docs/develop/integrate/plugins/interactive-messages/index.md index 7f0f5546095a..296879a0b14e 100644 --- a/docs/develop/integrate/plugins/interactive-messages/index.md +++ b/docs/develop/integrate/plugins/interactive-messages/index.md @@ -473,7 +473,7 @@ If your `ephemeral_text` gets incorrectly handled by the Slack-compatibility log Yes, message buttons and menus are supported in ephemeral messages in Mattermost 5.10 and later. This applies to integrations using plugins, the RESTful API and webhooks, across the browser and Desktop App. -As an advanced feature, you can also use plugins to update the contents of an ephemeral message with message buttons or menus with the [UpdateEphemeralMessage plugin API](/developers/integrate/reference/server/server-reference#API.UpdateEphemeralPost). +As an advanced feature, you can also use plugins to update the contents of an ephemeral message with message buttons or menus with the [UpdateEphemeralMessage plugin API](/developers/integrate/reference/server#API.UpdateEphemeralPost). ### Why does an interactive button or menu return a 400 error? diff --git a/docs/develop/integrate/plugins/manifest-reference.md b/docs/develop/integrate/plugins/manifest-reference.md index 64a2ccf45eec..65fe10ec7e98 100644 --- a/docs/develop/integrate/plugins/manifest-reference.md +++ b/docs/develop/integrate/plugins/manifest-reference.md @@ -3,10 +3,4 @@ title: "Manifest reference" sidebar_position: 130 --- - - - -This section was rendered by the Hugo `pluginmanifestdocs` shortcode from the upstream plugin reference. Migration follow-up — see PLAN.md §11.2. - - - + diff --git a/docs/develop/integrate/plugins/migration.md b/docs/develop/integrate/plugins/migration.md index ae1a19d713c4..cddd95183023 100644 --- a/docs/develop/integrate/plugins/migration.md +++ b/docs/develop/integrate/plugins/migration.md @@ -98,7 +98,7 @@ func main() { #### Hook parameters -Most hook callbacks now contain a leading `plugin.Context` parameter. Consult the [Hooks](/developers/integrate/reference/server/server-reference#Hooks) documentation for more details, but for example, the `ServeHTTP` hook was previously: +Most hook callbacks now contain a leading `plugin.Context` parameter. Consult the [Hooks](/developers/integrate/reference/server#Hooks) documentation for more details, but for example, the `ServeHTTP` hook was previously: ```go func (p *MyPlugin) ServeHTTP(w http.ResponseWriter, r *http.Request) { @@ -116,7 +116,7 @@ func (p *MyPlugin) ServeHTTP(c *plugin.Context, w http.ResponseWriter, r *http.R #### API changes -Most of the previous API calls remain available and unchanged, with the notable exception of removing the `KeyValueStore()`. Use [KVSet](/developers/integrate/reference/server/server-reference#API.KVSet), [KVGet](/developers/integrate/reference/server/server-reference#API.KVGet) and [KVDelete](/developers/integrate/reference/server/server-reference#API.KVDelete) instead test: +Most of the previous API calls remain available and unchanged, with the notable exception of removing the `KeyValueStore()`. Use [KVSet](/developers/integrate/reference/server#API.KVSet), [KVGet](/developers/integrate/reference/server#API.KVGet) and [KVDelete](/developers/integrate/reference/server#API.KVDelete) instead test: ```go func (p *MyPlugin) ServeHTTP(c *plugin.Context, w http.ResponseWriter, r *http.Request) { @@ -232,7 +232,7 @@ class MyPlugin { } ``` -The `initialize` callback now receives an instance of the plugin [registry](/developers/integrate/reference/webapp/webapp-reference#registry). In some cases, the registry's API now requires a more discrete breakdown of the registered component to allow the web app to handle various rendering scenarios: +The `initialize` callback now receives an instance of the plugin [registry](/developers/integrate/reference/webapp#registry). In some cases, the registry's API now requires a more discrete breakdown of the registered component to allow the web app to handle various rendering scenarios: ```js import ChannelHeaderButtonIcon from './components/channel_header_button/icon'; diff --git a/docs/develop/integrate/plugins/overview.md b/docs/develop/integrate/plugins/overview.md index 18b2a28e9a4c..e08fee6ee32e 100644 --- a/docs/develop/integrate/plugins/overview.md +++ b/docs/develop/integrate/plugins/overview.md @@ -17,14 +17,14 @@ The plugin manifest provides required metadata about the plugin, such as name an See the [manifest reference](/developers/integrate/plugins/manifest-reference) for more information. ### Server -The server component of a plugin is written in Go and runs as a subprocess of the Mattermost server process. The Go code extends the [MattermostPlugin](https://godoc.org/github.com/mattermost/mattermost/server/public/plugin#MattermostPlugin) struct that contains an [API](/developers/integrate/reference/server/server-reference#API) and allows for the implementation of [Hook](/developers/integrate/reference/server/server-reference#Hooks) methods that enable the plugin to interact with the Mattermost server. +The server component of a plugin is written in Go and runs as a subprocess of the Mattermost server process. The Go code extends the [MattermostPlugin](https://godoc.org/github.com/mattermost/mattermost/server/public/plugin#MattermostPlugin) struct that contains an [API](/developers/integrate/reference/server#API) and allows for the implementation of [Hook](/developers/integrate/reference/server#Hooks) methods that enable the plugin to interact with the Mattermost server. The sample plugin implements this simply in [plugin.go](https://github.com/mattermost/mattermost-plugin-starter-template/blob/master/server/plugin.go) and the demo plugin splits the API and hook usage throughout [multiple files](https://github.com/mattermost/mattermost-plugin-demo/tree/master/server). Read more about the server-side of plugins [here](/developers/integrate/plugins/components/server). ### Web/desktop app -The web app component of a plugin is written in JavaScript with [React](https://react.dev/) and [Redux](https://redux.js.org/). The plugin's bundled JavaScript is included on the page and runs alongside the web app code as a [PluginClass](/developers/integrate/reference/webapp/webapp-reference#pluginclass) that has initialize and uninitialize methods available for implementation. The initialize function is passed through the [registry](/developers/integrate/reference/webapp/webapp-reference#registry) which allows the plugin to register React components, actions and hooks to modify and interact with the Mattermost web app. +The web app component of a plugin is written in JavaScript with [React](https://react.dev/) and [Redux](https://redux.js.org/). The plugin's bundled JavaScript is included on the page and runs alongside the web app code as a [PluginClass](/developers/integrate/reference/webapp#pluginclass) that has initialize and uninitialize methods available for implementation. The initialize function is passed through the [registry](/developers/integrate/reference/webapp#registry) which allows the plugin to register React components, actions and hooks to modify and interact with the Mattermost web app. The sample plugin has a [shell of an implemented PluginClass](https://github.com/mattermost/mattermost-plugin-starter-template/blob/master/webapp/src/index.tsx), while the demo plugin [contains a more complete example](https://github.com/mattermost/mattermost-plugin-demo/blob/master/webapp/src/plugin.jsx). diff --git a/docs/develop/integrate/reference/server/server-reference.md b/docs/develop/integrate/reference/server/index.md similarity index 73% rename from docs/develop/integrate/reference/server/server-reference.md rename to docs/develop/integrate/reference/server/index.md index ecd97ef2c7d8..2f363e7749e0 100644 --- a/docs/develop/integrate/reference/server/server-reference.md +++ b/docs/develop/integrate/reference/server/index.md @@ -9,10 +9,4 @@ Visit the [Plugins](/developers/integrate/plugins) section to learn more about [ *** - - - -This section was rendered by the Hugo `plugingodocs` shortcode from the upstream plugin reference. Migration follow-up — see PLAN.md §11.2. - - - + diff --git a/docs/develop/integrate/reference/webapp/webapp-reference.md b/docs/develop/integrate/reference/webapp/index.md similarity index 98% rename from docs/develop/integrate/reference/webapp/webapp-reference.md rename to docs/develop/integrate/reference/webapp/index.md index 430cbaa2c408..b1c3ee65a6b4 100644 --- a/docs/develop/integrate/reference/webapp/webapp-reference.md +++ b/docs/develop/integrate/reference/webapp/index.md @@ -89,12 +89,7 @@ This will add a custom `UserPopularity` component to the profile popover, render An instance of the plugin registry is passed to each plugin via the `initialize` callback. - - -This section was rendered by the Hugo `pluginjsdocs` shortcode from the upstream plugin reference. Migration follow-up — see PLAN.md §11.2. - - - + ### Theme diff --git a/docs/develop/integrate/slash-commands/index.md b/docs/develop/integrate/slash-commands/index.md index 87963c80d21d..4fd8c5b3e1b7 100644 --- a/docs/develop/integrate/slash-commands/index.md +++ b/docs/develop/integrate/slash-commands/index.md @@ -102,7 +102,7 @@ See the [Slack compatibility](/slack) page. #### If you are developing a plugin -Use [`CreatePost`](/developers/integrate/reference/server/server-reference#API.CreatePost) plugin API. Make sure to set the `UserId` of the post to the `UserId` of the Bot Account. If you want to create an ephemeral post, use [`SendEphemeralPost`](/developers/integrate/reference/server/server-reference#API.SendEphemeralPost) plugin API instead. +Use [`CreatePost`](/developers/integrate/reference/server#API.CreatePost) plugin API. Make sure to set the `UserId` of the post to the `UserId` of the Bot Account. If you want to create an ephemeral post, use [`SendEphemeralPost`](/developers/integrate/reference/server#API.SendEphemeralPost) plugin API instead. ## Troubleshoot slash commands diff --git a/docs/main/administration-guide/configure/authentication-configuration-settings.mdx b/docs/main/administration-guide/configure/authentication-configuration-settings.mdx index 687d5bddc984..2a2c940ccce3 100644 --- a/docs/main/administration-guide/configure/authentication-configuration-settings.mdx +++ b/docs/main/administration-guide/configure/authentication-configuration-settings.mdx @@ -2266,7 +2266,7 @@ Access the following configuration settings in the System Console by going to ** -Guest billing depends on channel access. Guests in exactly one channel are treated as single-channel guests and don't count toward the primary paid seat count. They're free up to a 1:1 ratio with licensed seats. Guests in multiple channels continue to count as paid active users. Direct messages and group messages don't affect whether a guest is counted as a single-channel guest. See the [guest accounts](/administration-guide/onboard/guest-accounts) documentation for full details. +Guest billing depends on channel access. Guests in exactly one active channel are treated as single-channel guests and don't count toward the primary paid seat count. They're free up to a 1:1 ratio with licensed seats. Guests in multiple active channels continue to count as activated users for billing purposes. Direct messages and group messages don't affect whether a guest is counted as a single-channel guest. Only active channels count toward guest channel access for billing. Archived channels are excluded. See the [guest accounts](/administration-guide/onboard/guest-accounts) documentation for full details. diff --git a/docs/main/administration-guide/configure/configuration-in-your-database.mdx b/docs/main/administration-guide/configure/configuration-in-your-database.mdx index 0f064f94bfcc..6e1423412ced 100644 --- a/docs/main/administration-guide/configure/configuration-in-your-database.mdx +++ b/docs/main/administration-guide/configure/configuration-in-your-database.mdx @@ -99,7 +99,7 @@ sudo systemctl status mattermost.service The second line of output will have the location of the running `mattermost.service`. ``` text -Loaded: loaded (/lib/systemd/system/mattermost.service; enabled; vendor preset: enabled) + Loaded: loaded (/etc/systemd/system/mattermost.service; enabled; vendor preset: enabled) ``` Edit this file as *root* to add the below text just above the line that begins with `ExecStart`: diff --git a/docs/main/administration-guide/configure/environment-configuration-settings.mdx b/docs/main/administration-guide/configure/environment-configuration-settings.mdx index 2e23b6f6b43f..6a5ce0347d88 100644 --- a/docs/main/administration-guide/configure/environment-configuration-settings.mdx +++ b/docs/main/administration-guide/configure/environment-configuration-settings.mdx @@ -742,6 +742,18 @@ For an AWS High Availability RDS cluster deployment, point this configuration se + + +This limit applies **per data source, per Mattermost server node** - not as a cluster-wide total. Each server node opens its own connection pool, sized to this value, for the master database (`DataSource`) and separately for each entry configured under [read replicas](#read-replicas) and [search replicas](#search-replicas). + +To size `max_connections` on the database (or any connection-pooling proxy in front of it), first count the data sources per node - the master database counts as 1, then add the number of read replicas and the number of search replicas. Multiply that count by `MaxOpenConns`, then multiply again by the number of app server nodes (when deployed as a high availability cluster): + +`MaxOpenConns` x (data sources per node) x (number of app nodes) + +For example, in a 3-node HA cluster where each node is configured with 1 read replica and 1 search replica, at the default `MaxOpenConns` of 100, each node has 3 data sources, so that's 3 x 3 x 100 = 900 possible connections across the cluster. + + + ### Maximum idle connections @@ -916,6 +928,7 @@ Read-only display of the currently active backend used for search. Values can in - Each database connection string in the array must be in the same form used for the [Data source](#data-source) setting. - Space separate multiple read replicas in the array to allow Mattermost to load balance read queries across multiple database instances. For example, `MM_SQLSETTINGS_DATASOURCEREPLICAS=dc-1 dc-2` +- Each entry added here opens its own connection pool, sized to [MaxOpenConns](#maximum-open-connections), on every Mattermost server node - it does not share a pool with the other entries. See that setting's note for the full cluster-wide sizing calculation before adding replicas. @@ -940,7 +953,8 @@ For an AWS High Availability RDS cluster deployment, point this configuration se -Each database connection string in the array must be in the same form used for the [Data source](#data-source) setting. +- Each database connection string in the array must be in the same form used for the [Data source](#data-source) setting. +- Each entry added here opens its own connection pool, sized to [MaxOpenConns](#maximum-open-connections), on every Mattermost server node - it does not share a pool with the other entries. See that setting's note for the full cluster-wide sizing calculation before adding search replicas. diff --git a/docs/main/administration-guide/configure/push-notification-server-configuration-settings.mdx b/docs/main/administration-guide/configure/push-notification-server-configuration-settings.mdx index 9b1b66dc6c6c..d65a735295d2 100644 --- a/docs/main/administration-guide/configure/push-notification-server-configuration-settings.mdx +++ b/docs/main/administration-guide/configure/push-notification-server-configuration-settings.mdx @@ -79,8 +79,7 @@ See our [configuration settings](/administration-guide/configure/site-configurat - +

The physical location of the Mattermost Hosted Push Notification Service (HPNS) server.

-

Select from US (Default) or Germany to automatically populate the Push Notification Server field server URL.

The region of the Mattermost Hosted Push Notification Service (HPNS) server.

Select a region to automatically populate the Push Notification Server field with the corresponding URL:

  • Global: https://global.push.mattermost.com (load balances requests across the regional endpoints below)
  • US: https://us.push.mattermost.com
  • EU (Germany): https://eu.push.mattermost.com
  • AP (Japan): https://ap.push.mattermost.com
  • System Config path: Environment > Push Notification Server
  • config.json setting: EmailSettings > PushNotificationServer
  • @@ -90,6 +89,12 @@ See our [configuration settings](/administration-guide/configure/site-configurat
+ + +`https://us.push.mattermost.com` supersedes the legacy `https://push.mattermost.com` URL, and `https://eu.push.mattermost.com` supersedes the legacy `https://hpns-de.mattermost.com` URL. The legacy URLs still work, but are deprecated and now point to the same new infrastructure as their replacements above. + + + # Maximum notifications per channel diff --git a/docs/main/administration-guide/configure/reporting-configuration-settings.mdx b/docs/main/administration-guide/configure/reporting-configuration-settings.mdx index d913079f6e21..eeedcb63012e 100644 --- a/docs/main/administration-guide/configure/reporting-configuration-settings.mdx +++ b/docs/main/administration-guide/configure/reporting-configuration-settings.mdx @@ -38,8 +38,8 @@ View the following statistics for your overall deployment and specific teams, as - Bots, deactivated users, and synthetic users in [Microsoft Teams integrations](/end-user-guide/collaborate/collaborate-within-connected-microsoft-teams) and [connected workspaces](/administration-guide/onboard/connected-workspaces) users aren't counted towards the total number of activated users. -- **Single-channel Guests** shows the number of active guest accounts that belong to exactly one channel. Direct messages and group messages don't affect whether a guest is counted as a single-channel guest. Single-channel guests are counted separately from the primary paid seat count and are free up to a 1:1 ratio with licensed seats. When this count exceeds the allowance, the statistic is highlighted as a warning for system admins. -- Guests in multiple channels continue to count as paid active users. See the [guest accounts](/administration-guide/onboard/guest-accounts) documentation for details. +- **Single-channel Guests** shows the number of active guest accounts that belong to exactly one active channel. Direct messages and group messages don't affect whether a guest is counted as a single-channel guest. Archived channels are excluded. Single-channel guests are counted separately from the primary paid seat count and are free up to a 1:1 ratio with licensed seats. When this count exceeds the allowance, the statistic is highlighted as a warning for system admins. +- Guests in multiple active channels continue to count as activated users for billing purposes. See the [guest accounts](/administration-guide/onboard/guest-accounts) documentation for details. diff --git a/docs/main/administration-guide/configure/user-management-configuration-settings.mdx b/docs/main/administration-guide/configure/user-management-configuration-settings.mdx index 892a48e5a52c..5959ff6a064d 100644 --- a/docs/main/administration-guide/configure/user-management-configuration-settings.mdx +++ b/docs/main/administration-guide/configure/user-management-configuration-settings.mdx @@ -425,6 +425,26 @@ Users can only join the team if their email matches one of the specified domains ![Enable Only specific email domains can join this team option for a team using the System Console.](/images/specific-email-domains-can-join-a-team.png) +### Manage membership with attribute based membership policies + + + +From Mattermost v11.10, control who can be a member of this team based on their user attributes. + +On private teams the rules are enforced: users who don't match can't join, and members who no longer match are removed at the next sync. On public teams the rules are advisory — the team is recommended to qualifying users, but anyone can still join. + +1. Go to **System Console \> User Management \> Teams** to access all available teams. +2. Select the team from the list to view its configuration page. +3. In the **Team Management** section, enable the **Manage membership with attribute based membership policies** option. The **Membership policies** and **Team-specific membership rules** sections appear once this option is enabled. +4. Link a system-wide policy, define team-specific rules, or both. +5. Select **Save**. + +This option is unavailable on group-synced teams, because group sync and attribute-based membership are mutually exclusive. + +Team Admins with the **Manage Team Access Rules** permission can also define team membership rules from the **Team Membership** tab in [Team Settings](/end-user-guide/collaborate/team-settings), without access to the System Console. + +See [Team membership access policies](/administration-guide/manage/admin/abac-team-membership) for full details. + ### Synchronize team members Admins can choose between inviting members to a team manually or synchronizing members automatically from AD/LDAP groups. See the [using AD/LDAP synchronized groups](/administration-guide/onboard/ad-ldap-groups-synchronization#synchronize-adldap-groups-to-mattermost) documentation for details on managing team or private channel membership. diff --git a/docs/main/administration-guide/manage/admin/abac-channel-access-rules.mdx b/docs/main/administration-guide/manage/admin/abac-channel-access-rules.mdx index 28c26e8df673..3f6d74af77cf 100644 --- a/docs/main/administration-guide/manage/admin/abac-channel-access-rules.mdx +++ b/docs/main/administration-guide/manage/admin/abac-channel-access-rules.mdx @@ -142,7 +142,7 @@ From Mattermost v11.7, Team Admins can create, edit, and delete channel membersh ### Team Admin workflow -1. Open **Team Settings** from the team menu, and go to the **Membership Policies** tab. This tab is only visible to Team Admins with the `manage_team_access_rules` permission when ABAC is enabled system-wide. +1. Open **Team Settings** from the team menu, and go to the **Channel Membership** tab. This tab is only visible to Team Admins with the `manage_team_access_rules` permission when ABAC is enabled system-wide. 2. Select **Add Policy** and enter a name for the policy. Parent policy names must be unique; if you enter a name that's already in use, Mattermost displays a user-friendly error and prevents the policy from being saved. 3. Define the attribute rules that determine which users can be members of channels assigned to this policy. Rules use the same attribute conditions available for channel-specific access rules. 4. Assign the applicable private channels in the team to the policy. @@ -150,7 +150,7 @@ From Mattermost v11.7, Team Admins can create, edit, and delete channel membersh ### Team Settings sync status footer -The **Membership Policies** tab includes a sync status footer that shows: +The **Channel Membership** tab includes a sync status footer that shows: - **Last sync time**: The time of the most recent membership synchronization for policies in this team. - **Sync now**: An on-demand action that triggers an immediate synchronization for the team's policies. @@ -303,7 +303,7 @@ The auto-sync toggle is automatically disabled when: #### How quickly are membership changes applied? -When you save access rules, membership sync job is created and changes are applied as soon as the job is completed. Additionally, Mattermost runs synchronization jobs every 30 minutes to handle attribute changes from external systems (LDAP, SAML). +When you save access rules, membership sync job is created and changes are applied as soon as the job is completed. Additionally, Mattermost runs synchronization jobs on a schedule to handle attribute changes from external systems (LDAP, SAML). The interval is set by `AccessControlSettings.SyncJobIntervalSeconds` and defaults to 3600 seconds (60 minutes). #### Will users be notified when they're removed from a channel? @@ -321,7 +321,7 @@ You can use any user attributes either synchronized via LDAP/SAML or manually co #### What happens if a user attribute changes? -During the next synchronization (every 30 minutes), users who no longer match the access rules will be removed from the channel, and new users who now match will be added (if auto-sync is enabled). +During the next scheduled synchronization (every 60 minutes by default), users who no longer match the access rules will be removed from the channel, and new users who now match will be added (if auto-sync is enabled). #### Do guest users work with ABAC channels? diff --git a/docs/main/administration-guide/manage/admin/abac-system-wide-policies.mdx b/docs/main/administration-guide/manage/admin/abac-system-wide-policies.mdx index cd1f767f1592..dc69e0d129fd 100644 --- a/docs/main/administration-guide/manage/admin/abac-system-wide-policies.mdx +++ b/docs/main/administration-guide/manage/admin/abac-system-wide-policies.mdx @@ -6,7 +6,7 @@ import TabItem from '@theme/TabItem'; -Use this guide to create and manage organization-wide attribute-based access policies in the System Console. For channel-level rules managed by Channel Admins, see [Channel-specific access rules](/administration-guide/manage/admin/abac-channel-access-rules). +Use this guide to create and manage organization-wide attribute-based access policies in the System Console. Policies can be assigned to both channels and teams. For channel-level rules managed by Channel Admins, see [Channel-specific access rules](/administration-guide/manage/admin/abac-channel-access-rules). For team membership policies, see [Team membership access policies](/administration-guide/manage/admin/abac-team-membership). ## Prerequisites @@ -122,9 +122,24 @@ Private channels with attribute-based access control policies can't have guest u +### Assign policies to teams + +From Mattermost v11.10, system-wide policies can also be assigned to teams. Go to **System Console \> User Management \> Teams** and open the team you want to configure. In the **Team Management** section, enable **Manage membership with attribute based membership policies** — the **Membership policies** section only appears once this toggle is on. Then link an existing policy and select **Save**. + +Group-synced teams cannot use membership policies, so the toggle is unavailable on them. + +The policy behaves differently depending on the team's privacy mode: + +- **Private teams** — strict enforcement: join is gated, non-qualifying members are removed at sync, and the team is hidden from non-qualifying non-members in Browse Teams. +- **Public teams** — advisory: the policy is never a gate. Qualifying non-members see a **Recommended** chip in Browse Teams; anyone can still join freely. + +For a full description of team assignment, custom rules, sync configuration, and end-user surfaces, see [Team membership access policies](/administration-guide/manage/admin/abac-team-membership). + ### Delete policies -To delete a policy, select the **Delete** button next to the policy you want to remove. You can only delete policies that are not currently assigned to any channels. If a policy is assigned to channels, you must first remove it from those channels before you can delete it. +To delete a policy, select the **Delete** button next to the policy you want to remove. Policies that are still assigned to channels cannot be deleted — remove the policy from those channels first. + +Team assignments are not checked before deletion, so unlink the policy from every team that uses it before deleting it. Otherwise those teams keep a reference to a policy that no longer exists. ## Define access controls per channel diff --git a/docs/main/administration-guide/manage/admin/abac-team-channel-policies.mdx b/docs/main/administration-guide/manage/admin/abac-team-channel-policies.mdx index 8f99d3314775..39899786b1c9 100644 --- a/docs/main/administration-guide/manage/admin/abac-team-channel-policies.mdx +++ b/docs/main/administration-guide/manage/admin/abac-team-channel-policies.mdx @@ -6,6 +6,12 @@ sidebar_label: "Team channel policies" Team Admins can create and manage attribute-based membership policies for private channels within their team, directly from Team Settings, without requiring System Admin involvement. For organization-wide policies managed by System Admins, see [System-wide attribute-based access policies](/administration-guide/manage/admin/abac-system-wide-policies). + + +From Mattermost v11.10, Team Settings has four tabs: **Info**, **Access**, **Team Membership**, and **Channel Membership**. This page covers the **Channel Membership** tab — policies that Team Admins configure for *channels* within their team. For team-level membership policies (controlling who can join the team itself), see [Team membership access policies](/administration-guide/manage/admin/abac-team-membership). + + + With team-level channel membership policies, Team Admins can: - Create policies that apply attribute-based access rules to one or more private channels within their team. @@ -28,23 +34,23 @@ With team-level channel membership policies, Team Admins can: 1. Select the team name in the sidebar to open the team menu. 2. Select **Team Settings**. -3. Navigate to the **Membership Policies** tab. This tab is only visible when ABAC is enabled system-wide and you have Team Admin permissions. +3. Navigate to the **Channel Membership** tab (the fourth tab in Team Settings). This tab is only visible when ABAC is enabled system-wide and you have Team Admin permissions. -System Admins also have access to the **Membership Policies** tab in Team Settings and see the same policies as Team Admins. +System Admins also have access to the **Channel Membership** tab in Team Settings and see the same policies as Team Admins. ## Manage membership policies -The **Membership Policies** tab shows policies scoped to the team. Each policy displays its name and the number of private channels it applies to. +The **Channel Membership** tab shows policies scoped to the team. Each policy displays its name and the number of private channels it applies to. Team Admins only see policies whose access rules their own user attributes satisfy. If a policy has rules that exclude the Team Admin's attributes (for example, a policy requiring `Department=Engineering` and the Team Admin has `Department=Finance`), that policy will not appear in their list. This is a self-inclusion safety mechanism to prevent admins from being locked out of policies they manage. ### Create a policy -1. In the **Membership Policies** tab, select **Add policy**. +1. In the **Channel Membership** tab, select **Add policy**. 2. Enter a unique policy name. 3. Define access rules under **Access rules**: - Select **Add attribute** to add a condition. @@ -102,26 +108,26 @@ When both a system-wide policy and a team-level policy apply to the same channel ### Cross-team policies -A policy that has private channels from more than one team is considered a cross-team policy. Cross-team policies are not visible in any team's **Membership Policies** tab — they are managed exclusively through the System Console. +A policy that has private channels from more than one team is considered a cross-team policy. Cross-team policies are not visible in any team's **Channel Membership** tab — they are managed exclusively through the System Console. -If a System Admin adds a channel from another team to a policy that was previously scoped to one team, that policy will no longer appear in any team's **Membership Policies** tab. +If a System Admin adds a channel from another team to a policy that was previously scoped to one team, that policy will no longer appear in any team's **Channel Membership** tab. ## Synchronization -When you save a policy or modify channel assignments, Mattermost creates a membership synchronization job. Changes are applied as soon as the job completes. Synchronization also runs automatically every 30 minutes to handle attribute changes from external systems such as LDAP or SAML. +When you save a policy or modify channel assignments, Mattermost creates a membership synchronization job. Changes are applied as soon as the job completes. Synchronization also runs automatically on a schedule to handle attribute changes from external systems such as LDAP or SAML. The interval is set by `AccessControlSettings.SyncJobIntervalSeconds` and defaults to 3600 seconds (60 minutes). ## Troubleshooting and FAQs -### Why can't I see the Membership Policies tab in Team Settings? +### Why can't I see the Channel Membership tab in Team Settings? -The **Membership Policies** tab is only visible when: +The **Channel Membership** tab is only visible when: - You have Team Admin permissions. - ABAC is enabled system-wide by a System Admin in **System Console \> System Attributes \> Attribute-Based Access**. ### Why can't I see a policy that I know exists? -There are two reasons a policy may not appear in your **Membership Policies** tab: +There are two reasons a policy may not appear in your **Channel Membership** tab: - **Cross-team policy**: The policy includes private channels from more than one team. Cross-team policies are not visible in Team Settings for anyone and must be managed through the System Console. - **Self-inclusion filter**: Your own user attributes do not satisfy the policy's access rules. For example, if a policy requires `Department=Engineering` and your profile has `Department=Finance`, you will not see that policy. A System Admin or another Team Admin whose attributes do satisfy the rules would need to manage it instead. diff --git a/docs/main/administration-guide/manage/admin/abac-team-membership.mdx b/docs/main/administration-guide/manage/admin/abac-team-membership.mdx new file mode 100644 index 000000000000..2d25e4507984 --- /dev/null +++ b/docs/main/administration-guide/manage/admin/abac-team-membership.mdx @@ -0,0 +1,448 @@ +--- +title: "Team membership access policies" +sidebar_label: "Team membership policies" +--- + + +From Mattermost v11.10, system admins and team admins can apply attribute-based access control (ABAC) directly to teams — controlling who can join a team based on user profile attributes. This extends the existing ABAC channel membership system to the team boundary, closing the "hallway access" gap where users who fail channel policies could still see the team, its member list, and its channel structure. + +Team membership ABAC uses the same policies and attribute rules as channel ABAC, but behaves differently depending on whether the team is public or private: + +- **Public teams (advisory mode)**: The policy never blocks access. Anyone can still join freely. Qualifying users who are not yet members see a **Recommended** chip in Browse Teams. Sync can auto-add qualifying users when enabled but never removes anyone. +- **Private teams (strict mode)**: The policy gates directory visibility, join evaluation, and membership at sync. Non-qualifying users cannot find or join the team. Non-qualifying members are removed at the next sync. + + + +**Upgrade notice:** The Access tab in Team Settings has a new UI from Mattermost v11.10 that affects **every team on every deployment** — whether or not ABAC is licensed or enabled. The old "Allow any user to join" checkbox has been replaced by **Public Team / Private Team** selection cards. See [Access tab: Public/Private team cards](#access-tab-publicprivate-team-cards) for details. + + + +## Access tab: Public/Private team cards + + + +This change affects **all Mattermost teams on all deployments**, regardless of whether ABAC is enabled or whether your organization has an Enterprise Advanced license. Any team admin who opens **Team Settings \> Access** after upgrading will see the new UI. The exception is teams managed by LDAP/AD group sync, which show a static message in place of the cards — see [Switching modes](#switching-modes). + + + +**What changed:** The "Allow any user to join" checkbox has been permanently replaced by two selection cards: + +- **Public Team** — anyone on the server can find and join. +- **Private Team** — only invited members can join. + +**Why the change was made:** The cards make a team's public-vs-private state explicit and unambiguous, which is what team ABAC enforcement depends on to decide between advisory and strict mode. + +**Behavior without ABAC:** Functionally identical to the old checkbox. Public Team = "Allow any user to join" was ON. Private Team = it was OFF. No other behavior changes for teams that have no membership policy. + +**Behavior with ABAC:** The cards drive the enforcement mode — public teams get advisory ABAC, private teams get strict ABAC. Mode changes on policy-governed teams may trigger a confirmation modal (see below). + +**Default on new teams:** New teams are Private by default, so any policy assigned before explicitly choosing a mode activates strict enforcement. Teams are always protected by default; advisory mode requires explicitly selecting **Public Team**. + +### Switching modes + +**Private → Public:** Relaxes enforcement. Saves directly with no confirmation modal. If a policy is applied, the team immediately transitions to advisory mode: no existing members are removed. + +**Public → Private:** If team ABAC is enabled (Enterprise Advanced license and **Enable Attribute-Based Access Control**) and the team has a membership policy assigned, clicking **Private Team** opens a confirmation modal before saving: + +- Title: **"Switch to Private Team?"** +- Body shows how many current members do not meet the policy criteria and will be removed at the next sync. If all current members meet the criteria, the modal says no one will be removed. If no count is available, a generic warning is shown instead. +- **Cancel** — closes the modal, no changes made. +- **Switch to Private** — saves the change and immediately creates a team sync job to enforce strict mode. + +If the admin making the switch does not meet the policy criteria, a **"Cannot switch to Private Team"** error modal appears instead and the switch is blocked, since strict mode would remove them from the team. Update the rules to include yourself, or ask another admin to make the switch. + +If no policy is assigned, switching Public → Private saves directly with no modal. + +Other Access tab fields (Invite Code and Allowed Email Domain) are unaffected by this change. On teams managed by LDAP/AD group sync, the Access tab shows a static "Members of this team are added and removed by linked groups" message instead of the cards. + +## Advisory and strict enforcement + +Whether a policy is enforced strictly or treated as advisory depends only on whether the team is public or private. The table below summarizes how each combination behaves. + +| Team | ABAC policy? | Join gate | Browse Teams | Sync removal | Recommended tag | +|----|----|----|----|----|----| +| Public | No | Open | Visible to all | N/A | No | +| Public | Yes — **Advisory** | Open (no gate) | Visible to all | Skipped | Yes (qualifying non-members) | +| Private | No | Invite-only | Members only | N/A | No | +| Private | Yes — **Strict** | Denied for non-qualifying users | Hidden from non-qualifying non-members | Non-qualifiers removed | No | + + + +Auto-add is the only behavior that applies to **both** advisory and strict mode. When enabled, sync adds qualifying non-members regardless of whether the team is public or private. + + + +## Prerequisites + +Before configuring team membership policies: + +1. [Configure user attributes](/administration-guide/manage/admin/user-attributes) in the System Console. +2. Go to **System Console \> System Attributes \> Attribute-Based Access** and enable **Enable Attribute-Based Access Control**. +3. For Team Admins configuring rules: the `manage_team_access_rules` permission is required. This permission is included in the Team Admin role by default. + +Team membership ABAC is also gated by the `TeamMembershipAccessControl` feature flag, which is **enabled by default** from Mattermost v11.10. Disabling it turns off team enforcement without affecting channel ABAC. See the Mattermost developer documentation for details on [feature flags in a self-hosted deployment](https://developers.mattermost.com/contribute/more-info/server/feature-flags/#self-hosted-and-local-development). + +**What changes when team membership ABAC is off:** + +| Surface | Team membership ABAC ON | Team membership ABAC OFF | +|----|----|----| +| Join gate (private teams) | Enforced — non-qualifying users denied | Not evaluated — private teams stay invite-only, as before | +| Browse Teams filter | Private+ABAC teams hidden from non-qualifying users | No attribute filtering — standard privacy rules apply | +| Team Membership tab (Team Settings) | Visible to Team Admins and System Admins | Hidden — tab does not appear | +| System Console per-team ABAC controls | Policy assignment + custom rules panel visible | Hidden | +| Recommended tag | Shown to qualifying users on public+ABAC teams | Not shown | +| Sync job — removal pass | Removes non-qualifiers from private+ABAC teams | No team sync jobs run | +| Invite modal filtering | Filters on private+ABAC teams | All users shown, as before | +| Public/Private cards (Access tab) | **Visible** — not gated | **Still visible** — rendered on every team except group-synced ones | +| Channel ABAC | Unaffected | Unaffected | + +## System Admin configuration + +### Assign a membership policy to a team + +System Admins assign existing system-wide membership policies to teams via the per-team System Console page. + +1. Go to **System Console \> User Management \> Teams** and open the team you want to configure. +2. In the **Team Management** section, enable **Manage membership with attribute based membership policies**. The **Membership policies** and **Team-specific membership rules** sections appear only once this toggle is on. The toggle is unavailable on group-synced teams, and becomes read-only once a policy is linked. +3. In the **Membership policies** section, select **Link to a policy** and choose an existing policy from the picker. +4. Select **Save**. + +Before saving, an **Apply membership policy** confirmation modal appears. It shows only the outcomes that apply to this team: + +- The number of current members who do not meet the policy criteria and will be removed at the next sync — private teams only, and only when that number is above zero. +- The number of qualifying users who will be added at the next sync — only when auto-add is enabled and that number is above zero. +- An **empty-team warning** if the team is private and no user matches the policy ("Saving may result in an empty private team"). +- A confirmation prompt: "Are you sure you want to apply the membership policy?" + +**To remove a policy:** Select the trash icon next to the policy row and confirm in the **"Remove this team from policy"** modal, then **Save**. Existing members are retained and the team returns to its standard access mode at the next sync. + +**Policy list team counts:** The **Membership Policies** list page shows the count of channels and teams each policy is applied to — for example, `2 channels, 1 team`. A zero side is omitted (so `1 team` not `0 channels, 1 team`). + +### Configure team-specific membership rules + +In addition to a system-wide parent policy, System Admins can define team-specific rules directly on the per-team System Console page. + +1. Go to **System Console \> User Management \> Teams** and open the team. + +2. Enable the **Manage membership with attribute based membership policies** switch. + +3. Scroll to the **Team-specific membership rules** panel. + +4. Select **Add attribute** to add a condition. For each condition, choose: + + - **Attribute**: The user profile attribute to evaluate. + - **Operator**: How the attribute must match. Options: **Is**, **Is not**, **In**, **Starts with**, **Ends with**, **Contains**. For ranked attributes: **Is exactly**, **Is at least**, **Is greater than**, **Is at most**, **Is less than**. + - **Value**: The required attribute value. + + All conditions are combined with a logical AND — users must satisfy all of them. + +5. Optionally, check **Auto-add members based on access rules**. This checkbox is enabled once the team has at least one rule **or** a linked parent policy. There is only one auto-add setting per team — it is not configured per linked policy. + +6. Select **Save**. The **Apply membership policy** modal shows the impact counts before changes are applied. + + + +Saving rules always triggers an immediate team sync — **even when auto-add is off**. On private teams, this immediately enforces the rules by removing members who no longer qualify. Confirm the impact in the save modal before proceeding. + + + + + +Team-specific rules compose additively with any parent policy assigned to the team. A user must satisfy **both** the parent policy and the team-specific rules. Team-specific rules cannot weaken or bypass the parent. + + + +### Sync status footer (System Console) + +A sync status footer is rendered at the bottom of the **Team-specific membership rules** panel — scroll down within the panel to find it. + +- **"Never synced."** with a **Sync now** link — no sync has run for this team yet. +- **"Last synced N minutes ago."** with a **Sync now** link — after a prior sync. Older syncs are reported in hours or days. +- Clicking **Sync now** changes the link to **"Syncing…"** with a spinner while the job is in-flight, then updates to **"Last synced just now."** on completion. + +### Monitor membership sync + +System Admins can review the results of team sync jobs from the System Console. + +1. Go to **System Console \> System Attributes \> Membership Policies** and scroll to the **Membership Sync Jobs** panel. +2. Select a job row to open the **Sync Job Details** modal. +3. Select the **Teams** tab. + +The Teams tab shows per-team rows with: + +- A `+N added / −N removed` summary for each governed team. +- A **mass-removal warning indicator** on any team row where more than 50% of members would be removed. This is a warning only — the job is not blocked. +- An expandable per-team user drill-down showing which users were added and removed. + + + +The Teams tab appears only when viewing a team sync job directly, or a channel sync job that was chained from a team sync. The system console section heading was renamed from "Channel access control sync jobs" to **"Membership Sync Jobs"** to reflect both job types. + + + + + +The **Run Channel Sync** button on the Membership Policies page runs a channel sync only, not a team sync. To trigger a team sync, use the **Sync now** link on the per-team System Console page or in Team Settings \> Team Membership tab. + + + +## Team Admin configuration + +### Team Membership tab + +From Mattermost v11.10, Team Settings has four tabs: **Info**, **Access**, **Team Membership**, and **Channel Membership**. + + + +The fourth tab was previously labeled **Membership Policies**. It is now labeled **Channel Membership** and covers channel-scope policies only. The new **Team Membership** tab (the third tab) is for policies that control who can join the team itself. + + + +The **Team Membership** tab lets Team Admins view the system policy applied to their team and configure team-specific custom rules — without requiring System Admin involvement for every change. + +The tab is visible only when: + +- **Enable Attribute-Based Access Control** is on. +- The `TeamMembershipAccessControl` feature flag is on (enabled by default). +- The user has the `manage_team_access_rules` permission (Team Admin or System Admin). + +To open Team Settings: select the team name in the sidebar → **Team Settings** → **Team Membership** tab. + +### System policy indicator + +When a system-level policy is applied to the team by a System Admin, a non-dismissible information banner appears at the top of the Team Membership tab, showing the name of the applied policy. The banner is absent when no parent policy exists. + +### Configure custom rules + +Team Admins can add attribute rules that apply on top of any system policy. These rules use the same Basic Mode editor as channel rules. + +1. Select **Add attribute**. +2. Choose the attribute, operator, and value for each condition. +3. Add additional rules as needed. All rules are AND-combined. +4. Select **Save** to open the save confirmation modal. + +Clearing every rule and saving opens a **"Remove membership rules?"** modal instead. Confirming removes the team's attribute enforcement; current members keep their access. + +Available operators: **Is**, **Is not**, **In**, **Starts with**, **Ends with**, **Contains**. For ranked attributes: **Is exactly**, **Is at least**, **Is greater than**, **Is at most**, **Is less than**. + + + +Saving rules always triggers an immediate team sync — **even when auto-add is off**. On private teams, this removes members who no longer satisfy the rules. Review the impact counts in the confirmation modal before saving. + + + + + +Team Settings rules are Basic Mode only. Advanced CEL expressions are not available here. For complex rules with nested logic or mixed operators, a System Admin must create a system-wide parent policy in the System Console. + + + +### Auto-add members + +The **Auto-add members based on access rules** checkbox controls whether the sync job automatically adds qualifying non-members to the team. + +- This checkbox is enabled only when at least one rule exists, **or** when a system-level policy is applied. +- Checking it and saving triggers an immediate backfill scan — qualifying non-members are added right away. +- Subsequent syncs continue to add newly qualifying users. +- Turning auto-add **off** does not remove any members — it is additive only. Toggling auto-add off also does **not** trigger a sync job. + +### Test access rule + +Select **Test access rule** to open a preview modal listing users who match the current rules, before saving. This lets you verify your intended scope without applying the rules. + + + +If the current rules would exclude the editing Team Admin, the **Test access rule** button is disabled with an explanatory tooltip rather than returning results. + + + +### Save confirmation and safety + +Selecting **Save** opens a confirmation modal before changes are applied. What it shows depends on the team's mode: + +**Private teams (strict):** + +- The number of users who match the current rules and will have access. +- The number of current members who do not match the rules and may be affected — shown only when that number is above zero. + +**Public teams (advisory):** + +- A note that the rules are advisory: no one is blocked or removed. +- The number of users who match the current rules. + +The counts are evaluated against the team's rules combined with any parent policy. + +**Empty-team warning**: For private teams, if no user matches the rules, the modal displays a highlighted warning. Save is not blocked, but the team will be empty until sync runs. + +**Self-exclusion hard block**: On private teams, if the rules would exclude the editing Team Admin, a separate error modal appears *before* the confirmation modal and prevents saving. Select **Back to editing** to adjust the rules. Public teams are exempt — advisory mode never removes anyone. + + + +By design, the self-exclusion block evaluates only the admin's own team rules. A system-level parent policy that excludes the admin is a System Admin decision and is not blocked here. + + + +### Sync status footer (Team Settings) + +Below the auto-add section, a sync status footer appears whenever the team has at least one rule or a parent policy applied: + +- **"Never synced."** + **Sync now** link. +- **"Last synced N minutes ago."** + **Sync now** link. +- After clicking **Sync now**: **"Syncing…"** with spinner → **"Last synced just now."** on completion. + +The footer is not shown in the empty state (no rules and no parent policy). + +Clicking **Sync now** creates a team sync job scoped to this team only. + +## End-user experience + +### Browse Teams + +The Browse Teams directory respects team ABAC enforcement: + +**Private + ABAC teams (strict mode):** + +- Non-qualifying users who are not already members do not see the team in Browse Teams at all. The team is simply absent — not greyed out or locked. +- Qualifying users and existing members see the team normally. + +**Public + ABAC teams (advisory mode):** + +- All users see the team. +- Qualifying users who are not yet members see a **Recommended** chip (lightbulb outline icon) next to the team name. +- Users who are already members, or who do not qualify for the policy, do not see the chip. + +**Teams without a policy:** + +- Behave exactly as before — no filtering, no chip. + +### Invite People modal + +The Invite People modal adapts to the team's enforcement mode: + +**Private + ABAC team (strict mode):** + +- Only users who qualify for the team's membership policy appear in search results. Non-qualifying users are filtered out before any results are shown. +- A notice titled **"Team access is restricted by user attributes"** informs admins: *"Only users who meet the membership requirements can be added to this team."* +- The notice lists the policy's attribute value tags (for example, "Department: Engineering"). +- The invite link warns: *"People who use this link must meet the membership requirements to join."* + +**Public + ABAC team (advisory mode):** + +- All users appear in search results — there is no filtering because advisory mode never blocks access. +- A notice titled **"This team has membership requirements"** is still shown, explaining that users who do not meet them can still join but will not be automatically added. +- The invite link warns: *"People who use this link can join even if they do not meet the membership requirements, but will not be automatically added."* + +**Team without a policy:** + +- No change from previous behavior — all users appear, no notice shown. + +### Add Members flow (admin) + +When a System Admin or Team Admin uses the **Add Members** admin flow on a private + ABAC team, non-qualifying users are blocked at selection time rather than at submission: + +- Non-qualifying candidates show an inline **"Does not meet membership requirements"** indicator on their row and cannot be selected, including by keyboard. +- Only qualifying users can be added to the selection, so the add never fails partway through. + +On a public + ABAC team (advisory mode), all users can be added without restriction. + +### Team Members modal + +When a team has an active membership policy, a notice banner appears at the top of the Team Members modal: + +- On private teams: **"Team access is restricted by user attributes"** — only people who meet the membership requirements can be members. +- On public teams: **"This team has membership requirements"** — people who do not meet them can still join, but will not be automatically added. +- The banner lists the policy's attribute value tags (for example, "Department: Engineering"). Values the viewer is not permitted to see are stripped server-side, so a non-holder sees only the notice. + +### Membership notifications + +**Removal notification:** When the sync job removes a non-qualifying member from a private team, that user receives a direct message from the System Bot identifying the team they were removed from. The message does not include policy names, attribute values, or CEL expressions. + +**Auto-add notification:** When the sync job auto-adds a qualifying user to a team, that user receives a direct message from the System Bot identifying the team they were added to. Removal and auto-add notifications use different icons so users can distinguish them at a glance. + +## Policy inheritance and composition + +When a parent (system-level) policy and custom team rules both apply: + +- The parent policy is shown in a non-dismissible info banner at the top of the Team Membership tab (read-only). +- The user must satisfy **both** the parent policy and the custom team rules to be admitted. +- Custom rules can only add restrictions — they cannot weaken or bypass the parent policy. +- Deleting a parent policy does not unlink it from the team or delete the team's own rules. Unlink the policy from each team before deleting it. + +## Sync behavior + +A team sync batch runs in the following order: + +1. **Evaluate team membership rules** for all teams that have a policy assigned. +2. **Removal pass** (private + ABAC teams only): remove members who no longer qualify. Each removal triggers a channel cascade — the user is removed from all channels within the team. Each removal notifies the user by system-bot DM and is recorded in the audit log. Ordinary, non-ABAC team leaves are not recorded as policy-driven cascades. +3. **Auto-add pass** (any mode, when auto-add is enabled): add qualifying non-members to the team. Each addition emits a system-bot DM. +4. **Channel membership sync** (chained): evaluate and apply channel policy changes. Deduped against any already-pending or in-progress channel sync job. + +**Mass-removal guardrail**: If a sync pass would remove more than 50% of a team's current members, the job sets a warning flag visible in the Sync Job Details \> Teams tab. The job is not blocked — all removals proceed — but the warning is surfaced for admin review. + +Team sync also runs automatically on a schedule to handle attribute changes propagated from LDAP or SAML. The interval is set by `AccessControlSettings.SyncJobIntervalSeconds` and defaults to 3600 seconds (60 minutes). The minimum accepted value is 60 seconds, and a change requires a server restart to take effect. The same interval governs channel membership sync. + +## Mutual exclusivity with group sync + +A team managed by LDAP/AD group synchronization cannot have an ABAC membership policy assigned. Attempting to assign a policy to a group-synced team returns an error. + +You must choose one membership control mechanism per team: group sync or ABAC. + +## Troubleshooting and FAQs + +### Why did the Access tab change and where did the "Allow any user to join" checkbox go? + +From Mattermost v11.10, the "Allow any user to join" checkbox has been permanently replaced by **Public Team** and **Private Team** selection cards on the Access tab. This change applies to all teams on all deployments regardless of ABAC. The cards are functionally equivalent to the old checkbox — Public Team is the same as having the checkbox enabled, Private Team is the same as having it disabled. + +### Why is the Team Membership tab not visible in Team Settings? + +The tab requires all of the following: + +- **Enable Attribute-Based Access Control** is ON in System Console \> System Attributes \> Attribute-Based Access. +- The `TeamMembershipAccessControl` feature flag is ON (enabled by default). +- The user has the `manage_team_access_rules` permission (Team Admin or System Admin). + +If all three conditions are met but the tab is still missing, confirm the feature flag has not been disabled by checking **System Console \> Experimental \> Feature Flags** or the server configuration. + +### Why are private ABAC teams not appearing in Browse Teams for some users? + +This is intended behavior. When a private team has an ABAC policy and a user does not satisfy that policy, the team is completely hidden from them in Browse Teams and search results. They will not see an error or a locked entry — the team simply does not appear. Qualifying users see the team normally. + +### Can I use advanced CEL expressions in Team Settings? + +No. The Team Membership tab uses Basic Mode only — the same simple attribute editor available in Channel Settings. For rules that require nested logic, mixed `&&` / `||` operators, or grouping, a System Admin must create a system-wide parent policy using the CEL editor in the System Console. + +### Can a group-synced team use ABAC? + +No. Group sync and ABAC are mutually exclusive on a per-team basis. If a team is group-constrained, assigning an ABAC policy returns an error. You must remove the group sync configuration before applying an ABAC policy, or vice versa. + +### How quickly are membership changes applied? + +Saving rules in Team Settings or the System Console triggers an immediate team sync — **including when auto-add is off**, because enforcement (removal on private teams) runs regardless of the auto-add setting. Changes are applied as soon as the sync completes. A scheduled sync also runs on the interval set by `AccessControlSettings.SyncJobIntervalSeconds` (60 minutes by default) to process attribute changes from LDAP or SAML. + +### Does System Admin role bypass team ABAC enforcement? + +No. All roles — including System Admin — are subject to team ABAC policy evaluation. A System Admin who does not satisfy a private team's policy cannot join that team as a member through the standard UI, though they can still access the team's configuration in the System Console and make changes. + +### What happens when I switch a team from public to private while a policy is assigned? + +If team ABAC is enabled (Enterprise Advanced license and **Enable Attribute-Based Access Control**) and a policy is assigned to the team, clicking **Private Team** opens a confirmation modal — **"Switch to Private Team?"** — showing how many current members do not meet the policy criteria. Confirming the switch saves the change and triggers an immediate sync to enforce strict mode. Members who don't qualify are removed at that sync. + +If the admin making the switch does not meet the criteria themselves, the switch is blocked with a **"Cannot switch to Private Team"** modal. + +If no policy is assigned, the switch saves directly with no confirmation. + +### What happens when I switch a team from private to public while a policy is assigned? + +Switching from Private to Public always saves directly with no confirmation modal. The team immediately transitions to advisory mode: existing members (including non-qualifying ones) are retained, and no removals occur. The policy continues to drive the Recommended tag and optional auto-add for qualifying users. + +### Can I add a non-qualifying user to a private ABAC team? + +No. The enforcement gate applies to all add paths: the Invite People modal (non-qualifying users are filtered from search results entirely), the Add Members admin flow (non-qualifying users cannot be selected), and direct API calls. The error message is generic and does not expose policy names or attribute details. + +### How does ABAC interact with email-domain restrictions? + +Email-domain restrictions (configured on the Access tab) and ABAC rules (Team Membership tab) apply independently, and a user must satisfy both to join the team. The domain check runs first, so a user rejected on domain grounds never reaches policy evaluation. The two settings are not cross-validated at configuration time, so review them together when debugging unexpected access denials. + +### Why does saving rules trigger a sync even when auto-add is off? + +Auto-add controls only the **add pass** (whether sync adds qualifying non-members). The **enforcement pass** (removing non-qualifying members from private teams) runs whenever rules exist, regardless of auto-add. This ensures that newly saved or changed rules take effect immediately rather than waiting up to 60 minutes for the next scheduled sync. diff --git a/docs/main/administration-guide/manage/admin/attribute-based-access-control.mdx b/docs/main/administration-guide/manage/admin/attribute-based-access-control.mdx index 785832d4c8cb..1e49833803f8 100644 --- a/docs/main/administration-guide/manage/admin/attribute-based-access-control.mdx +++ b/docs/main/administration-guide/manage/admin/attribute-based-access-control.mdx @@ -5,13 +5,14 @@ title: "Attribute-Based Access Control" From Mattermost v10.9, system admins in large or complex organizations who require Zero Trust Security when handling with sensitive information can prevent unauthorized access through attribute-based access controls. -Enforcing strict access controls based on user attributes eliminates manual role adjustment processes that can lead to security risks, inefficiencies, or inappropriate access, while maintaining security and compliance by ensuring that only authorized users can access specific Mattermost channels. +Enforcing strict access controls based on user attributes eliminates manual role adjustment processes that can lead to security risks, inefficiencies, or inappropriate access, while maintaining security and compliance by ensuring that only authorized users can access specific private Mattermost channels and teams. On public channels and teams, policies are advisory rather than a gate — see the advisory and strict behaviour described below. Attribute-based access control (ABAC) can be used with the following policy types: -- **System-wide access policies** (managed by System Admins): Centralized policies created in the System Console that can be applied across multiple channels. See [System-wide attribute-based access policies](/administration-guide/manage/admin/abac-system-wide-policies). +- **System-wide access policies** (managed by System Admins): Centralized policies created in the System Console that can be applied across multiple channels and teams. See [System-wide attribute-based access policies](/administration-guide/manage/admin/abac-system-wide-policies). - **Permission policies** (managed by System Admins): Attribute-based restrictions on user actions such as file upload and file download. See [Permission policies](/administration-guide/manage/admin/abac-system-wide-policies#permission-policies). -- **Team-scoped membership policies** (managed by Team Admins): Channel membership policies that Team Admins can create, edit, and delete directly from Team Settings for channels in their team. See [Manage team-scoped membership policies in Team Settings](/administration-guide/manage/admin/abac-channel-access-rules#manage-team-scoped-membership-policies-in-team-settings). +- **Team membership policies** (managed by System Admins and Team Admins): Attribute-based rules that control who can join a team. On private teams, rules gate directory visibility, join evaluation, and removal at sync (strict mode). On public teams, rules drive a "Recommended" tag and optional auto-add without restricting access (advisory mode). See [Team membership access policies](/administration-guide/manage/admin/abac-team-membership). +- **Team-scoped channel membership policies** (managed by Team Admins): Channel membership policies that Team Admins can create, edit, and delete directly from the Channel Membership tab in Team Settings for channels in their team. See [Team-level channel membership policies](/administration-guide/manage/admin/abac-team-channel-policies). - **Channel-specific access rules** (managed by Channel Admins): Self-service access rules that Channel Admins can configure directly in Channel Settings for individual channels. See [Channel-specific access rules](/administration-guide/manage/admin/abac-channel-access-rules). From Mattermost v11.8, ABAC policies can be applied to **both private and public channels**, with deliberately different semantics for each: @@ -21,6 +22,8 @@ From Mattermost v11.8, ABAC policies can be applied to **both private and public Default channels (Town Square, Off-Topic), shared channels, and group-synced channels remain ineligible. +From Mattermost v11.10, ABAC policies can also be applied to **teams**, with the same advisory/strict model keyed on whether the team is public or private. See [Team membership access policies](/administration-guide/manage/admin/abac-team-membership) for details. + ## Before you begin Attribute-based access controls require defined user attributes that are either synchronized from an external system (such as LDAP or SAML) or manually configured and enabled on your Mattermost server. You'll need to [configure user attributes](/administration-guide/manage/admin/user-attributes) in the System Console first before creating access policies. @@ -39,15 +42,16 @@ From Mattermost v11.8.0, admins can configure membership policies for both publi **System Admins can:** -- Create [system-wide access policies](/administration-guide/manage/admin/abac-system-wide-policies) that can be assigned across multiple channels in the System Console. Membership policies can be applied to both public and private channels, with [advisory behavior on public channels](/administration-guide/manage/admin/abac-channel-access-rules#public-and-private-channel-behavior). +- Create [system-wide access policies](/administration-guide/manage/admin/abac-system-wide-policies) that can be assigned across multiple channels and teams in the System Console. Membership policies can be applied to both public and private channels, with [advisory behavior on public channels](/administration-guide/manage/admin/abac-channel-access-rules#public-and-private-channel-behavior). - Assign [individual channel policies](/administration-guide/manage/admin/abac-system-wide-policies#define-access-controls-per-channel) to specific channels in the System Console. +- [Assign membership policies to teams](/administration-guide/manage/admin/abac-team-membership#assign-a-membership-policy-to-a-team) via the per-team System Console page, with advisory enforcement on public teams and strict enforcement on private teams. - Define [permission policies](/administration-guide/manage/admin/abac-system-wide-policies#permission-policies) that restrict actions such as file upload and file download based on user attributes. - [Simulate policy outcomes](/administration-guide/manage/admin/abac-system-wide-policies#simulate-access) to preview whether selected users can perform actions such as joining a channel or uploading and downloading files before saving policy changes. **Team Admins can:** -- Create, edit, and delete [team-scoped channel membership policies](/administration-guide/manage/admin/abac-channel-access-rules#manage-team-scoped-membership-policies-in-team-settings) for channels in their team directly from Team Settings, when granted the `manage_team_access_rules` permission. -- Create and manage [team-level channel membership policies](/administration-guide/manage/admin/abac-team-channel-policies) in Team Settings, scoping attribute-based rules to one or more private channels within their team. +- View the system policy applied to their team and [configure custom team membership rules](/administration-guide/manage/admin/abac-team-membership#configure-custom-rules) directly from the **Team Membership** tab in Team Settings, when granted the `manage_team_access_rules` permission. +- Create and manage [team-level channel membership policies](/administration-guide/manage/admin/abac-team-channel-policies) from the **Channel Membership** tab in Team Settings, scoping attribute-based rules to one or more channels within their team. **Channel Admins can:** diff --git a/docs/main/administration-guide/manage/admin/installing-license-key.mdx b/docs/main/administration-guide/manage/admin/installing-license-key.mdx index b2d84571c2d2..86347e4f5195 100644 --- a/docs/main/administration-guide/manage/admin/installing-license-key.mdx +++ b/docs/main/administration-guide/manage/admin/installing-license-key.mdx @@ -46,7 +46,7 @@ You don't need to wait for your current license key to expire before replacing i -To review license usage before uploading a new key, go to **System Console \> Reporting \> System Statistics**. The **Total Activated Users** field shows the primary paid seat count used for license validation. Review **Single-channel Guests** separately because guests in exactly one channel are tracked outside the primary paid seat count, are free up to a 1:1 ratio with licensed seats, and generate warnings instead of hard enforcement when that allowance is exceeded. +To review license usage before uploading a new key, go to **System Console \> Reporting \> System Statistics**. The **Total Activated Users** field shows the primary paid seat count used for license validation. Review **Single-channel Guests** separately because guests in exactly one active channel are tracked outside the primary paid seat count, are free up to a 1:1 ratio with licensed seats, and generate warnings instead of hard enforcement when that allowance is exceeded. Only active channels count toward guest channel access for billing. Archived channels are excluded. diff --git a/docs/main/administration-guide/manage/admin/migration.mdx b/docs/main/administration-guide/manage/admin/migration.mdx index 547ad92c7c1b..5c41d1cb8821 100644 --- a/docs/main/administration-guide/manage/admin/migration.mdx +++ b/docs/main/administration-guide/manage/admin/migration.mdx @@ -8,6 +8,7 @@ Whether you’re migrating from another platform, upgrading your database, or us - [Migrate from MySQL to PostgreSQL](/deployment-guide/postgres-migration) - Learn how to migrate from MySQL to PostgreSQL. - [Server migration guide](/administration-guide/onboard/migrating-to-mattermost) - Learn about about migrating to Mattermost. - [Migrate from Slack](/administration-guide/onboard/migrate-from-slack) - Learn how to migrate from Slack to Mattermost. +- [Migrate from Rocket.Chat](/administration-guide/onboard/migrate-from-rocketchat) - Learn how to migrate from Rocket.Chat to Mattermost. - [Migrate from Gitlab Omnibus](/administration-guide/onboard/migrate-gitlab-omnibus) - Learn how to migrate from GitLab Omnibus to a standalone Mattermost installation. - [Bulk export tool](/administration-guide/manage/bulk-export-tool) - Learn about the bulk export tool for Mattermost. - [Bulk loading tool](/administration-guide/onboard/bulk-loading-data) - Learn about the bulk loading tool for Mattermost. diff --git a/docs/main/administration-guide/manage/statistics.mdx b/docs/main/administration-guide/manage/statistics.mdx index 5c86963394df..1b45c9607866 100644 --- a/docs/main/administration-guide/manage/statistics.mdx +++ b/docs/main/administration-guide/manage/statistics.mdx @@ -21,7 +21,7 @@ Total Users The total number of active accounts created on your system. Excludes deactivated accounts and single-channel guests. Single-channel Guests -The number of active guest accounts that belong to exactly one channel on the server. Direct messages and group messages don't affect whether a guest is counted as a single-channel guest. Single-channel guests are counted separately from the primary paid seat count and are free up to a 1:1 ratio with licensed seats. When this count exceeds the allowance, the statistic is highlighted as a warning for system admins. +The number of active guest accounts that belong to exactly one active channel on the server. Direct messages and group messages don't affect whether a guest is counted as a single-channel guest. Archived channels are excluded. Single-channel guests are counted separately from the primary paid seat count and are free up to a 1:1 ratio with licensed seats. When this count exceeds the allowance, the statistic is highlighted as a warning for system admins. Total Teams The total number of teams created on your system. diff --git a/docs/main/administration-guide/onboard/advanced-permissions-backend-infrastructure.mdx b/docs/main/administration-guide/onboard/advanced-permissions-backend-infrastructure.mdx index 81881a5e09bf..5195aa4a8420 100644 --- a/docs/main/administration-guide/onboard/advanced-permissions-backend-infrastructure.mdx +++ b/docs/main/administration-guide/onboard/advanced-permissions-backend-infrastructure.mdx @@ -614,7 +614,7 @@ Permissions in Mattermost are a property of the server code base and are not cre - + diff --git a/docs/main/administration-guide/onboard/guest-accounts.mdx b/docs/main/administration-guide/onboard/guest-accounts.mdx index 24b9e82019e6..7bb9e5023b1e 100644 --- a/docs/main/administration-guide/onboard/guest-accounts.mdx +++ b/docs/main/administration-guide/onboard/guest-accounts.mdx @@ -9,7 +9,7 @@ Guest accounts in Mattermost are a way to collaborate with individuals, such as - A system admin must [enable guest access](/administration-guide/configure/authentication-configuration-settings#guest-access) before guests can be invited. - Mattermost Enterprise and Professional customers can [control who can invite guests](/administration-guide/onboard/advanced-permissions) in their organization. By default, only system admins can invite guests. -- Guest accounts don't all consume a licensed seat in the same way. Guests in exactly one channel are treated as single-channel guests and don't count toward the primary paid seat count. They're free up to a 1:1 ratio with licensed seats. Guests in multiple channels continue to count as paid active users. Direct messages and group messages don't affect whether a guest is counted as a single-channel guest. +- Guest accounts don't all consume a licensed seat in the same way. Guests in exactly one active channel are treated as single-channel guests and don't count toward the primary paid seat count. They're free up to a 1:1 ratio with licensed seats. Guests in multiple active channels continue to count as activated users for billing purposes. Direct messages and group messages don't affect whether a guest is counted as a single-channel guest. Only active channels count toward guest channel access for billing. Archived channels are excluded. - You'll identify guest users in Mattermost based on their **GUEST** badge next to their name and profile picture. Channels that contain guests also display the message **\*This channel has guests** in the channel header. @@ -140,9 +140,10 @@ Previous guest users will be activated with the next synchronization. If their c Guest billing depends on how many channels a guest can access: -- Guests in exactly one channel are treated as single-channel guests. They don't count toward the primary paid seat count and are free up to a 1:1 ratio with your licensed seats. -- Guests in multiple channels continue to count as regular paid active users. +- Guests in exactly one active channel are treated as single-channel guests. They don't count toward the primary paid seat count and are free up to a 1:1 ratio with your licensed seats. +- Guests in multiple active channels continue to count as activated users. - Direct messages and group messages don't change whether a guest is treated as a single-channel guest. +- Only active channels count toward guest channel access for billing. Archived channels are excluded. If your single-channel guest count exceeds the 1:1 allowance, Mattermost shows soft warnings to system admins. Guest creation and guest access aren't blocked. @@ -150,7 +151,7 @@ If your single-channel guest count exceeds the 1:1 allowance, Mattermost shows s Mattermost now supports single-channel guests. -Guests who belong to exactly one channel are counted separately from your primary paid seat count and are free up to a 1:1 ratio with licensed seats. Guests who belong to multiple channels continue to count as paid active users. Direct messages and group messages don't change whether a guest is treated as a single-channel guest. +Guests who belong to exactly one active channel are counted separately from your primary paid seat count and are free up to a 1:1 ratio with licensed seats. Guests who belong to multiple active channels continue to count as activated users. Direct messages and group messages don't change whether a guest is treated as a single-channel guest. Only active channels count toward guest channel access for billing. Archived channels are excluded. If the number of single-channel guests exceeds the 1:1 allowance, Mattermost shows dismissible warning indicators to system admins on the relevant reporting and license pages. Mattermost doesn't block adding guests or starting the server when this limit is exceeded. diff --git a/docs/main/administration-guide/onboard/migrate-from-rocketchat.mdx b/docs/main/administration-guide/onboard/migrate-from-rocketchat.mdx new file mode 100644 index 000000000000..759a19e1fdec --- /dev/null +++ b/docs/main/administration-guide/onboard/migrate-from-rocketchat.mdx @@ -0,0 +1,303 @@ +--- +title: "Migrate from Rocket.Chat" +--- + + +## Overview + +Mattermost provides a migration path from Rocket.Chat, bringing your users, channels, messages, threads, direct messages, reactions, and file attachments into a self-hosted Mattermost environment. + +Rocket.Chat has no hosted "export workspace" feature. Instead, you export the underlying MongoDB database with `mongodump` and transform that dump into a Mattermost bulk import file using the `mmetl` tool. This means the export step is a database operation that typically requires access to the Rocket.Chat server and its MongoDB instance. + +The migration is a multi-step process: + +1. [Preparations](#1-preparations) — scope the migration, gather MongoDB and attachment-storage details, and prepare the Mattermost server. +2. [Export your Rocket.Chat data](#2-export-your-rocketchat-data) — produce a `mongodump` of the Rocket.Chat database. +3. [Transform the export](#3-transform-the-export-for-mattermost) — validate with `mmetl check rocketchat` and convert with `mmetl transform rocketchat`. +4. [Import into Mattermost](#4-import-into-mattermost) — upload and process the archive with `mmctl`. +5. [Validate, test, and go live](#5-validate-test-and-go-live) — verify the trial import before scheduling the production cutover. + + + +These instructions describe a *best effort* migration designed to preserve the majority of your messages, files, and channel structure. Manual adjustments are often required, and larger deployments should plan for multiple trial runs in a staging environment before a production import. Consider [talking to a Mattermost expert](https://mattermost.com/contact-sales/) if your organization needs migration support. + + + +## 1. Preparations + +This guide assumes you already have a Mattermost server deployed and ready to accept your data. If not, review the [deployment documentation](/deployment-guide/server/server-deployment-planning#deployment-options) first. + +### Scope definition + +- **Data history**: Decide how much history you need. Because `mongodump` captures the whole database, scoping is done mainly through what you migrate and validate rather than by trimming the export. +- **Export size**: The size of your Rocket.Chat database and attachments directly affects processing and import time. Plan for longer iteration cycles on large deployments. +- **File attachments**: Consider excluding very large or non-critical attachments with `--skip-attachments` for early test runs to speed up iteration. + +### Rocket.Chat / MongoDB prerequisites + +- You need access to the Rocket.Chat MongoDB instance and the `mongodump` tool from the [MongoDB Database Tools](https://www.mongodb.com/docs/database-tools/). +- Identify the database name (commonly `meteor`) and the connection URI. +- The transform reads these collections from the dump: `users`, `rocketchat_room`, `rocketchat_message`, and `rocketchat_subscription` (all required), plus `rocketchat_uploads` and `rocketchat_uploads.chunks` (for attachments). + + + +This tool was validated against **Rocket.Chat v8.5**. Rocket.Chat changes its MongoDB schema between versions, so exports from other versions may parse differently. If you hit unexpected parse errors, check for a newer `mmetl` release before assuming the export is at fault. + + + +### Attachment storage: GridFS vs. FileSystem + +Rocket.Chat can store uploaded files in one of two ways. Confirm which your deployment uses (**Admin \> Settings \> File Upload \> Storage Type**) before you export, because it changes how you run the transform: + +- **GridFS** (stored inside MongoDB): attachments are captured directly in the `mongodump` (`rocketchat_uploads.chunks.bson`) and extracted automatically. No extra flag needed. +- **FileSystem** (stored on disk): the `mongodump` contains only file metadata. You must also copy the Rocket.Chat uploads directory and point `--uploads-dir` at it during the transform. + +### Infrastructure considerations + +- **Test environment**: Always run the migration in a development or staging environment first. Most migrations require several iterations. +- **Operating system**: `mmetl` is supported on Linux and macOS. Windows (including WSL) is not recommended. +- **Storage requirements**: Ensure you have room for the `mongodump` output, the transformed import file, and the extracted attachments. Plan for several times the size of your Rocket.Chat data. +- **File storage**: Imports into AWS S3 (or S3-compatible storage) typically complete faster than local or NFS storage for large datasets. + +### Mattermost server considerations + +- **Fresh server**: The most reliable imports happen on a fresh installation. If importing into an existing server, never import over an existing team, and back up the database and data directory first. +- **Server version**: Run the latest supported version of [Mattermost](/product-overview/mattermost-server-releases). +- **The target team must already exist** in Mattermost and be set to **Public Team**. +- **Configuration settings**: Before importing, adjust: + - `TeamSettings.MaxChannelsPerTeam` and `TeamSettings.MaxUsersPerTeam`: set well above the number of channels/users you are migrating. + - `EmailSettings.EnableSignUpWithEmail` and `EmailSettings.EnableSignInWithEmail`: both `true`. + - `FileSettings.MaxFileSize`: higher than the largest file in your export. + - `ElasticsearchSettings.EnableIndexing`, `EnableSearching`, and `EnableAutocomplete`: set to `false` during the import, then purge and reindex afterward. + +## 2. Export your Rocket.Chat data + +Export the Rocket.Chat MongoDB database with `mongodump`. Replace the URI and database name to match your deployment: + +``` sh +mongodump --uri="mongodb://localhost:3001/meteor" --out=/tmp/rc-dump +``` + +This creates a subdirectory named after the database (for example `/tmp/rc-dump/meteor`) containing the `.bson` files. That database subdirectory — not the parent — is what you pass to `--dump-dir` in the next step. + +If your deployment uses **FileSystem** storage for attachments, also copy the Rocket.Chat uploads directory to a known location so you can reference it with `--uploads-dir`. + +## 3. Transform the export for Mattermost + +[Download the latest release of mmetl](https://github.com/mattermost/mmetl/releases/) for your OS and architecture. Run `mmetl help` to learn more about the tool. + +### Validate the export + +Before transforming, check the integrity of the dump: + +``` sh +./mmetl check rocketchat --dump-dir /tmp/rc-dump/meteor +``` + +This reports structural issues (for example, missing required collections or invalid records) that would cause the transform or import to fail. Details are written to `check-rocketchat.log`. + +`check rocketchat` accepts the same `--guest-handling` flag as the transform, so you can preview how guest users will be treated before running the full transform. + +### Run the transform + +Convert the dump into a Mattermost bulk import file. Replace `` with your Mattermost team name, which must be one word and lowercase (a team named `My Team` becomes `my-team`): + +``` sh +./mmetl transform rocketchat --team --dump-dir /tmp/rc-dump/meteor --output mattermost_import.jsonl +``` + +For **FileSystem** attachment storage, add `--uploads-dir`: + +``` sh +./mmetl transform rocketchat --team --dump-dir /tmp/rc-dump/meteor --uploads-dir /path/to/rocketchat/uploads --output mattermost_import.jsonl +``` + +The tool produces a [.jsonl](https://jsonlines.org/examples) file containing your users, channels, and posts, plus a `data` folder containing the extracted attachments. + +A successful run ends with a summary line in `transform-rocketchat.log` like: + +``` text +Transformation succeeded! Users: 152, Public channels: 48, Private channels: 12, Posts: 39184 +``` + +If the run stops with an error instead — for example, `the RocketChat export contains bot users but --bot-owner was not specified` — no valid import file is produced. Resolve the error (see the flags below) and re-run. + + + +**Iterate incrementally.** Run a small trial first: transform, import into a fresh or restored trial target, and confirm a few channels look right before committing to a full production import. Re-running the same import avoids duplicate posts only when the records' identity fields are unchanged; not every imported entity is deduplicated. Don't rely on re-importing into a modified trial target to reset it. + + + +### Useful transform flags + +- `--uploads-dir `: Path to the Rocket.Chat FileSystem uploads directory. Required when attachments are not stored in GridFS. +- `--bot-owner `: Username of the Mattermost user who will own all imported bots. **Required if the export contains any bot users** — the transform errors out otherwise. +- `--guest-handling `: How to migrate Rocket.Chat guest users (default `guest`): + - `guest` — migrate them as Mattermost guests. Highest fidelity, but the destination server must have Guest Accounts **licensed** (Professional/Enterprise) and **enabled** (`GuestAccountsSettings.Enable`); otherwise the accounts won't behave correctly. + - `user` — migrate them as regular Mattermost members. Works everywhere, but grants guests full member permissions. + - `skip` — drop guest users entirely, along with their memberships and authored posts. +- `--skip-attachments` / `-a`: Skip extracting file attachments. Useful for faster iteration while testing. +- `--attachments-dir `: Directory for extracted attachments (default `data`). +- `--default-email-domain `: When a user's email is missing, generate one from their username and this domain (for example `example.com`). +- `--skip-empty-emails`: Allow users with empty emails. Note that this produces invalid import data that must be corrected before importing. +- `--debug`: Emit `DEBUG`-level detail to `transform-rocketchat.log` to help diagnose slow or failing runs. + +## 4. Import into Mattermost + +Package the `.jsonl` file and `data` folder into a single zip: + +``` sh +zip -r mattermost-bulk-import.zip data mattermost_import.jsonl +``` + +Validate the archive locally before uploading: + +``` sh +mmctl import validate ./mattermost-bulk-import.zip +``` + +Ensure `mmctl` is installed and [authenticated](/administration-guide/manage/mmctl-command-line-tool#mmctl-auth). Then choose an upload method. + +### Standard upload + +For most imports, upload through `mmctl`: + +``` sh +mmctl import upload ./mattermost-bulk-import.zip +mmctl import list available +``` + +Process the import using the name returned by `import list available`: + +``` sh +mmctl import process +``` + +Check the job status. If it shows `pending`, wait and re-run. The `--json` flag is required to see error messages: + +``` sh +mmctl import job show --json +``` + +### Large imports (file store method) + +For large archives (multiple GB), uploading through `mmctl` is slow and error-prone. Instead, place the archive directly into the server's import directory and let the server process it in place: + +1. Copy `mattermost-bulk-import.zip` (with a unique name) into `data/import` in the Mattermost file store — the local data directory, or the `import` prefix of your S3 bucket. +2. Run `mmctl import list available` to confirm the server sees the file. +3. Run `mmctl import process ` and monitor with `mmctl import job show --json`. + +This avoids re-uploading gigabytes through the API and is the recommended path for large migrations. + +### Fixing unread channels and threads + +After importing, messages may appear unread for all users. The following fix is for PostgreSQL deployments only. + + + +Back up the Mattermost database before running these statements. Test the backup and the SQL in a non-production environment first. + + + +``` sql +begin; +UPDATE channelmembers +SET + msgcount = channels.totalmsgcount, + lastupdateat = channels.lastpostat, + lastviewedat = channels.lastpostat, + msgcountroot = channels.totalmsgcountroot +FROM channels +WHERE channelmembers.channelid = channels.id; + +INSERT INTO preferences (UserId, Category, Name, Value) +SELECT + cm.userid, + 'channel_approximate_view_time', + cm.channelid, + cm.lastupdateat::text +FROM + channelmembers cm +ON CONFLICT (userid, category, name) +DO UPDATE SET + Value = EXCLUDED.Value; + +update preferences set value = 'false' where category = 'direct_channel_show'; +update preferences set value = 'false' where category = 'group_channel_show'; + +commit; +``` + +### Placeholder emails and account activation + +Mattermost accounts are created from the emails and usernames in the export. Where an email is missing, a placeholder (for example `username@local`) is generated and must be corrected by a system administrator. Search the final `.jsonl` file for placeholder emails before importing. + +Users activate their accounts through Mattermost's **Password Reset** screen using their email address: + +- **Imports performed by a system administrator**: emails are automatically verified, and users can reset their password immediately. +- **Imports performed by a non-administrator**: users must verify their email address before resetting their password. + +See how to [migrate user authentication to LDAP or SAML](/administration-guide/manage/mmctl-command-line-tool#mmctl-user-migrate-auth) if you use SSO. + +## 5. Validate, test, and go live + +Before production cutover, validate a fresh or restored trial import end to end: + +1. Compare the transform and import logs with source counts for users, channels, posts, and attachments, and investigate errors or unexpected omissions. +2. Sign in as representative users and verify public and private channels, direct and group messages, threads, reactions, files, mentions, permissions, and authentication. +3. Recreate integrations and custom emoji, then purge and rebuild the search index before testing search. +4. Back up the production Mattermost database and file store, schedule a maintenance window, stop writes in Rocket.Chat, create a final export, and repeat the validated process on a fresh or restored production target. +5. After final verification, update DNS or client configuration, invite users to activate their accounts, and keep the Rocket.Chat deployment read-only until the migration is accepted. + +## What migrates and what doesn't + +For core collaboration data — posts, threads, reactions, attachments, users, and channels — you can expect high fidelity. Integrations and Rocket.Chat-specific features do not carry over. + +| Content type | Migrates? | Notes | +|----|----|----| +| Posts and threads | Yes | Rocket.Chat threads become Mattermost threaded replies. Oversized posts are split into continuation replies rather than truncated. | +| Public channels | Yes | Display name, purpose (description), and header (topic) are preserved. | +| Private channels | Yes | | +| Discussions | Yes (converted) | Rocket.Chat discussions are converted to standalone Mattermost channels (public or private, matching the discussion's visibility). The parent-child relationship is not preserved. | +| 1:1 direct messages | Yes | Map directly. Self-DMs are preserved as a direct channel with yourself. | +| Group DMs (3–8 members) | Yes (converted) | Become Mattermost **Group Messages** — functionally equivalent, different terminology. | +| Group DMs (over 8 members) | Converted | Mattermost group messages support at most 8 members, so larger group DMs are converted to **private channels**. | +| Reactions | Yes | Emoji skin-tone modifiers are stripped to a default rendering. Custom emoji require matching names (see below). | +| File attachments | Yes | From GridFS or FileSystem storage. Auto-generated thumbnails are skipped to avoid duplicates. | +| Users | Yes | Inactive Rocket.Chat users are imported as deactivated accounts. | +| Bots | Yes | Reassigned to the `--bot-owner` user. | +| Channel mentions | Best effort | `#channel` references are translated to Mattermost `~channel` links where the channel exists. | +| Join / leave / add / remove events | Yes | Converted to Mattermost system messages. | +| Custom emoji images | No | Reaction *names* are preserved, but the emoji images are not imported (see below). | +| Guest users | Configurable | Controlled by `--guest-handling` (default `guest`). By default, Rocket.Chat guest accounts are imported as Mattermost [guest users](/administration-guide/onboard/guest-accounts) — this requires Guest Accounts to be **licensed** (Professional/Enterprise) and [guest access](/administration-guide/configure/authentication-configuration-settings#guest-access) enabled on the target server. Use `--guest-handling user` to import them as regular members instead (no guest licensing needed), or `--guest-handling skip` to drop them entirely. | +| Encrypted (E2E) channels | No | End-to-end encrypted rooms are skipped entirely, including their messages. | +| Apps, integrations, slash commands, webhooks | No | Recreate using Mattermost [integrations](/integrations-guide/integrations-guide-index). | +| Avatars, user status, custom profile fields | No | Users update their profiles in Mattermost after import. | +| Pinned/starred messages, topic-change and mute events | No | These Rocket.Chat-specific records are not migrated. | + +### Custom emoji + +Custom emoji images are **not** imported with your messages — only the emoji *names* used in reactions are preserved. A reaction is stored as text (`:emoji-name:`) and resolved at render time: + +- If a custom emoji with the same name exists in Mattermost, the reaction renders correctly. +- If not, it shows as a placeholder until the emoji is added. + +Because resolution happens at render time, you can add custom emoji to Mattermost **at any time** — before or after the import — and reactions on historical messages will render once a matching name exists. Names must match exactly. + +## FAQ + +**Do I need to create users before importing?** No. `mmetl` and the import process handle user creation and ordering automatically. + +**What happens if I run the same import twice?** Re-running the same import avoids duplicate posts when identity fields are unchanged, but not every entity is deduplicated and edits to identifying fields can create additional records. Use a fresh or restored trial target for each test run. + +**Where do all my channels and DMs go?** Into the single team you specify with `--team`. Rocket.Chat has no multi-workspace concept, so there is no team-mapping step. + +**How are attachments stored, and why do I need `--uploads-dir`?** Rocket.Chat stores files either in MongoDB (GridFS) or on disk (FileSystem). GridFS files are captured in the `mongodump` automatically; FileSystem files are not, so you point `--uploads-dir` at the uploads directory. See [Attachment storage](#attachment-storage-gridfs-vs-filesystem). + +**Why are some channels missing after import?** End-to-end encrypted rooms are skipped and their messages are not migrated. Check `transform-rocketchat.log` for skipped rooms. + +**Do I need to import custom emoji before messages?** No. Emoji resolve at render time, so you can add them whenever. + +**How do I handle a very large import?** Use the file store method — copy the archive directly into the server's `data/import` directory rather than uploading through `mmctl`. See [Large imports](#large-imports-file-store-method). + +**I hit a parse error. Is my export broken?** Possibly not. Rocket.Chat changes its MongoDB schema between versions (this tool was validated against v8.5). Run `mmetl check rocketchat` first, and check for a newer `mmetl` release before assuming the data is at fault. diff --git a/docs/main/administration-guide/onboard/migrating-to-mattermost.mdx b/docs/main/administration-guide/onboard/migrating-to-mattermost.mdx index 82a7bd4628bf..beca1a12ae2b 100644 --- a/docs/main/administration-guide/onboard/migrating-to-mattermost.mdx +++ b/docs/main/administration-guide/onboard/migrating-to-mattermost.mdx @@ -34,6 +34,10 @@ Once your migration is complete and verified, you can optionally [upgrade the Te See the [Migrate from Slack](/administration-guide/onboard/migrate-from-slack) documentation for details on migrating from Slack to Mattermost. +## Move from Rocket.Chat + +See the [Migrate from Rocket.Chat](/administration-guide/onboard/migrate-from-rocketchat) documentation for details on migrating from Rocket.Chat to Mattermost. + ## Move from Jabber BrightScout helped a major U.S. Federal Agency rapidly migrate from Jabber to Mattermost and open sourced their Extract, Transform and Load (ETL) tool at [https://github.com/Brightscout/mattermost-etl](https://github.com/Brightscout/mattermost-etl). Read more about their [case study](https://mattermost.com/blog/u-s-federal-agency-migrates-from-jabber-to-mattermost-the-open-source-way/) online. diff --git a/docs/main/administration-guide/upgrade/admin-onboarding-tasks.mdx b/docs/main/administration-guide/upgrade/admin-onboarding-tasks.mdx index 8ce3ada47fe5..fa4843bea074 100644 --- a/docs/main/administration-guide/upgrade/admin-onboarding-tasks.mdx +++ b/docs/main/administration-guide/upgrade/admin-onboarding-tasks.mdx @@ -139,6 +139,6 @@ Then, enable batched email notifications by setting **System Console \> Notifica **9. Enable Elasticsearch** -Mattermost Enterprise customers can enable [enterprise search](/deployment-guide/reference-architecture/scale/enterprise-search) for optimized search performance at enterprise-scale. Both Elasticsearch and AWS OpenSearch solve many known issues with full text database search, such as dots, dashes, and email addresses returning unexpected results. +Mattermost Enterprise customers can enable [enterprise search](/deployment-guide/reference-architecture/scale/enterprise-search) for optimized search performance at enterprise-scale. Both Elasticsearch and AWS OpenSearch solve many known issues with full text message search in the database, such as dots, dashes, and email addresses returning unexpected results. Before enabling, review the [enterprise search limitations](/deployment-guide/reference-architecture/scale/common-configure-mattermost-for-enterprise-search#enterprise-search-limitations), as some user search behavior differs from database search. Enable Elasticsearch by setting **System Console \> Elasticsearch \> Enable Indexing** to **true**. See the [Elasticsearch](/administration-guide/configure/environment-configuration-settings#enterprise-search) configuration settings documentation for details. Enabling Elasticsearch requires [setting up an Elasticsearch server](/deployment-guide/reference-architecture/scale/elasticsearch-setup#set-up-elasticsearch). diff --git a/docs/main/administration-guide/upgrade/important-upgrade-notes.mdx b/docs/main/administration-guide/upgrade/important-upgrade-notes.mdx index 219da7ae1709..e49c17f4beb0 100644 --- a/docs/main/administration-guide/upgrade/important-upgrade-notes.mdx +++ b/docs/main/administration-guide/upgrade/important-upgrade-notes.mdx @@ -21,8 +21,11 @@ We recommend reviewing the [additional upgrade notes](#additional-upgrade-notes) - - + + + + + diff --git a/docs/main/administration-guide/upgrade/open-source-components.mdx b/docs/main/administration-guide/upgrade/open-source-components.mdx index 4c56a79eec5a..4738928bb668 100644 --- a/docs/main/administration-guide/upgrade/open-source-components.mdx +++ b/docs/main/administration-guide/upgrade/open-source-components.mdx @@ -7,6 +7,7 @@ The following open source components are used to provide the full benefits of Ma ## Desktop +- Mattermost Desktop v6.3.0 - [View Open Source Components](https://github.com/mattermost/desktop/blob/release-6.3/NOTICE.txt). - Mattermost Desktop v6.2.0 - [View Open Source Components](https://github.com/mattermost/desktop/blob/release-6.2/NOTICE.txt). - Mattermost Desktop v6.1.0 - [View Open Source Components](https://github.com/mattermost/desktop/blob/release-6.1/NOTICE.txt). - Mattermost Desktop v6.0.0 - [View Open Source Components](https://github.com/mattermost/desktop/blob/release-6.0/NOTICE.txt). @@ -36,6 +37,7 @@ The following open source components are used to provide the full benefits of Ma ## Mobile +- Mattermost Mobile v2.43.0 - [View Open Source Components](https://github.com/mattermost/mattermost-mobile/blob/release-2.43/NOTICE.txt). - Mattermost Mobile v2.42.0 - [View Open Source Components](https://github.com/mattermost/mattermost-mobile/blob/release-2.42/NOTICE.txt). - Mattermost Mobile v2.41.0 - [View Open Source Components](https://github.com/mattermost/mattermost-mobile/blob/release-2.41/NOTICE.txt). - Mattermost Mobile v2.40.0 - [View Open Source Components](https://github.com/mattermost/mattermost-mobile/blob/release-2.40/NOTICE.txt). @@ -138,6 +140,7 @@ The following open source components are used to provide the full benefits of Ma ## Server +- Mattermost Enterprise Edition v11.10.0 - [View Open Source Components](https://github.com/mattermost/mattermost-server/blob/release-11.10/NOTICE.txt). - Mattermost Enterprise Edition v11.9.0 - [View Open Source Components](https://github.com/mattermost/mattermost-server/blob/release-11.9/NOTICE.txt). - Mattermost Enterprise Edition v11.8.0 - [View Open Source Components](https://github.com/mattermost/mattermost-server/blob/release-11.8/NOTICE.txt). - Mattermost Enterprise Edition v11.7.0 - [View Open Source Components](https://github.com/mattermost/mattermost-server/blob/release-11.7/NOTICE.txt). diff --git a/docs/main/administration-guide/upgrade/prepare-to-upgrade-mattermost.mdx b/docs/main/administration-guide/upgrade/prepare-to-upgrade-mattermost.mdx index c6370b37b4ef..ba9b2218aa8c 100644 --- a/docs/main/administration-guide/upgrade/prepare-to-upgrade-mattermost.mdx +++ b/docs/main/administration-guide/upgrade/prepare-to-upgrade-mattermost.mdx @@ -53,7 +53,7 @@ We strongly recommend that you: -Support for Mattermost Server v10.11 [Extended Support Release](/product-overview/mattermost-server-releases) is coming to the end of its life cycle on August 15, 2026. Upgrading to Mattermost Server v11.7 Extended Support Release or later is recommended. Upgrading from the previous Extended Support Release to the latest Extended Support Release is supported. Review the [important upgrade notes](/administration-guide/upgrade/important-upgrade-notes) for all intermediate versions in between to ensure you’re aware of the possible migrations that could affect your upgrade. +Support for Mattermost Server v10.11 [Extended Support Release](/product-overview/mattermost-server-releases) has come to the end of its life cycle on August 15, 2026. Upgrading to Mattermost Server v11.7 Extended Support Release or later is required. Upgrading from the previous Extended Support Release to the latest Extended Support Release is supported. Review the [important upgrade notes](/administration-guide/upgrade/important-upgrade-notes) for all intermediate versions in between to ensure you’re aware of the possible migrations that could affect your upgrade. diff --git a/docs/main/deployment-guide/calls/calls-rtcd-setup.mdx b/docs/main/deployment-guide/calls/calls-rtcd-setup.mdx index 5b14fab38871..938b0908a1bc 100644 --- a/docs/main/deployment-guide/calls/calls-rtcd-setup.mdx +++ b/docs/main/deployment-guide/calls/calls-rtcd-setup.mdx @@ -377,6 +377,144 @@ To scale RTCD horizontally: When a call starts, the Mattermost server examines the available RTCD servers (via the configured DNS record) and starts the call on the RTCD server with the lowest CPU usage. All participants in the call will connect to that RTCD server; a single call cannot be shared across multiple servers. +## Upgrading RTCD + +RTCD is released and upgraded independently of the Mattermost server. An upgrade consists of replacing the binary or container image and restarting the service. There's no database or schema migration involved. The two things to plan for are preserving the data store and timing the restart so that calls in progress aren't dropped. + +Releases are published to the [RTCD GitHub repository](https://github.com/mattermost/rtcd/releases) as `rtcd-linux-amd64` and `rtcd-linux-arm64` binaries, and to Docker Hub as the [mattermost/rtcd](https://hub.docker.com/r/mattermost/rtcd) image. + +### Preserve the Data Store + +RTCD keeps a small local store at the path set by `data_source` in the `[store]` section of the configuration file, which defaults to `/tmp/rtcd_db`. It holds the client IDs registered by Mattermost servers along with a bcrypt hash of each client's authentication key. This is the only state RTCD persists, and it has to survive the upgrade: + +- **Bare metal or VM.** The store lives outside the binary, so replacing the binary in place preserves it. Verify that `data_source` doesn't point at a location cleared on reboot: the default `/tmp/rtcd_db` is on a temporary filesystem on many distributions. +- **Docker.** The store is inside the container filesystem unless it's mounted, so recreating the container discards it. Mount a volume over the `data_source` path to keep it across image replacements. + +Back the store up by copying its directory while the service is stopped. + + + +If the store is lost, the credentials the Calls plugin holds no longer match anything on the RTCD side, and the plugin can't authenticate. Recovery depends on `allow_self_registration` under `[api.security]`: + +- When it's disabled, which is the default, registration itself requires authenticating first, so the plugin can neither authenticate nor re-register. Calls stays broken until the store is restored or new credentials are provisioned. +- When it's enabled, the plugin detects the failure and registers again automatically, so a lost store recovers on its own. + +Enabling `allow_self_registration` lets any client that can reach the API port register without authenticating. Leave it disabled on any RTCD service reachable from the internet, and enable it only on a private, access-controlled network. + + + + + +The Calls plugin opens its connection to RTCD when the plugin starts, and fails to start if the service isn't reachable. The same applies to the `calls-offloader` service when recording, transcription, or live captions are configured. RTCD therefore has to be up and running before the Mattermost server starts, or before Calls is re-enabled. + +Failures at startup and failures later on behave differently: + +- **During plugin activation**, an initial connection failure leaves Calls deactivated, and the server's plugin health check doesn't retry it, because it only monitors plugins that activated successfully. Once RTCD is reachable, restart the Calls plugin to bring it back. +- **After a connection is established**, later disconnections are retried automatically, so a brief RTCD restart needs no action on the Mattermost side. The plugin makes up to 8 reconnection attempts for a host before dropping it, and a dropped host that's still advertised in DNS is picked up again by the 10-second host check. + + + +### Version Compatibility + +The Calls plugin enforces a minimum RTCD version and won't use a server running an older one. + +For this reason, upgrade RTCD **before** upgrading the Mattermost server to a release shipping a newer version of Calls. When the plugin finds a server below the minimum version: + +- On plugin activation, such as after a Mattermost server restart or upgrade, the failed version check prevents the Calls plugin from starting at all. This happens if *any* of the servers resolved by the **RTCD Service URL** fails the check, not only if all of them do. +- On a server discovered through DNS while the plugin is already running, the failure is logged as an error and the server isn't used. Calls continue to be routed to the remaining servers. + +This means an RTCD server below the minimum version that's left in the DNS record can prevent Calls from starting the next time the Mattermost server restarts, even if calls are working at the time. + +See [Important Upgrade Notes](/administration-guide/upgrade/important-upgrade-notes) for version-specific requirements. To check the version a server is running, query it directly with `curl http://YOUR_RTCD_SERVER:8045/version`. + +### How RTCD Shuts Down + +When RTCD receives a `SIGTERM` or `SIGINT` signal, it drains instead of exiting immediately: it waits for all active call sessions to end before shutting down. Calls in progress are never force-closed, and there's no drain timeout, so the process waits for as long as the last call lasts. + +Two things follow from this behavior: + +- The HTTP and WebSocket API listeners stay open while the service drains, so a draining server can still be assigned new calls. Remove the server from the DNS record *before* signalling the process; otherwise the plugin can keep sending new calls to it, and the drain may never complete. +- Any process supervisor that force-kills the service after a timeout cuts off the calls still running on it, and the default timeouts are generally shorter than a call. + +`systemctl stop rtcd` sends `SIGTERM` to the service, and with the default `KillMode=control-group`, to every process in the unit's control group. systemd then waits for `TimeoutStopSec` before escalating to `SIGKILL`. When that value isn't set explicitly it inherits `DefaultTimeoutStopSec`, which gives a 90-second timeout on a stock systemd installation, so calls still running when the timeout expires are dropped. + +The rolling upgrade below avoids this entirely by draining a server through DNS before stopping it, so the server is already idle by the time the service is stopped and the timeout never comes into play. + +### Upgrading a Single Server + +With a single RTCD server, an upgrade interrupts the service: no new calls can be started while the process is down, and because the service drains on shutdown, the restart doesn't complete until the existing calls end. There are two options: + +- **Wait for the drain to complete.** Send `SIGTERM` and let the service exit after the last call ends. No call is dropped, but the length of the outage depends on how long those calls run, and new calls fail in the meantime. Note that the drain only runs to completion if the process supervisor allows it: with systemd's 90 second default stop timeout, a longer drain is cut short and the remaining calls are dropped. +- **Stop the service at a set time.** Notify participants, then force the process down with `SIGKILL` after a fixed period. Any calls still running are dropped and clients see those calls end. + +Scheduling the upgrade for a period of low usage keeps either option short. See [Communicate scheduled maintenance](/administration-guide/upgrade/communicate-scheduled-maintenance) for templates to notify your users. + +### Rolling Upgrade with Multiple Servers + +When [horizontal scaling](#horizontal-scaling) is configured, servers can be upgraded one at a time without dropping calls. For each server in turn: + +1. **Remove the server from DNS**: + + Remove its IP address from the DNS record that the **RTCD Service URL** resolves to. + +2. **Wait for the plugin to pick up the change**: + + The plugin re-resolves the hostname every 10 seconds and flags servers that are no longer advertised. A flagged server is excluded from new calls, while the calls already running on it continue uninterrupted. + +3. **Wait for the server to go idle**: + + The `rtcd_rtc_sessions_total` metric reports the number of active RTC sessions per call group (see [RTCD Metrics](calls-metrics-monitoring#rtcd-metrics)). The server can be restarted safely once the sum across all groups reaches zero. + +4. **Stop the service**: + + ```bash + sudo systemctl stop rtcd + ``` + + Because the server is already idle at this point, it exits immediately and the stop timeout doesn't come into play. + +5. **Install the new version**: + + Replace the binary or container image with the new version and start the service again. + +6. **Verify the upgrade**: + + ```bash + curl http://YOUR_RTCD_SERVER:8045/version + ``` + +7. **Return the server to DNS**: + + Add its IP address back to the DNS record. The plugin picks the server up on its next resolution cycle and starts assigning new calls to it again. + +Once the server is back in rotation, repeat the process for the next one. + + + +- Since a call always lives entirely on a single server, restarting one server only ever affects the calls hosted on that server. +- Keep enough capacity in the fleet to absorb new calls while a server is out of rotation. Waiting for a server to reach zero sessions can take a while when calls are long-running. + + + +### Upgrading in Kubernetes + +The [RTCD Helm chart](calls-kubernetes#rtcd-helm-chart) defaults to a `RollingUpdate` strategy with `maxUnavailable: 1`, and sets `configuration.terminationGracePeriod` to `18000` seconds (5 hours). That value maps to the pod's `terminationGracePeriodSeconds`, so Kubernetes allows a pod 5 hours to drain its calls before killing it. + +Before changing the image, decide how the data store is handled. The chart ships no `PersistentVolumeClaim` template, and the store defaults to a path inside the container, so each replaced pod starts with an empty store. Since the store is a local embedded database with one instance per pod, a single volume can't be shared across replicas. There are two workable approaches: + +- **Let pods re-register.** Enable `allow_self_registration` on a private, access-controlled network, as described in the warning above, and the plugin re-registers against each new pod automatically. This is the simpler option and needs no storage configuration. +- **Give each pod its own storage.** With `deploymentType: daemonset`, one pod runs per node, so a per-node `hostPath` mounted at the `data_source` path through `configuration.extraVolumes` and `configuration.extraVolumeMounts` gives each pod a store that survives image replacement. + +To upgrade, set `image.tag` to the new version in your values file and apply the chart. Kubernetes sends `SIGTERM` to each pod it replaces, which starts the drain described above. + +The chart doesn't set `maxSurge`, so a `Deployment` rollout uses the Kubernetes default and new pods can be created before the draining ones have exited. Expect old and new pods to run side by side for as long as the drains take, and size the node pool accordingly. `maxUnavailable: 1` bounds how many pods can be unavailable at once; it doesn't serialize the replacements. + + + +Don't reduce `terminationGracePeriod` to a conventional value such as 30 or 60 seconds. When the grace period expires, Kubernetes sends `SIGKILL` and every call still running on that pod is dropped. The default of 5 hours is deliberately long enough to outlast extended meetings. + + + ## Integration with Mattermost Once RTCD is properly set up and validated, configure Mattermost to use it: diff --git a/docs/main/deployment-guide/desktop/desktop-msi-installer-and-group-policy-install.mdx b/docs/main/deployment-guide/desktop/desktop-msi-installer-and-group-policy-install.mdx index 98f29a101d84..0f4021b4f2b2 100644 --- a/docs/main/deployment-guide/desktop/desktop-msi-installer-and-group-policy-install.mdx +++ b/docs/main/deployment-guide/desktop/desktop-msi-installer-and-group-policy-install.mdx @@ -43,9 +43,9 @@ If a user reports a broken shortcut after upgrading to v6.1.0, the user should: ![Go to the mattermost/desktop repository on GitHub.](/images/desktop/msi_gpo/msi_gpo_installation_test_00002.png) -3. Navigate to the release page for [version v6.2.2](https://github.com/mattermost/desktop/releases/latest) and download the appropriate installer for your version of Windows (32-bit vs. 64-bit). +3. Navigate to the release page for [version v6.3.0](https://github.com/mattermost/desktop/releases/tag/v6.3.0) and download the appropriate installer for your version of Windows (32-bit vs. 64-bit). -4. Download the [source.zip](https://github.com/mattermost/desktop/archive/v6.2.2.zip) file as well to extract group policy files. +4. Download the [source.zip](https://github.com/mattermost/desktop/archive/v6.3.0.zip) file as well to extract group policy files. ![In the mattermost/desktop repository on GitHub, go to the release page for the latest desktop release, then download the installer for your version of Windows. Download the source.zip file as well to extract group policy files.](/images/desktop/msi_gpo/msi_gpo_installation_test_00003.png) @@ -90,11 +90,11 @@ The following group policies are available supporting a state option of Not Conf > >
manage_team_access_rules teamManage attribute-based channel membership policies for a team from Team Settings.Manage attribute-based team and channel membership policies for a team from Team Settings.
v12.0

Mattermost v12.0 removes the deprecated interactive dialog date/datetime fields. Top-level min_date, max_date, and time_interval on dialog elements and app fields, and datetime_config.allow_manual_time_entry, are no longer accepted. Integrations must migrate to datetime_config (using manual_time_entry instead of allow_manual_time_entry) before upgrading to v12.0. Legacy keys are silently ignored, so date constraints and manual time entry will not apply until payloads are updated. See the interactive dialogs documentation for details.

v11.10

This migration adds a new composite index, idx_propertyvalues_groupid_updateat_id, on the PropertyValues table covering the columns GroupID, UpdateAt, and ID. The PropertyValues table is part of the Properties/Custom Attributes feature introduced in recent Mattermost versions. This index improves query performance for lookups and range scans that filter or sort by GroupID and UpdateAt, which are common access patterns for this feature. The index is created using CONCURRENTLY, so the build process does not block concurrent reads or writes against the PropertyValues table. The migrations are fully backwards-compatible and no database downtime is expected for this upgrade. The SQL queries included are:

{"-- morph:nontransactional\nCREATE INDEX CONCURRENTLY IF NOT EXISTS idx_propertyvalues_groupid_updateat_id\n    ON PropertyValues(GroupID, UpdateAt, ID);"}
{"-- morph:nontransactional\nDROP INDEX CONCURRENTLY IF EXISTS idx_propertyvalues_groupid_updateat_id;"}

This migration adds a new nullable lastnotifiedat column (bigint) to the useraccesstokens table. The column is intended to track the last time a notification was sent for a given user access token, enabling improved token-related notification logic. Because the column is nullable with no default value, PostgreSQL performs a catalog-only operation—no table rewrite occurs—and the lock is held for only a few milliseconds. Previous versions of Mattermost will simply ignore the new column, ensuring seamless compatibility across a rolling upgrade. The migrations are fully backwards-compatible and no database downtime is expected for this upgrade. The SQL queries included are:

{"-- Up migration\nALTER TABLE useraccesstokens ADD COLUMN IF NOT EXISTS lastnotifiedat bigint;\n\n-- Down migration\nALTER TABLE useraccesstokens DROP COLUMN IF EXISTS lastnotifiedat;"}
v11.9
-1. Browse to the folder the above files were downloaded to and unzip the `desktop-6.2.2.zip` file in place. +1. Browse to the folder the above files were downloaded to and unzip the `desktop-6.3.0.zip` file in place. ![Go to the install download directory on your machine and unzip the ZIP file.](/images/desktop/msi_gpo/msi_gpo_installation_test_00004.png) -2. Navigate to the unzipped `desktop-6.2.2\resources\windows\gpo` folder and copy the contents. +2. Navigate to the unzipped `desktop-6.3.0\resources\windows\gpo` folder and copy the contents. ![Go to the \resources\windows\gpo directory and copy its contents.](/images/desktop/msi_gpo/msi_gpo_installation_test_00005.png) @@ -215,13 +215,13 @@ Ensure the desktop app is closed before proceeding with a silent installation. B -**Command Prompt:** `msiexec /i mattermost-desktop-v6.2.2-x64.msi /qn` +**Command Prompt:** `msiexec /i mattermost-desktop-v6.3.0-x64.msi /qn` -**PowerShell:** `Start-Process -FilePath "$env:systemroot\system32\msiexec.exe" -ArgumentList '/i mattermost-desktop-v6.2.2-x64.msi /qn'` +**PowerShell:** `Start-Process -FilePath "$env:systemroot\system32\msiexec.exe" -ArgumentList '/i mattermost-desktop-v6.3.0-x64.msi /qn'` -\- Replace `<version>` with the actual version number (e.g., `v6.2.2`). - From v6.1.0, the MSI installs per-machine by default, requiring administrator privileges. +\- Replace `<version>` with the actual version number (e.g., `v6.3.0`). - From v6.1.0, the MSI installs per-machine by default, requiring administrator privileges. @@ -231,8 +231,8 @@ From version v5.9.0 of the Mattermost desktop app, the following silent MSI inst Use the `APPLICATIONFOLDER` parameter to specify an installation directory for the MSI installation: -- **Command Prompt:** `msiexec /i mattermost-desktop-v6.2.2-x64.msi APPLICATIONFOLDER="<install directory>"` -- **PowerShell:** `Start-Process -FilePath "$env:systemroot\system32\msiexec.exe" -ArgumentList '/i mattermost-desktop-v6.2.2-x64.msi APPLICATIONFOLDER="<install directory>"'` +- **Command Prompt:** `msiexec /i mattermost-desktop-v6.3.0-x64.msi APPLICATIONFOLDER="<install directory>"` +- **PowerShell:** `Start-Process -FilePath "$env:systemroot\system32\msiexec.exe" -ArgumentList '/i mattermost-desktop-v6.3.0-x64.msi APPLICATIONFOLDER="<install directory>"'` Change this command as new versions of the Mattermost Desktop App are released. diff --git a/docs/main/deployment-guide/desktop/linux-desktop-install.mdx b/docs/main/deployment-guide/desktop/linux-desktop-install.mdx index a2fd552e06c7..16650780986a 100644 --- a/docs/main/deployment-guide/desktop/linux-desktop-install.mdx +++ b/docs/main/deployment-guide/desktop/linux-desktop-install.mdx @@ -63,11 +63,11 @@ Beta `.rpm` packages are available for CentOS and RHEL 7 and 8. Automatic app up ## Install the Mattermost desktop app -1. Download the latest version of the Mattermost desktop app for 64-bit systems: [mattermost-desktop-6.2.2-linux-x86_64.rpm](https://releases.mattermost.com/desktop/6.2.2/mattermost-desktop-6.2.2-linux-x86_64.rpm) +1. Download the latest version of the Mattermost desktop app for 64-bit systems: [mattermost-desktop-6.3.0-linux-x86_64.rpm](https://releases.mattermost.com/desktop/6.3.0/mattermost-desktop-6.3.0-linux-x86_64.rpm) 2. At the command line, execute the following command: > ``` sh -> sudo rpm -i mattermost-desktop-6.2.2-linux-x86_64.rpm +> sudo rpm -i mattermost-desktop-6.3.0-linux-x86_64.rpm > ``` 3. Run Mattermost as a desktop app. @@ -75,7 +75,7 @@ Beta `.rpm` packages are available for CentOS and RHEL 7 and 8. Automatic app up To manually update the desktop app, run the following command: > ``` sh -> sudo rpm -u mattermost-desktop-6.2.2-linux-x86_64.rpm +> sudo rpm -u mattermost-desktop-6.3.0-linux-x86_64.rpm > ``` @@ -113,7 +113,7 @@ Flatpak packages are available for: > ``` sh > flatpak install mattermost-desktop-{VERSION}-linux-{ARCH}.flatpak > -> Replace ``{VERSION}`` with the version number (e.g., ``6.2.2``) and ``{ARCH}`` with your architecture (``x86_64`` or ``aarch64``). +> Replace ``{VERSION}`` with the version number (e.g., ``6.3.0``) and ``{ARCH}`` with your architecture (``x86_64`` or ``aarch64``). > ``` 4. Run Mattermost as a desktop app: @@ -143,7 +143,7 @@ For instructions on how to use the AppImage binary, please refer to the [AppImag ## Install the Desktop App's compressed tarball -1. Download the latest version of the Mattermost desktop app for 64-bit systems: [mattermost-desktop-6.2.2-linux-x64.tar.gz](https://releases.mattermost.com/desktop/6.2.2/mattermost-desktop-6.2.2-linux-x64.tar.gz) +1. Download the latest version of the Mattermost desktop app for 64-bit systems: [mattermost-desktop-6.3.0-linux-x64.tar.gz](https://releases.mattermost.com/desktop/6.3.0/mattermost-desktop-6.3.0-linux-x64.tar.gz) 2. Extract the archive to a convenient location, then give `chrome-sandbox` in the extracted directory the required ownership and permissions: `sudo chown root:root chrome-sandbox && sudo chmod 4755 chrome-sandbox` 3. Execute `mattermost-desktop` located inside the extracted directory. 4. To create a Desktop launcher, open the file `README.md`, and follow the instructions in the **Desktop launcher** section. diff --git a/docs/main/deployment-guide/mobile/mobile-troubleshooting.mdx b/docs/main/deployment-guide/mobile/mobile-troubleshooting.mdx index cb20bfb6b3b4..dbcbde480afd 100644 --- a/docs/main/deployment-guide/mobile/mobile-troubleshooting.mdx +++ b/docs/main/deployment-guide/mobile/mobile-troubleshooting.mdx @@ -51,13 +51,13 @@ If you are seeing this message all the time, and your internet connection seems You can set up an internal server to proxy the connection out of their network to the Mattermost Hosted Push Notification Service (HPNS) by following the steps below: 1. Make sure your proxy server is properly configured to support SSL. Confirm it works by checking the URL at [https://www.digicert.com/help/](https://www.digicert.com/help/). -2. Setup a proxy to forward requests to `https://push.mattermost.com`. +2. Setup a proxy to forward requests to the HPNS URL matching your server's [push notification server location](/administration-guide/configure/push-notification-server-configuration-settings#push-notification-server): `https://global.push.mattermost.com`, `https://us.push.mattermost.com`, `https://eu.push.mattermost.com`, or `https://ap.push.mattermost.com`. 3. In Mattermost set **System Console** \> **Notification Settings** \> **Mobile Push** \> **Enable Push Notifications** in prior versions or **System Console \> Environment \> Push Notification Server \> Enable Push Notifications** in versions after 5.12 to "Manually enter Push Notification Service location" 4. Enter the URL of your proxy in the **Push Notification Server** field. -Depending on how your proxy is configured you may need to add a port number and create a URL like `https://push.internalproxy.com:8000` mapped to `https://push.mattermost.com` +Depending on how your proxy is configured you may need to add a port number and create a URL like `https://push.internalproxy.com:8000` mapped to your region's HPNS URL, such as `https://us.push.mattermost.com`. @@ -147,3 +147,7 @@ To conserve disk space, once your push notification issue is resolved, go to **S If push notifications are not being delivered on the mobile device, confirm that you're logged in to the **Native** mobile app session through **Profile \> Security \> View and Log Out of Active Sessions**. Otherwise, the DeviceId won't get registered in the Sessions table and notifications won't be delivered. + +## Integration posts (Mattermost Blocks) do not render or respond + +If buttons, menus, or structured content from an integration post is missing or unresponsive on mobile, see the [Mattermost Blocks reference](https://developers.mattermost.com/integrate/reference/mm-blocks/) in the developer documentation. diff --git a/docs/main/deployment-guide/reference-architecture/scale/common-configure-mattermost-for-enterprise-search.mdx b/docs/main/deployment-guide/reference-architecture/scale/common-configure-mattermost-for-enterprise-search.mdx index d9c175a6ebd5..69b212f46f9b 100644 --- a/docs/main/deployment-guide/reference-architecture/scale/common-configure-mattermost-for-enterprise-search.mdx +++ b/docs/main/deployment-guide/reference-architecture/scale/common-configure-mattermost-for-enterprise-search.mdx @@ -46,6 +46,7 @@ Once the configuration is saved, new posts made to the database are automaticall ## Enterprise search limitations -1. Elasticsearch and AWS OpenSearch uses a standard selection of "stop words" to keep search results relevant. Results for the following words will not be returned: "a", "an", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", and "with". +1. Elasticsearch and AWS OpenSearch use a standard selection of "stop words" to keep search results relevant. Results for the following words will not be returned: "a", "an", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", and "with". 2. Searching stop words in quotes returns more results than just the searched terms ([ticket](https://mattermost.atlassian.net/browse/MM-7216)). 3. By default, search results are limited to a user's team and channel membership. This is enforced by the Mattermost server. The entities are indexed in Elasticsearch or AWS OpenSearch in a way that allows Mattermost to filter them when querying, so the Mattermost server narrows down the results on every Elasticsearch or AWS OpenSearch request applying those filters. From Mattermost v11.6, admins can [allow searching public channels without membership](/administration-guide/configure/environment-configuration-settings#allow-searching-public-channels-without-membership) so that users can find messages in public channels they haven't joined, scoped to teams they belong to. +4. User search and autocomplete served by Elasticsearch or AWS OpenSearch match on username, nickname, and first and last name only. Email addresses aren't indexed, so no user can be found by email address, including system admins. User searches served from the database continue to match on email address. For channel and team member searches, system admins always match on email address, and all other users also require [Show email address](/administration-guide/configure/site-configuration-settings#show-email-address) to be enabled. The **System Console > User Management > Users** list always matches on email address, independently of that setting. diff --git a/docs/main/deployment-guide/reference-architecture/scale/elasticsearch-setup.mdx b/docs/main/deployment-guide/reference-architecture/scale/elasticsearch-setup.mdx index cdc12d945214..50928e964fb8 100644 --- a/docs/main/deployment-guide/reference-architecture/scale/elasticsearch-setup.mdx +++ b/docs/main/deployment-guide/reference-architecture/scale/elasticsearch-setup.mdx @@ -60,10 +60,24 @@ We highly recommend that you set up Elasticsearch server on a dedicated machine 10. Create an Elasticsearch directory and give it the proper permissions. 11. Install the [icu-analyzer plugin](https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-icu.html) to the `/usr/share/elasticsearch/plugins` directory by running the following command: +> +> +> The `analysis-icu` plugin is **required on every node in the cluster**, not optional. Mattermost's post and file index templates depend on it. Without the plugin, Mattermost cannot create these templates. +> +> +> > ``` sh > sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install analysis-icu > ``` > +> Restart Elasticsearch on each node to load the newly installed plugin before verifying it; `_cat/plugins` only reports active plugins, so a restart is required first. For production clusters, restart nodes one at a time (rolling restart) rather than all at once. Confirm the plugin is installed and active on every node before continuing. Replace `` and ``, and update the CA path if needed: +> +> ``` sh +> curl --silent --show-error --fail-with-body --cacert /etc/elasticsearch/certs/http_ca.crt --user 'elastic:' 'https://:9200/_cat/plugins?v&h=name,component,version&s=name,component' +> ``` +> +> Running this command should show `analysis-icu` once per node in the cluster. If the `analysis-icu` line is missing for any node, the plugin is not installed there. Use plain HTTP without credentials only for a cluster where Elasticsearch security has been explicitly disabled. +> > **(Optional) CJK language analyzer plugins**: To improve search for Korean, Japanese, or Chinese content, install one or more of the following language-specific analyzer plugins: `analysis-nori` (Korean), `analysis-kuromoji` (Japanese), and `analysis-smartcn` (Chinese). > > ``` sh diff --git a/docs/main/deployment-guide/reference-architecture/scale/high-availability-cluster-based-deployment.mdx b/docs/main/deployment-guide/reference-architecture/scale/high-availability-cluster-based-deployment.mdx index 2e6f5fc5d64f..899f073f4c39 100644 --- a/docs/main/deployment-guide/reference-architecture/scale/high-availability-cluster-based-deployment.mdx +++ b/docs/main/deployment-guide/reference-architecture/scale/high-availability-cluster-based-deployment.mdx @@ -702,7 +702,13 @@ Amazon Aurora PostgreSQL provides managed database service with built-in high av mmctl config set SqlSettings.MaxIdleConns 50 ``` - The recommended ratio is 2:1 (MaxOpenConns:MaxIdleConns). These settings apply **per data source**, so with one primary and two read replicas, the total maximum connections would be 300. + The recommended ratio is 2:1 (MaxOpenConns:MaxIdleConns). These settings apply **per data source, per Mattermost server node**, not as a cluster-wide total: each node opens its own connection pool, sized to `MaxOpenConns`, for the primary database and for each read replica and search replica. + + To size `max_connections` on the database (or any connection-pooling proxy in front of it), first count the data sources per node—the primary counts as 1, then add the number of read replicas and the number of search replicas. Multiply that count by `MaxOpenConns`, then multiply again by the number of app server nodes: + + `MaxOpenConns` x (data sources per node) x (number of app nodes) + + For example, with one primary and two read replicas, each node has 3 data sources. Across a 3-node cluster, at the default `MaxOpenConns` of 100, that's 3 x 3 x 100 = 900 possible connections. 4. **Verify database configuration:** Restart Mattermost and check that database connections are healthy: diff --git a/docs/main/deployment-guide/reference-architecture/scale/opensearch-setup.mdx b/docs/main/deployment-guide/reference-architecture/scale/opensearch-setup.mdx index 50482c51a6dd..9d8cbb1bfe63 100644 --- a/docs/main/deployment-guide/reference-architecture/scale/opensearch-setup.mdx +++ b/docs/main/deployment-guide/reference-architecture/scale/opensearch-setup.mdx @@ -106,10 +106,24 @@ Starting in Mattermost v12.0 (October 2026), OpenSearch v1.x is no longer suppor 8. Install the [icu-analyzer plugin](https://docs.opensearch.org/latest/install-and-configure/additional-plugins/index/) to the `/usr/share/opensearch/plugins` directory by running the following command: + + + The `analysis-icu` plugin is **required on every node in the cluster**, not optional. Mattermost's post and file index templates depend on it. Without the plugin, Mattermost cannot create these templates. + + + ``` sh sudo /usr/share/opensearch/bin/opensearch-plugin install analysis-icu ``` + Restart OpenSearch on each node to load the newly installed plugin before verifying it; `_cat/plugins` only reports active plugins, so a restart is required first. For production clusters, restart nodes one at a time (rolling restart) rather than all at once. Confirm the plugin is installed and active on every node before continuing. Replace the host, admin password, and path to your cluster's CA certificate: + + ``` sh + curl --silent --show-error --fail-with-body --cacert --user 'admin:' 'https://:9200/_cat/plugins?v&h=name,component,version&s=name,component' + ``` + + Running this command should show `analysis-icu` once per node in the cluster. If the `analysis-icu` line is missing for any node, the plugin is not installed there. + **(Optional) CJK language analyzer plugins**: To improve search for Korean, Japanese, or Chinese content, install one or more of the following language-specific analyzer plugins: `analysis-nori` (Korean), `analysis-kuromoji` (Japanese), and `analysis-smartcn` (Chinese). ``` sh diff --git a/docs/main/deployment-guide/server/kubernetes/deploy-k8s-oke.mdx b/docs/main/deployment-guide/server/kubernetes/deploy-k8s-oke.mdx index a0b1444e9f5f..2c8ca3c825f8 100644 --- a/docs/main/deployment-guide/server/kubernetes/deploy-k8s-oke.mdx +++ b/docs/main/deployment-guide/server/kubernetes/deploy-k8s-oke.mdx @@ -2,16 +2,17 @@ title: "Deploy Mattermost on Oracle Kubernetes Engine (OKE)" sidebar_label: "Deploy on OKE (Oracle)" --- -You can use the supported [Oracle Cloud Marketplace listing](https://cloudmarketplace.oracle.com/marketplace/en_US/listing/188386963) to install Mattermost Enterprise Edition on Oracle Cloud Infrastructure (OCI) using Oracle Kubernetes Engine (OKE). +You can use the supported [Oracle Cloud Marketplace listing](https://cloudmarketplace.oracle.com/marketplace/en_US/listing/188386963), **Mattermost - OCI-Native (Kubernetes-based)**, to deploy a high-availability Mattermost environment on Oracle Cloud Infrastructure (OCI). One guided stack provisions a new Oracle Kubernetes Engine (OKE) cluster, a managed OCI Database with PostgreSQL system, an Object Storage bucket for file attachments, the Mattermost Kubernetes Operator, and HTTPS ingress through the OCI Native Ingress Controller. + +## Before you begin Before deploying, make sure you have the following: -- **Oracle Cloud Account** with appropriate permissions -- **Permissions** to create/manage OKE, Compute, Networking, Database, Resource Manager, and Secrets -- **Compartment** for deployment -- **Domain Name and TLS Certificate** for secure access -- **Mattermost License Key** (Trial or Enterprise) -- **Node Capacity**: At least 2 OKE nodes for high availability when deploying for 100 users or more +- **An Oracle Cloud tenancy and compartment** you have permission to create resources in (VCN, OKE, IAM policies, OCI Database with PostgreSQL, Object Storage, Resource Manager) +- **Sufficient service limits** for a new OKE cluster and its default worker pool (3 nodes, `VM.Standard.E5.Flex` at 2 OCPUs/16GB each) and for an OCI Database with PostgreSQL system +- **A registered domain name** you can create a DNS `A` record for, pointing to the Mattermost load balancer +- **A TLS certificate for that domain, imported into OCI Certificate Service**, with its OCID ready before you deploy. The stack does not accept a raw PEM/private key, only a certificate OCID. +- **A Mattermost Enterprise license** if you plan to deploy for more than 100 users. Larger sizes run Mattermost and PostgreSQL in high-availability mode, which requires a license. ## Installation steps @@ -19,139 +20,169 @@ The installation process includes deploying Mattermost and configuring the neces ### Step 1: Start from Oracle Cloud Marketplace -Go to the Mattermost listing and select **Launch Stack**. +Go to the **Mattermost - OCI-Native (Kubernetes-based)** listing and select **Launch Stack**. -![Oracle Cloud Marketplace listing for Mattermost](/images/oracle/marketplace-listing.png) +![Oracle Cloud Marketplace listing for Mattermost - OCI-Native (Kubernetes-based)](/images/oracle/marketplace-listing.png) ### Step 2: Stack Information -On the **Create stack** page, review the information, and then set the name, compartment, and Terraform version. +On the **Create stack** page, review the information, and then set the stack name, description, compartment, and Terraform version. -![Stack information page](/images/oracle/stack-info.png) +![Create stack information page for Mattermost on OKE](/images/oracle/stack-info.png) ### Step 3: Configure Variables -Set all the details for your Mattermost deployment. Each section is important for a successful and secure installation. - -#### OKE Cluster Configuration - -- **Create new OKE Cluster:** - - Check this if you want to create a new Kubernetes cluster. - - If you already have a cluster, you can uncheck and select your existing one. -- **Kubernetes Version:** - - Choose the latest stable version unless you have a specific requirement. -- **Node Pool Shape (Flex/Fixed):** - - Select a shape that fits your workload. For production, use at least 2 OCPUs and 16GB RAM per node. -- **Number of Nodes:** - - Minimum 2 for high availability. For testing, 1 is enough. For production environments, always use at least 2 nodes and enable high availability. -- **Operating System:** - - Oracle Linux 8 is recommended for best compatibility. - -#### OKE Network Configuration - -- **Worker Node Visibility:** - - Private is more secure for production. Public is easier for testing. For production environments, use private nodes and restrict access to the API endpoint. -- **API Endpoint Visibility:** - - Public allows you to manage the cluster from anywhere. Private is more secure but requires VPN or bastion. -- **Create new Virtual Cloud Network (VCN):** - - Check this to create a new network, or uncheck to use an existing one. -- **VCN CIDR Block:** - - Set a unique network range (e.g., `10.20.0.0/16`). Avoid overlap with other networks. - -#### OKE Worker Nodes - -- **Enable Cluster Autoscaler:** - - Allows the cluster to automatically add or remove nodes based on usage. -- **Initial/Min Number of Worker Nodes:** - - Set the minimum number of nodes. For high availability, use at least 2. Autoscaling helps manage costs and performance automatically. -- **Node Shape:** - - Choose a shape (e.g., `VM.Standard.E4.Flex`) and set OCPUs and memory. -- **Auto Generate SSH Key:** - - Enable this if you do not have your own SSH key for node access. -- **Image OS and Version:** - - Oracle Linux 8 is recommended. - -#### PostgreSQL Configuration - -- **Admin Username:** - - The main user for your PostgreSQL database (e.g., `admin1`). -- **Password Type:** - - `PLAIN_TEXT` for testing, `SECRET` for production (uses Oracle Vault). Always use Oracle Vault for production passwords. -- **Password/Secret Name:** - - Enter a strong password or the name of a secret in Oracle Vault. -- **Database Password:** - - Required if not using a secret. +Set all the details for your Mattermost deployment. Variables are grouped by area; advanced groups are hidden behind a **Show advanced options** toggle so the default flow stays simple. #### General Configuration +- **Compartment:** + - Target compartment for every resource the stack creates: the OKE cluster, VCN, PostgreSQL DB system, and Object Storage bucket. - **Cluster Name Prefix:** - - Used to identify all resources (e.g., `mm-oke`). -- **Show Advanced Options:** - - Enable for more control (encryption keys, SSH keys, etc.). Use advanced options if you need custom encryption or want to manage your own SSH keys. -- **PostgreSQL Deployment Strategy:** - - Use "Database For PostgreSQL" for managed service. -- **Object Storage for File Storage:** - - Enable to use OCI Object Storage for Mattermost files. + - Used as a prefix on all OCI resources created by the stack (default: `mattermost`). +- **Show Recovery Options:** + - Leave off for a normal deployment. Only enable this if a previous apply failed and left resources blocking re-apply; it reveals a **Deploy ID Revision** field that forces new resource names. + +#### Mattermost Installation + +- **Mattermost Installation Name:** + - Name for this installation (default: `mattermost-prod`). +- **Mattermost Installation Size:** + - Choose the size that matches your expected active user count: `100users`, `1000users`, `5000users`, `10000users`, or `25000users` (default: `100users`). This drives both the Mattermost pod resources and the PostgreSQL topology (instance count, shape). It's a **create-time-only setting**: changing it later requires deploying a new stack because OCI can't modify PostgreSQL topology in place. Sizes above 100 users deploy Mattermost and PostgreSQL in high-availability mode and require an Enterprise license. - **Mattermost Version:** - - Use the latest stable version. -- **Namespace:** - - Default is `mattermost`. -- **License Key:** - - Upload or paste your Mattermost license. -- **Helm Repository:** - - Default is `https://helm.mattermost.com`. + - The Mattermost server version to install. +- **Mattermost License Key:** + - Upload your Enterprise license file. Optional at `100users`; leave empty to start unlicensed and add a license later from **System Console > Edition and License**. Required for every larger size. +- **Mattermost FQDN:** + - The hostname end users will browse to (for example, `mattermost.domain.com`). You'll point its DNS `A` record at the stack's output load balancer IP after deployment. +- **OCI Certificate Service OCID:** + - The OCID of the certificate you imported into OCI Certificate Service for that FQDN. +- **Mattermost LB Allowed CIDR Blocks:** + - IP ranges allowed to reach Mattermost over HTTPS. Default (`0.0.0.0/0`) allows access from anywhere; restrict this for corporate or internal-only deployments. +- **Show Advanced Mattermost Options:** + - Turn this on to reveal the following fields, all of which have sensible defaults for most deployments: + - **Kubernetes Namespace:** The namespace Mattermost is installed into (default: `mattermost`). + - **Helm Repository URL:** Source of the Mattermost Operator Helm chart (default: `https://helm.mattermost.com`). + - **Operator Helm Chart Version:** Choose the Mattermost Operator Helm chart version to install from the list (default: the newest version offered). + - **NIC Readiness Wait Timeout:** How long to wait for the Native Ingress Controller to become ready before failing the apply (default: 180 seconds). + +#### OKE Configuration + +- **Kubernetes Version:** + - Leave empty to auto-select the newest version OKE publishes. +- **Worker OS Version:** + - Oracle Linux `8` or `9` (default: `8`). +- **Worker Count:** + - Number of worker nodes in the cluster (default: 3, recommended for high availability). You can adjust this later by editing and re-applying the stack. +- **Show Advanced OKE Options:** + - Turn this on to reveal the following fields, all of which have sensible defaults for most deployments: + - **Virtual Cloud Network (VCN) CIDR:** IP address range for the cluster's network (default: `10.20.0.0/16`). Only change this if it conflicts with an existing network you need to peer with. + - **API Endpoint Allowed CIDR Blocks:** IP ranges allowed to reach the Kubernetes API (default: `0.0.0.0/0`, i.e. anywhere). Restrict this to your corporate gateway or VPN range for tighter security. Make sure the range you choose covers your own admin access, since there's no bastion host as a fallback path. + - **Cluster CNI:** The pod networking mode: `OCI_VCN_IP_NATIVE` (default, recommended for better performance and tighter VCN integration) or `FLANNEL_OVERLAY`. + - **Worker Shape:** Compute shape for each worker node (default: `VM.Standard.E5.Flex` with 2 OCPUs/16 GB memory), suitable for most Mattermost deployments. + - **Worker Pool Name:** The name for the worker node pool as it appears in the OCI Console and CLI. + +#### Cluster Tools + +- **Install Metrics Server:** + - Enables `kubectl top` and the metrics API HPA relies on, if you add your own autoscaler later. On by default; recommended for all deployments. +- **Create OKE IAM Policies:** + - Automatically creates the IAM policies OKE needs to manage cluster resources. On by default; disable only if these policies already exist in your compartment. + +#### PostgreSQL + +- **PostgreSQL Database Name / Description:** + - The display name and description for the OCI Database with PostgreSQL system (separate from the Mattermost application database name below). +- **PostgreSQL Major Version:** + - `14`, `15`, `16`, or `17` (default: `16`). +- **PostgreSQL Admin Username / Password:** + - Admin credentials for the DB system. Passwords must be 8–32 characters with at least one uppercase letter, one lowercase letter, one number, and one special character, and cannot contain single quotes, double quotes, backslashes, or semicolons. +- **Mattermost Database Name / User / Password:** + - The database, user, and password Mattermost itself connects with inside PostgreSQL (defaults: `mattermost` / `mmuser`). The password follows the same rules as the PostgreSQL Admin Password above (8–32 characters, upper/lowercase, number, special character; no quotes, backslashes, or semicolons). +- **Create a Subnet for the Mattermost Database:** + - On by default, to create a dedicated subnet for the DB system. Disable to select an existing subnet instead. +- **PostgreSQL Backup Retention (Days):** + - Automatic-backup retention, 7–35 days (default: 30). +- **Show Advanced PostgreSQL Options:** + - Turn this on to reveal the following fields, all of which have sensible defaults for most deployments: + - **PostgreSQL Port:** The port PostgreSQL listens on (default: `5432`). + - **Backup Window:** Daily UTC time window for automatic backups. + - **Maintenance Window:** Weekly UTC time window for maintenance operations. + - **Per-Tier Overrides:** Instance count, OCPUs, and memory overrides for each Mattermost Installation Size tier. + +#### Object Storage + +- **Bucket Compartment:** + - Compartment for the Object Storage bucket. Defaults to the main compartment. +- **Object Storage Bucket Name:** + - Name of the bucket used to store Mattermost file attachments. + +#### Tagging + +- **Tag Resources:** + - Optionally apply OCI free-form or defined tags to every resource the stack creates. ### Step 4: Review and Apply -Check all your settings and select **Create** to start the deployment. Monitor the Resource Manager job and logs. +Check all your settings and select **Create** to start the deployment. Monitor the Resource Manager job and logs. The first apply takes about 30 minutes. ![Resource Manager job monitor](/images/oracle/job-monitor.png) ### Step 5: After Deployment -When the job is finished, your OKE cluster, PostgreSQL database, and Mattermost will be ready. To find the Mattermost web address, run: +When the job finishes, open the stack's **Application information** tab to review the deployment details: -``` sh -kubectl -n mattermost-operator get ingress -``` +![Application information tab showing deployment, Kubernetes, and Mattermost details](/images/oracle/application-information.png) -Copy the address and create a DNS record for your domain. Open your browser and go to your Mattermost URL. +- **Load Balancer IP Address**: Copy the IP shown beside this label and create a DNS `A` record from your **Mattermost FQDN** to it. This reserved OCI Public IP stays stable across re-applies. +- **Mattermost URL** (top-right button): The public HTTPS URL, reachable once DNS propagates. +- **OKE Cluster OCID** and **Deployed Kubernetes Version:** Identify the OKE cluster if you need to connect with `kubectl` or the OCI CLI. + +Once the `A` record resolves, open your browser and go to the Mattermost URL. ### Step 6: Upgrade Mattermost To upgrade your Mattermost installation: -1. Access your OKE cluster through the Oracle Cloud Console -2. Navigate to the Mattermost operator deployment -3. Update the Mattermost version in the configuration -4. Apply the changes and wait for the upgrade to complete +1. Go to your Resource Manager stack and select **Edit**. +2. Update the **Mattermost Version** variable to the target release. +3. Save and run **Plan**, then **Apply**. + +The Native Ingress Controller uses Pod Readiness Gates to hold new pods out of rotation until their OCI load balancer backend reports healthy. On an HA-sized installation (above `100users`, multiple Mattermost replicas), this minimizes disruption during the rollout since other replicas keep serving traffic. On the default `100users` size, which runs a single replica, a brief interruption while that pod restarts is expected. **Tips for Success** - Make sure you have all the permissions you need before you start. -- Use Oracle Vault to store passwords and sensitive data. -- Use private nodes and secure your network for production. -- Always monitor logs from the Resource Manager and pods using `kubectl logs` for more specific error messages. +- Import your TLS certificate into OCI Certificate Service and have its OCID ready before configuring variables. The stack won't accept a raw certificate/key pair. +- Choose your **Mattermost Installation Size** carefully: it can't be changed on an existing stack without recreating the PostgreSQL system. +- To run `kubectl` against the cluster (for example, from OCI Cloud Shell), pull a kubeconfig using the **OKE Cluster OCID** and **Deployment Region** from the Application Information tab: `oci ce cluster create-kubeconfig --cluster-id --region --file $HOME/.kube/config --kube-endpoint PUBLIC_ENDPOINT --token-version 2.0.0`. Run `kubectl get nodes` to confirm access. +- Always monitor logs from the Resource Manager job and from pods with `kubectl logs` for more specific error messages. - For more details, see the official [OCI Database with PostgreSQL documentation](https://www.oracle.com/cloud/postgresql/) and [OKE documentation](https://docs.oracle.com/en-us/iaas/Content/ContEng/Concepts/contengoverview.htm). ## Common Errors and How to Avoid Them -- **Error: Kubernetes API not reachable** - - *Cause:* API endpoint is private and you're not connected to the VCN via VPN or Bastion. - - *Solution:* Ensure you have access to the network or make the endpoint public for testing. - **Error: Stack creation fails with missing permissions** - - *Cause:* IAM policies are not set properly for the user or group. - - *Solution:* Ensure you have permissions for Resource Manager, OKE, Networking, and Secrets. -- **Error: No ingress returned by kubectl** - - *Cause:* Mattermost Ingress might not be ready or was misconfigured. - - *Solution:* Check with `kubectl describe ingress` and validate DNS, TLS, and Helm values. + - *Cause:* IAM policies are not set properly for the user or group running the stack. + - *Solution:* Ensure you have permissions for Resource Manager, OKE, Networking, OCI Database with PostgreSQL, Object Storage, and Certificate Service. +- **Error: Plan fails because a Mattermost license is required** + - *Cause:* **Mattermost Installation Size** is set above `100users` without a license uploaded; larger sizes deploy in high-availability mode, which is Enterprise-licensed. + - *Solution:* Upload a valid Mattermost Enterprise license, or choose `100users`. +- **Error: Mattermost URL doesn't resolve after deployment** + - *Cause:* The DNS `A` record for your FQDN hasn't been created yet, or hasn't propagated. + - *Solution:* Create an `A` record from your **Mattermost FQDN** to the `mattermost_lb_ip` output, then wait for DNS propagation. +- **Error: Certificate OCID rejected or ingress never becomes healthy** + - *Cause:* The **OCI Certificate Service OCID** doesn't exist, isn't in the same tenancy, or doesn't match the configured FQDN. + - *Solution:* Re-check the certificate in OCI Certificate Service and confirm the OCID was copied correctly. - **Error: PostgreSQL password rejected** - - *Cause:* Password not set or mismatched with Oracle Vault. - - *Solution:* Re-check the password value or Vault secret used during setup. + - *Cause:* The **PostgreSQL Admin Password** or **Mattermost Database Password** doesn't meet the required complexity rules (8–32 characters, upper/lowercase, number, special character; no quotes, backslashes, or semicolons). + - *Solution:* Re-enter a password that satisfies the pattern shown in the field description. +- **Error: Terraform destroy fails on the PostgreSQL system or the bucket** + - *Cause:* The database system has destroy protection enabled by design, and OCI refuses to delete a non-empty Object Storage bucket. + - *Solution:* Empty the bucket first, then disable the database's lifecycle protection before destroying. @@ -159,4 +190,4 @@ You are responsible for Oracle Cloud Infrastructure costs for the resources you -Learn more about managing your Mattermost server by visiting the [Administration Guide](/administration-guide/administration-guide-index). +Learn more about managing your Mattermost server in the [Administration Guide](/administration-guide/administration-guide-index). diff --git a/docs/main/deployment-guide/server/linux/deploy-rhel.mdx b/docs/main/deployment-guide/server/linux/deploy-rhel.mdx index 324a7b9d5647..327a91ad663d 100644 --- a/docs/main/deployment-guide/server/linux/deploy-rhel.mdx +++ b/docs/main/deployment-guide/server/linux/deploy-rhel.mdx @@ -37,14 +37,14 @@ SSH onto the target host and download the release. Replace `amd64` with `arm64` ```sh -wget https://releases.mattermost.com/11.9.0/mattermost-11.9.0-linux-amd64.tar.gz +wget https://releases.mattermost.com/11.10.0/mattermost-11.10.0-linux-amd64.tar.gz ``` ```sh -wget https://releases.mattermost.com/11.7.7/mattermost-11.7.7-linux-amd64.tar.gz +wget https://releases.mattermost.com/11.7.9/mattermost-11.7.9-linux-amd64.tar.gz ``` @@ -81,7 +81,13 @@ If you use a path other than `/opt/mattermost` or a user/group name other than ` -Create the systemd unit file at `/lib/systemd/system/mattermost.service`: +Create the systemd unit file at `/etc/systemd/system/mattermost.service`: + + + +Earlier versions of this guide had you create the unit file under `/lib/systemd/system/`, which is reserved for unit files installed and owned by a package manager. + + ```ini [Unit] diff --git a/docs/main/deployment-guide/server/linux/deploy-tar.mdx b/docs/main/deployment-guide/server/linux/deploy-tar.mdx index 33e320700e50..f4f174af26e3 100644 --- a/docs/main/deployment-guide/server/linux/deploy-tar.mdx +++ b/docs/main/deployment-guide/server/linux/deploy-tar.mdx @@ -48,14 +48,14 @@ SSH onto the target host and download the release. Replace `amd64` with `arm64` ```sh -wget https://releases.mattermost.com/11.9.0/mattermost-11.9.0-linux-amd64.tar.gz +wget https://releases.mattermost.com/11.10.0/mattermost-11.10.0-linux-amd64.tar.gz ``` ```sh -wget https://releases.mattermost.com/11.7.7/mattermost-11.7.7-linux-amd64.tar.gz +wget https://releases.mattermost.com/11.7.9/mattermost-11.7.9-linux-amd64.tar.gz ``` @@ -91,7 +91,13 @@ If you use a path other than `/opt/mattermost` or a user/group name other than ` -Create the systemd unit file at `/lib/systemd/system/mattermost.service`: +Create the systemd unit file at `/etc/systemd/system/mattermost.service`: + + + +Earlier versions of this guide had you create the unit file under `/lib/systemd/system/`, which is reserved for unit files installed and owned by a package manager. + + ```ini [Unit] diff --git a/docs/main/deployment-guide/server/prepare-mattermost-mysql-database.mdx b/docs/main/deployment-guide/server/prepare-mattermost-mysql-database.mdx index b5e1cbd644d7..2258559a534b 100644 --- a/docs/main/deployment-guide/server/prepare-mattermost-mysql-database.mdx +++ b/docs/main/deployment-guide/server/prepare-mattermost-mysql-database.mdx @@ -208,7 +208,7 @@ sudo systemctl status mattermost.service The second line of output will have the location of the running `mattermost.service`. ``` text -Loaded: loaded (/lib/systemd/system/mattermost.service; enabled; vendor preset: enabled) +Loaded: loaded (/etc/systemd/system/mattermost.service; enabled; vendor preset: enabled) ``` Edit this file as *root* to add the below text just above the line that begins with `ExecStart`: diff --git a/docs/main/deployment-guide/server/troubleshooting.mdx b/docs/main/deployment-guide/server/troubleshooting.mdx index cff80b14aa3d..a7090777a6b7 100644 --- a/docs/main/deployment-guide/server/troubleshooting.mdx +++ b/docs/main/deployment-guide/server/troubleshooting.mdx @@ -11,7 +11,7 @@ To have the Mattermost Server start at system boot, the systemd unit file needs sudo systemctl enable mattermost.service ``` -If your database is on the same system as your Mattermost Server, we recommend editing the default `/lib/systemd/system/mattermost.service` systemd unit file to add `After=postgresql.service` and `BindsTo=postgresql.service` to the `[Unit]` section. +If your database is on the same system as your Mattermost Server, we recommend editing the default `/etc/systemd/system/mattermost.service` systemd unit file to add `After=postgresql.service` and `BindsTo=postgresql.service` to the `[Unit]` section. ## Run Mattermost without a proxy diff --git a/docs/main/deployment-guide/software-hardware-requirements.mdx b/docs/main/deployment-guide/software-hardware-requirements.mdx index a40942444be1..8046db36ce2c 100644 --- a/docs/main/deployment-guide/software-hardware-requirements.mdx +++ b/docs/main/deployment-guide/software-hardware-requirements.mdx @@ -75,8 +75,8 @@ Flatpak packages are available for x86_64 (Intel/AMD) and aarch64 (ARM) architec Chrome -v144+ -v144+ +v150+ +v150+ Firefox @@ -90,8 +90,8 @@ Flatpak packages are available for x86_64 (Intel/AMD) and aarch64 (ARM) architec Edge -v144+ -v144+ +v150+ +v150+ @@ -139,11 +139,11 @@ Flatpak packages are available for x86_64 (Intel/AMD) and aarch64 (ARM) architec iOS -iOS 16.0+ with Safari 26.2+ or Chrome 144+ +iOS 16.0+ with Safari 26.2+ or Chrome 150+ Android -Android 7+ with Chrome 144+ +Android 7+ with Chrome 150+ @@ -207,17 +207,17 @@ When a PostgreSQL version reaches its end of life (EOL), Mattermost will require v9.11 ESR -2024-8-15 +2024-8-16 11.x v10.5 ESR -2025-2-15 +2025-2-14 11.x v10.6 -2025-3-15 +2025-3-14 13.x diff --git a/docs/main/deployment-guide/transport-encryption.mdx b/docs/main/deployment-guide/transport-encryption.mdx index a02a7dee21e8..fb4c75a078f5 100644 --- a/docs/main/deployment-guide/transport-encryption.mdx +++ b/docs/main/deployment-guide/transport-encryption.mdx @@ -105,7 +105,7 @@ systemctl status mattermost ``` text ● mattermost.service - Mattermost - Loaded: loaded (/lib/systemd/system/mattermost.service; static; vendor preset: enabled) + Loaded: loaded (/etc/systemd/system/mattermost.service; static; vendor preset: enabled) Active: active (running) since Mon 2019-10-28 16:45:29 UTC; 1h 15min ago [...] ``` @@ -209,7 +209,7 @@ systemctl status mattermost ``` text ● mattermost.service - Mattermost - Loaded: loaded (/lib/systemd/system/mattermost.service; static; vendor preset: enabled) + Loaded: loaded (/etc/systemd/system/mattermost.service; static; vendor preset: enabled) Active: active (running) since Fri 2019-10-18 16:47:08 UTC; 3s ago Process: 3424 ExecStartPre=/opt/mattermost/bin/pre_start.sh (code=exited, status=0/SUCCESS) Main PID: 3443 (mattermost) @@ -440,7 +440,7 @@ systemctl status mattermost.service ``` text ● mattermost.service - Mattermost - Loaded: loaded (/lib/systemd/system/mattermost.service; static; vendor preset: enabled) + Loaded: loaded (/etc/systemd/system/mattermost.service; static; vendor preset: enabled) Active: active (running) since Fri 2019-10-04 19:44:20 UTC; 5min ago Process: 16734 ExecStartPre=/opt/mattermost/bin/pre_start.sh (code=exited, status=0/SUCCESS) ``` diff --git a/docs/main/end-user-guide/access/client-availability.mdx b/docs/main/end-user-guide/access/client-availability.mdx index 64936baee0c5..27d58ec65994 100644 --- a/docs/main/end-user-guide/access/client-availability.mdx +++ b/docs/main/end-user-guide/access/client-availability.mdx @@ -1,6 +1,8 @@ --- title: "Client Availability" --- +import useBaseUrl from '@docusaurus/useBaseUrl'; + The following tables highlight the end user features of Mattermost and their support across Web, Desktop, and Mobile applications (iOS and Android). @@ -317,6 +319,10 @@ The following tables highlight the end user features of Mattermost and their sup checkmark | checkmark | checkmark | +Mattermost Blocks +Included | Included | Included | + + Message attachments checkmark | checkmark | checkmark | @@ -333,7 +339,7 @@ The following tables highlight the end user features of Mattermost and their sup checkmark | checkmark | | -Right-hand sidebar +Right-hand sidebar checkmark | checkmark | | diff --git a/docs/main/end-user-guide/collaborate/flag-messages.mdx b/docs/main/end-user-guide/collaborate/flag-messages.mdx index 6b608a07eea7..73aba3f5125b 100644 --- a/docs/main/end-user-guide/collaborate/flag-messages.mdx +++ b/docs/main/end-user-guide/collaborate/flag-messages.mdx @@ -11,6 +11,12 @@ Every Mattermost user contributes to data security. From Mattermost v11.1, you c For example, you notice a public post in a channel that contains internal project details that not all users should have access to. You can quarantine that message as **Sensitive data** to alert designated content reviewers right away. + + +You can only quarantine messages posted in public or private channels. The **Quarantine for Review** action isn't available in direct messages or group messages. + + + 1. Hover over the message, select the **More actions** Use the More icon to access additional message options. icon, and then select **Quarantine for Review**. 2. Select a **reason** for quarantining the message, and add a comment explaining why you're quarantining it, when required. 3. Select **Submit**. diff --git a/docs/main/end-user-guide/collaborate/learn-about-roles.mdx b/docs/main/end-user-guide/collaborate/learn-about-roles.mdx index 0b43f51fd8b1..7ad6412e3106 100644 --- a/docs/main/end-user-guide/collaborate/learn-about-roles.mdx +++ b/docs/main/end-user-guide/collaborate/learn-about-roles.mdx @@ -43,7 +43,8 @@ When a team is first created, the person who set it up is made a team admin. It - Ability to change the team name and import data from Slack export files. - Access to the **Manage Members** menu, where they can control whether team members are a **Member** or a **Team Admin**. - Ability to manage all aspects of a team, such as joining and managing private channels they're not a member of. -- Ability to create and manage [attribute-based channel membership policies](/administration-guide/manage/admin/abac-team-channel-policies) for private channels within the team, when ABAC is enabled by a System Admin (Enterprise Advanced). +- Ability to create and manage [attribute-based channel membership policies](/administration-guide/manage/admin/abac-team-channel-policies) for channels within the team, from the **Channel Membership** tab in Team Settings, when ABAC is enabled by a System Admin (Enterprise Advanced). +- From Mattermost v11.10, ability to define [attribute-based team membership rules](/administration-guide/manage/admin/abac-team-membership) that control who can be a member of the team itself, from the **Team Membership** tab in Team Settings, when ABAC is enabled by a System Admin (Enterprise Advanced). ## Channel admin diff --git a/docs/main/end-user-guide/collaborate/organize-using-teams.mdx b/docs/main/end-user-guide/collaborate/organize-using-teams.mdx index f51fe0b3ff43..d2a96f067a13 100644 --- a/docs/main/end-user-guide/collaborate/organize-using-teams.mdx +++ b/docs/main/end-user-guide/collaborate/organize-using-teams.mdx @@ -70,6 +70,12 @@ You can be a member of multiple teams at the same time. To join additional teams ![Select a team name to join another team.](/images/join-team.png) + + +When your organization uses [team membership access policies](/administration-guide/manage/admin/abac-team-membership), the list of teams you can join depends on your user attributes. Public teams whose requirements you meet are marked **Recommended**, and private teams whose requirements you don't meet aren't listed at all. + + + From Mattermost Mobile v2.40.0, you can join another team from the mobile app by tapping the team name in the channel list header, then tapping **Join Another Team**. ## Leave a team @@ -86,7 +92,7 @@ Team admins can remove users from a team via **Team menu \> Manage Members \> Re When a user is removed from a team, the team will no longer be visible or accessible in their team sidebar. If they currently have the team open, they are redirected to the first team that appears in their team sidebar. If they didn't belong to any other teams, the user is sent to the team selection page. -Removing a user from the team does not deactivate the account. The user will still be able to log in to the site, and join other teams. They will also be able to rejoin the team they were removed from if they receive another invite, or if the team is set to ["Allow anyone with an account on this server to join this team"](/end-user-guide/collaborate/team-settings#users-on-this-server). If the user does rejoin the team, they will no longer belong to the channels they were previously a part of, and they will lose all Admin privileges if they had them previously. +Removing a user from the team does not deactivate the account. The user will still be able to log in to the site, and join other teams. They will also be able to rejoin the team they were removed from if they receive another invite. When a private team has a team membership access policy, invited users must also satisfy that policy. Users can also rejoin if the team is set to [Public Team](/end-user-guide/collaborate/team-settings#discoverability) and they meet any other join restrictions, such as approved email domains. Team membership access policies on public teams are advisory and don't prevent users from rejoining. If the user does rejoin the team, they will no longer belong to the channels they were previously a part of, and they will lose all Admin privileges if they had them previously. A system admin can also remove users from teams via **System Console \> Users**, and selecting the dropdown beside a user entry and selecting **Manage Teams**. The list of teams an individual user belongs to can be viewed on the user's profile page via **System Console \> Users** and selecting the member's name from the list provided in the **User Configuration** screen. diff --git a/docs/main/end-user-guide/collaborate/team-settings.mdx b/docs/main/end-user-guide/collaborate/team-settings.mdx index 692005198566..66a55f8b7183 100644 --- a/docs/main/end-user-guide/collaborate/team-settings.mdx +++ b/docs/main/end-user-guide/collaborate/team-settings.mdx @@ -61,6 +61,33 @@ When a team icon is configured, select **Remove image** to reset the team icon t Access settings enable the ability to control who can join the team. +### Discoverability + +System and team administrators control whether the team is public or private using two selection cards: + +- **Public Team** — anyone on the server can find the team, and join it if they meet any other join restrictions, such as approved email domains. The team appears on the server landing page and in the **Teams you can join** page. +- **Private Team** — only invited members can join. The team isn't listed for users who aren't already members. + + + +From Mattermost v11.10, these cards replace the **Allow any user to join** checkbox. This change applies to every team on every deployment. **Public Team** is equivalent to the checkbox being enabled, and **Private Team** is equivalent to it being disabled. + + + + + +Switching a team from **Public Team** to **Private Team** regenerates the team's invite code. This creates a new invitation link and invalidates any link shared previously. + + + + + +When a team is set to **Public Team**, users looking for more teams to join will also see this team in the list when they select the The Plus icon provides access to channel and direct message functionality. icon in the team sidebar. + + + +On teams managed by AD/LDAP group synchronization, the cards aren't shown. Instead, the Access tab displays a message noting that members of the team are added and removed by linked groups. + ### Users with a specific email domain System and team administrators can limit who can join the team based on their email domain. Enable this option to specify approved email domains. Separate multiple email domains using spaces, commas, pressing Tab, or pressing Enter. @@ -73,24 +100,30 @@ Mattermost deployments using [email authentication](/administration-guide/config -### Users on this server +### Invite code -System and team administrators can include the team in a list of teams to join for new Mattermost users who aren't yet members of a team. Enable this option to allow any user with a Mattermost account on this instance to join this team from the **Teams you can join** page. +The **Invite Code** is used as part of the URL in team invitation links. Select **Regenerate** to create a new invitation link and invalidate any previous link. - +## Team Membership -When you enable this option, users looking for more teams to join will also see this team in the list when they select the The Plus icon provides access to channel and direct message functionality. icon in the team sidebar. + - +From Mattermost v11.10, the **Team Membership** tab is available to Team Admins when [Attribute-Based Access Control (ABAC)](/administration-guide/manage/admin/attribute-based-access-control) is enabled by a System Admin. It allows Team Admins to view the system policy applied to their team and define attribute-based rules that control who can be a member of the team itself. -### Invite code +On private teams these rules are enforced: users who don't match can't join, and members who no longer match are removed at the next sync. On public teams the rules are advisory — qualifying users are highlighted as recommended, but anyone can still join. -The **Invite Code** is used as part of the URL in team invitation links. Select **Regenerate** to create a new invitation link and invalidate any previous link. +See [Team membership access policies](/administration-guide/manage/admin/abac-team-membership) for full details. -## Membership Policies +## Channel Membership -The **Membership Policies** tab is available to Team Admins when [Attribute-Based Access Control (ABAC)](/administration-guide/manage/admin/attribute-based-access-control) is enabled by a System Admin. It allows Team Admins to create and manage attribute-based membership policies that control access to private channels within the team. +The **Channel Membership** tab is available to Team Admins when [Attribute-Based Access Control (ABAC)](/administration-guide/manage/admin/attribute-based-access-control) is enabled by a System Admin. It allows Team Admins to create and manage attribute-based membership policies for private and public channels within the team. On private channels the policies are enforced. On public channels they're advisory — matching users can be added automatically or shown the channel as recommended, but no one is removed. + + + +This tab was previously labelled **Membership Policies**. It was renamed in Mattermost v11.10 to distinguish it from the new **Team Membership** tab. + + See [Team-level channel membership policies](/administration-guide/manage/admin/abac-team-channel-policies) for full details. diff --git a/docs/main/end-user-guide/messaging-collaboration.mdx b/docs/main/end-user-guide/messaging-collaboration.mdx index 7aaf88351721..eb426666ae90 100644 --- a/docs/main/end-user-guide/messaging-collaboration.mdx +++ b/docs/main/end-user-guide/messaging-collaboration.mdx @@ -18,4 +18,4 @@ This Mattermost end user documentation is designed for anyone who wants guidance - [Communicate with messages and threads](/end-user-guide/collaborate/communicate-with-messages) Learn how to get started collaborating within Mattermost channels. - [Collaborate within Microsoft Teams](/end-user-guide/collaborate/collaborate-within-connected-microsoft-teams) - Learn how to get started collaborating within Microsoft Teams. - [Keyboard shortcuts](/end-user-guide/collaborate/keyboard-shortcuts) - Make a more efficient use of your keyboard with keyboard shortcuts. -- [Extend Mattermost with integrations](/end-user-guide/collaborate/extend-mattermost-with-integrations) - Find open source integrations to common tools in the Mattermost Marketplace. +- [Extend Mattermost with integrations](/end-user-guide/collaborate/extend-mattermost-with-integrations) - Find open-source integrations to common tools in the Mattermost Marketplace, and learn how to interact with rich integration messages. diff --git a/docs/main/end-user-guide/preferences/troubleshoot-notifications.mdx b/docs/main/end-user-guide/preferences/troubleshoot-notifications.mdx index c40b8785d6e2..3a43971d29bc 100644 --- a/docs/main/end-user-guide/preferences/troubleshoot-notifications.mdx +++ b/docs/main/end-user-guide/preferences/troubleshoot-notifications.mdx @@ -225,7 +225,7 @@ Yes, push notifications are free if you compile your own [push-proxy service](ht TPNS, hosted at [https://push-test.mattermost.com](https://push-test.mattermost.com), offers transport-level encryption, but not production-level service level agreements (SLAs). -If you need production-level SLAs for push notifications, you can either compile your own push-proxy service, with your own key, or you can use a paid option and become a Mattermost Professional subscriber [agreeing to our Conditions of Use](https://mattermost.com/terms-of-use/), which enables you to use a production-level Hosted Push Notification Service (HPNS) at `https://push.mattermost.com`. +If you need production-level SLAs for push notifications, you can either compile your own push-proxy service, with your own key, or you can use a paid option and become a Mattermost Professional subscriber [agreeing to our Conditions of Use](https://mattermost.com/terms-of-use/), which enables you to use a production-level Hosted Push Notification Service (HPNS) at a regional URL such as `https://global.push.mattermost.com` — see the [push notification server location](/administration-guide/configure/push-notification-server-configuration-settings#push-notification-server-location) setting for the full list of regions. Learn more about [our push notification service](/administration-guide/configure/environment-configuration-settings#enable-push-notifications). diff --git a/docs/main/integrations-guide/faq.mdx b/docs/main/integrations-guide/faq.mdx index 1bb6d78440b3..e10ffbf410a0 100644 --- a/docs/main/integrations-guide/faq.mdx +++ b/docs/main/integrations-guide/faq.mdx @@ -37,6 +37,16 @@ When "attachments" are mentioned in Mattermost integrations documentation, it re Mattermost doesn't currently support the ability to attach files to a post made via webhook. You can use the API to attach files to a message if needed. +## What are Mattermost Blocks? + +Mattermost Blocks are the structured format for rich, interactive integration posts. Integrations can extend messages with text, images, buttons, menus, collapsible sections, and different layout options. + +Starting in Mattermost v11.10, Mattermost Blocks are the recommended replacement for [message attachments](https://developers.mattermost.com/integrate/reference/message-attachments/). They are the preferred way to create interactive messages for integrations such as [incoming webhooks](/integrations-guide/incoming-webhooks), plugins, and bot accounts. + +Legacy message attachments and other interactive message formats continue to work; clients translate them into the Mattermost Blocks format at render time. We encourage new and updated integrations to use Mattermost Blocks instead. + +For payload structure, block types, action handling, migration guidance, and troubleshooting, see the [Mattermost Blocks reference](https://developers.mattermost.com/integrate/reference/mm-blocks/) in the developer documentation. + ## Where can I find existing integrations? Visit the [Mattermost Marketplace](https://mattermost.com/marketplace) to access open source integrations to common tools like Jira, Jenkins, and GitLab, along with interactive bot applications, and other communication tools that are freely available for use and customization. diff --git a/docs/main/integrations-guide/incoming-webhooks.mdx b/docs/main/integrations-guide/incoming-webhooks.mdx index 7c59d2a72f26..ff77c73cccc4 100644 --- a/docs/main/integrations-guide/incoming-webhooks.mdx +++ b/docs/main/integrations-guide/incoming-webhooks.mdx @@ -9,6 +9,8 @@ import useBaseUrl from '@docusaurus/useBaseUrl'; Send or receive real-time data from external tools. Webhooks require minimal coding and are easy to set up with virtually any tool or platform because they use lightweight HTTP POST requests with JSON payloads. +For richly formatted interactive posts with buttons and menus, see [What are Mattermost Blocks?](/integrations-guide/faq#what-are-mattermost-blocks). + Using incoming webhooks in Mattermost requires only basic setup. You generate a webhook URL using the Mattermost interface, then point another service to send data to that address. No coding is required if your external service triggering the events is able to send data via webhooks or HTTP POST requests, which most modern applications and platforms support. Setting this up usually involves pasting the Mattermost webhook URL into the service’s settings and selecting what type of events you want it to send. ## Example Use Cases @@ -95,7 +97,7 @@ The JSON payload can contain the following parameters: text -Yes (if attachments is not set) +Yes (if props.mm_blocks is not set) Markdown-formatted message. Use @<username>, @channel, and @here for notifications. @@ -119,11 +121,6 @@ The JSON payload can contain the following parameters: Overrides the icon_url with an emoji. Use the emoji name (e.g., :tada:). The Enable integrations to override profile picture icons setting must be enabled. -attachments -Yes (if text is not set) -An array of message attachment objects for richer formatting. - - type No Sets the post type, mainly for use by plugins. If set, must begin with custom_. @@ -131,7 +128,7 @@ The JSON payload can contain the following parameters: props No -A JSON object for storing metadata. The card property can be used to display extra Markdown-formatted text in the post's info panel (RHS). This is available in Mattermost v5.14 and later, and is not yet supported on mobile. +A JSON object for storing metadata. Use Mattermost Blocks for rich, interactive content. The card property can be used to display extra Markdown-formatted text in the post's info panel (RHS). This is available in Mattermost v5.14 and later, and is not yet supported on mobile. priority @@ -220,8 +217,7 @@ If your integration posts the JSON payload as plain text instead of a rendered m Transform basic message posts into rich, interactive notifications by including buttons, menus, and other interactive elements in your webhook messages, making them more engaging and useful for your team. -- [Message Attachments](https://developers.mattermost.com/integrate/reference/message-attachments/): Present rich, structured summaries such as status, priority, fields, links, or images for faster triage and comprehension. (Slack‑compatible schema.) -- [Interactive Messages](https://developers.mattermost.com/integrate/plugins/interactive-messages): Make notifications actionable with buttons or menus such as Acknowledge, Assign, or Escalate that enable an immediate user response without switching tools or context. +- [Mattermost Blocks](https://developers.mattermost.com/integrate/reference/mm-blocks/): Create structured, interactive posts with text, images, buttons, and menus. - [Interactive Dialogs](https://developers.mattermost.com/integrate/plugins/interactive-dialogs/): Guide users to successful outcomes when interactions need structured input or confirmation (for example, “Acknowledge with note” or “Assign to user”). Improve data quality with required fields, minimum/maximum input lengths, server‑driven user/channel pickers, validated defaults, inline field errors, placeholders, and help text that help users enter the right data the first time. - [Message Priority](https://developers.mattermost.com/integrate/reference/message-priority/): Set `priority` to elevate critical posts and optionally request acknowledgements or persistent notifications. diff --git a/docs/main/integrations-guide/integrations-guide-index.mdx b/docs/main/integrations-guide/integrations-guide-index.mdx index 8878d54a073f..dafe882c753e 100644 --- a/docs/main/integrations-guide/integrations-guide-index.mdx +++ b/docs/main/integrations-guide/integrations-guide-index.mdx @@ -93,7 +93,7 @@ Learn more about [Mattermost webhooks](/integrations-guide/webhook-integrations) [Incoming webhooks](/integrations-guide/incoming-webhooks) allow external applications to post messages into Mattermost channels and direct messages. They are a simple way to receive notifications and data from other services in real-time and require only basic setup. -Additionally, Mattermost webhook payloads are [fully compatible](/integrations-guide/incoming-webhooks#slack-compatibility) with Slack’s webhook format to make migration easier. +Additionally, Mattermost webhook payloads are [fully compatible](/integrations-guide/incoming-webhooks#slack-compatibility) with Slack’s webhook format to make migration easier. For new interactive content, use [Mattermost Blocks](https://developers.mattermost.com/integrate/reference/mm-blocks/) instead of message attachments. #### Outgoing Webhooks diff --git a/docs/main/integrations-guide/outgoing-webhooks.mdx b/docs/main/integrations-guide/outgoing-webhooks.mdx index efa778708560..0a462b39eabf 100644 --- a/docs/main/integrations-guide/outgoing-webhooks.mdx +++ b/docs/main/integrations-guide/outgoing-webhooks.mdx @@ -7,7 +7,7 @@ import useBaseUrl from '@docusaurus/useBaseUrl'; **Technical complexity:** [Low-code](./faq#low-code) -Outgoing webhooks can be used to create rich, interactive experiences in Mattermost by letting external services respond with rich message attachments, such as structured fields, buttons, and menus. Additionally, these responses can trigger interactive dialog forms where users provide additional input directly in Mattermost, or interactive messages that update dynamically based on user actions. Together, these capabilities turn simple keyword triggers into powerful in-product workflows that streamline how teams interact with external systems, all with minimal coding required. +Outgoing webhooks can be used to create rich, interactive experiences in Mattermost by letting external services respond with [Mattermost Blocks](https://developers.mattermost.com/integrate/reference/mm-blocks/)—structured content with buttons, menus, and other interactive elements. Additionally, these responses can trigger interactive dialog forms where users provide additional input directly in Mattermost. Together, these capabilities turn simple keyword triggers into powerful in-product workflows that streamline how teams interact with external systems, all with minimal coding required. Outgoing webhooks require no coding to configure on in Mattermost, however the external service that receives the HTTP POST request needs to process the data, and then format and send a respond with a message back to Mattermost. This usually requires light coding to parse the request and format a JSON response payload, though many [automation platforms](/integrations-guide/integrations-guide-index#build-and-automate-workflows) handle this without writing custom code. @@ -23,11 +23,11 @@ When a user types `bug` in a channel, an outgoing webhook sends the message to a **Knowledge base lookup** -A keyword like `docs` triggers an outgoing webhook that queries a documentation service and returns a rich interactive message with a list of suggested articles, each with clickable buttons or menus. Users can refine their search or open links without leaving Mattermost. +A keyword like `docs` triggers an outgoing webhook that queries a documentation service and returns a response with [Mattermost Blocks](https://developers.mattermost.com/integrate/reference/mm-blocks/) listing suggested articles, each with clickable buttons or menus. Users can refine their search or open links without leaving Mattermost. **Security incident enrichment** -Typing a keyword like `ioc` (indicator of compromise) in a security channel can trigger an outgoing webhook that queries a threat intelligence platform. The response can return a formatted message attachment with reputation scores, related incidents, and quick-action buttons for escalating, investigating, or dismissing the alert. +Typing a keyword like `ioc` (indicator of compromise) in a security channel can trigger an outgoing webhook that queries a threat intelligence platform. The response can return [Mattermost Blocks](https://developers.mattermost.com/integrate/reference/mm-blocks/) with reputation scores, related incidents, and quick-action buttons for escalating, investigating, or dismissing the alert. ## Create @@ -168,7 +168,7 @@ The JSON response can contain the following parameters: text -(Required if attachments is not set) Markdown-formatted message. +(Required unless attachments or props.mm_blocks is set) Markdown-formatted message. response_type @@ -184,7 +184,7 @@ The JSON response can contain the following parameters: attachments -(Required if text is not set) An array of message attachment objects. +Legacy array of message attachment objects. Use Mattermost Blocks for new integrations. type @@ -192,7 +192,7 @@ The JSON response can contain the following parameters: props -A JSON object for storing metadata. +A JSON object for storing metadata. Use Mattermost Blocks for rich, interactive content. priority @@ -223,22 +223,21 @@ This response would produce a threaded reply to the original message that trigge Example of a full response from an outgoing webhook. -You can also include [message attachments](https://developers.mattermost.com/integrate/reference/message-attachments/) and [interactive messages](https://developers.mattermost.com/integrate/plugins/interactive-messages/) in your response to create more advanced workflows. +You can also include [Mattermost Blocks](https://developers.mattermost.com/integrate/reference/mm-blocks/) in your response to create more advanced workflows. ## Do More with Outgoing Webhooks Turn keyword-triggered callbacks into guided, in-channel workflows by returning buttons, menus, and other interactive elements in your webhook responses so users can act immediately. -- [Message Attachments](https://developers.mattermost.com/integrate/reference/message-attachments/): Return rich, structured results (IDs, statuses, fields, links, images) for quick confirmation and follow-up. -- [Interactive Messages](https://developers.mattermost.com/integrate/plugins/interactive-messages/): Present next-step actions (Acknowledge, Assign, Escalate) as buttons/menus directly in your response—no context switching. +- [Mattermost Blocks](https://developers.mattermost.com/integrate/reference/mm-blocks/): Return structured, interactive content with text, buttons, and menus. - [Interactive Dialogs](https://developers.mattermost.com/integrate/plugins/interactive-dialogs/): When a button/menu click requires more info (e.g., “Acknowledge with note”, “Assign to user”), open a dialog to collect structured inputs with required fields, min/max lengths, server-driven user/channel pickers, validated defaults, inline field errors, placeholders, and help text. - [Message Priority](https://developers.mattermost.com/integrate/reference/message-priority/): Include `priority` in your response to mark critical updates and optionally request acknowledgements or persistent notifications. -- Outgoing webhook responses support attachments and interactive actions. When a user clicks an action, your integration receives a signed trigger ID and can open an interactive dialog via the dialog API. You can also control visibility with the response type (in-channel vs ephemeral). +- Outgoing webhook responses support Mattermost Blocks and interactive actions. The outgoing webhook response_type accepts post or comment. When a user clicks an action, the callback payload includes a trigger_id field that can be used to open an interactive dialog; the trigger ID isn't a request signature. Return ephemeral_text in the action response when feedback should be visible only to the user who clicked the action. - Need a dedicated identity, permissions scoping, or need to post outside of webhook/command flows? Use a [bot account](https://developers.mattermost.com/integrate/reference/bot-accounts/) if you need a more permanent solution than using overrides for simple branding. - If your command backend needs to call Mattermost APIs (e.g., posting messages, ephemeral posts, opening interactive dialogs, etc.), authenticate with a bot user [personal access token](https://developers.mattermost.com/integrate/reference/personal-access-token/). We recommend avoiding human/System Admin personal access tokens for automations and rotating and storing tokens securely. -- Looking to support private channels, direct messages, and autocomplete? Use a [built-in slash command](/integrations-guide/built-in-slash-commands), or create a [custom slash command](https://developers.mattermost.com/integrate/slash-commands/custom/). You can additionally tegrate Mattermost with custom integrations hosted within your internal OAuth infrastructure [using the Client Credentials OAuth 2.0 grant type](https://developers.mattermost.com/integrate/slash-commands/outgoing-oauth-connections/). Mattermost also makes it easy to [migrate integrations written for Slack to Mattermost](https://developers.mattermost.com/integrate/slash-commands/slack/). +- Looking to support private channels, direct messages, and autocomplete? Use a [built-in slash command](/integrations-guide/built-in-slash-commands), or create a [custom slash command](https://developers.mattermost.com/integrate/slash-commands/custom/). You can additionally integrate Mattermost with custom integrations hosted within your internal OAuth infrastructure [using the Client Credentials OAuth 2.0 grant type](https://developers.mattermost.com/integrate/slash-commands/outgoing-oauth-connections/). Mattermost also makes it easy to [migrate integrations written for Slack to Mattermost](https://developers.mattermost.com/integrate/slash-commands/slack/). diff --git a/docs/main/integrations-guide/plugins.mdx b/docs/main/integrations-guide/plugins.mdx index 2a24f5212e0d..7bcf7a53bf06 100644 --- a/docs/main/integrations-guide/plugins.mdx +++ b/docs/main/integrations-guide/plugins.mdx @@ -21,7 +21,7 @@ The [Mattermost Marketplace](https://mattermost.com/marketplace/) offers an expa **Technical complexity:** [Pro-code](./faq#pro-code) -Building a custom plugin for your self-hosted deployment is a **software development** task, using `Go` for the server-side functionality and optionally `TypeScript/React` for UI components. Developers should be comfortable with Git, modern build tooling, and the [Mattermost Plugin API](https://developers.mattermost.com/integrate/reference/server/server-reference/), including lifecycle hooks, KV storage, slash commands, and interactivity. Knowledge of testing, logging, and security best practices is essential for production-ready plugins, along with experience packaging and deploying plugins through the System Console or CLI. For teams without these skills, simpler options like webhooks, slash commands, or no-code workflow tools may be more practical. +Building a custom plugin for your self-hosted deployment is a **software development** task, using `Go` for the server-side functionality and optionally `TypeScript/React` for UI components. Developers should be comfortable with Git, modern build tooling, and the [Mattermost Plugin API](https://developers.mattermost.com/integrate/reference/server/), including lifecycle hooks, KV storage, slash commands, and interactivity. Knowledge of testing, logging, and security best practices is essential for production-ready plugins, along with experience packaging and deploying plugins through the System Console or CLI. For teams without these skills, simpler options like webhooks, slash commands, or no-code workflow tools may be more practical. Plugins can authenticate and interact with Mattermost through [bot accounts](https://developers.mattermost.com/integrate/reference/bot-accounts/), utilizing the [RESTful API](https://developers.mattermost.com/api-documentation/). diff --git a/docs/main/integrations-guide/slash-commands.mdx b/docs/main/integrations-guide/slash-commands.mdx index 82713735ccfd..a21687541bdd 100644 --- a/docs/main/integrations-guide/slash-commands.mdx +++ b/docs/main/integrations-guide/slash-commands.mdx @@ -39,4 +39,4 @@ Using `/pagerduty trigger` can open a form to start a new incident, notify on-ca **Knowledge retrieval** -A command like `/docs search authentication` queries your documentation system and returns a list of relevant articles as interactive message attachments with links. +A command like `/docs search authentication` queries your documentation system and returns a list of relevant articles rendered using [Mattermost Blocks](https://developers.mattermost.com/integrate/reference/mm-blocks/) with links. diff --git a/docs/main/product-overview/common-esr-support-rst.mdx b/docs/main/product-overview/common-esr-support-rst.mdx index e23cd4084bcf..d1e98e244573 100644 --- a/docs/main/product-overview/common-esr-support-rst.mdx +++ b/docs/main/product-overview/common-esr-support-rst.mdx @@ -2,6 +2,6 @@ --- -Support for Mattermost Server v10.11 [Extended Support Release](/product-overview/release-policy#extended-support-releases) is coming to the end of its life cycle on August 15, 2026. Upgrading to [Mattermost Server v11.7 or later](/product-overview/mattermost-server-releases) is recommended. +Support for Mattermost Server v10.11 [Extended Support Release](/product-overview/release-policy#extended-support-releases) has come to the end of its life cycle on August 15, 2026. Upgrading to [Mattermost Server v11.7 or later](/product-overview/mattermost-server-releases) is required. diff --git a/docs/main/product-overview/common-esr-support-upgrade.mdx b/docs/main/product-overview/common-esr-support-upgrade.mdx index 59125315f5a4..2befe922a4b8 100644 --- a/docs/main/product-overview/common-esr-support-upgrade.mdx +++ b/docs/main/product-overview/common-esr-support-upgrade.mdx @@ -2,7 +2,7 @@ --- {/* Snippet include; not intended to be a standalone page */} -- Support for Mattermost Server v10.11 [Extended Support Release](https://docs.mattermost.com/product-overview/release-policy.html#extended-support-releases) is coming to the end of its life cycle on August 15, 2026. Upgrading to Mattermost Server v11.7 or later is recommended. +- Support for Mattermost Server v10.11 [Extended Support Release](https://docs.mattermost.com/product-overview/release-policy.html#extended-support-releases) has come to the end of its life cycle on August 15, 2026. Upgrading to Mattermost Server v11.7 or later is required. - Upgrading from one Extended Support Release (ESR) to the next ESR (``major`` -> ``major_next``) is fully supported and tested. However, upgrading across multiple ESR versions (``major`` to ``major+2``) is supported, but not tested. If you plan to skip versions, we strongly recommend upgrading only between ESR releases. For example, if you're upgrading from v8.1 ESR, upgrade to the v9.5 ESR or the v9.11 ESR before attempting to upgrade to the [v10.11 ESR](https://docs.mattermost.com/product-overview/mattermost-v10-changelog.html#release-v10-11-extended-support-release) or the [v11.7 ESR](https://docs.mattermost.com/product-overview/mattermost-server-releases.html). - See the [Important Upgrade Notes](https://docs.mattermost.com/upgrade/important-upgrade-notes.html) documentation for details on upgrading to a newer release. - See the [changelog in progress](https://bit.ly/2nK3cVf) for details about the upcoming release. diff --git a/docs/main/product-overview/common-esr-support.mdx b/docs/main/product-overview/common-esr-support.mdx index 256f8f4e832e..0bdb8a91e89b 100644 --- a/docs/main/product-overview/common-esr-support.mdx +++ b/docs/main/product-overview/common-esr-support.mdx @@ -2,5 +2,5 @@ --- {/* Snippet include; not intended to be a standalone page */} -- Support for Mattermost Server v10.11 [Extended Support Release](https://docs.mattermost.com/product-overview/release-policy.html#extended-support-releases) is coming to the end of its life cycle on August 15, 2026. Upgrading to [Mattermost Server v11.7](https://docs.mattermost.com/product-overview/mattermost-server-releases.html) or later is recommended. +- Support for Mattermost Server v10.11 [Extended Support Release](https://docs.mattermost.com/product-overview/release-policy.html#extended-support-releases) has come to the end of its life cycle on August 15, 2026. Upgrading to [Mattermost Server v11.7](https://docs.mattermost.com/product-overview/mattermost-server-releases.html) or later is required. - All Mattermost users must accept Mattermost's [Acceptable Use Policy](https://mattermost.com/terms-of-use/#acceptable-use-policy) and [Privacy Policy](https://mattermost.com/privacy-policy/) when creating an account or accessing Mattermost. For customers with a Mattermost subscription, including self-hosted deployments, organizations may replace or override the Acceptable Use Policy in the [Mattermost System Console](https://docs.mattermost.com/administration-guide/configure/site-configuration-settings.html#terms-of-use-link) with their own acceptable use or conduct policies, based on contractual terms with Mattermost, so long as your own terms either incorporate the Acceptable Use Policy or include equivalent terms. If you change the default link to add your own terms for using the service you provide, your new terms must include a link to the default terms so end users are aware of the Mattermost Acceptable Use Policy for Mattermost software. diff --git a/docs/main/product-overview/deprecated-features.mdx b/docs/main/product-overview/deprecated-features.mdx index 95064a681f02..e5092d5ae079 100644 --- a/docs/main/product-overview/deprecated-features.mdx +++ b/docs/main/product-overview/deprecated-features.mdx @@ -11,6 +11,16 @@ This page describes features that are removed from support for Mattermost, or wi - Starting with Mattermost Server v12.0 (October 2026), OpenSearch 1.x will no longer be a supported search backend. OpenSearch 1.x reached end-of-life on May 6, 2025, and Mattermost is setting a minimum supported version of OpenSearch 2.x going forward. Mattermost v12.0 (October 2026) is the first release that requires OpenSearch 2.x or newer; v11 releases will continue to work with 1.x while admins plan their migration. OpenSearch 2.x, 3.x, and Elasticsearch 8.x/9.x remain fully supported search backends. Admins running OpenSearch 1.x should plan to upgrade to 2.x (or migrate to Elasticsearch) before the v12.0 release. See the [forum post](https://forum.mattermost.com/t/starting-with-mattermost-v12-0-october-2026-opensearch-1-x-is-no-longer-a-supported-search-backend/25979) for full details and migration options. - Starting with Mattermost Server v12.0 (October 2026), ``atmos/camo`` will no longer be supported as an image proxy. The ``atmos/camo`` project has been archived and is no longer maintained. If ``ImageProxySettings.ImageProxyType`` is set to ``atmos/camo``, the server will log a configuration error on startup and fail to start; the ``RemoteImageProxyURL`` and ``RemoteImageProxyOptions`` settings are also removed and will be ignored. Admins should switch to the built-in local image proxy (set ``ImageProxySettings.ImageProxyType`` to ``local``) or disable image proxying entirely (``ImageProxySettings.Enable`` set to ``false``) before upgrading. The local proxy requires no external service and includes SVG content blocking and security response headers. See the [forum post](https://forum.mattermost.com/t/starting-with-mattermost-v12-0-october-2026-atmos-camo-is-no-longer-supported-as-an-image-proxy/25980) for full details and migration options. +- Starting with v12.0 (October release), the Mattermost web and desktop apps will be built on [React 19](https://react.dev/blog/2024/04/25/react-19-upgrade-guide). This only affects plugins that register web app (frontend) components — server-only plugins are unaffected. Web app plugins use the React version provided by the web app, so your plugin's components will render under React 19 whether or not you rebuild. Plugins that call APIs removed in React 19 (``ReactDOM.findDOMNode``, ``propTypes``/``defaultProps`` on function components, legacy Context, string refs) or depend on legacy synchronous rendering may break. To prepare: run ``npx codemod@latest run react-19-migration-recipe``, fix any removed-API usage, and test your plugin against a v12.0 release candidate during the beta window. See the [forum post](https://forum.mattermost.com/t/starting-with-mattermost-v12-0-october-2026-the-mattermost-web-and-desktop-apps-are-built-on-react-19/26038) for full details. +- Starting with v12.0 (October release), the Mattermost mobile app will require your server to be running v10.11 or later. Server v10.11 reaches End of Support on **August 15, 2026** as scheduled. Separately, in **October 2026** the mobile app will begin requiring server **v10.11 or later** — users on earlier servers won't be able to sign in from mobile. The minimum tracks the most recently retired [ESR](https://docs.mattermost.com/product-overview/release-policy.html#extended-support-releases), so the next bump is to **v11.7** in 2027. Deployments on MySQL will need to migrate to PostgreSQL to move past v10.11. See the [forum post](https://forum.mattermost.com/t/starting-in-october-2026-the-mattermost-mobile-app-will-require-mattermost-server-v10-11-or-later/26039) for full details. +- Starting with Mattermost Server v12.0 (October 2026), user sessions and personal access tokens (PATs) can no longer set post identity or display-override props. Some deployments have relied on forging props such as ``from_webhook`` with ``override_username`` and ``override_icon_url`` so posts appear under a custom name and icon — a pattern indistinguishable from impersonation. In v12.0, the server strips these props from client and PAT payloads and re-applies them only under verified integration authority. Posts are still created, but forged props are silently removed and the message appears as the authenticating user, with no error returned. Legitimate integrations are unaffected: incoming webhooks and slash commands can still override the username and icon when enabled in the System Console, and bots post as the bot account. Admins relying on PAT forging should migrate those scripts to an incoming webhook or bot account before upgrading. See the [forum post](https://forum.mattermost.com/t/starting-with-mattermost-v12-0-october-2026-user-and-personal-access-token-pat-sessions-can-no-longer-set-post-identity-or-display-override-props/26052) for full details and migration options. +- Starting with Mattermost Server v12.0 (October 2026), deprecated interactive dialog ``date/datetime`` fields will be removed. Top-level ``min_date``, ``max_date``, and ``time_interval``, and ``datetime_config.allow_manual_time_entry``, will no longer be accepted; use ``datetime_config`` (with ``manual_time_entry``) instead. Legacy keys will be silently ignored. +- Starting with Mattermost Server v12.0 (October 2026), deprecated Slack compatibility type aliases and functions will be removed (``SlackAttachment``, ``SlackAttachmentField``, ``ParseSlackAttachment``, ``StringifySlackFieldValue``) from the go package. Use ``MessageAttachment``, ``MessageAttachmentField``, ``ParseMessageAttachment``, and ``StringifyMessageAttachmentFieldValue`` instead. + +### Mattermost Desktop App v6.4 (November 2026) + +- Starting with Mattermost Desktop App v6.4 (November 2026), servers configured with a subpath in their Site URL will require Boards v9.4.0 or later. The Desktop App will no longer strip the server subpath from paths sent by Boards, a workaround that caused "Team not found" errors when a team name matched the subpath, so older Boards versions may show navigation errors. Update the Boards plugin to v9.4.0 or later before updating the Desktop App. Follow the [Boards installation instructions](https://docs.mattermost.com/administration-guide/configure/install-boards.html). Deployments without a subpath will be unaffected. See the [forum post](https://forum.mattermost.com/t/desktop-app-v6-4-requires-boards-v9-4-0-for-subpath-deployments/26064) for full details and migration options. + ## Removed features by Mattermost version ### Mattermost Desktop App v6.1 (March 2026) diff --git a/docs/main/product-overview/desktop-app-changelog.mdx b/docs/main/product-overview/desktop-app-changelog.mdx index 9adc72cf15a0..2fbf67d7bd32 100644 --- a/docs/main/product-overview/desktop-app-changelog.mdx +++ b/docs/main/product-overview/desktop-app-changelog.mdx @@ -10,8 +10,69 @@ This changelog summarizes updates to Mattermost desktop app releases for [Matter +## Release v6.3 \{#release-v6-3} + +**v6.3.0 Release Day: 2026-08-14** + +**Download Binaries:** [Mattermost Desktop on GitHub](https://github.com/mattermost/desktop/releases/latest) + +### Compatibility + +- Desktop App is supported on any currently supported [Mattermost server version](https://docs.mattermost.com/product-overview/mattermost-desktop-releases.html#latest-releases). +- Updated Chromium minimum supported version to 150+. + +### Improvements + +#### All Platforms + +- Added koffi native module, and added connectors for macOS and Windows native session attributes. +- Added support for explicitly trusted embedded media origins for media permission requests. +- Updated onboarding and server connection welcome messaging. +- Added an advanced setting to enable or disable session attributes. Some resources may be inaccessible when disabled. +- Enabled client-collected **Session Attributes** to be sent to enabled servers. +- Added ``F12`` to open **Developer Tools** for current tab. +- Improved how network requests and embedded content from connected servers are handled, keeping requests scoped to configured servers. +- Improved handling of page redirects and embedded content navigation across Desktop App windows. + +### Architectural Changes + +- Major version upgrade of Electron to v43.0.0. Electron is the underlying technology used to build the Desktop App. + +### Bug Fixes + +#### macOS +- Fixed an issue where a ``mattermost://`` deep link could open the **Add Server** dialog. + +#### Linux +- Fixed download URL construction in "Download Options" for Linux releases. +- Fixed the association to the desktop launcher and the wrong icon being shown in Ubuntu. + +#### All Platforms + +- Fixed an issue where other views could end an active call. +- Fixed a rare crash where closing a server tab or window while it was still loading could throw "Object has been destroyed" in the main process. + +### Open Source Components + +- Added ``joi`` and ``fast-xml-parser`` to https://github.com/mattermost/desktop/. + +### Known Issues + +- Sometimes during installation you may see this message: ``Warning 1946. Property 'System.AppUserModel.ID' for shortcut 'Mattermost.Ink' could not be set``. This message can be safely ignored. +- Users seeing an endless "Loading..." screen when attempting to log in to the app may need to manually clear cached data. The Mattermost data directory is `/Users//Library/Containers/Mattermost/Data/Library/Application Support/Mattermost` on macOS, `Users//AppData/Roaming/Mattermost` on Windows, and `~/.config/Mattermost` on Linux. Delete only the `Cache`, `Code Cache`, and `GPUCache` subdirectories. Deleting the full Mattermost data directory also resets desktop configuration and session data. +- On Linux, a left-click on the Mattermost tray icon doesn't open the app window but opens the tray menu. +- Crashes might be experienced in some Linux desktop clients due to an upstream bug in the `libnotifyapp` library. A recommended workaround is to disable the Mattermost system tray icon via Desktop Settings. + ## Release v6.2 (Extended Support Release) \{#release-v6-2} +- **v6.2.3, released 2026-08-17** + + - Mattermost Desktop App v6.2.3 contains low to medium severity level security fixes. Upgrading is recommended. Details will be posted on our [security updates page](https://mattermost.com/security-updates/) 30 days after release as per the [Mattermost Responsible Disclosure Policy](https://mattermost.com/security-vulnerability-report/). + - Major version upgrade of Electron to v43.3.0. Electron is the underlying technology used to build the Desktop App. + - Fixed an issue where other views could end an active call. + - Fixed an issue in the Desktop App's internal URL validation. + - Improved how network requests and embedded content from connected servers are handled, keeping requests scoped to your configured servers. + - **v6.2.2, released 2026-06-23** - Fixed an issue where notifications were dropped when the web app sent empty fields for Direct Messages, Group Messages, or system notifications. @@ -25,12 +86,12 @@ This changelog summarizes updates to Mattermost desktop app releases for [Matter - Original v6.2.0 release -**Download Binaries:** [Mattermost Desktop on GitHub](https://github.com/mattermost/desktop/releases/v6.2.2) +**Download Binaries:** [Mattermost Desktop on GitHub](https://github.com/mattermost/desktop/releases/v6.2.3) ### Compatibility - Desktop App is supported on any currently supported [Mattermost server version](https://docs.mattermost.com/product-overview/mattermost-desktop-releases.html#latest-releases). -- Updated Chromium minimum supported version to 146+. +- Updated Chromium minimum supported version to 150+. ### Improvements @@ -76,7 +137,7 @@ This changelog summarizes updates to Mattermost desktop app releases for [Matter ### Known Issues - Sometimes during installation you may see this message: ``Warning 1946. Property 'System.AppUserModel.ID' for shortcut 'Mattermost.Ink' could not be set``. This message can be safely ignored. -- Users seeing an endless "Loading..." screen when attempting to log in to the app may need to manually delete their cache directory. For macOS it is located in `/Users//Library/Containers/Mattermost/Data/Library/Application Support/Mattermost`, for Windows in `Users//AppData/Roaming/Mattermost` and for Linux in `~/config/Mattermost` (where `~` is the home directory). +- Users seeing an endless "Loading..." screen when attempting to log in to the app may need to manually clear cached data. The Mattermost data directory is `/Users//Library/Containers/Mattermost/Data/Library/Application Support/Mattermost` on macOS, `Users//AppData/Roaming/Mattermost` on Windows, and `~/.config/Mattermost` on Linux. Delete only the `Cache`, `Code Cache`, and `GPUCache` subdirectories. Deleting the full Mattermost data directory also resets desktop configuration and session data. - On Linux, a left-click on the Mattermost tray icon doesn't open the app window but opens the tray menu. - Crashes might be experienced in some Linux desktop clients due to an upstream bug in the `libnotifyapp` library. A recommended workaround is to disable the Mattermost system tray icon via Desktop Settings. diff --git a/docs/main/product-overview/faq-enterprise.mdx b/docs/main/product-overview/faq-enterprise.mdx index 6a1cc69d7c54..6111b5575484 100644 --- a/docs/main/product-overview/faq-enterprise.mdx +++ b/docs/main/product-overview/faq-enterprise.mdx @@ -21,7 +21,7 @@ Please contact the Mattermost sales team at [https://mattermost.com/contact-sale Mattermost Enterprise and Mattermost Professional licenses are sold as prepaid annual subscriptions based on the number of annual seat licenses purchased, or “seats”. Each seat license purchased entitles a customer to an “activated user”, which is a user registered on a specific Mattermost server and not deactivated. Administrators can view user status in the System Console and activate and deactivate registered users at any time. Deactivated users have history and preferences saved. -Guests in exactly one channel are tracked separately as single-channel guests and are free up to a 1:1 ratio with licensed seats. Guests in multiple channels continue to count as activated users. Direct messages and group messages don't affect whether a guest is counted as a single-channel guest. +Guests in exactly one active channel are tracked separately as single-channel guests and are free up to a 1:1 ratio with licensed seats. Guests in multiple active channels continue to count as activated users. Direct messages and group messages don't affect whether a guest is counted as a single-channel guest. Only active channels count toward guest channel access for billing. Archived channels are excluded. ## What happens when activated users exceed the number of licensed seats? diff --git a/docs/main/product-overview/mattermost-desktop-releases.mdx b/docs/main/product-overview/mattermost-desktop-releases.mdx index 26390f972085..d5d973b9fcbb 100644 --- a/docs/main/product-overview/mattermost-desktop-releases.mdx +++ b/docs/main/product-overview/mattermost-desktop-releases.mdx @@ -23,7 +23,8 @@ Mattermost releases a new desktop app version every 4 months, in February, May, | **Release** | **Support** | **Compatible with** | |:---|:---|:---| -| v6.2 [Download](https://github.com/mattermost/desktop/releases/tag/v6.2.2) \| [Changelog](./desktop-app-changelog#release-v6-2) \| [SBOM download](https://github.com/mattermost/desktop/releases/download/v6.2.2/sbom-desktop-v6.2.2.json) | Released: 2026-05-15
Support Ends: 2027-05-15 [EXTENDED](./release-policy#release-types) | [v11.9](./mattermost-v11-changelog#release-v11-9-feature-release), [v11.8](./mattermost-v11-changelog#release-v11-8-feature-release), [v11.7](./mattermost-v11-changelog#release-v11-7-extended-support-release), [v11.6](./mattermost-v11-changelog#release-v11-6-feature-release), [v11.5](./mattermost-v11-changelog#release-v11-5-feature-release), [v10.11](./mattermost-v10-changelog#release-v10-11-extended-support-release) | +| v6.3 [Download](https://github.com/mattermost/desktop/releases/tag/v6.3.0) \| [Changelog](./desktop-app-changelog#release-v6-3) \| [SBOM download](https://github.com/mattermost/desktop/releases/download/v6.3.0/sbom-desktop-v6.3.0.json) | Released: 2026-08-14
Support Ends: 2026-11-15 | [v11.10](./mattermost-v11-changelog#release-v11-10-feature-release), [v11.9](./mattermost-v11-changelog#release-v11-9-feature-release), [v11.8](./mattermost-v11-changelog#release-v11-8-feature-release), [v11.7](./mattermost-v11-changelog#release-v11-7-extended-support-release) | +| v6.2 [Download](https://github.com/mattermost/desktop/releases/tag/v6.2.3) \| [Changelog](./desktop-app-changelog#release-v6-2) \| [SBOM download](https://github.com/mattermost/desktop/releases/download/v6.2.3/sbom-desktop-v6.2.3.json) | Released: 2026-05-15
Support Ends: 2027-05-15 [EXTENDED](./release-policy#release-types) | [v11.9](./mattermost-v11-changelog#release-v11-9-feature-release), [v11.8](./mattermost-v11-changelog#release-v11-8-feature-release), [v11.7](./mattermost-v11-changelog#release-v11-7-extended-support-release), [v11.6](./mattermost-v11-changelog#release-v11-6-feature-release), [v11.5](./mattermost-v11-changelog#release-v11-5-feature-release), [v10.11](./mattermost-v10-changelog#release-v10-11-extended-support-release) | | v6.1 [Download](https://github.com/mattermost/desktop/releases/tag/v6.1.2) \| [Changelog](./desktop-app-changelog#release-v6-1) \| [SBOM download](https://github.com/mattermost/desktop/releases/download/v6.1.2/sbom-desktop-v6.1.2.json) | Released: 2026-03-02
Support Ends: 2026-05-15 | [v11.6](./mattermost-v11-changelog#release-v11-6-feature-release), [v11.5](./mattermost-v11-changelog#release-v11-5-feature-release), [v11.4](./mattermost-v11-changelog#release-v11-4-feature-release), [v11.3](./mattermost-v11-changelog#release-v11-3-feature-release), [v11.2](./mattermost-v11-changelog#release-v11-2-feature-release), [v10.11](./mattermost-v10-changelog#release-v10-11-extended-support-release) | | v6.0 [Download](https://github.com/mattermost/desktop/releases/tag/v6.0.4) \| [Changelog](./desktop-app-changelog#release-v6-0) \| [SBOM download](https://github.com/mattermost/desktop/releases/download/v6.0.4/sbom-desktop-v6.0.4.json) | Released: 2025-11-14
Support Ends: 2026-03-15 | [v11.4](./mattermost-v11-changelog#release-v11-4-feature-release), [v11.3](./mattermost-v11-changelog#release-v11-3-feature-release), [v11.2](./mattermost-v11-changelog#release-v11-2-feature-release), [v11.1](./mattermost-v11-changelog#release-v11-1-feature-release), [v11.0](./mattermost-v11-changelog#release-v11-0-major-release), [v10.12](./mattermost-v10-changelog#release-v10-12-feature-release), [v10.11](./mattermost-v10-changelog#release-v10-11-extended-support-release) | | v5.13 [Download](https://github.com/mattermost/desktop/releases/tag/v5.13.7) \| [Changelog](./desktop-app-changelog#release-v5-13) \| [SBOM download](https://github.com/mattermost/desktop/releases/download/v5.13.7/sbom-desktop-v5.13.7.json) | Released: 2025-08-15
Support Ends: 2026-08-15 [EXTENDED](./release-policy#release-types) | [v11.0](./mattermost-v11-changelog#release-v11-0-major-release), [v10.12](./mattermost-v10-changelog#release-v10-12-feature-release), [v10.11](./mattermost-v10-changelog#release-v10-11-extended-support-release), [v10.10](./mattermost-v10-changelog#release-v10-10-feature-release), [v10.9](./mattermost-v10-changelog#release-v10-9-feature-release), [v10.5](./mattermost-v10-changelog#release-v10-5-extended-support-release) | diff --git a/docs/main/product-overview/mattermost-mobile-releases.mdx b/docs/main/product-overview/mattermost-mobile-releases.mdx index a427178dd2bf..75de2cea792c 100644 --- a/docs/main/product-overview/mattermost-mobile-releases.mdx +++ b/docs/main/product-overview/mattermost-mobile-releases.mdx @@ -24,7 +24,8 @@ We strongly recommend using the latest mobile app release available that contain | **Release** | **Support** | **Compatible with** | |:---|:---|:---| -| v2.42 [FEATURE](./mobile-app-changelog#release-v2-42-2) \| [Download](https://github.com/mattermost/mattermost-mobile/releases/tag/v2.42.2) \| [Changelog](./mobile-app-changelog#release-v2-42-2) \| [SBOM download](https://github.com/mattermost/mattermost-mobile/releases/download/v2.42.2/sbom-mattermost-mobile-v2.42.2.json) | Released: 2026-07-16
Support Ends: 2026-08-15 | [v11.9](./mattermost-v11-changelog#release-v11-9-feature-release), [v11.8](./mattermost-v11-changelog#release-v11-8-feature-release), [v11.7](./mattermost-v11-changelog#release-v11-7-extended-support-release), [v10.11](./mattermost-v10-changelog#release-v10-11-extended-support-release) | +| v2.43 [FEATURE](./mobile-app-changelog#release-v2-43-0) \| [Download](https://github.com/mattermost/mattermost-mobile/releases/tag/v2.43.0) \| [Changelog](./mobile-app-changelog#release-v2-43-0) \| [SBOM download](https://github.com/mattermost/mattermost-mobile/releases/download/v2.43.0/sbom-mattermost-mobile-v2.43.0.json) | Released: 2026-08-14
Support Ends: 2026-09-15 | [v11.10](./mattermost-v11-changelog#release-v11-10-feature-release), [v11.9](./mattermost-v11-changelog#release-v11-9-feature-release), [v11.8](./mattermost-v11-changelog#release-v11-8-feature-release), [v11.7](./mattermost-v11-changelog#release-v11-7-extended-support-release) | +| v2.42 [FEATURE](./mobile-app-changelog#release-v2-42-3) \| [Download](https://github.com/mattermost/mattermost-mobile/releases/tag/v2.42.3) \| [Changelog](./mobile-app-changelog#release-v2-42-3) \| [SBOM download](https://github.com/mattermost/mattermost-mobile/releases/download/v2.42.3/sbom-mattermost-mobile-v2.42.3.json) | Released: 2026-07-16
Support Ends: 2026-08-15 | [v11.9](./mattermost-v11-changelog#release-v11-9-feature-release), [v11.8](./mattermost-v11-changelog#release-v11-8-feature-release), [v11.7](./mattermost-v11-changelog#release-v11-7-extended-support-release), [v10.11](./mattermost-v10-changelog#release-v10-11-extended-support-release) | | v2.41 [FEATURE](./mobile-app-changelog#release-v2-41-3) \| [Download](https://github.com/mattermost/mattermost-mobile/releases/tag/v2.41.3) \| [Changelog](./mobile-app-changelog#release-v2-41-3) \| [SBOM download](https://github.com/mattermost/mattermost-mobile/releases/download/v2.41.3/sbom-mattermost-mobile-v2.41.3.json) | Released: 2026-06-16
Support Ends: 2026-07-15 | [v11.8](./mattermost-v11-changelog#release-v11-8-feature-release), [v11.7](./mattermost-v11-changelog#release-v11-7-extended-support-release), [v11.6](./mattermost-v11-changelog#release-v11-6-feature-release), [v10.11](./mattermost-v10-changelog#release-v10-11-extended-support-release) | | v2.40 [FEATURE](./mobile-app-changelog#release-v2-40-0) \| [Download](https://github.com/mattermost/mattermost-mobile/releases/tag/v2.40.0) \| [Changelog](./mobile-app-changelog#release-v2-40-0) \| [SBOM download](https://github.com/mattermost/mattermost-mobile/releases/download/v2.40.0/sbom-mattermost-mobile-v2.40.0.json) | Released: 2026-05-15
Support Ends: 2026-06-15 | [v11.7](./mattermost-v11-changelog#release-v11-7-extended-support-release), [v11.6](./mattermost-v11-changelog#release-v11-6-feature-release), [v11.5](./mattermost-v11-changelog#release-v11-5-feature-release), [v10.11](./mattermost-v10-changelog#release-v10-11-extended-support-release) | | v2.39 [FEATURE](./mobile-app-changelog#release-v2-39-0) \| [Download](https://github.com/mattermost/mattermost-mobile/releases/tag/v2.39.0) \| [Changelog](./mobile-app-changelog#release-v2-39-0) \| [SBOM download](https://github.com/mattermost/mattermost-mobile/releases/download/v2.39.0/sbom-mattermost-mobile-v2.39.0.json) | Released: 2026-04-16
Support Ends: 2026-05-15 | [v11.6](./mattermost-v11-changelog#release-v11-6-feature-release), [v11.5](./mattermost-v11-changelog#release-v11-5-feature-release), [v11.4](./mattermost-v11-changelog#release-v11-4-feature-release), [v10.11](./mattermost-v10-changelog#release-v10-11-extended-support-release) | @@ -74,8 +75,9 @@ Note that the below versions have not yet been tested. The information below is | **Release** | **Support** | **Compatible with** | |:---|:---|:---| -| v2.47 | Releasing: 2026-12-16
Support Ends: 2027-01-15 | v11.14, v11.13, v11.12, v11.7 | -| v2.46 | Releasing: 2026-11-16
Support Ends: 2026-12-15 | v11.13, v11.12, v11.11, v11.7 | -| v2.45 | Releasing: 2026-10-16
Support Ends: 2026-11-15 | v11.12, v11.11, v11.10, v11.7 | +| v2.49 | Releasing: 2027-02-16
Support Ends: 2027-03-15 | v12.4, v12.3, v12.2, v11.7 | +| v2.48 | Releasing: 2027-01-16
Support Ends: 2027-02-15 | v12.3, v12.2, v12.1, v11.7 | +| v2.47 | Releasing: 2026-12-16
Support Ends: 2027-01-15 | v12.2, v12.1, v12.0, v11.7 | +| v2.46 | Releasing: 2026-11-16
Support Ends: 2026-12-15 | v12.1, v12.0, v11.11, v11.7 | +| v2.45 | Releasing: 2026-10-16
Support Ends: 2026-11-15 | v12.0, v11.11, v11.10, v11.7 | | v2.44 | Releasing: 2026-09-16
Support Ends: 2026-10-15 | v11.11, v11.10, v11.9, v11.7 | -| v2.43 | Releasing: 2026-08-16
Support Ends: 2026-09-15 | v11.10, v11.9, v11.8, v11.7, v10.11 | diff --git a/docs/main/product-overview/mattermost-server-releases.mdx b/docs/main/product-overview/mattermost-server-releases.mdx index ad5185e1f4c9..d0925699722e 100644 --- a/docs/main/product-overview/mattermost-server-releases.mdx +++ b/docs/main/product-overview/mattermost-server-releases.mdx @@ -17,9 +17,10 @@ Mattermost releases a new server version on the 16th of each month in [binary fo | **Release** | **Released on** | **Support ends** | |:---|:---|:---| -| v11.9 [Download](https://releases.mattermost.com/11.9.0/mattermost-11.9.0-linux-amd64.tar.gz) \| [Changelog](./mattermost-v11-changelog#release-v11-9-feature-release) \|
SBOM
| 2026-07-16 | 2026-10-15 | -| v11.8 [Download](https://releases.mattermost.com/11.8.4/mattermost-11.8.4-linux-amd64.tar.gz) \| [Changelog](./mattermost-v11-changelog#release-v11-8-feature-release) \|
SBOM
| 2026-06-16 | 2026-09-15 | -| v11.7 [Download](https://releases.mattermost.com/11.7.7/mattermost-11.7.7-linux-amd64.tar.gz) \| [Changelog](./mattermost-v11-changelog#release-v11-7-extended-support-release) \|
SBOM
| 2026-05-15 | 2027-05-15 [EXTENDED](./release-policy#release-types) | +| v11.10 [Download](https://releases.mattermost.com/11.10.0/mattermost-11.10.0-linux-amd64.tar.gz) \| [Changelog](./mattermost-v11-changelog#release-v11-10-feature-release) \|
SBOM
| 2026-08-14 | 2026-11-15 | +| v11.9 [Download](https://releases.mattermost.com/11.9.1/mattermost-11.9.1-linux-amd64.tar.gz) \| [Changelog](./mattermost-v11-changelog#release-v11-9-feature-release) \|
SBOM
| 2026-07-16 | 2026-10-15 | +| v11.8 [Download](https://releases.mattermost.com/11.8.5/mattermost-11.8.5-linux-amd64.tar.gz) \| [Changelog](./mattermost-v11-changelog#release-v11-8-feature-release) \|
SBOM
| 2026-06-16 | 2026-09-15 | +| v11.7 [Download](https://releases.mattermost.com/11.7.9/mattermost-11.7.9-linux-amd64.tar.gz) \| [Changelog](./mattermost-v11-changelog#release-v11-7-extended-support-release) \|
SBOM
| 2026-05-15 | 2027-05-15 [EXTENDED](./release-policy#release-types) | | v11.6 [Download](https://releases.mattermost.com/11.6.6/mattermost-11.6.6-linux-amd64.tar.gz) \| [Changelog](./mattermost-v11-changelog#release-v11-6-feature-release) \|
SBOM
| 2026-04-16 | 2026-07-15 | | v11.5 [Download](https://releases.mattermost.com/11.5.7/mattermost-11.5.7-linux-amd64.tar.gz) \| [Changelog](./mattermost-v11-changelog#release-v11-5-feature-release) \|
SBOM
| 2026-03-16 | 2026-06-15 | | v11.4 [Download](https://releases.mattermost.com/11.4.5/mattermost-11.4.5-linux-amd64.tar.gz) \| [Changelog](./mattermost-v11-changelog#release-v11-4-feature-release) \|
SBOM
| 2026-02-16 | 2026-05-15 | @@ -28,7 +29,7 @@ Mattermost releases a new server version on the 16th of each month in [binary fo | v11.1 [Download](https://releases.mattermost.com/11.1.3/mattermost-11.1.3-linux-amd64.tar.gz) \| [Changelog](./mattermost-v11-changelog#release-v11-1-feature-release) \|
SBOM
| 2025-11-14 | 2026-02-15 | | v11.0 [Download](https://releases.mattermost.com/11.0.7/mattermost-11.0.7-linux-amd64.tar.gz) \| [Changelog](./mattermost-v11-changelog#release-v11-0-major-release) \|
SBOM
| 2025-10-16 | 2026-01-15 | | v10.12 [Download](https://releases.mattermost.com/10.12.4/mattermost-10.12.4-linux-amd64.tar.gz) \| [Changelog](./mattermost-v10-changelog#release-v10-12-feature-release) \|
SBOM
| 2025-09-16 | 2025-12-15 | -| v10.11 [Download](https://releases.mattermost.com/10.11.22/mattermost-10.11.22-linux-amd64.tar.gz) \| [Changelog](./mattermost-v10-changelog#release-v10-11-extended-support-release) \|
SBOM
| 2025-08-15 | 2026-08-15 [EXTENDED](./release-policy#release-types) | +| v10.11 [Download](https://releases.mattermost.com/10.11.23/mattermost-10.11.23-linux-amd64.tar.gz) \| [Changelog](./mattermost-v10-changelog#release-v10-11-extended-support-release) \|
SBOM
| 2025-08-15 | 2026-08-15 [EXTENDED](./release-policy#release-types) | | v10.10 [Download](https://releases.mattermost.com/10.10.3/mattermost-10.10.3-linux-amd64.tar.gz) \| [Changelog](./mattermost-v10-changelog#release-v10-10-feature-release) \|
SBOM
| 2025-07-16 | 2025-10-15 | | v10.9 [Download](https://releases.mattermost.com/10.9.5/mattermost-10.9.5-linux-amd64.tar.gz) \| [Changelog](./mattermost-v10-changelog#release-v10-9-feature-release) \|
SBOM
| 2025-06-16 | 2025-09-15 | | v10.8 [Download](https://releases.mattermost.com/10.8.4/mattermost-10.8.4-linux-amd64.tar.gz) \| [Changelog](./mattermost-v10-changelog#release-v10-8-feature-release) \|
SBOM
| 2025-05-16 | 2025-08-15 | diff --git a/docs/main/product-overview/mattermost-v10-changelog.mdx b/docs/main/product-overview/mattermost-v10-changelog.mdx index d4d52585566e..8d5a0bad446a 100644 --- a/docs/main/product-overview/mattermost-v10-changelog.mdx +++ b/docs/main/product-overview/mattermost-v10-changelog.mdx @@ -92,6 +92,14 @@ If you upgrade from a release earlier than v10.10, please read the other [Import +- **10.11.23, released 2026-08-13** + - Mattermost v10.11.23 contains low to high severity level security fixes. [Upgrading](https://docs.mattermost.com/upgrade/upgrading-mattermost-server.html) to this release is recommended. Details will be posted on our [security updates page](https://mattermost.com/security-updates/) 30 days after release as per the [Mattermost Responsible Disclosure Policy](https://mattermost.com/security-vulnerability-report/). + - Pre-packaged Boards plugin version [v9.2.7](https://github.com/mattermost/mattermost-plugin-boards/releases/tag/v9.2.7). + - Pre-packaged Playbooks plugin version [v2.4.8](https://github.com/mattermost/mattermost-plugin-playbooks/releases/tag/v2.4.8). + - Pre-packaged Calls plugin version [v1.11.6](https://github.com/mattermost/mattermost-plugin-calls/releases/tag/v1.11.6). + - Pre-packaged Microsoft Calendar plugin version [v1.6.2](https://github.com/mattermost/mattermost-plugin-mscalendar/releases/tag/v1.6.2). + - Fixed an issue where the data retention policy teams endpoint returned more team information than intended. + - Mattermost v10.11.23 contains no database schema changes. - **10.11.22, released 2026-07-17** - Mattermost v10.11.22 contains low to high severity level security fixes. [Upgrading](https://docs.mattermost.com/upgrade/upgrading-mattermost-server.html) to this release is recommended. Details will be posted on our [security updates page](https://mattermost.com/security-updates/) 30 days after release as per the [Mattermost Responsible Disclosure Policy](https://mattermost.com/security-vulnerability-report/). - Pre-packaged Playbooks plugin version [v2.4.7](https://github.com/mattermost/mattermost-plugin-playbooks/releases/tag/v2.4.7). diff --git a/docs/main/product-overview/mattermost-v11-changelog.mdx b/docs/main/product-overview/mattermost-v11-changelog.mdx index 06ffb83f5024..89befa5b3ed3 100644 --- a/docs/main/product-overview/mattermost-v11-changelog.mdx +++ b/docs/main/product-overview/mattermost-v11-changelog.mdx @@ -14,9 +14,190 @@ Platform and OS scope reflects reported and tested environments and may not repr +## Release v11.10 - [Feature Release](https://docs.mattermost.com/product-overview/release-policy.html#release-types) \{#release-v11-10-feature-release} + +**Release Day: 2026-08-14** + +### Upgrade Impact + +#### Database Schema Changes + - The following schema changes are included in the v11.10 release. No database downtime is expected for this upgrade. See the [Important Upgrade Notes](https://docs.mattermost.com/upgrade/important-upgrade-notes.html) for more details. + - Added nullable ``bigint`` column ``lastnotifiedat`` to the ``useraccesstokens`` table to support token notification tracking; catalog-only change with negligible production impact. + - Adds composite index ``idx_propertyvalues_groupid_updateat_id`` on ``PropertyValues(GroupID, UpdateAt, ID)`` to improve Custom Attributes query performance. The index is created concurrently, so its creation does not block DML. + +#### config.json +New setting options were added to ``config.json``. Below is a list of the additions and their default values on install. The settings can be modified in ``config.json``, or the System Console when available. + - **Changes to Enterprise Advanced plan:** + - Under ``AccessControlSettings`` in ``config.json``, added ``EnableChannelPolicyIndicators`` configuration setting (default ``true``) under **Attribute-Based Access Control** that lets admins control whether channel access attribute indicators (the attribute tags shown in the channel members list and invite dialog) are displayed. Admins who don't want to reveal policy details to end users can disable this setting to hide the indicators. Requires Enterprise Advanced license. + - Under ``AccessControlSettings`` in ``config.json``, added ``SyncJobIntervalSeconds`` configuration setting to configure how often the ABAC membership sync jobs run. + - **Changes to Enterprise plans:** + - Under ``TeamSettings`` in ``config.json``, added a new Enterprise configuration setting, ``TeamSettings.LockProfileFieldsForEmailUsers`` (**System Console > Site Configuration > Users and Teams**), which prevents users who sign in with email and password from changing their first name, last name, and username ("name_and_username"), or additionally their nickname, position, and profile picture ("all"). System Admins are exempt, and empty first/last names can be filled in once. When enabled, users with the Invite Users permission can pre-set the first name, last name, and username on email invitations; the ``POST /api/v4/teams/{'{'}team_id{'}'}/invite/email`` endpoint accepts a new optional "profiles" field, and the System Console user detail page now supports editing a user's first and last name. + +#### Compatibility + - Updated minimum Edge and Chrome versions to 150+. + + + +If you upgrade from a release earlier than v11.9, please read the other [Important Upgrade Notes](https://docs.mattermost.com/administration-guide/upgrade/important-upgrade-notes.html). In case of an upgrade failure, please check the [Downgrade Guide](https://docs.mattermost.com/administration-guide/upgrade/downgrading-mattermost-server.html) and the [Recovery Guide](https://docs.mattermost.com/deployment-guide/backup-disaster-recovery.html) for rollback steps and interim mitigation strategy. + + +### Improvements +See [this blog post](https://mattermost.com/blog/mattermost-v11-10-is-now-available/) on the highlights in our latest release. + +#### User Interface + - Pre-packaged Playbooks plugin version [v2.11.1](https://github.com/mattermost/mattermost-plugin-playbooks/releases/tag/v2.11.1). + - Pre-packaged Agents plugin version [v2.5.1](https://github.com/mattermost/mattermost-plugin-agents/releases/tag/v2.5.1). + - Pre-packaged Calls plugin version [v1.12.2](https://github.com/mattermost/mattermost-plugin-calls/releases/tag/v1.12.2). + - Pre-packaged MS Calendar plugin version [v1.7.0](https://github.com/mattermost/mattermost-plugin-mscalendar/releases/tag/v1.7.0). + - Pre-packaged Boards plugin version [v9.3.1](https://github.com/mattermost/mattermost-plugin-boards/releases/tag/v9.3.1). + - Added a WYSIWYG editor option for message composition, allowing users to compose messages with rich-text formatting while preserving full markdown round-trip (in Beta and behind a feature flag). + - Added a media gallery layout for posts with multiple images or videos, plus inline frame previews for single videos. + - Added support for a file upload element type in interactive dialogs. + - Added support for Mattermost Blocks as a new way to create Interactive Messages (including webapp and mobile app). + - Plugins and integrations can now open stacked child dialogs from within an interactive dialog using the new ``action_button`` element type. + - Bot accounts, OAuth apps, incoming webhooks, and plugins can now deliver posts silently — visible in the channel without producing notifications, unread badges, or the "New Messages" separator (including desktop and mobile apps). + - Bot accounts managed by a plugin now display the managing plugin's ID in the **Bot Accounts** list instead of a generic "Managed by plugin" label. + - Added inline plugin metadata to the **Plugin Management** page and plugin settings page showing the plugin ID, version, and links to the website and release notes when available. + - The agent selector now respects the configured default agent and remembers your last-selected agent. + - Mattermost now proactively warns the owner of a personal access token with a direct message from the system bot as the token approaches expiry (7, 3, and 1 days before), so token-backed integrations no longer break without warning. Added the ``pat_expiry_notify`` job, which runs hourly when ``EnableUserAccessTokens`` is set and can also be triggered on demand by admins via the jobs API. + - Token owners are now notified by a direct message from the system bot when one of their personal access tokens is removed after expiring. + - Added a **Regenerate** option to Personal Access Tokens in **Account Settings > Security** (including webapp). + - Changed left-hand-side/right-hand-side to only be resizable with the left mouse button. + +#### Performance + - Benchmarking test results showed no significant difference: a -2.61% decrease in the number of supported users for the new release, which lies within the ``[-5%, +5%]`` prediction interval. View the full raw data and methodology in our [Performance Reports repository](https://github.com/mattermost/performance-reports/tree/main/performance-comparisons/v11.10). + +#### Plugins/Integrations + - Added plugin support for pluggable tabs in the **Channel Settings** modal, including a new ``ChannelSettingsTab`` webapp registration surface. + - Allowed plugins to implement ``MessagesWillBeConsumed`` without requiring the feature flag. + - Outgoing integration requests for post action button and interactive dialog endpoints now surface upstream 429/503 responses verbatim (preserving retry semantics) and map other upstream 5xx responses to 502, instead of collapsing all non-200 responses to 400. + +#### Administration + - Added a new **Board Attributes** panel under **System Console > System Attributes** for managing the default attributes shown on every board, including the locked **Status** and **Assignee** fields. Available when the ``IntegratedBoards`` feature flag is enabled. + - Added a "Revoke non-compliant tokens" action in **System Console > Integrations > Integration Management** that lets admins revoke existing personal access tokens that violate the configured **Maximum Personal Access Token Lifetime** (tokens that never expire or expire beyond the cap). Bot account tokens are exempt, and the number of affected tokens is shown for confirmation before revoking. + - Added a discovery page for **Classification Markings** in the **System Console** so the feature is surfaced with an upgrade path on licenses below Enterprise when the ``ClassificationMarkings`` feature flag is enabled. + - Added a **Session Attributes** management page under **System Console > System Attributes**, and made enabled session attributes selectable in Attribute-Based permission-policy editors (generating ``user.session.<name>`` conditions). Requires Enterprise Advanced license. + - Added the ability to edit a team's name and description from the System Console **Team Configuration** page. + - Added a Teams column to the System Console user data CSV export, listing each user's team memberships. + - Team membership can now be controlled by [user attributes](https://docs.mattermost.com/administration-guide/manage/admin/attribute-based-access-control.html) (department, program, etc.) — private teams automatically enforce access rules, block non-qualifying joins, and remove ineligible members via sync; public teams use advisory mode, surfacing a "Recommended" tag to qualifying users without blocking anyone. Team admins and system admins can define per-team membership rules, configure auto-add, and trigger or monitor sync jobs directly from Team Settings and the System Console, with inline enforcement in the Invite People and Add Members modals. + - Added a specific error message when uploading a license signed for a different service environment (a production license on a test/dev server, or vice versa) instead of the generic "Invalid license file." error. + - Corrected the System Console "Max Users Per Team" description to accurately state that only active members with active accounts count toward the limit; deactivated users and removed members are not counted. + - Improved accessibility of the **Content Flagging** "Content Reviewers" admin settings: each per-team enable/disable toggle now includes the team name in its ``aria-label``. + - Improved the precision of the OAuth Dynamic Client Registration (DCR) redirect URI allowlist by matching patterns per URL component. + - The server now pushes a ``job_updated`` WebSocket event when a job changes status. System Console job tables (LDAP sync, data retention, message export, etc.) now reflect job status changes in real time instead of polling every 15 seconds. + - Removed the ``ChannelBookmarks`` feature flag. The Channel Bookmarks feature is now always enabled (subject to licensing). + - Removed the ``WebSocketEventScope`` feature flag; scoping of typing and reaction WebSocket events to clients that have the relevant channel or thread open is now permanently enabled. + - Removed the ``ExperimentalAuditSettingsSystemConsoleUI`` feature flag. The experimental **Audit Logging** configuration page in the System Console (Enterprise, beta) is now permanently enabled. + - Removed the ``NotificationMonitoring`` feature flag for webapp/desktop app. Notification delivery metrics collection is now permanently enabled and controlled solely by the ``MetricsSettings.EnableNotificationMetrics`` setting. + - Removed the ``StreamlinedMarketplace`` feature flag; the streamlined plugin Marketplace is now always enabled. + - Removed the ``AttributeBasedAccessControl`` feature flag. Attribute-based access control is now exclusively controlled by the ``AccessControlSettings.EnableAttributeBasedAccessControl`` configuration setting. + - Removed ``CloudIPFiltering`` feature flag and enabled this functionality by default for licensed Cloud servers. + - Sent a wipe signal to mobile apps with open sessions when a session is revoked. + - Removed Google Fonts references from server email templates so notification emails no longer load fonts from external URLs when opened. + - Added ``ClusterGracefulDrain`` feature flag (default on) to reduce cluster message errors during rolling restarts of high-availability deployments. + - Added delta support for the PSAv2 property fields and values endpoints, and a new fields search endpoint (including mobile apps). + - Added property owners, audit logs for all custom profile attribute value changes, and new plugin APIs for property values. + - Improved performance of the **Scheduled Messages** page by virtualizing the scheduled posts list, so opening the tab is no longer slow when there are many scheduled posts. + - Added ``window.WebappUtils.modals.openModalById`` and ``canOpenModalId``, letting plugins open and feature-detect an allowlisted set of core modals by id. The plugin-facing modal types now ship from ``@mattermost/shared/types/global`` (including webapp). + - Made ``SendBestEffort`` cluster messages fall back to using TCP when their length is larger than a UDP datagram. + - Aligned the logic that updates a user's authentication method with other credential and authentication paths, so that all existing sessions of a user are revoked when their authentication method is changed. + - Plugins calling ``p.API.UpdateUserAuth`` to change a user's authentication method will now revoke all existing sessions for that user, logging them out of all active clients. Plugin developers should be aware of this new behavior. + - Replaced "Enable Concurrent React (Experimental)" user setting with a feature flag. + - Removed an unused feature flag ``OnboardingTourTips``. + - Added an audit trail for property values. + - Added support for team-scoped plugin products: a product registered via ``registerProduct`` with ``isTeamScoped`` set to true is now mounted under the team route with team context initialized from the URL. Products with global ``baseURLs`` are unaffected (including webapp). + - Hard-coded a second plugin signing key from Mattermost. + +#### mmctl + - Added the ability to send direct messages with ``mmctl`` using ``mmctl post create @username --message <text>``. + - Added new ``mmctl`` commands: ``job create`` to create jobs with type-specific options, ``job show`` to display job details, and ``job cancel`` to cancel running jobs. + - Added a new ``--auto-add-users`` flag to the ``mmctl channel move`` command. The command now also lists the channel members that are missing from the destination team when a move is rejected. + - Added a new ``mmctl channel users list`` command that lists the members of a channel (ID, username, email, and roles), with ``--page``, ``--per-page``, and ``--all`` pagination flags. + - Added the ``mmctl user status`` and ``mmctl user status set`` commands to read and update a user's presence status (online, away, dnd, offline), with an optional ``--dnd-end-time`` flag. The user status GET/PUT endpoints are now also available over the ``mmctl`` local mode socket. + - Added a ``--show-ids`` flag to the ``mmctl channel list`` command to include channel IDs in the plain-text output. + - Added the user's roles to the plain-text output of the ``mmctl user search`` command. + - Moved the ``mmctl user deleteall`` command to ``mmctl system nuke users`` to reduce the risk of accidental invocation. The ``mmctl user deleteall`` command has been removed. + +### Bug Fixes + - Fixed an issue where reactions using emoji names with mixed case (e.g. ``:Mattermost:``) could not be added or removed. + - Fixed a webapp issue that caused private chat message content to be copied into the Web Notifications API ``tag`` option, where Chromium-based browsers can expose it through notification activation metadata (reported on webapp, Windows, and Chromium browsers). + - Fixed Markdown list items containing multiple paragraphs appearing as a single paragraph (reported on webapp, Firefox and Mac). + - Fixed code blocks in Markdown lists not being able to scroll horizontally (reported on webapp, Firefox and Mac). + - Fixed an issue where the Recaps sparkle icon in the left-hand sidebar appeared dimmer than the other sidebar item icons (reported on webapp). + - Fixed an issue where the AI-generated indicator was only shown on the first message when an agent posted multiple messages in a row. + - Fixed an issue where the W3C specification links in the Signature Algorithm and Canonicalization Algorithm help text on the SAML 2.0 System Console page were not clickable. + - Fixed an issue where action buttons in interactive message attachments could overflow horizontally instead of wrapping when they had long labels. + - Fixed the System Console permissions page to label the Playbook role as "Playbook Administrators" (plural), consistent with the other role headings. + - Fixed an issue where a GUEST tag could be shown next to bot and webhook posts when the webhook creator was demoted to a guest. + - Fixed a data race in ``pluginapi.ConfigureLogrus`` that could panic with "concurrent map read and map write" when a plugin configured logrus while logging was in flight. ``ConfigureLogrus`` now also applies ``SetReportCaller``/``SetLevel`` to the logger passed in rather than the global standard logger. + - Fixed an issue where the access control Job Details modal showed a confusing search-style empty state (and, in some cases, a blank body) when a sync job affected no channels; it now shows a neutral "No channels were affected by this job." message. + - Fixed the System Console feature discovery "Learn more" links for Auto-translation and Mobile Ephemeral Mode so they open the corresponding documentation pages instead of the generic documentation landing page. + - Fixed layout shift sometimes caused by post previews for posts in Direct Message channels. + - Fixed an issue where the "Upload files" permission was pre-selected by default when creating a new rule in a channel's Permissions Policy. New rules now start with no permissions selected. + - Fixed an issue where the Quarantine for Review modal could overflow its boundary when flagging a post with many file attachments on smaller screens. + - Fixed an issue where the System Console permission policy rule editor defaulted to advanced (CEL) mode instead of simple (table) mode when editing rules that used multiselect "has any of" conditions or ranked operators. + - Fixed an issue where the Last Sync column in the output of the ``/share-channel status`` command always showed "--" instead of the actual last sync time. + - Fixed an issue where the shared channel sync loop repeatedly logged a warning for orphaned ``SharedChannelRemotes`` rows whose ``RemoteCluster`` had been deleted. The sync loop now self-heals by soft-deleting the orphaned row. + - Fixed the ``/secure-connection status`` slash command so deleted connections are listed after active ones and the results render as a valid Markdown table. + - Fixed unquoted searches for hyphenated compound words (e.g. ``t-shirt``) on PostgreSQL to match the compound word instead of the individual words. + - Fixed an issue where the data retention policy teams endpoint returned more team information than intended. + - Fixed an issue with the wrong scroll position in the permalink view of channels with images. + - Fixed an issue where the Global Relay compliance export undercounted skipped-attachment warnings: the run-level warning count reflected only the last channel/batch processed instead of the sum across all channels and batches. + - Fixed an issue where the "save" button did not appear in some scenarios when updating connected workspaces in the channel settings. + - Fixed an issue with plugins receiving hooks and logging errors after shutting down. + - Fixed the Playbooks Become a Participant modal text alignment. + - Fixed an issue where broken draft state occurred when uploads failed or were interrupted, preventing users from sending messages again. + - Fixed most layout shifts caused by images in posts loading. + - Fixed an issue where shared channel messages sent while a remote connection was briefly interrupted would not sync until the next message was sent. + - Fixed an issue with plugin configuration loss on High Availability nodes with incomplete plugin sync. + - Fixed an issue where bots and integrations could not update markdown action buttons (``mm_blocks_actions``) on their own posts via the API. + - Fixed an issue where the web app didn't load the channel header and post textbox earlier. + - Fixed an issue where editing a message could cause it to appear as a draft (reported on Chrome, webapp). + - Fixed an issue with the focus outline on multi-image gallery thumbnails being clipped after closing the image preview. + - Fixed an issue where typing in a thread or the right-hand sidebar with rich text editing enabled moved focus to the center channel message box. + - Fixed an issue where pressing **Enter** inside a heading could crash the web app. + +### API Changes + - Modified ``POST /actions/{'{'}action_id:[A-Za-z0-9_-]+{'}'}`` (``doPostAction``) API endpoint to accept underscore and hyphen in the ``action_id`` parameter. + - Added ``GET /tokens/non_compliant/count`` (``countNonCompliantUserAccessTokens``) API endpoint. + - Added ``POST /tokens/non_compliant/revoke`` (``revokeNonCompliantUserAccessTokens``) API endpoint. + - Added ``GET /access_control/attributes`` (``getTeamAccessControlAttributes``) API endpoint. + - Added ``POST /properties/groups/{'{'}group_name{'}'}/fields/search`` API endpoint. + - Added new API endpoint ``POST /api/v4/users/tokens/rotate`` to rotate (regenerate) the secret of an existing Personal Access Token. The old secret is invalidated immediately on rotation. + +### WebSocket Event Changes + - Added a ``job_updated`` WebSocket event that is pushed when a job changes status. System Console job tables (LDAP sync, data retention, message export, etc.) now reflect job status changes in real time instead of polling every 15 seconds. + +### Audit Log Event Changes + - Added ``AuditEventRevokeNonCompliantUserAccessTokens`` audit log event. + - Added ``AuditEventRotateUserAccessToken`` audit log event. + - Added ``AuditEventTeamMembershipRemoved`` audit log event. + - Added ``obtained_user_email`` field to ``completeSaml`` audit log events. + - Added ``AuditEventTeamCascadedChannelRemoval`` audit log event. + - Added ``AuditEventTeamMembershipAdded`` audit log event. + - Added ``AuditEventCPAValueChange`` audit log event. + +### Go Version + - v11.10 is built with Go ``v1.26.4``. + +### Open Source Components + - Added ``@tiptap/extension-code-block-lowlight``, ``@tiptap/extension-link``, ``@tiptap/extension-placeholder``, ``@tiptap/extension-table``, ``@tiptap/extension-table-cell``, ``@tiptap/extension-table-header``, ``@tiptap/extension-table-row``, ``@tiptap/markdown``, ``@tiptap/react``, ``@tiptap/starter-kit``, ``lowlight``, ``Azure/azure-sdk-for-go``, ``jaytaylor/html2text`` and ``wneessen/go-mail``, and removed ``go-mail/mail``. + ## Release v11.9 - [Feature Release](https://docs.mattermost.com/product-overview/release-policy.html#release-types) \{#release-v11-9-feature-release} -**Release day: 2026-07-16** +- **11.9.1, released 2026-08-13** + - Mattermost v11.9.1 contains medium to high severity level security fixes. [Upgrading](https://docs.mattermost.com/upgrade/upgrading-mattermost-server.html) to this release is recommended. Details will be posted on our [security updates page](https://mattermost.com/security-updates/) 30 days after release as per the [Mattermost Responsible Disclosure Policy](https://mattermost.com/security-vulnerability-report/). + - Pre-packaged Boards plugin version [v9.3.1](https://github.com/mattermost/mattermost-plugin-boards/releases/tag/v9.3.1). + - Pre-packaged Playbooks plugin version [v2.10.1](https://github.com/mattermost/mattermost-plugin-playbooks/releases/tag/v2.10.1). + - Pre-packaged Calls plugin version [v1.12.2](https://github.com/mattermost/mattermost-plugin-calls/releases/tag/v1.12.2). + - Pre-packaged Microsoft Calendar plugin version [v1.6.2](https://github.com/mattermost/mattermost-plugin-mscalendar/releases/tag/v1.6.2). + - Fixed an issue where the data retention policy teams endpoint returned more team information than intended. + - Improved the precision of the OAuth Dynamic Client Registration (DCR) redirect URI allowlist by matching patterns per URL component. + - Hard-coded a second plugin signing key from Mattermost. + - Fixed an issue where the **Classification Markings** section in the **System Console** was accessible and configurable under an Enterprise license; it is now correctly gated behind an Enterprise Advanced license and shows an upgrade prompt for lower tiers. + - Mattermost v11.9.1 contains no database or functional changes. +- **11.9.0, released 2026-07-16** + - Original 11.9.0 release. @@ -81,6 +262,7 @@ See [this blog post](https://mattermost.com/blog/mattermost-v11-9-is-now-availab #### Plugins/Integrations - Implemented clickable action buttons inside post markdown for bots, webhooks, and plugins. Integrations bind ``mmaction://`` markdown links to actions defined in a new ``mm_blocks_actions`` post property. - Added channel bookmark type ``board`` with an optional ``target_id``. The bookmarks API rejects creating, updating, or deleting board bookmarks but allows reordering them when the caller has bookmark order permission. + - The ``MessagesWillBeConsumed`` plugin hook now fires on the edit path in addition to the create path, making ``UpdatePost`` symmetric with ``CreatePost``. Plugins implementing the hook will see their ``Message`` transformations applied to the editor's HTTP response and the ``post_edited`` websocket event. This aligns the runtime behaviour with the documented contract ("before it is returned to the client"); plugins relying on the prior edit-path no-op may observe a behaviour change. - Added a webapp hook ``registerChannelTypeOption``. - Added a ``MessagesWillBeConsumedWithContext`` plugin hook. - Added a ``ChannelWillBeUpdated`` plugin hook. @@ -116,7 +298,7 @@ See [this blog post](https://mattermost.com/blog/mattermost-v11-9-is-now-availab - Expanded session attribute collection to include values provided by Desktop App and Mobile clients. - Removed legacy interactive dialog code path on webapp. - Added a channel-guard enforcement for scheduled posts and drafts. - - Added Phase 8b, 8c, 8d, 8e, 8f, 8h, 12, and 12e of the ``mbe-tech-preview``. + - Added Phase 2, 3, 4, 5, 8b, 8c, 8d, 8e, 8f, 8h, 12, and 12e of the ``mbe-tech-preview``. - Added a ``mattermost db ping`` [subcommand](https://docs.mattermost.com/deployment-guide/reference-architecture/deployment-scenarios/air-gapped-deployment.html) that waits for the database to become reachable, with configurable ``--timeout`` and ``--retry-interval`` flags. - Added a new "rank" [custom profile attribute](https://docs.mattermost.com/administration-guide/manage/admin/abac-system-wide-policies.html#define-access-control-policies) type whose options carry an explicit ordering. System Admins can create and manage ranked attributes in the **System Console** and assign ranked values to users, enabling attribute-based access control policies that compare clearance- or classification-style attributes with ordinal operators (for example, "is at least Secret") instead of enumerating every qualifying value. - Added a new ``ClusterReliableFallbackLength`` [metric](https://docs.mattermost.com/administration-guide/scale/performance-monitoring-metrics.html) with the total length in bytes of the ``SendBestEffort`` calls (UDP) that had to fallback to TCP because of the message length. @@ -183,6 +365,16 @@ See [this blog post](https://mattermost.com/blog/mattermost-v11-9-is-now-availab ## Release v11.8 - [Feature Release](https://docs.mattermost.com/product-overview/release-policy.html#release-types) \{#release-v11-8-feature-release} +- **11.8.5, released 2026-08-13** + - Mattermost v11.8.5 contains medium to high severity level security fixes. [Upgrading](https://docs.mattermost.com/upgrade/upgrading-mattermost-server.html) to this release is recommended. Details will be posted on our [security updates page](https://mattermost.com/security-updates/) 30 days after release as per the [Mattermost Responsible Disclosure Policy](https://mattermost.com/security-vulnerability-report/). + - Pre-packaged Boards plugin version [v9.2.7](https://github.com/mattermost/mattermost-plugin-boards/releases/tag/v9.2.7). + - Pre-packaged Playbooks plugin version [v2.9.4](https://github.com/mattermost/mattermost-plugin-playbooks/releases/tag/v2.9.4). + - Pre-packaged Calls plugin version [v1.11.6](https://github.com/mattermost/mattermost-plugin-calls/releases/tag/v1.11.6). + - Pre-packaged Microsoft Calendar plugin version [v1.6.2](https://github.com/mattermost/mattermost-plugin-mscalendar/releases/tag/v1.6.2). + - Fixed an issue where the data retention policy teams endpoint returned more team information than intended. + - Improved the precision of the OAuth Dynamic Client Registration (DCR) redirect URI allowlist by matching patterns per URL component. + - Fixed an issue where the **Classification Markings** section in the **System Console** was accessible and configurable under an Enterprise license; it is now correctly gated behind an Enterprise Advanced license and shows an upgrade prompt for lower tiers. + - Mattermost v11.8.5 contains no database or functional changes. - **11.8.4, released 2026-07-17** - Mattermost v11.8.4 contains medium to high severity level security fixes. [Upgrading](https://docs.mattermost.com/upgrade/upgrading-mattermost-server.html) to this release is recommended. Details will be posted on our [security updates page](https://mattermost.com/security-updates/) 30 days after release as per the [Mattermost Responsible Disclosure Policy](https://mattermost.com/security-vulnerability-report/). - Pre-packaged Boards plugin version [v9.2.6](https://github.com/mattermost/mattermost-plugin-boards/releases/tag/v9.2.6). @@ -373,6 +565,22 @@ See [this blog post](https://mattermost.com/blog/mattermost-v11-8-0-is-now-avail ## Release v11.7 - [Extended Support Release](https://docs.mattermost.com/product-overview/release-policy.html#release-types) \{#release-v11-7-extended-support-release} +- **11.7.9, released 2026-08-13** + - Mattermost v11.7.9 contains a medium severity level security fix. [Upgrading](https://docs.mattermost.com/upgrade/upgrading-mattermost-server.html) to this release is recommended. Details will be posted on our [security updates page](https://mattermost.com/security-updates/) 30 days after release as per the [Mattermost Responsible Disclosure Policy](https://mattermost.com/security-vulnerability-report/). + - Fixed a memory leak due to Elasticsearch starting bulk indexers and not stopping them, leading to an Out Of Memory. Added logging to alert System Admins when they are missing the required ``analysis-icu`` Elasticsearch/OS plugin. + - Mattermost v11.7.9 contains no database or functional changes. +- **11.7.8, released 2026-07-31** + - Mattermost v11.7.8 contains low to high severity level security fixes. [Upgrading](https://docs.mattermost.com/upgrade/upgrading-mattermost-server.html) to this release is recommended. Details will be posted on our [security updates page](https://mattermost.com/security-updates/) 30 days after release as per the [Mattermost Responsible Disclosure Policy](https://mattermost.com/security-vulnerability-report/). + - Pre-packaged Boards plugin version [v9.2.7](https://github.com/mattermost/mattermost-plugin-boards/releases/tag/v9.2.7). + - Pre-packaged Playbooks plugin version [v2.9.4](https://github.com/mattermost/mattermost-plugin-playbooks/releases/tag/v2.9.4). + - Pre-packaged Calls plugin version [v1.11.6](https://github.com/mattermost/mattermost-plugin-calls/releases/tag/v1.11.6). + - Pre-packaged Microsoft Calendar plugin version [v1.6.2](https://github.com/mattermost/mattermost-plugin-mscalendar/releases/tag/v1.6.2). + - Fixed an issue where the data retention policy teams endpoint returned more team information than intended. + - Improved the precision of the OAuth Dynamic Client Registration (DCR) redirect URI allowlist by matching patterns per URL component. + - Fixed an issue with the wrong scroll position in the permalink view of channels with images. + - Fixed incorrect encoding of image URLs containing query parameters when using an image proxy. + - Fixed a bot import panic when a user existed without a bot record. + - Mattermost v11.7.8 contains no database or functional changes. - **11.7.7, released 2026-07-17** - Mattermost v11.7.7 contains low to high severity level security fixes. [Upgrading](https://docs.mattermost.com/upgrade/upgrading-mattermost-server.html) to this release is recommended. Details will be posted on our [security updates page](https://mattermost.com/security-updates/) 30 days after release as per the [Mattermost Responsible Disclosure Policy](https://mattermost.com/security-vulnerability-report/). - Pre-packaged Playbooks plugin version [v2.9.2](https://github.com/mattermost/mattermost-plugin-playbooks/releases/tag/v2.9.2). diff --git a/docs/main/product-overview/mobile-app-changelog.mdx b/docs/main/product-overview/mobile-app-changelog.mdx index 451407dfccf5..b688a4d22466 100644 --- a/docs/main/product-overview/mobile-app-changelog.mdx +++ b/docs/main/product-overview/mobile-app-changelog.mdx @@ -16,6 +16,48 @@ Platform and OS scope reflects reported and tested environments and may not repr +## 2.43.0 Release \{#release-v2-43-0} + - Release Date: August 14, 2026 + - Server Versions Supported: Server v11.7.0+ is required. Self-Signed SSL certificates are not supported unless the user installs the CA certificate on their device. + +### Compatibility + - **Upgrade to server version v11.7.0 or later is required.** Support for server [Extended Support Release](https://docs.mattermost.com/product-overview/release-policy.html#extended-support-releases) (ESR) v10.11.0 has ended and upgrading to server ESR v11.7.0 or later is required. As we innovate and offer newer versions of our mobile apps, we maintain backwards compatibility only with supported server versions. Users who upgrade to the newest mobile apps while being connected to an unsupported server version can be exposed to compatibility issues, which can cause crashes or severe bugs that break core functionality of the app. + - Android operating system 7+ [is required by Google](https://android-developers.googleblog.com/2017/12/improving-app-security-and-performance.html). + - iPhone 8+ devices and later with iOS 16.0+ are [required](https://support.apple.com/en-il/guide/iphone/iphe3fa5df43/16.0/ios/16.0). + +### Improvements + - Added [classification markings](https://docs.mattermost.com/end-user-guide/collaborate/display-channel-banners.html) for global and per-channel banners. Requires server v11.9.0+. + - Added support for Mattermost Blocks as a new way to create interactive messages. + - Added timezone support and manual time entry for Interactive Dialog datetime fields. Plugins can now display times in specific timezones and allow text input for exact times. + - Wipe notifications sent by the server are now processed. + - Applied **Zero Persistence Mode** server setting for Mobile Ephemeral Mode. + +### Bug Fixes + - Fixed an issue where the app did not automatically recover from database corruption errors. + - Fixed back-button behaviour, especially on newer Android versions. + - Fixed a critical timezone preservation bug. + +### Known Issues + - Users are unable to adjust the font size via the OS font size setting. + - Some Google Pixel phones on Android 12+ might not continue past the login screen. This is a known issue with the OS, and the current workaround is to restart the device. + +## 2.42.3 Release \{#release-v2-42-3} + - Release Date: August 5, 2026 + - Server Versions Supported: Server v10.11.0+ is required. Self-Signed SSL certificates are not supported unless the user installs the CA certificate on their device. + +### Compatibility + - **Upgrade to server version v10.11.0 or later is required.** Support for server [Extended Support Release](https://docs.mattermost.com/product-overview/release-policy.html#extended-support-releases) (ESR) v10.5.0 has ended and upgrading to server ESR v10.11.0 or later is required. As we innovate and offer newer versions of our mobile apps, we maintain backwards compatibility only with supported server versions. Users who upgrade to the newest mobile apps while being connected to an unsupported server version can be exposed to compatibility issues, which can cause crashes or severe bugs that break core functionality of the app. + - Android operating system 7+ [is required by Google](https://android-developers.googleblog.com/2017/12/improving-app-security-and-performance.html). + - iPhone 8+ devices and later with iOS 16.0+ are [required](https://support.apple.com/en-il/guide/iphone/iphe3fa5df43/16.0/ios/16.0). + +### Bug Fixes + - Fixed potential causes of rendering a channel empty. + - Fixed an issue where **Enter** did not work on channels. + +### Known Issues + - Users are unable to adjust the font size via the OS font size setting. + - Some Google Pixel phones on Android 12+ might not continue past the login screen. This is a known issue with the OS, and the current workaround is to restart the device. + ## 2.42.2 Release \{#release-v2-42-2} - Release Date: July 18, 2026 - Server Versions Supported: Server v10.11.0+ is required. Self-Signed SSL certificates are not supported unless the user installs the CA certificate on their device. diff --git a/docs/main/product-overview/plans.mdx b/docs/main/product-overview/plans.mdx index f84641c5bdfc..64ca379f26a2 100644 --- a/docs/main/product-overview/plans.mdx +++ b/docs/main/product-overview/plans.mdx @@ -206,7 +206,7 @@ import useBaseUrl from '@docusaurus/useBaseUrl'; Included*IncludedIncludedIncludedv9.11+ - Guest accounts: Bring external users and users who need to have restricted access into your Mattermost instance as guests who can interact with your team with limited permissions. Guests in exactly one channel are treated as single-channel guests and are free up to a 1:1 ratio with licensed seats. Guests in multiple channels continue to count as paid active users. Direct messages and group messages do not affect whether a guest is counted as a single-channel guest. + Guest accounts: Bring external users and users who need to have restricted access into your Mattermost instance as guests who can interact with your team with limited permissions. Guests in exactly one active channel are treated as single-channel guests and are free up to a 1:1 ratio with licensed seats. Guests in multiple active channels continue to count as activated users. Direct messages and group messages do not affect whether a guest is counted as a single-channel guest. Only active channels count toward guest channel access for billing. Archived channels are excluded. IncludedIncludedIncludedIncludedv9.11+ diff --git a/docs/main/product-overview/release-policy.mdx b/docs/main/product-overview/release-policy.mdx index a725eca9a967..a52d0b8ccf10 100644 --- a/docs/main/product-overview/release-policy.mdx +++ b/docs/main/product-overview/release-policy.mdx @@ -24,9 +24,9 @@ See the full list of all Mattermost Server and desktop app releases and life cyc Mattermost Extended Support Releases (ESRs) are a strategic choice for organizations looking for stability and reduced frequency of updates. Using ESRs can minimize disruptions associated with frequent upgrades, making them an attractive option for environments where stability is paramount. -Starting with the August 2025 Mattermost server and desktop app releases (server v10.11 and desktop app v5.13), Mattermost has adjusted the ESR life cycle as follows: - - **Extended Cadence**: ESRs are released every 9 months. - - **Prolonged Support**: ESRs are supported for 12 months. +The lifecycle for Mattermost server and desktop app Extended Support Releases is as follows: + - **Cadence**: ESRs are released every 9 months. + - **Support**: ESRs are supported for 12 months. We strongly recommend planning ahead for upgrades before the end of an ESR's life cycle to ensure continuity in receiving security updates. @@ -73,7 +73,6 @@ gantt axisFormat %b %y section Releases - v10.10 :done, 2025-07-16, 2025-10-15 v10.11 & Desktop App v5.13 Extended Support :crit, 2025-08-16, 2026-08-15 v10.12 :done, 2025-09-16, 2025-12-15 v11.0 :done, 2025-10-16, 2026-01-15 @@ -86,7 +85,8 @@ gantt v11.7 & Desktop App v6.2 Extended Support :crit, 2026-05-15, 2027-05-15 v11.8 :active, 2026-06-16, 2026-09-15 v11.9 :active, 2026-07-16, 2026-10-15 - v11.10 :active, 2026-08-16, 2026-11-15 + v11.10 :active, 2026-08-14, 2026-11-15 + v11.11 :active, 2026-09-16, 2026-12-15 ``` @@ -95,8 +95,8 @@ gantt The chart above shows both release dates and end-of-life dates for each version. ESRs provide longer-term stability for organizations preferring less frequent updates. - 🔵 **Blue bars**: Regular feature releases (monthly releases with standard support lifecycle) - 🔴 **Red bars**: Extended Support Releases (ESRs), released every 9 months with 12 months of support - - v10.11 & Desktop App v5.13: Supported until August 15, 2026 - v11.7 & Desktop App v6.2: Supported until May 15, 2027 + - v10.11 & Desktop App v5.13: Support ended August 15, 2026 ### ESR Notifications \{#esr-notifications} @@ -115,7 +115,7 @@ The following table lists all releases across Mattermost v7.0, v8.0, and v9.0, i - If you're on a legacy Mattermost release prior to v7.1, in order to take advantage of newer Mattermost releases, you must upgrade to [v7.1 ESR](https://docs.mattermost.com/product-overview/unsupported-legacy-releases.html#release-v7-1-extended-support-release) at a minimum. -- Upgrading from one Extended Support Release (ESR) to the next ESR (``major`` -> ``major_next``) is fully supported and tested. However, upgrading across multiple ESR versions (``major`` to ``major+2``) is supported, but not tested. If you plan to skip versions, we strongly recommend upgrading only between ESR releases. For example, if you're upgrading from v8.1 ESR, upgrade to the v9.5 ESR or the v9.11 ESR before attempting to upgrade to the [v10.11 ESR](https://docs.mattermost.com/product-overview/mattermost-v10-changelog.html#release-v10-11-extended-support-release) or the [v11.7 ESR](https://docs.mattermost.com/product-overview/mattermost-v11-changelog.html#release-v11-7-extended-support-release). +- Upgrading from one Extended Support Release (ESR) to the next ESR (``major`` -> ``major_next``) is fully supported and tested. However, upgrading across multiple ESR versions (``major`` to ``major+2``) is supported, but not tested. If you plan to skip versions, we strongly recommend upgrading only between ESR releases. For example, if you're upgrading from v8.1 ESR, upgrade to the v9.5 ESR or the v9.11 ESR before attempting to upgrade to the [v11.7 ESR](https://docs.mattermost.com/product-overview/mattermost-v11-changelog.html#release-v11-7-extended-support-release). diff --git a/docs/main/product-overview/self-hosted-subscriptions.mdx b/docs/main/product-overview/self-hosted-subscriptions.mdx index 39ed4cb3e35e..e519acf9ed04 100644 --- a/docs/main/product-overview/self-hosted-subscriptions.mdx +++ b/docs/main/product-overview/self-hosted-subscriptions.mdx @@ -31,7 +31,7 @@ If at any time you'd like to add more users to your Mattermost subscription, tal When you buy an annual Mattermost subscription, you agree to provide Mattermost with quarterly reports of the actual number of activated users within your system. An activated user is a user who has a Mattermost account and doesn't show as **Deactivated** in **System Console \> User Management \> Users**. -Single-channel guests are tracked separately from activated users. Guests in exactly one channel are free up to a 1:1 ratio with licensed seats, while guests in multiple channels continue to count as activated users. Direct messages and group messages don't affect whether a guest is counted as a single-channel guest. +Single-channel guests are tracked separately from activated users. Guests in exactly one active channel are free up to a 1:1 ratio with licensed seats, while guests in multiple active channels continue to count as activated users. Direct messages and group messages don't affect whether a guest is counted as a single-channel guest. We'll send you an email notice around the end of the quarter reminding you to send us your report. @@ -67,7 +67,7 @@ A true-up report is our quarterly request for you to provide us with the actual As your organization grows, you may need to add additional users during your subscription period. Mattermost needs to have insight into changes in your activated user count so that we can charge you appropriately for your self-hosted license usage. Additionally, we don’t want to over estimate/charge activated users at your renewal time. -Single-channel guests are visible separately in reporting and on the **Edition and License** page. They don't count toward the primary paid seat count up to a 1:1 ratio with licensed seats, and exceeding that allowance generates system-admin warnings rather than hard limits. +Single-channel guests are visible separately in reporting and on the **Edition and License** page. They don't count toward the primary paid seat count up to a 1:1 ratio with licensed seats, and exceeding that allowance generates system-admin warnings rather than hard limits. Only active channels count toward guest channel access for billing. Archived channels are excluded. When you receive the quarterly true-up notice from Mattermost, please share your activated user count with us. diff --git a/docs/main/product-overview/subscription.mdx b/docs/main/product-overview/subscription.mdx index 441194f02a4b..3349c291f8f9 100644 --- a/docs/main/product-overview/subscription.mdx +++ b/docs/main/product-overview/subscription.mdx @@ -73,9 +73,10 @@ For the purpose of billing, an activated user is any account created in Mattermo Guests are billed based on channel access: -- Guests in exactly one channel are treated as single-channel guests. They don't count toward the primary paid seat count and are free up to a 1:1 ratio with licensed seats. -- Guests in multiple channels continue to count as activated users for billing purposes. +- Guests in exactly one active channel are treated as single-channel guests. They don't count toward the primary paid seat count and are free up to a 1:1 ratio with licensed seats. +- Guests in multiple active channels continue to count as activated users for billing purposes. - Direct messages and group messages don't affect whether a guest is counted as a single-channel guest. +- Only active channels count toward guest channel access for billing. Archived channels are excluded. Bots, deactivated users, and synthetic users in [Microsoft Teams integrations](/end-user-guide/collaborate/collaborate-within-connected-microsoft-teams) and [connected workspace](/administration-guide/onboard/connected-workspaces) users aren't counted towards the total number of activated users. diff --git a/docs/main/product-overview/ui-ada-changelog.mdx b/docs/main/product-overview/ui-ada-changelog.mdx index 8847ad305bdd..0ca54e8d3045 100644 --- a/docs/main/product-overview/ui-ada-changelog.mdx +++ b/docs/main/product-overview/ui-ada-changelog.mdx @@ -18,6 +18,58 @@ This changelog tracks User Interface (UI) and Accessibility (ADA) changes across +v11.10 +(UI) Added a WYSIWYG editor option for message composition, allowing users to compose messages with rich-text formatting while preserving full markdown round-trip. + + +v11.10 +(UI) Added a media gallery layout for posts with multiple images or videos, plus inline frame previews for single videos. + + +v11.10 +(UI) Added support for a file upload element type in interactive dialogs. + + +v11.10 +(UI) Added support for Mattermost Blocks as a new way to create Interactive Messages. + + +v11.10 +(UI) Plugins and integrations can now open stacked child dialogs from within an interactive dialog using the new action_button element type. + + +v11.10 +(UI) Bot accounts, OAuth apps, incoming webhooks, and plugins can now deliver posts silently — visible in the channel without producing notifications, unread badges, or the "New Messages" separator. + + +v11.10 +(UI) Bot accounts managed by a plugin now display the managing plugin's ID in the Bot Accounts list instead of a generic "Managed by plugin" label. + + +v11.10 +(UI) Added inline plugin metadata to the Plugin Management page and plugin settings page showing the plugin ID, version, and links to the website and release notes when available. + + +v11.10 +(UI) The agent selector now respects the configured default agent and remembers your last-selected agent. + + +v11.10 +(UI) Mattermost now proactively warns the owner of a personal access token with a direct message from the system bot as the token approaches expiry (7, 3, and 1 days before), so token-backed integrations no longer break without warning. + + +v11.10 +(UI) Token owners are now notified by a direct message from the system bot when one of their personal access tokens is removed after expiring. + + +v11.10 +(UI) Added a Regenerate option to Personal Access Tokens in Account Settings > Security. + + +v11.10 +(UI) Changed left-hand-side/right-hand-side to only be resizable with the left mouse button. + + v11.9 (UI) Added zoom and pan support to the image file preview: use the scroll wheel to zoom at the cursor, click-and-drag to pan, and +/-/0 keyboard shortcuts (reported on webapp). diff --git a/docs/main/product-overview/version-archive.mdx b/docs/main/product-overview/version-archive.mdx index 8ad84c3f5647..3d2137fce3e4 100644 --- a/docs/main/product-overview/version-archive.mdx +++ b/docs/main/product-overview/version-archive.mdx @@ -19,23 +19,33 @@ Our package signing key has been moved away from Keybase. If you still reference -Mattermost Enterprise Edition v11.9.0 - [View Changelog](https://docs.mattermost.com/product-overview/mattermost-v11-changelog.html#release-v11-9-feature-release) - [Download](https://releases.mattermost.com/11.9.0/mattermost-11.9.0-linux-amd64.tar.gz?src=arc) -- `https://releases.mattermost.com/11.9.0/mattermost-11.9.0-linux-amd64.tar.gz` -- SHA-256 Checksum: `8b335213debfa817084870f09e28c3ecabb899cbfbf39a167d81dee68d96d6e3` -- GPG Signature: [https://releases.mattermost.com/11.9.0/mattermost-11.9.0-linux-amd64.tar.gz.sig](https://releases.mattermost.com/11.9.0/mattermost-11.9.0-linux-amd64.tar.gz.sig) -- SBOM Download Link: [https://releases.mattermost.com/11.9.0/sbom-enterprise-v11.9.0.json](https://releases.mattermost.com/11.9.0/sbom-enterprise-v11.9.0.json) - -Mattermost Enterprise Edition v11.8.4 - [View Changelog](https://docs.mattermost.com/product-overview/mattermost-v11-changelog.html#release-v11-8-feature-release) - [Download](https://releases.mattermost.com/11.8.4/mattermost-11.8.4-linux-amd64.tar.gz?src=arc) -- `https://releases.mattermost.com/11.8.4/mattermost-11.8.4-linux-amd64.tar.gz` -- SHA-256 Checksum: `a1809895094cae12c9d091b97380daf0fff9530ff61e50990aa03db58f67eaa1` -- GPG Signature: [https://releases.mattermost.com/11.8.4/mattermost-11.8.4-linux-amd64.tar.gz.sig](https://releases.mattermost.com/11.8.4/mattermost-11.8.4-linux-amd64.tar.gz.sig) -- SBOM Download Link: [https://releases.mattermost.com/11.8.4/sbom-enterprise-v11.8.4.json](https://releases.mattermost.com/11.8.4/sbom-enterprise-v11.8.4.json) - -Mattermost Enterprise Edition v11.7.7 *Extended Support Release (ESR)* - [View Changelog](https://docs.mattermost.com/product-overview/mattermost-v11-changelog.html#release-v11-7-extended-support-release) - [Download](https://releases.mattermost.com/11.7.7/mattermost-11.7.7-linux-amd64.tar.gz?src=arc) -- `https://releases.mattermost.com/11.7.7/mattermost-11.7.7-linux-amd64.tar.gz` -- SHA-256 Checksum: `e498312ed51ab0d91a1b0f79bc927ef6b0b0b6cbc7905d8c96a7f9d329ea6d7c` -- GPG Signature: [https://releases.mattermost.com/11.7.7/mattermost-11.7.7-linux-amd64.tar.gz.sig](https://releases.mattermost.com/11.7.7/mattermost-11.7.7-linux-amd64.tar.gz.sig) -- SBOM Download Link: [https://releases.mattermost.com/11.7.7/sbom-enterprise-v11.7.7.json](https://releases.mattermost.com/11.7.7/sbom-enterprise-v11.7.7.json) +Mattermost Enterprise Edition v11.10.0 - [View Changelog](https://docs.mattermost.com/product-overview/mattermost-v11-changelog.html#release-v11-10-feature-release) - [Download](https://releases.mattermost.com/11.10.0/mattermost-11.10.0-linux-amd64.tar.gz?src=arc) + +- `https://releases.mattermost.com/11.10.0/mattermost-11.10.0-linux-amd64.tar.gz` +- SHA-256 Checksum: `8ae404ed0c0fbab2b01c00c031b9d0f3e17c51007e3bb3401bebaf3e60da0c3e` +- GPG Signature: [https://releases.mattermost.com/11.10.0/mattermost-11.10.0-linux-amd64.tar.gz.sig](https://releases.mattermost.com/11.10.0/mattermost-11.10.0-linux-amd64.tar.gz.sig) +- SBOM Download Link: [https://releases.mattermost.com/11.10.0/sbom-enterprise-v11.10.0.json](https://releases.mattermost.com/11.10.0/sbom-enterprise-v11.10.0.json) + +Mattermost Enterprise Edition v11.9.1 - [View Changelog](https://docs.mattermost.com/product-overview/mattermost-v11-changelog.html#release-v11-9-feature-release) - [Download](https://releases.mattermost.com/11.9.1/mattermost-11.9.1-linux-amd64.tar.gz?src=arc) + +- `https://releases.mattermost.com/11.9.1/mattermost-11.9.1-linux-amd64.tar.gz` +- SHA-256 Checksum: `0a7a38eb36ba91ee5ff1438957f4138a985befcfdaee1dedc9953067a2ba72ef` +- GPG Signature: [https://releases.mattermost.com/11.9.1/mattermost-11.9.1-linux-amd64.tar.gz.sig](https://releases.mattermost.com/11.9.1/mattermost-11.9.1-linux-amd64.tar.gz.sig) +- SBOM Download Link: [https://releases.mattermost.com/11.9.1/sbom-enterprise-v11.9.1.json](https://releases.mattermost.com/11.9.1/sbom-enterprise-v11.9.1.json) + +Mattermost Enterprise Edition v11.8.5 - [View Changelog](https://docs.mattermost.com/product-overview/mattermost-v11-changelog.html#release-v11-8-feature-release) - [Download](https://releases.mattermost.com/11.8.5/mattermost-11.8.5-linux-amd64.tar.gz?src=arc) + +- `https://releases.mattermost.com/11.8.5/mattermost-11.8.5-linux-amd64.tar.gz` +- SHA-256 Checksum: `b9724edc0b622638af70f7fd6a1f3225dbfcbca8570a1c294a637f154c8974f7` +- GPG Signature: [https://releases.mattermost.com/11.8.5/mattermost-11.8.5-linux-amd64.tar.gz.sig](https://releases.mattermost.com/11.8.5/mattermost-11.8.5-linux-amd64.tar.gz.sig) +- SBOM Download Link: [https://releases.mattermost.com/11.8.5/sbom-enterprise-v11.8.5.json](https://releases.mattermost.com/11.8.5/sbom-enterprise-v11.8.5.json) + +Mattermost Enterprise Edition v11.7.9 *Extended Support Release (ESR)* - [View Changelog](https://docs.mattermost.com/product-overview/mattermost-v11-changelog.html#release-v11-7-extended-support-release) - [Download](https://releases.mattermost.com/11.7.9/mattermost-11.7.9-linux-amd64.tar.gz?src=arc) + +- `https://releases.mattermost.com/11.7.9/mattermost-11.7.9-linux-amd64.tar.gz` +- SHA-256 Checksum: `a22e631ae4a1f704c2bcf45ad8dcc377184081c50954a9269b7f62bd663a7a04` +- GPG Signature: [https://releases.mattermost.com/11.7.9/mattermost-11.7.9-linux-amd64.tar.gz.sig](https://releases.mattermost.com/11.7.9/mattermost-11.7.9-linux-amd64.tar.gz.sig) +- SBOM Download Link: [https://releases.mattermost.com/11.7.9/sbom-enterprise-v11.7.9.json](https://releases.mattermost.com/11.7.9/sbom-enterprise-v11.7.9.json) Mattermost Enterprise Edition v11.6.6 - [View Changelog](https://docs.mattermost.com/product-overview/mattermost-v11-changelog.html#release-v11-6-feature-release) - [Download](https://releases.mattermost.com/11.6.6/mattermost-11.6.6-linux-amd64.tar.gz?src=arc) - `https://releases.mattermost.com/11.6.6/mattermost-11.6.6-linux-amd64.tar.gz` @@ -85,11 +95,12 @@ Mattermost Enterprise Edition v10.12.4 - [View Changelog](https://docs.mattermos - GPG Signature: [https://releases.mattermost.com/10.12.4/mattermost-10.12.4-linux-amd64.tar.gz.sig](https://releases.mattermost.com/10.12.4/mattermost-10.12.4-linux-amd64.tar.gz.sig) - SBOM Download Link: [https://releases.mattermost.com/10.12.4/sbom-enterprise-v10.12.4.json](https://releases.mattermost.com/10.12.4/sbom-enterprise-v10.12.4.json) -Mattermost Enterprise Edition v10.11.22 *Extended Support Release (ESR)* - [View Changelog](https://docs.mattermost.com/product-overview/mattermost-v10-changelog.html#release-v10-11-extended-support-release) - [Download](https://releases.mattermost.com/10.11.22/mattermost-10.11.22-linux-amd64.tar.gz?src=arc) -- `https://releases.mattermost.com/10.11.22/mattermost-10.11.22-linux-amd64.tar.gz` -- SHA-256 Checksum: `e2259cea0c6395334e1be3c745c615cc276145f1e078a884e1af6147e101fed1` -- GPG Signature: [https://releases.mattermost.com/10.11.22/mattermost-10.11.22-linux-amd64.tar.gz.sig](https://releases.mattermost.com/10.11.22/mattermost-10.11.22-linux-amd64.tar.gz.sig) -- SBOM Download Link: [https://releases.mattermost.com/10.11.22/sbom-enterprise-v10.11.22.json](https://releases.mattermost.com/10.11.22/sbom-enterprise-v10.11.22.json) +Mattermost Enterprise Edition v10.11.23 *Extended Support Release (ESR)* - [View Changelog](https://docs.mattermost.com/product-overview/mattermost-v10-changelog.html#release-v10-11-extended-support-release) - [Download](https://releases.mattermost.com/10.11.23/mattermost-10.11.23-linux-amd64.tar.gz?src=arc) + +- `https://releases.mattermost.com/10.11.23/mattermost-10.11.23-linux-amd64.tar.gz` +- SHA-256 Checksum: `c1560b3ac30179ae02f28ee53c4ba9632a092a7923ad150cfaa0a76c5f2290a3` +- GPG Signature: [https://releases.mattermost.com/10.11.23/mattermost-10.11.23-linux-amd64.tar.gz.sig](https://releases.mattermost.com/10.11.23/mattermost-10.11.23-linux-amd64.tar.gz.sig) +- SBOM Download Link: [https://releases.mattermost.com/10.11.23/sbom-enterprise-v10.11.23.json](https://releases.mattermost.com/10.11.23/sbom-enterprise-v10.11.23.json) Mattermost Enterprise Edition v10.10.3 - [View Changelog](https://docs.mattermost.com/about/mattermost-v10-changelog.html#release-v10-10-feature-release) - [Download](https://releases.mattermost.com/10.10.3/mattermost-10.10.3-linux-amd64.tar.gz?src=arc) - `https://releases.mattermost.com/10.10.3/mattermost-10.10.3-linux-amd64.tar.gz` @@ -621,23 +632,33 @@ The open source Mattermost Team Edition is functionally identical to the commerc We generally recommend installing Enterprise Edition, even if you don't currently need a license. This provides the flexibility to seamlessly unlock Enterprise features should you need them. However, if you only want to install software with a fully open source code base, then Team Edition is the best choice for you. -Mattermost Team Edition v11.9.0 - [View Changelog](https://docs.mattermost.com/product-overview/mattermost-v11-changelog.html#release-v11-9-feature-release) - [Download](https://releases.mattermost.com/11.9.0/mattermost-team-11.9.0-linux-amd64.tar.gz?src=arc) -- `https://releases.mattermost.com/11.9.0/mattermost-team-11.9.0-linux-amd64.tar.gz` -- SHA-256 Checksum: `5f1172535f43a5444a0896e8ad3ca2dbef7b2c20ca4e616a92691eaca03ae05f` -- GPG Signature: [https://releases.mattermost.com/11.9.0/mattermost-team-11.9.0-linux-amd64.tar.gz.sig](https://releases.mattermost.com/11.9.0/mattermost-team-11.9.0-linux-amd64.tar.gz.sig) -- SBOM Download Link: [https://github.com/mattermost/mattermost/releases/download/v11.9.0/sbom-mattermost-v11.9.0.json](https://github.com/mattermost/mattermost/releases/download/v11.9.0/sbom-mattermost-v11.9.0.json) +Mattermost Team Edition v11.10.0 - [View Changelog](https://docs.mattermost.com/product-overview/mattermost-v11-changelog.html#release-v11-10-feature-release) - [Download](https://releases.mattermost.com/11.10.0/mattermost-team-11.10.0-linux-amd64.tar.gz?src=arc) + +- `https://releases.mattermost.com/11.10.0/mattermost-team-11.10.0-linux-amd64.tar.gz` +- SHA-256 Checksum: `376f4be1fcd83bd65ab3f4dc580ba87684e4caed93d357e965b95703854f7c05` +- GPG Signature: [https://releases.mattermost.com/11.10.0/mattermost-team-11.10.0-linux-amd64.tar.gz.sig](https://releases.mattermost.com/11.10.0/mattermost-team-11.10.0-linux-amd64.tar.gz.sig) +- SBOM Download Link: [https://github.com/mattermost/mattermost/releases/download/v11.10.0/sbom-mattermost-v11.10.0.json](https://github.com/mattermost/mattermost/releases/download/v11.10.0/sbom-mattermost-v11.10.0.json) + +Mattermost Team Edition v11.9.1 - [View Changelog](https://docs.mattermost.com/product-overview/mattermost-v11-changelog.html#release-v11-9-feature-release) - [Download](https://releases.mattermost.com/11.9.1/mattermost-team-11.9.1-linux-amd64.tar.gz?src=arc) + +- `https://releases.mattermost.com/11.9.1/mattermost-team-11.9.1-linux-amd64.tar.gz` +- SHA-256 Checksum: `0165795db023f3262f2e3de0a6e20e160a21bf9d8375ee13d5323a1966d73a2f` +- GPG Signature: [https://releases.mattermost.com/11.9.1/mattermost-team-11.9.1-linux-amd64.tar.gz.sig](https://releases.mattermost.com/11.9.1/mattermost-team-11.9.1-linux-amd64.tar.gz.sig) +- SBOM Download Link: [https://github.com/mattermost/mattermost/releases/download/v11.9.1/sbom-mattermost-v11.9.1.json](https://github.com/mattermost/mattermost/releases/download/v11.9.1/sbom-mattermost-v11.9.1.json) -Mattermost Team Edition v11.8.4 - [View Changelog](https://docs.mattermost.com/product-overview/mattermost-v11-changelog.html#release-v11-8-feature-release) - [Download](https://releases.mattermost.com/11.8.4/mattermost-team-11.8.4-linux-amd64.tar.gz?src=arc) -- `https://releases.mattermost.com/11.8.4/mattermost-team-11.8.4-linux-amd64.tar.gz` -- SHA-256 Checksum: `553d6b36073125f84a283ccf4cc50c270a71be21024274b5c35e4a1d12bf49c1` -- GPG Signature: [https://releases.mattermost.com/11.8.4/mattermost-team-11.8.4-linux-amd64.tar.gz.sig](https://releases.mattermost.com/11.8.4/mattermost-team-11.8.4-linux-amd64.tar.gz.sig) -- SBOM Download Link: [https://github.com/mattermost/mattermost/releases/download/v11.8.4/sbom-mattermost-v11.8.4.json](https://github.com/mattermost/mattermost/releases/download/v11.8.4/sbom-mattermost-v11.8.4.json) +Mattermost Team Edition v11.8.5 - [View Changelog](https://docs.mattermost.com/product-overview/mattermost-v11-changelog.html#release-v11-8-feature-release) - [Download](https://releases.mattermost.com/11.8.5/mattermost-team-11.8.5-linux-amd64.tar.gz?src=arc) -Mattermost Team Edition v11.7.7 *Extended Support Release (ESR)* - [View Changelog](https://docs.mattermost.com/product-overview/mattermost-v11-changelog.html#release-v11-7-extended-support-release) - [Download](https://releases.mattermost.com/11.7.7/mattermost-team-11.7.7-linux-amd64.tar.gz?src=arc) -- `https://releases.mattermost.com/11.7.7/mattermost-team-11.7.7-linux-amd64.tar.gz` -- SHA-256 Checksum: `8324eee1f979863883a9c8e71112f2ec127037da81f4efb90639b56187c6b0f7` -- GPG Signature: [https://releases.mattermost.com/11.7.7/mattermost-team-11.7.7-linux-amd64.tar.gz.sig](https://releases.mattermost.com/11.7.7/mattermost-team-11.7.7-linux-amd64.tar.gz.sig) -- SBOM Download Link: [https://github.com/mattermost/mattermost/releases/download/v11.7.7/sbom-mattermost-v11.7.7.json](https://github.com/mattermost/mattermost/releases/download/v11.7.7/sbom-mattermost-v11.7.7.json) +- `https://releases.mattermost.com/11.8.5/mattermost-team-11.8.5-linux-amd64.tar.gz` +- SHA-256 Checksum: `92f9c661dc14e24dfb6dc1af99c32a64ae5b58c866269a4750c614d3c5ba846b` +- GPG Signature: [https://releases.mattermost.com/11.8.5/mattermost-team-11.8.5-linux-amd64.tar.gz.sig](https://releases.mattermost.com/11.8.5/mattermost-team-11.8.5-linux-amd64.tar.gz.sig) +- SBOM Download Link: [https://github.com/mattermost/mattermost/releases/download/v11.8.5/sbom-mattermost-v11.8.5.json](https://github.com/mattermost/mattermost/releases/download/v11.8.5/sbom-mattermost-v11.8.5.json) + +Mattermost Team Edition v11.7.9 *Extended Support Release (ESR)* - [View Changelog](https://docs.mattermost.com/product-overview/mattermost-v11-changelog.html#release-v11-7-extended-support-release) - [Download](https://releases.mattermost.com/11.7.9/mattermost-team-11.7.9-linux-amd64.tar.gz?src=arc) + +- `https://releases.mattermost.com/11.7.9/mattermost-team-11.7.9-linux-amd64.tar.gz` +- SHA-256 Checksum: `df9b76ee40212c1552162486befc80f52ba9eefbde1ac6a490bdda4188ba54f0` +- GPG Signature: [https://releases.mattermost.com/11.7.9/mattermost-team-11.7.9-linux-amd64.tar.gz.sig](https://releases.mattermost.com/11.7.9/mattermost-team-11.7.9-linux-amd64.tar.gz.sig) +- SBOM Download Link: [https://github.com/mattermost/mattermost/releases/download/v11.7.9/sbom-mattermost-v11.7.9.json](https://github.com/mattermost/mattermost/releases/download/v11.7.9/sbom-mattermost-v11.7.9.json) Mattermost Team Edition v11.6.6 - [View Changelog](https://docs.mattermost.com/product-overview/mattermost-v11-changelog.html#release-v11-6-feature-release) - [Download](https://releases.mattermost.com/11.6.6/mattermost-team-11.6.6-linux-amd64.tar.gz?src=arc) - `https://releases.mattermost.com/11.6.6/mattermost-team-11.6.6-linux-amd64.tar.gz` @@ -687,11 +708,12 @@ Mattermost Team Edition v10.12.4 - [View Changelog](https://docs.mattermost.com/ - GPG Signature: [https://releases.mattermost.com/10.12.4/mattermost-team-10.12.4-linux-amd64.tar.gz.sig](https://releases.mattermost.com/10.12.4/mattermost-team-10.12.4-linux-amd64.tar.gz.sig) - SBOM Download Link: [https://github.com/mattermost/mattermost/releases/download/v10.12.4/sbom-mattermost-v10.12.4.json](https://github.com/mattermost/mattermost/releases/download/v10.12.4/sbom-mattermost-v10.12.4.json) -Mattermost Team Edition v10.11.22 *Extended Support Release (ESR)* - [View Changelog](https://docs.mattermost.com/product-overview/mattermost-v10-changelog.html#release-v10-11-extended-support-release) - [Download](https://releases.mattermost.com/10.11.22/mattermost-team-10.11.22-linux-amd64.tar.gz?src=arc) -- `https://releases.mattermost.com/10.11.22/mattermost-team-10.11.22-linux-amd64.tar.gz` -- SHA-256 Checksum: `5aa384716f0ee2be99c03d4d5af8e488a090a63caca2b78f539a1e199fde5452` -- GPG Signature: [https://releases.mattermost.com/10.11.22/mattermost-team-10.11.22-linux-amd64.tar.gz.sig](https://releases.mattermost.com/10.11.22/mattermost-team-10.11.22-linux-amd64.tar.gz.sig) -- SBOM Download Link: [https://github.com/mattermost/mattermost/releases/download/v10.11.22/sbom-mattermost-v10.11.22.json](https://github.com/mattermost/mattermost/releases/download/v10.11.22/sbom-mattermost-v10.11.22.json) +Mattermost Team Edition v10.11.23 *Extended Support Release (ESR)* - [View Changelog](https://docs.mattermost.com/product-overview/mattermost-v10-changelog.html#release-v10-11-extended-support-release) - [Download](https://releases.mattermost.com/10.11.23/mattermost-team-10.11.23-linux-amd64.tar.gz?src=arc) + +- `https://releases.mattermost.com/10.11.23/mattermost-team-10.11.23-linux-amd64.tar.gz` +- SHA-256 Checksum: `c20528c64fc1378b866040b10a05ddacff336cb87dd797a2be9cddf1a201cbd0` +- GPG Signature: [https://releases.mattermost.com/10.11.23/mattermost-team-10.11.23-linux-amd64.tar.gz.sig](https://releases.mattermost.com/10.11.23/mattermost-team-10.11.23-linux-amd64.tar.gz.sig) +- SBOM Download Link: [https://github.com/mattermost/mattermost/releases/download/v10.11.23/sbom-mattermost-v10.11.23.json](https://github.com/mattermost/mattermost/releases/download/v10.11.23/sbom-mattermost-v10.11.23.json) Mattermost Team Edition v10.10.3 - [View Changelog](https://docs.mattermost.com/about/mattermost-v10-changelog.html#release-v10-10-feature-release) - [Download](https://releases.mattermost.com/10.10.3/mattermost-team-10.10.3-linux-amd64.tar.gz?src=arc) - `https://releases.mattermost.com/10.10.3/mattermost-team-10.10.3-linux-amd64.tar.gz` diff --git a/docs/main/security-guide/zero-trust.mdx b/docs/main/security-guide/zero-trust.mdx index 88f889a33b4b..57c7791b0380 100644 --- a/docs/main/security-guide/zero-trust.mdx +++ b/docs/main/security-guide/zero-trust.mdx @@ -1,124 +1,190 @@ --- title: "Zero Trust with Mattermost" --- -Mattermost helps organizations adopt and implement Zero Trust principles to safeguard their mission-critical communications and collaboration. +Mattermost is designed from the ground up to blend seamlessly into an organization’s existing Zero Trust practices and requirements. Rather than treating Zero Trust as a checklist of security controls bolted on after the fact, Mattermost implements it as a continuous enforcement model across every layer of collaboration-identity, devices, networks, applications, and data. For security teams, Mattermost’s zero-trust-first approach ensures consistent compliance with organizational risk policies by automating key governance processes like incident response or data lifecycle management. -Unlike traditional security approaches, Zero Trust assumes every user and system may be a potential threat. Mattermost implements this paradigm by offering customizable, secure solutions that protect sensitive communication workflows from both internal and external risks. +This guide maps Mattermost's security capabilities to the five pillars of the [CISA Zero Trust Maturity Model](https://www.cisa.gov/zero-trust-maturity-model) and describes how organizations can progress from a traditional perimeter-based stance to full, dynamic Zero Trust enforcement. Features are available on Enterprise or Enterprise Advanced editions as noted. -This document outlines how Mattermost supports the core tenets of Zero Trust, for organizations of different sizes, including [Identity and access management](#identity-and-access-management), [Continuous monitoring](#continuous-monitoring), [Deployment and host control](#deployment-and-host-control), [Encryption](#encryption), [Micro-segmentation](#micro-segmentation), [Multi-factor authentication](#multi-factor-authentication-mfa), [Data management](#data-management), and [Incident response](#incident-response). Links to detailed documentation resources are provided below. +## User Management / Identity -## Identity and access management +Zero Trust requires that every user be continuously verified, not just at login. Mattermost integrates with enterprise Identity, Credential, and Access Management (ICAM) platforms to automate this verification and make access decisions dynamic rather than static. -Mattermost integrates seamlessly with enterprise identity providers (IdPs), enabling strong identity verification and strict access control. +### Foundation: federated authentication and directory sync -By using one of the secure identity mechanisms listed below and enforcing least-privilege access via roles and groups, Mattermost ensures that only verified individuals gain access to the platform and its resources: +At the most basic level, Mattermost replaces standalone passwords with enterprise identity providers (IdPs) and keeps access rights synchronized automatically. -- [SAML](/administration-guide/onboard/sso-saml): Enables seamless Single Sign-On, ensuring centralized authentication to continuously enforce user verification. -- [LDAP](/administration-guide/onboard/ad-ldap): Facilitates integration with enterprise directories to tightly control user access, adhering to granular identity verification. -- [OpenID Connect](/administration-guide/configure/authentication-configuration-settings#openid-connect): Provides secure, standards-based user authentication to verify identities and enforce secure access. -- [Session Management](/administration-guide/configure/environment-configuration-settings#session-lengths): Strengthens continuous authentication by controlling session lengths and automatically revoking sessions based on inactivity or policy violations, ensuring constant identity verification. By limiting session lifetimes and enforcing strict session policies, Mattermost mitigates the risk of stolen session tokens or extended unauthorized access. +- [Single Sign-On (SSO)](/administration-guide/onboard/sso-saml) [Enterprise] — Supports SAML 2.0, and OpenID Connect with Okta, Microsoft ADFS, Entra ID, OneLogin, and GitLab. User accounts and attributes are created and synchronized automatically on first login, eliminating locally managed credentials. +- [AD/LDAP User Sync](/administration-guide/onboard/ad-ldap) [Enterprise] — Continuously synchronizes user attributes and group memberships from Active Directory or LDAP. When a user is disabled in the directory, their Mattermost access is revoked automatically on the next sync cycle. +- [Role-Based Granular Access Controls](/administration-guide/onboard/advanced-permissions) [Enterprise] — Defines System, Team, and Channel Admin roles with fine-grained permission scopes. Roles can be synchronized from AD/LDAP and updated automatically, keeping permissions current with organizational policy. +- [Multifactor Authentication (MFA)](/administration-guide/onboard/multi-factor-authentication) [Enterprise] — TOTP-based second factor compatible with Google Authenticator, Microsoft Authenticator, and FreeOTP. Admins can enforce MFA across all users or delegate enforcement to the identity provider. +- [Session Management](/administration-guide/configure/environment-configuration-settings#session-lengths) [Enterprise] — Controls session lifetimes and revokes sessions on inactivity or policy violation, limiting the window of exposure from stolen tokens. +- [Custom Profile Attributes](/administration-guide/manage/admin/user-attributes) [Enterprise] — Admin-managed user metadata (clearance level, program affiliation, location, role) displayed on profiles and available for use in access policy definitions. +- [Guest Accounts](/administration-guide/onboard/guest-accounts) [Enterprise] — External users receive scoped access limited to specific channels. Single-channel guests are free up to a 1:1 ratio with licensed seats. Guests cannot discover other channels or teams. +- [Magic Link for Guests](/administration-guide/onboard/guest-accounts) [Enterprise] — Passwordless, expiring access links for external users eliminate shared credential risk. Links expire after 48 hours; guests can request a new link with the same email address. -Authorized users can seamlessly be added and removed from channels utilizing the native AD/LDAP integration based on group memberships: +### Advanced: attribute-based and session-scoped access -- [LDAP Synchronized User Groups](/administration-guide/onboard/ad-ldap-groups-synchronization): Automates user management and access control by dynamically syncing with organizational directories to minimize risks and enforce policies. +As organizations mature, role-based controls give way to attribute-based policies that adapt to the user's current context—not their role at the time they were provisioned. -## Continuous monitoring +- [Advanced Access Controls](/administration-guide/manage/admin/attribute-based-access-control) [Enterprise Advanced] — Combines RBAC system and team override schemes with CEL-syntax Attribute-Based Access Control (ABAC) for complex, context-sensitive authorization decisions. +- [ABAC for Team Admins](/administration-guide/manage/admin/abac-team-channel-policies) [Enterprise Advanced] — Channel membership policies are evaluated continuously against user attributes. As a user's profile changes (e.g., program affiliation, clearance level), they are automatically added to matching channels without admin intervention. On private channels, members who no longer match are removed. On public channels the policy is advisory — no one is removed, and matching channels are surfaced as recommendations. +- [Team membership access policies](/administration-guide/manage/admin/abac-team-membership) [Enterprise Advanced] — From Mattermost v11.10, the same continuous evaluation applies at the team boundary. On private teams, users who no longer match are removed from the team and its channels; on public teams the policy is advisory and highlights the team to qualifying users. -Mattermost offers tools for monitoring activity, identifying suspicious behavior, session management, and real-time incident response. Audit trails and performance monitoring ensure the proactive detection of potential issues or breaches, delivering visibility into the activity across the platform. +### Optimal: continuous, dynamic enforcement synchronized from ICAM -- [Audit Logging](/administration-guide/manage/logging): Tracks detailed activity logs for monitoring and identifying real-time anomaly-detection use cases, such as detecting anomalous behavior from compromised accounts or insider threats, or responding to unusual file-sharing activity within sensitive channels. -- [SIEM Integrations](https://developers.mattermost.com/integrate/webhooks/): Streamlines monitoring within existing security systems to detect and respond to lateral movement threats or policy violations consistently. -- [Performance Monitoring](/administration-guide/scale/deploy-prometheus-grafana-for-performance-monitoring): Protects against potential threats by analyzing system and user behaviors via proactive monitoring. +At the highest maturity level, access is evaluated in real time against authoritative sources, and no trust is assumed to persist between sessions. -## Deployment and host control +- [Dynamic Attribute-Based Access Controls](/administration-guide/manage/admin/abac-system-wide-policies) [Enterprise Advanced] — Eliminates manual role management by enforcing access based on attributes synchronized from multiple authoritative sources. Policies evaluate clearance level, program affiliation, device type, and network location dynamically. +- [User Authoritative Source Interface](/administration-guide/manage/admin/attribute-based-access-control) [Enterprise Advanced] — For government organizations using a secure User Authoritative Source system, this interface queries individual clearances on demand rather than storing them locally. Clearances are evaluated at access time for real-time Zero Trust policy enforcement. -Flexibility and control to host Mattermost securely to minimize the risk of vulnerabilities, downtime, and unauthorized modifications by ensuring secure, efficient, and reliable deployment of applications while maintaining strict control over the hosting environment. +## Devices -Mattermost's self-hosting enables tailored configurations for on-premises systems with specialized security needs, while cloud IP filtering ensures scalable control for remote or hybrid teams operating across distributed environments: +Zero Trust requires that device health be a factor in every access decision. Mattermost's mobile and endpoint security features ensure that only compliant, uncompromised devices can reach sensitive data. -- [Self-hosting Mattermost](/deployment-guide/deployment-guide-index): Enforces stricter data sovereignty requirements, and complete control over deployment environments, enabling organizations to implement custom Zero Trust security measures. -- [Cloud IP Filtering](/administration-guide/manage/cloud-ip-filtering): Prevents untrusted entities from gaining initial access, restricting platform access to trusted network ranges, enforcing an evaluation of every connection. +### Foundation: managed device deployment -## Encryption +- [Enterprise Mobility Management (AppConfig)](/deployment-guide/mobile/deploy-mobile-apps-using-emm-provider) [Enterprise] — Deploy the Mattermost mobile app via any EMM provider using the AppConfig standard. Pre-configure server URLs, authentication settings, and data protection policies including AppTunnel, app-level encryption, and backup prevention—without requiring full device enrollment. +- [Private Mobility with ID-Only Push Notifications](/deployment-guide/mobile/host-your-own-push-proxy-service) [Enterprise] — Replaces notification text with an opaque message ID. The mobile app retrieves the full notification content directly from your Mattermost server over an encrypted connection. Apple and Google notification infrastructure never sees message content. -Encryption protects both data at rest and data in transit, ensuring end-to-end security for sensitive communications. Encryption mitigates the risk of data theft in both storage and transfer, while granular permissions limit access to sensitive files and data to only authorized users. +### Advanced: device posture enforcement -- [Database Encryption](/deployment-guide/encryption-options#database): Protects user and organizational data at rest, safeguarding sensitive information from unauthorized access. -- [Transport Layer Security (TLS) Encryption](/deployment-guide/encryption-options#encryption-in-transit): Secures data in transit by encrypting communications. -- [Policy Enforcement](/deployment-guide/encryption-options#file-storage): Ensures strict compliance through automated enforcement, protecting data integrity. +- [Mobile Biometrics](/security-guide/mobile-security#biometric-authentication) [Enterprise Advanced] — Requires biometric authentication (Face ID or fingerprint) via the device OS at each app launch. Administrators can enforce this requirement, adding a hardware-anchored second factor that cannot be bypassed at the software level. +- [Intune MAM for iOS](/deployment-guide/mobile/configure-microsoft-intune-mam) [Enterprise Advanced] — Applies Microsoft Intune App Protection Policies to the Mattermost iOS app with identity-based controls, without requiring full device enrollment. Prevents data leakage between work and personal apps. -## Micro-segmentation +### Optimal: real-time device integrity verification -Segmenting and isolating sensitive resources is vital in minimizing lateral movement during an attack. Mattermost supports micro-segmentation through its organizational and role-based capabilities. Micro-segmentation enables organizations to restrict access to sensitive conversations, ensuring secure communication channels tailored to individual teams or missions. +- [Mobile Jailbreak / Root Detection](/security-guide/mobile-security#jailbreak-and-root-detection) [Enterprise Advanced] — Detects jailbroken iOS and rooted Android devices at runtime and blocks access automatically. Access from tampered devices is denied regardless of valid credentials. +- [Mobile Data-at-Rest Encryption](/deployment-guide/mobile/mobile-security-features#mobile-data-isolation) [Enterprise Advanced] — Mandatory OS-level encryption using Apple iOS and Android native security architecture. Data is confined to the app's private sandboxed storage container. Users cannot disable this protection. +- [Mobile Screenshot Prevention](/security-guide/mobile-security#screenshot-and-screen-recording-prevention) [Enterprise Advanced] — Blocks screenshots and screen recordings on the Mattermost mobile app. Enforceable by administrators via mobile security policies. +- [Secure File Viewer (Mobile)](/deployment-guide/mobile/secure-mobile-file-storage) [Enterprise Advanced] — Allows users to view PDFs, images, and videos without downloading files to the device. Sensitive and classified documents remain under organizational control at all times. -To achieve comprehensive micro-segmentation, the following areas of Mattermost functionality play a critical role. +## Networks -### Access control and permissions +Zero Trust treats every network as hostile. Mattermost supports deployment models that eliminate implicit trust in network location—from air-gapped installations to federated cross-organizational connectivity over hardened channels. -Ensure precise and role-based access to sensitive resources in order to minimize the risk of unauthorized access and potential data breaches: +### Foundation: self-hosted and encrypted transport -- [Advanced Access Controls](/administration-guide/manage/team-channel-members#advanced-access-controls): Enforces specific permissions configurations to restrict access based on roles. -- [Playbook-Specific Permissions](/end-user-guide/workflow-automation/share-and-collaborate): Controls access to sensitive workflows, ensuring resources are available only to authorized team members. +- [Self-Hosting Mattermost](/deployment-guide/deployment-guide-index) [Enterprise] — Complete data sovereignty with no dependence on public cloud infrastructure. Administrators retain full control over network placement, access controls, and configuration. +- [Transport Layer Security (TLS)](/deployment-guide/encryption-options#encryption-in-transit) [Enterprise] — All data in transit is encrypted. TLS configuration is documented for both direct server deployments and NGINX proxy deployments. +- [Cloud IP Filtering](/administration-guide/manage/cloud-ip-filtering) [Enterprise] — Restricts platform access to trusted network ranges for cloud deployments, ensuring every inbound connection is evaluated against an allowlist. -### Organizational design and user management +### Advanced: resilient, distributed, and isolated deployment -Establish a structured and scalable framework for managing user identities, roles, and access workflows to ensure accountability, facilitate collaboration, and enforce security policies: +- [High Availability Cluster-Based Deployment](/deployment-guide/reference-architecture/scale/high-availability-cluster-based-deployment) [Enterprise] — Multiple redundant application servers, database servers, and load balancers ensure no single point of failure. Supports inter-node state synchronization and HA for WebSocket connections. +- [Horizontal Scalability Architecture](/deployment-guide/reference-architecture/scale/scaling-for-enterprise) [Enterprise] — Stateless application nodes scale horizontally. Reference architectures support 5K, 10K, 25K, and 50K+ concurrent users. Load balancer distributes traffic across nodes transparently. +- [Supported Kubernetes Deployment](/deployment-guide/server/deploy-kubernetes) [Enterprise] — Production deployments on EKS, AKS, GKE, and DigitalOcean Kubernetes using the Mattermost Kubernetes Operator and Helm. Enables declarative, auditable infrastructure configuration. +- [Air-Gapped & DDIL/CDO-L Environments](/deployment-guide/reference-architecture/deployment-scenarios/air-gapped-deployment) [Enterprise] — Offline installation packages, private container registries, and Kubernetes-based orchestration for fully disconnected or intermittent-connectivity environments. Integrates with on-premises LDAP, PostgreSQL, and Elasticsearch with no internet dependency. +- [Air-Gapped Deployment](/deployment-guide/reference-architecture/deployment-scenarios/air-gapped-deployment) [Enterprise] — Engineered for Amazon GovCloud, Azure Government Cloud (including IL5), and Oracle AGC. Supports classified government networks and U.S. federal defense agency requirements. +- [Offline Operation and Smart Resync](/deployment-guide/reference-architecture/deployment-scenarios/deploy-ddil-operations) [Enterprise] — Local collaboration continues when network connectivity is unavailable. All messages and updates are automatically synchronized once connectivity is restored, with zero data loss. +- [Shared Channels (Federated)](/administration-guide/onboard/connected-workspaces) [Enterprise] — Real-time message and file synchronization across separate Mattermost servers over HTTPS/VPN. Enables controlled inter-organizational information flow without merging identity namespaces. +- [Federated Communications](/administration-guide/onboard/connected-workspaces) [Enterprise] — Cross-organizational workflows via connected workspaces and Matrix/XMPP bridge support for legacy system integration. -- [Teams](/end-user-guide/collaborate/organize-using-teams): Enables segmentation of access and collaboration, fostering compartmentalization and limiting exposure to unauthorized users. -- [Private Channels](/end-user-guide/collaborate/channel-types#private-channels): Restricts conversations to authorized participants, protecting sensitive data and adhering to need-to-know principles. -- [Guest Accounts](/administration-guide/onboard/guest-accounts): Enables secure, scoped access for external parties, ensuring least privilege principles are maintained. -- [Custom User Groups](/end-user-guide/collaborate/organize-using-custom-user-groups): Allows precise administrative control of access and permissions for specific user sets, enhancing access segmentation. +### Optimal: micro-segmented access with dynamic policy enforcement -### Administrative controls +- [Zero Trust Channel Access](/administration-guide/manage/admin/abac-channel-access-rules) [Enterprise Advanced] — Administrators configure channel-level access policies using Common Expression Language (CEL) or a graphical interface. Access decisions evaluate credentials, clearances, device posture, network attributes, and environmental data at entry time. +- [Mission Partner Environments](/deployment-guide/reference-architecture/deployment-scenarios/deploy-mission-partner) [Enterprise Advanced] — Designed for multi-national and multi-domain operations. External partner users receive guest accounts with least-privilege access. DMZ deployment topology supports external federation with defense-in-depth architecture. +- [Ultra-High Resiliency](/deployment-guide/reference-architecture/scale/scale-to-200000-users) [Enterprise Advanced] — Supports up to 200,000 concurrent users via high-availability cluster architecture with dedicated Redis write-through caching and zero-downtime upgrades. Designed for operational continuity in DDIL and mission partner environments. +- [DDIL Microsoft Teams App](/integrations-guide/mattermost-mission-collaboration-for-m365) [Enterprise] — When Microsoft Teams is inaccessible in a DDIL environment, the embedded Mattermost experience within Teams and Outlook clients maintains workflow continuity independently. -Enforce logical segmentation through team-level and group-level management, enhancing productivity and security by aligning user access with their specific roles: +## Applications and Workloads -- [Delegated Granular Administration](/administration-guide/onboard/delegated-granular-administration): Ensures operational security by enabling controlled management access based on responsibilities. -- [Custom Terms of Service](/administration-guide/comply/custom-terms-of-service): Requires users to acknowledge organization-specific Terms of Service before access ensures alignment with security policies and strengthens compliance, particularly in regulated industries where custom terms may reflect specific mandates. -- [Granular Permissions](/administration-guide/onboard/delegated-granular-administration): Facilitates precise control over user and system permissions, adhering to the principle of least privilege. -- [Read-Only Permissions for Files](/administration-guide/configure/site-configuration-settings#file-sharing-and-downloads): Limits file-sharing capabilities to safeguard sensitive information from unauthorized alterations. +Zero Trust requires that applications verify every request, integrate security testing into their lifecycle, and enforce controls at the application layer rather than relying on network perimeter protections. -### Security policies and tokens +### Foundation: access-controlled applications and integrations -Enhance security with tailored authentication tools to protect systems and data from unauthorized API usage and credential misuse by establishing and enforcing secure, consistent, and scalable authentication mechanisms: +- [Advanced Permissions Infrastructure](/administration-guide/onboard/advanced-permissions-backend-infrastructure) [Enterprise] — System-wide and team-override permission schemes control create, read, update, and delete capabilities per resource type. Channel-level controls restrict posting, reactions, and member management independently. +- [ABAC for File Permissions](/administration-guide/manage/admin/attribute-based-access-control) [Enterprise Advanced] — Granular rules governing whether a user can upload or download files based on their user and channel attributes. Enforces data handling policies at the application layer without relying on file system permissions. +- [Anonymous ID-Based URLs](/administration-guide/configure/site-configuration-settings) [Enterprise] — Team and channel URLs use random identifiers, preventing team and channel names from being enumerated via shared links. +- [Agent Control Plane](/administration-guide/configure/agents-admin-guide) [Enterprise] — Security boundaries for AI integration defined by user and channel. Tool integrations are restricted to direct messages by default. Explicit user approval is required before any AI agent executes an action. +- [Tool Policy Editor](/administration-guide/configure/agents-admin-guide) [Enterprise] — Admins configure which AI tools require approval based on context (DM vs. channel) and can disable specific tools entirely. Provides centralized, auditable control over AI-assisted workflows. -- [Personal Access Tokens](https://developers.mattermost.com/integrate/reference/personal-access-token/): Enables secure API access with identity verification aligned to least privilege. +### Advanced: automated, monitored, and security-tested workflows -## Multi-factor authentication (MFA) +- [Collaborative Playbooks](/end-user-guide/workflow-automation/work-with-playbooks) [Enterprise] — Structured, automated workflows with configurable task checklists, trigger conditions, and approval gates. Provides a complete audit log of all user actions within each playbook run. +- [Conditional Workflows](/end-user-guide/workflow-automation/work-with-tasks) [Enterprise] — Tasks are conditionally included based on attribute values and runtime conditions (e.g., severity, category, ticket ID). Consolidates compliance documentation into a single workflow run with full audit trail. +- [STIG-Hardened Image](/deployment-guide/server/deploy-containers) [Enterprise] — DISA-approved STIG-hardened configuration per DoD Security Technical Implementation Guide standards. Rigorous vulnerability scanning of base images. Required for DoD Information Assurance and IA-enabled systems. +- [FIPS 140-3 Compliant](/deployment-guide/server/containers/fips-stig) [Enterprise] — FIPS 140-3 validated cryptographic algorithms and modules. Available in a FIPS-validated container image for FedRAMP and NIST 800-53 compliance. Enforced at both build time and runtime. +- [CyberSecurity Toolchain Integrations](/use-case-guide/integrated-security-operations) [Enterprise] — Native integrations with Microsoft Sentinel, Defender, Entra ID, and Intune for real-time, out-of-band security collaboration. Deployable to segregated networks for SOC and red team operations. +- [Performance Monitoring](/administration-guide/scale/deploy-prometheus-grafana-for-performance-monitoring) [Enterprise] — Prometheus collects CPU, request latency, goroutine, and connection metrics. Pre-built Grafana dashboards for application, cluster, job server, and system-level visibility. Enables detection of anomalous behavior patterns in production environments. +- [Advanced Logging](/administration-guide/manage/logging) [Enterprise] — Error, panic, debug, trace, and conditional logging to Syslog and TCP destinations. Grafana Loki integration for centralized log aggregation across all servers. Supports compliance-grade audit requirements. -Mattermost supports MFA to strengthen authentication practices by adding an extra layer of protection for high-risk workflows beyond passwords: +### Optimal: classified information controls and immutable workloads -- [MFA](/administration-guide/onboard/multi-factor-authentication): Enhances user identity verification by requiring multiple factors for authentication. MFA ensures that unauthorized users are denied access even if passwords are compromised, reducing the risk of account breaches. +- [Classified and Sensitive Information Control](/administration-guide/manage/admin/content-flagging) [Enterprise Advanced] — Program-specific information labelling for channels. Visibility time limits on messages. Content flagging and moderation for spillage mitigation. Aligned with FIPS 140-3 and STIG-hardened deployment requirements. +- [Channel Banners](/end-user-guide/collaborate/display-channel-banners) [Enterprise Advanced] — Customizable per-channel classification notices with Markdown styling. Ensures users are continuously reminded of data handling requirements for sensitive, classified, or CUI channels, consistent with U.S. government notification mandates. +- [Critical Infrastructure Hardening](/deployment-guide/server/containers/fips-stig) [Enterprise Advanced] — Combines FIPS 140-3 validated cryptography with STIG-hardened Chainguard base images for Docker and Kubernetes deployments. Rigorously scanned against DoD security standards. -Alternatively, often enforced through the identity provider (IDP). +## Data -## Data management +Zero Trust treats data protection as a continuous obligation—not a perimeter defense. Mattermost provides controls across the full data lifecycle: classification, retention, export, recovery, and cryptographic protection. -Data management directly addresses how sensitive information is managed, controlled, and safeguarded at every stage of the data lifecycle. Proper data retention practices ensure that data is not only securely stored but also that it is not retained longer than necessary, thereby reducing risks. +### Foundation: encryption and basic inventory -By retaining data only for the duration that it is needed and then securely disposing of it, the exposure to malicious activity or unauthorized access is significantly reduced. Even if attackers gain access, their exposure is minimized. The less data stored, the smaller the "footprint" for potential exploitation: +- [Database Encryption](/deployment-guide/encryption-options#encryption-at-rest) [Enterprise] — Protects user and organizational data at rest. Encryption configuration options are documented for PostgreSQL deployments. +- [Channel Export](/administration-guide/comply/export-mattermost-channel-data) [Enterprise] — Exports channel message data to CSV. Restricted to system, team, and channel admins. Provides an initial mechanism for data inventory and auditability. +- [Custom End-User Terms of Service](/administration-guide/comply/custom-terms-of-service) [Enterprise] — Enforces acceptance of organization-specific terms before platform access. Configurable re-acceptance periods ensure terms remain current and users are regularly reminded of data handling obligations. -- [Data Retention Policies](/administration-guide/comply/data-retention-policy): Enforces strict retention controls to reduce data exposure and help comply with governance standards. -- [Compliance Export](/administration-guide/comply/compliance-export): Ensures data portability for audit and compliance purposes in a secure and controlled manner. -- [Compliance Monitoring](/administration-guide/comply/compliance-monitoring): Offers visibility into adherence to security and compliance policies, supporting compliance mandates. -- [E-Discovery](/administration-guide/comply/electronic-discovery): Boosts organizational oversight by ensuring discoverability of stored data for legal and compliance audits under secure protocols. E-Discovery capabilities help organizations meet compliance expectations for legal audits under frameworks like GDPR or HIPAA without sacrificing secure collaboration workflows. -- [Archiving Inactive Teams or Channels](/administration-guide/manage/team-channel-members#archive-a-team) & [Unarchive Channels](/end-user-guide/collaborate/archive-unarchive-channels): Reduces the potential attack surface by securely deactivating and storing inactive resources, minimizing both live data exposure and the likelihood of exploitation. This approach ensures adherence to security best practices while maintaining the ability to securely restore resources if needed. +### Advanced: governed retention, eDiscovery, and sovereign AI -## Incident response +- [Data Retention Policies](/administration-guide/comply/data-retention-policy) [Enterprise] — Granular retention controls at the team and channel level. Reduces the data footprint available for exploitation. Supports compliance with data minimization requirements under GDPR, HIPAA, and other frameworks. +- [Legal Hold](/administration-guide/comply/legal-hold) [Enterprise] — Preserves all electronically stored information (ESI) for specified users and durations in anticipation of legal action. Can be combined with eDiscovery integration and retention policies for customized compliance posture. +- [Compliance Export and eDiscovery](/administration-guide/comply/compliance-export) [Enterprise] — Export to Actiance XML, Global Relay EML, or generic CSV. Reconstructs channel state and determines message visibility history. Supports Smarsh, Actiance Vantage, and Proofpoint integrations. +- [Compliance Monitoring](/administration-guide/comply/compliance-monitoring) [Enterprise] — Ongoing visibility into adherence to security and compliance policies. +- [Sovereign AI](/agents/docs/sovereign_ai) [Enterprise] — Fully self-hosted LLM integration with pgvector for semantic search. Complete organizational control over AI data processing and infrastructure. Compatible with air-gapped and disconnected environments; no data leaves the organization's control. +- [Advanced Logging](/administration-guide/manage/logging) [Enterprise] — Trace-level audit logs to Syslog and TCP targets. Enables compliance with stringent operational and security audit standards across multi-server deployments. -Incident response ensures that organizations can effectively detect, investigate, and respond to security threats within a framework that assumes no entity, whether inside or outside the network, should be trusted by default. Incident response is the operational arm that ensures that organizations are vigilant, prepared, and capable of protecting themselves in a dynamic and evolving threat landscape. +### Optimal: classified data controls, spillage handling, and cryptographic enforcement -Mattermost Playbooks reduce the time to respond to threats and ensure compliancy-aligned documentation through automated incident notifications by empowering organizations to predefine and automate incident response workflows, ensuring that responses are consistent, documented, and transparent: +- [Data Spillage Handling](/administration-guide/manage/admin/content-flagging) [Enterprise Advanced] — Any user can flag potentially sensitive content, and designated reviewers are notified with context. Depending on the configured workflow, flagged content can be hidden while under review. After review, content can be retained or permanently deleted. +- [Burn-on-Read Messages](/administration-guide/configure/site-configuration-settings#enable-burn-on-read-messages) [Enterprise Advanced] — Messages are concealed until recipients reveal them and are automatically deleted after a configurable timer expires. Deletion is permanent and prevents recovery. Senders can track read status and delete for all recipients before expiration. +- [FIPS 140-3 Compliant](/deployment-guide/server/containers/fips-stig) [Enterprise] — FIPS 140-3 validated cryptographic modules used throughout the product for all cryptographic operations. Satisfies NIST 800-53 standards for agencies processing sensitive, classified, or regulated data. +- [Mobile Data-at-Rest Encryption](/deployment-guide/mobile/mobile-security-features#mobile-data-isolation) [Enterprise Advanced] — Mandatory OS-level encryption on iOS and Android. Data stored in the app's private container cannot be accessed outside the sandboxed environment, even on a lost or stolen device. -- [Incident-Specific Channels for Secure Collaboration](/end-user-guide/workflow-automation/work-with-playbooks#actions): Maintains secure collaboration workflows across broader incident response workflows involving external tools, enforcing a centralized control model for operational continuity during incidents. Incident-specific channels reduce the time to assemble expert response teams, ensuring faster mitigation of active threats like phishing or ransomware attacks. -- [Automated Incident Notifications](/end-user-guide/workflow-automation/notifications-and-updates): Streamlines response workflows with authenticated alerts. - -Enhance learning from incidents, ensure historical accountability, reduce future attack surfaces, and meet compliance expectations by securely centralizing documentation to improve future response processes: - -- [Post-Incident Documentation](/end-user-guide/workflow-automation/metrics-and-goals): Enables secure storage and access for learnings, ensuring compliance with attack surface minimization principles. - -By embedding Zero Trust principles across access, monitoring, data management, and incident response, Mattermost equips organizations with the tools needed to safeguard collaboration workflows in today's evolving threat landscape. - -Discover how Mattermost can transform your Zero Trust strategy today. Book a live demo with a [Mattermost Zero Trust Expert](https://mattermost.com/contact-sales/) to explore tailored solutions for your organization’s secure collaboration needs. +## Progressing through Zero Trust maturity + +No organization starts at Optimal maturity, and no single product delivers Zero Trust in isolation. Mattermost is designed to meet organizations at their current maturity level and provide a concrete capability path forward. + + + + + + + + + + + + + + + + + + + + + + + + + + +
Maturity LevelWhat Mattermost enables
TraditionalMFA, SSO, guest accounts, role-based access, basic audit logging, and TLS encryption. A secure collaboration baseline without implicit perimeter trust.
InitialAD/LDAP sync, RBAC with team override schemes, EMM mobile deployment, air-gapped and Kubernetes deployment, advanced logging, and compliance export. Automated access lifecycle with formal integration into security operations.
AdvancedABAC with CEL syntax, HA cluster deployment, FIPS 140-3, STIG-hardened images, sovereign AI, legal hold, playbook-driven incident response, biometric mobile authentication, and federated cross-org channels. Context-aware access with security testing integrated throughout the deployment lifecycle.
OptimalDynamic ABAC with ICAM sync, Zero Trust channel access policies, User Authoritative Source integration, data spillage handling, burn-on-read messages, classified channel controls, and full mobile security hardening. Continuous, attribute-driven enforcement with no implicit trust at any layer.
+ +## Related resources + +- [Set up attribute-based access controls](/administration-guide/manage/admin/attribute-based-access-control) +- [Mobile security features](/deployment-guide/mobile/mobile-security-features) +- [Air-gapped deployment](/deployment-guide/reference-architecture/deployment-scenarios/air-gapped-deployment) +- [Compliance export](/administration-guide/comply/compliance-export) +- [FIPS 140-3 and encryption options](/deployment-guide/server/containers/fips-stig) +- [STIG-hardened image and DoD IA standards](/deployment-guide/server/deploy-containers) +- [High availability cluster deployment](/deployment-guide/reference-architecture/scale/high-availability-cluster-based-deployment) +- [Sovereign AI implementation](/agents/docs/sovereign_ai) +- [Content flagging and data spillage](/administration-guide/manage/admin/content-flagging) +- [CMMC Compliance](/security-guide/cmmc-compliance) +- [Mobile Security](/security-guide/mobile-security) + +To explore how Mattermost can support your organization's Zero Trust strategy, [contact a Mattermost Zero Trust Expert](https://mattermost.com/contact-sales/). diff --git a/docs/site/.gitignore b/docs/site/.gitignore index b9846fb3465d..55f21e43ed6a 100644 --- a/docs/site/.gitignore +++ b/docs/site/.gitignore @@ -9,6 +9,11 @@ .cache-loader sidebars/documentation.generated.json sidebars/developers.generated.json +data/plugin-godocs.json +data/plugin-godocs.json.tmp +data/plugin-jsdocs.json +data/plugin-manifest-docs.json +data/plugin-manifest-docs.json.tmp # Misc .DS_Store diff --git a/docs/site/README.md b/docs/site/README.md index 340d9a4eb84d..0ce1a8f56086 100644 --- a/docs/site/README.md +++ b/docs/site/README.md @@ -18,7 +18,8 @@ via the relative paths `../main`, `../develop`, `../api` (from `docs/site/`). ## Prerequisites - Node.js ≥ 20 — use `nvm use` inside `docs/site/` to pick up `.nvmrc` -- Go and `make` (required only for the OpenAPI prebuild step — see below) +- Go and `make` (required for the OpenAPI prebuild step, and for two of the three plugin SDK + reference generators — see below) - Vale ≥ 3 (for content linting) ## Local development @@ -141,6 +142,24 @@ behavior: it stages `admin_guide.md`/`user_guide.md` as normal (but show the full vendored guide content directly, with zero extra clicks, instead of just linking out to a separate page. +### Plugin SDK reference generators + +Three developer pages render content generated at build time from the plugin SDK's own source +rather than hand-written prose, each backed by a gitignored JSON file under `data/`: + +| Page | Generator | Reads | +|---|---|---| +| [Server plugin SDK reference](/developers/integrate/reference/server) | `scripts/gen-plugin-godocs` (Go) | `server/public/plugin` | +| [Web app plugin SDK reference](/developers/integrate/reference/webapp) | `scripts/gen-plugin-jsdocs.mjs` (Node) | `webapp/channels/src/plugins/registry.ts` | +| [Manifest reference](/developers/integrate/plugins/manifest-reference) | `scripts/gen-plugin-manifest-docs` (Go) | `server/public/model`'s `Manifest` struct | + +They're consumed by the ``, ``, ``, and +`` components (registered globally in `src/theme/MDXComponents.tsx`), and run +via `npm run build:plugin-docs`, wired into `prestart`/`prebuild` like everything else in this +section. The two Go generators parse their target packages with `go/parser` + `go/doc` rather than +type-checking them via `golang.org/x/tools/go/packages`, so they have no dependency on the Go +toolchain version declared in `server/public/go.mod` — only stdlib, no `go.sum`. + The API reference section (`docs/api/reference/`, also gitignored) has the same requirement: `docusaurus-plugin-openapi-docs` needs `docusaurus gen-api-docs mattermost` run before it has any pages to render. `prestart` @@ -197,6 +216,7 @@ shell before running `npm start`/`npm run build`. | `npm run build:openapi:spec` | Regenerate the OpenAPI spec only (slow — invokes `make -C api build`) | | `npm run build:openapi:docs` | Regenerate the API reference MDX pages from the existing spec (fast) | | `npm run build:openapi` | Full OpenAPI pipeline: spec then docs | +| `npm run build:plugin-docs` | Regenerate all three plugin SDK reference data files (see above) | | `npm run serve` | Serve the `build/` output locally | | `npm run typecheck` | TypeScript type check | | `node scripts/gen-active-redirects.mjs` | Regenerate legacy redirect map (committed to git; run manually when it changes) | diff --git a/docs/site/package-lock.json b/docs/site/package-lock.json index 0f1eb9e04361..e64cc88f1fb4 100644 --- a/docs/site/package-lock.json +++ b/docs/site/package-lock.json @@ -27,6 +27,7 @@ "@docusaurus/tsconfig": "3.10.1", "@docusaurus/types": "3.10.1", "@types/react": "^19.0.0", + "@typescript-eslint/typescript-estree": "^8.67.0", "typescript": "~6.0.2" }, "engines": { @@ -7256,6 +7257,144 @@ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", "license": "MIT" }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.67.0.tgz", + "integrity": "sha512-cvE8c7ulYeXN9fYuszhCeCsbzyVEXuhrRCybnBre7TUmqb5nRmBfQAwCj0O3WJFDeyAZt4VYv51vMCC9LHSdYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.67.0", + "@typescript-eslint/types": "^8.67.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.67.0.tgz", + "integrity": "sha512-vV+LUSv5njUWsknE71fqKTlXUva+R76SaeORd6Zojcunk/6DvKFXONU3BrAs2H49mbygUXt6gbYunzwqNwlhdg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.67.0.tgz", + "integrity": "sha512-sBtgslww8nsMYUjhdPBiSyUqSzT8uR6g93A2QXnQC8+cGdjz0CyaOdqHDRJb1AtORbZCNUJBBeFA/tNR2uQmww==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.67.0.tgz", + "integrity": "sha512-EKQBCE9yNlRJYm7jdTW5AhDacDUmSwQb0FAJAmK2EKYrNXIsa2vxcSZx6PvJ/dEdI6lS+Y9W+EXckLj0iPFGcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.67.0", + "@typescript-eslint/tsconfig-utils": "8.67.0", + "@typescript-eslint/types": "8.67.0", + "@typescript-eslint/visitor-keys": "8.67.0", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.8" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.67.0.tgz", + "integrity": "sha512-fkv8dHRDqfGtTHuJeebdrQ7cX6Ad4WAS00rgHh9UGvMycF1mjBfsxry1XsLIFhWZ6Judlh6UdzK+TYlbpCXgnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.67.0", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@ungap/structured-clone": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.1.tgz", @@ -10791,6 +10930,19 @@ "node": ">=8.0.0" } }, + "node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -21356,6 +21508,19 @@ "integrity": "sha512-kloPhf1hq3JbCPOTYoOWDKxebWjNb2o/LKnNfkWhxVVisFFmMJPPdJeGoGmM+iRLyoXAR61e08Pb+vUXINg8aA==", "license": "MIT" }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, "node_modules/ts-dedent": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.3.0.tgz", diff --git a/docs/site/package.json b/docs/site/package.json index 3e9f47f19bb8..ea1585c3de37 100644 --- a/docs/site/package.json +++ b/docs/site/package.json @@ -11,8 +11,12 @@ "build:openapi:spec": "node scripts/build-openapi.mjs", "build:openapi:docs": "docusaurus gen-api-docs mattermost", "build:openapi": "npm run build:openapi:spec && npm run build:openapi:docs", - "prestart": "npm run stage:agents-docs && npm run build:sidebars && ( [ -f openapi/mattermost-openapi-v4.yaml ] || npm run build:openapi:spec ) && npm run build:openapi:docs", - "prebuild": "npm run stage:agents-docs && npm run build:sidebars && npm run build:openapi", + "build:plugin-godocs": "mkdir -p data && go run -C scripts/gen-plugin-godocs . > data/plugin-godocs.json.tmp && mv data/plugin-godocs.json.tmp data/plugin-godocs.json", + "build:plugin-jsdocs": "node scripts/gen-plugin-jsdocs.mjs", + "build:plugin-manifest-docs": "mkdir -p data && go run -C scripts/gen-plugin-manifest-docs . > data/plugin-manifest-docs.json.tmp && mv data/plugin-manifest-docs.json.tmp data/plugin-manifest-docs.json", + "build:plugin-docs": "npm run build:plugin-godocs && npm run build:plugin-jsdocs && npm run build:plugin-manifest-docs", + "prestart": "npm run stage:agents-docs && npm run build:sidebars && ( [ -f openapi/mattermost-openapi-v4.yaml ] || npm run build:openapi:spec ) && npm run build:openapi:docs && npm run build:plugin-docs", + "prebuild": "npm run stage:agents-docs && npm run build:sidebars && npm run build:openapi && npm run build:plugin-docs", "swizzle": "docusaurus swizzle", "deploy": "docusaurus deploy", "clear": "docusaurus clear", @@ -41,6 +45,7 @@ "@docusaurus/tsconfig": "3.10.1", "@docusaurus/types": "3.10.1", "@types/react": "^19.0.0", + "@typescript-eslint/typescript-estree": "^8.67.0", "typescript": "~6.0.2" }, "browserslist": { diff --git a/docs/site/scripts/gen-documentation-sidebar.mjs b/docs/site/scripts/gen-documentation-sidebar.mjs index c0d4a44a8bec..fcf2804fae4c 100644 --- a/docs/site/scripts/gen-documentation-sidebar.mjs +++ b/docs/site/scripts/gen-documentation-sidebar.mjs @@ -506,6 +506,7 @@ const ADMIN_MANAGE_GROUPS = { {label: 'Attribute-Based Access Control', landing: 'admin/attribute-based-access-control', items: [ 'admin/abac-system-wide-policies', 'admin/abac-team-channel-policies', + 'admin/abac-team-membership', 'admin/abac-channel-access-rules', ]}, ], @@ -594,7 +595,7 @@ const ADMIN_MANAGE_ORDER = [ const ADMIN_MANAGE_HIDDEN = new Set([ 'admin/user-management', 'admin/user-provisioning', 'admin/user-attributes', 'team-channel-members', 'admin/attribute-based-access-control', 'admin/abac-system-wide-policies', - 'admin/abac-team-channel-policies', 'admin/abac-channel-access-rules', + 'admin/abac-team-channel-policies', 'admin/abac-team-membership', 'admin/abac-channel-access-rules', 'admin/server-configuration', 'admin/server-maintenance', 'code-signing-custom-builds', 'command-line-tools', 'mmctl-command-line-tool', 'admin/monitoring-and-performance', 'statistics', 'telemetry', @@ -809,6 +810,7 @@ const ADMIN_ONBOARD_GROUPS = { landing: 'migrating-to-mattermost', items: [ 'migrate-from-slack', + 'migrate-from-rocketchat', 'migrate-gitlab-omnibus', 'migration-announcement-email', ], @@ -840,7 +842,7 @@ const ADMIN_ONBOARD_HIDDEN = new Set([ 'guest-accounts', 'delegated-granular-administration', 'advanced-permissions', 'advanced-permissions-backend-infrastructure', 'user-provisioning-workflows', 'bulk-loading-data', 'connected-workspaces', - 'migrating-to-mattermost', 'migrate-from-slack', 'migrate-gitlab-omnibus', + 'migrating-to-mattermost', 'migrate-from-slack', 'migrate-from-rocketchat', 'migrate-gitlab-omnibus', 'migration-announcement-email', ]); diff --git a/docs/site/scripts/gen-plugin-godocs/go.mod b/docs/site/scripts/gen-plugin-godocs/go.mod new file mode 100644 index 000000000000..7484b4613710 --- /dev/null +++ b/docs/site/scripts/gen-plugin-godocs/go.mod @@ -0,0 +1,3 @@ +module github.com/mattermost/mattermost/docs/site/scripts/gen-plugin-godocs + +go 1.26 diff --git a/docs/site/scripts/gen-plugin-godocs/main.go b/docs/site/scripts/gen-plugin-godocs/main.go new file mode 100644 index 000000000000..242f7e88d890 --- /dev/null +++ b/docs/site/scripts/gen-plugin-godocs/main.go @@ -0,0 +1,324 @@ +// Command gen-plugin-godocs generates docs/site/data/plugin-godocs.json, the data source consumed +// by the and React components that render the server plugin +// SDK reference (docs/develop/integrate/reference/server/index.md). +// +// It reads the server/public/plugin package directly from this monorepo. It deliberately parses +// the package with go/parser + go/doc rather than type-checking it via golang.org/x/tools/go/packages, +// so it has no dependency on the Go toolchain version required by server/public/go.mod (the docs +// site's build environment may lag behind it). +package main + +import ( + "bytes" + "encoding/json" + "fmt" + "go/ast" + "go/doc" + "go/parser" + "go/printer" + "go/token" + "log" + "os" + "path/filepath" + "regexp" + "runtime" + "sort" + "strings" +) + +const pluginImportPath = "github.com/mattermost/mattermost/server/public/plugin" + +type Field struct { + Names []string `json:"Names,omitempty"` + Type string +} + +type MethodDocs struct { + Name string + Tags []string `json:"Tags,omitempty"` + HTML string + Parameters []*Field `json:"Parameters,omitempty"` + Results []*Field `json:"Results,omitempty"` +} + +type InterfaceDocs struct { + HTML string + Tags []string `json:"Tags,omitempty"` + Methods []*MethodDocs +} + +type ExampleDocs struct { + HTML string + Code string +} + +type Docs struct { + HTML string + API InterfaceDocs + Hooks InterfaceDocs + Helpers InterfaceDocs + Examples map[string]*ExampleDocs +} + +func pluginPackageDir() string { + _, thisFile, _, ok := runtime.Caller(0) + if !ok { + log.Fatal("unable to determine source file location") + } + repoRoot := filepath.Clean(filepath.Join(filepath.Dir(thisFile), "..", "..", "..", "..")) + return filepath.Join(repoRoot, "server", "public", "plugin") +} + +func docHTML(text string) string { + buf := &bytes.Buffer{} + doc.ToHTML(buf, text, nil) + return buf.String() +} + +func removeDuplicates(items []string) []string { + seen := make(map[string]bool, len(items)) + out := make([]string, 0, len(items)) + for _, item := range items { + if !seen[item] { + seen[item] = true + out = append(out, item) + } + } + return out +} + +var tagRegexp = regexp.MustCompile(`@tag\s+(\w+)\s*`) + +func tags(text string) []string { + submatches := tagRegexp.FindAllStringSubmatch(text, -1) + out := make([]string, len(submatches)) + for i, submatch := range submatches { + out[i] = submatch[1] + } + return removeDuplicates(out) +} + +// builtinTypes is the set of predeclared Go types documented at https://pkg.go.dev/builtin. +var builtinTypes = map[string]bool{ + "bool": true, "byte": true, "complex128": true, "complex64": true, "error": true, + "float32": true, "float64": true, "int": true, "int16": true, "int32": true, "int64": true, + "int8": true, "rune": true, "string": true, "uint": true, "uint16": true, "uint32": true, + "uint64": true, "uint8": true, "uintptr": true, "any": true, +} + +// importAliases maps the local identifier a file uses for an imported package (its alias, or the +// last path segment when unaliased) to that package's full import path. +func importAliases(file *ast.File) map[string]string { + aliases := make(map[string]string) + for _, imp := range file.Imports { + path := strings.Trim(imp.Path.Value, `"`) + alias := path[strings.LastIndex(path, "/")+1:] + if imp.Name != nil { + alias = imp.Name.Name + } + aliases[alias] = path + } + return aliases +} + +// typeString renders a field's type expression as a dotted, fully-qualified string, e.g. +// "[]*github.com/mattermost/mattermost/server/public/model.Manifest", the same shape the old +// go/types-based generator produced. Types local to the plugin package are qualified with +// pluginImportPath so the renderer can link to them the same way it links to imported types. +func typeString(expr ast.Expr, aliases map[string]string) string { + switch x := expr.(type) { + case *ast.StarExpr: + return "*" + typeString(x.X, aliases) + case *ast.ArrayType: + return "[]" + typeString(x.Elt, aliases) + case *ast.Ellipsis: + return "[]" + typeString(x.Elt, aliases) + case *ast.MapType: + return "map[" + typeString(x.Key, aliases) + "]" + typeString(x.Value, aliases) + case *ast.ChanType: + return "chan " + typeString(x.Value, aliases) + case *ast.InterfaceType: + if x.Methods == nil || len(x.Methods.List) == 0 { + return "interface{}" + } + return "interface{ ... }" + case *ast.SelectorExpr: + pkgIdent, ok := x.X.(*ast.Ident) + if !ok { + return x.Sel.Name + } + if path, ok := aliases[pkgIdent.Name]; ok { + return path + "." + x.Sel.Name + } + return pkgIdent.Name + "." + x.Sel.Name + case *ast.Ident: + if builtinTypes[x.Name] || x.Name == "byte" || x.Name == "rune" { + return x.Name + } + // A bare identifier that isn't a builtin must refer to a type declared in this same + // package (plugin), since any imported type is always qualified with a selector. + return pluginImportPath + "." + x.Name + default: + buf := &bytes.Buffer{} + _ = printer.Fprint(buf, token.NewFileSet(), expr) + return buf.String() + } +} + +func fields(list *ast.FieldList, aliases map[string]string) (out []*Field) { + if list == nil { + return nil + } + for _, x := range list.List { + field := &Field{} + for _, name := range x.Names { + field.Names = append(field.Names, name.Name) + } + + t := typeString(x.Type, aliases) + if _, ok := x.Type.(*ast.Ellipsis); ok { + t = "..." + strings.TrimPrefix(t, "[]") + } + field.Type = t + + out = append(out, field) + } + return out +} + +func fileForPos(fset *token.FileSet, files map[string]*ast.File, pos token.Pos) *ast.File { + name := fset.Position(pos).Filename + return files[name] +} + +func generateDocs() (*Docs, error) { + pluginDir := pluginPackageDir() + + fset := token.NewFileSet() + pkgs, err := parser.ParseDir(fset, pluginDir, nil, parser.ParseComments) + if err != nil { + return nil, err + } + + docs := &Docs{ + Examples: make(map[string]*ExampleDocs), + } + + // Files keyed by absolute path, across both the "plugin" and "plugin_test" (external test) + // packages, so we can recover which file a given interface method came from and resolve its + // imports, and so examples defined in either package are picked up. + filesByPath := make(map[string]*ast.File) + var allFiles []*ast.File + for _, pkg := range pkgs { + for path, file := range pkg.Files { + filesByPath[path] = file + allFiles = append(allFiles, file) + } + } + + for _, example := range doc.Examples(allFiles...) { + // Play is a synthesized, standalone runnable program and is preferred when available; + // it's nil when go/doc can't build one (e.g. the example can't be wrapped as a whole + // program), in which case Code — the example function's body, always non-nil — is used + // instead. + var node ast.Node = example.Play + if example.Play == nil { + node = example.Code + } + + buf := &bytes.Buffer{} + if err := printer.Fprint(buf, fset, node); err != nil { + return nil, fmt.Errorf("failed to print example %q: %w", example.Name, err) + } + docs.Examples[example.Name] = &ExampleDocs{ + HTML: docHTML(example.Doc), + Code: buf.String(), + } + } + + pluginPkg, ok := pkgs["plugin"] + if !ok { + return nil, os.ErrNotExist + } + + godocs := doc.New(pluginPkg, pluginImportPath, doc.Mode(0)) + + if godocs.Name == "plugin" && godocs.Doc != "" { + docs.HTML = docHTML(godocs.Doc) + } + + for _, t := range godocs.Types { + var interfaceDocs *InterfaceDocs + switch t.Name { + case "API": + interfaceDocs = &docs.API + case "Hooks": + interfaceDocs = &docs.Hooks + case "Helpers": + interfaceDocs = &docs.Helpers + default: + continue + } + if t.Doc != "" { + interfaceDocs.HTML = docHTML(t.Doc) + } + + for _, spec := range t.Decl.Specs { + typeSpec, ok := spec.(*ast.TypeSpec) + if !ok { + continue + } + iface, ok := typeSpec.Type.(*ast.InterfaceType) + if !ok { + continue + } + + file := fileForPos(fset, filesByPath, typeSpec.Pos()) + var aliases map[string]string + if file != nil { + aliases = importAliases(file) + } + + allTags := make([]string, 0) + for _, method := range iface.Methods.List { + funcType, ok := method.Type.(*ast.FuncType) + if !ok || len(method.Names) == 0 { + continue + } + methodDocs := &MethodDocs{ + Name: method.Names[0].Name, + Tags: tags(method.Doc.Text()), + HTML: docHTML(method.Doc.Text()), + Parameters: fields(funcType.Params, aliases), + Results: fields(funcType.Results, aliases), + } + interfaceDocs.Methods = append(interfaceDocs.Methods, methodDocs) + allTags = append(allTags, methodDocs.Tags...) + } + allTags = removeDuplicates(allTags) + sort.Strings(allTags) + interfaceDocs.Tags = allTags + } + } + + return docs, nil +} + +func main() { + docs, err := generateDocs() + if err != nil { + log.Fatal(err) + } + + b, err := json.MarshalIndent(docs, "", " ") + if err != nil { + log.Fatal(err) + } + + if _, err := os.Stdout.Write(b); err != nil { + log.Fatal(err) + } + if _, err := os.Stdout.Write([]byte("\n")); err != nil { + log.Fatal(err) + } +} diff --git a/docs/site/scripts/gen-plugin-jsdocs.mjs b/docs/site/scripts/gen-plugin-jsdocs.mjs new file mode 100644 index 000000000000..73627cc69a3f --- /dev/null +++ b/docs/site/scripts/gen-plugin-jsdocs.mjs @@ -0,0 +1,113 @@ +#!/usr/bin/env node +// Generates docs/site/data/plugin-jsdocs.json, the data source consumed by the +// component that renders the web app plugin SDK reference +// (docs/develop/integrate/reference/webapp/index.md). +// +// Reads webapp/channels/src/plugins/registry.ts directly from this monorepo instead of fetching it +// from GitHub over HTTP. +// +// Usage: node scripts/gen-plugin-jsdocs.mjs (from docs/site/) + +import {parse} from '@typescript-eslint/typescript-estree'; +import {readFileSync, writeFileSync, mkdirSync} from 'node:fs'; +import {resolve, dirname} from 'node:path'; +import {fileURLToPath} from 'node:url'; + +const HERE = dirname(fileURLToPath(import.meta.url)); // docs/site/scripts +const SITE_ROOT = resolve(HERE, '..'); // docs/site +const REPO_ROOT = resolve(SITE_ROOT, '../..'); // mattermost/ +const REGISTRY_PATH = resolve(REPO_ROOT, 'webapp/channels/src/plugins/registry.ts'); +const OUT_PATH = resolve(SITE_ROOT, 'data/plugin-jsdocs.json'); + +function paramNamesFromPattern(pattern) { + if (pattern.type === 'Identifier') return [pattern.name]; + if (pattern.type === 'ObjectPattern') { + return pattern.properties.flatMap((prop) => (prop.type === 'Property' ? paramNamesFromPattern(prop.value) : paramNamesFromPattern(prop))); + } + if (pattern.type === 'ArrayPattern') { + return pattern.elements.flatMap((el) => (el ? paramNamesFromPattern(el) : [])); + } + if (pattern.type === 'AssignmentPattern') return paramNamesFromPattern(pattern.left); + if (pattern.type === 'RestElement') return paramNamesFromPattern(pattern.argument); + return []; +} + +// Comments attached to `node`: walk backward from its start, collecting comments as long as only +// whitespace separates them from each other and from the node. Node-scoped, so unlike a global +// "which comments sit on consecutive lines" pass, it can't attribute a comment to the wrong member. +function leadingComments(sourceText, comments, node) { + const attached = []; + let cursor = node.range[0]; + for (let i = comments.length - 1; i >= 0; i--) { + const comment = comments[i]; + if (comment.range[1] > cursor) continue; + if (!/^\s*$/.test(sourceText.slice(comment.range[1], cursor))) break; + attached.unshift(comment); + cursor = comment.range[0]; + } + return attached.flatMap((comment) => + comment.value + .split('\n') + .map((line) => line.replace(/^\s*\*\s?/, '').trimEnd()) + .filter((line) => line.length > 0), + ); +} + +// reArg(['name', ...], handler) documents its public parameter names explicitly in that array — +// that's the contract callers see, so prefer it over inferring names from the handler's own +// (possibly renamed or destructured) parameters. +function reArgParameterNames(callExpr) { + const [firstArg, ...rest] = callExpr.arguments; + if (callExpr.callee.type === 'Identifier' && callExpr.callee.name === 'reArg' && firstArg?.type === 'ArrayExpression') { + return firstArg.elements.filter((el) => el?.type === 'Literal' && typeof el.value === 'string').map((el) => el.value); + } + const handler = rest.find((arg) => arg.type === 'ArrowFunctionExpression' || arg.type === 'FunctionExpression'); + return handler ? handler.params.flatMap(paramNamesFromPattern) : []; +} + +function findPluginRegistryClass(program) { + return program.body.find( + (statement) => + statement.type === 'ExportDefaultDeclaration' && + statement.declaration.type === 'ClassDeclaration' && + statement.declaration.id?.name === 'PluginRegistry', + )?.declaration; +} + +function main() { + const sourceText = readFileSync(REGISTRY_PATH, 'utf8'); + const ast = parse(sourceText, {comment: true, range: true}); + + const classDecl = findPluginRegistryClass(ast); + if (!classDecl) { + throw new Error(`Could not find "export default class PluginRegistry" in ${REGISTRY_PATH}`); + } + + const methods = []; + for (const member of classDecl.body.body) { + if (member.key?.type !== 'Identifier') continue; + + let params; + if (member.type === 'MethodDefinition' && member.kind !== 'constructor') { + params = member.value.params.flatMap(paramNamesFromPattern); + } else if (member.type === 'PropertyDefinition' && member.value?.type === 'CallExpression') { + params = reArgParameterNames(member.value); + } else { + continue; + } + + methods.push({ + Name: member.key.name, + Parameters: params, + Comments: leadingComments(sourceText, ast.comments, member), + }); + } + + const output = {Interface: {Methods: methods}}; + + mkdirSync(dirname(OUT_PATH), {recursive: true}); + writeFileSync(OUT_PATH, JSON.stringify(output, null, 2)); + console.log(`[plugin-jsdocs] wrote ${methods.length} methods to ${OUT_PATH}`); +} + +main(); diff --git a/docs/site/scripts/gen-plugin-manifest-docs/go.mod b/docs/site/scripts/gen-plugin-manifest-docs/go.mod new file mode 100644 index 000000000000..d1e9658932d6 --- /dev/null +++ b/docs/site/scripts/gen-plugin-manifest-docs/go.mod @@ -0,0 +1,3 @@ +module github.com/mattermost/mattermost/docs/site/scripts/gen-plugin-manifest-docs + +go 1.26 diff --git a/docs/site/scripts/gen-plugin-manifest-docs/main.go b/docs/site/scripts/gen-plugin-manifest-docs/main.go new file mode 100644 index 000000000000..7a55148351fa --- /dev/null +++ b/docs/site/scripts/gen-plugin-manifest-docs/main.go @@ -0,0 +1,278 @@ +// Command gen-plugin-manifest-docs generates docs/site/data/plugin-manifest-docs.json, the data +// source consumed by the component that renders the plugin manifest +// reference (docs/develop/integrate/plugins/manifest-reference.md). +// +// It reads server/public/model directly from this monorepo, walking the AST with go/parser + +// go/doc instead of type-checking with golang.org/x/tools/go/packages (see gen-plugin-godocs for +// why: it avoids requiring a Go toolchain matching server/public/go.mod's declared version). +// Because of that, type resolution only follows types declared inside the model package's own +// source (which is all model.Manifest ever references) — it doesn't resolve identifiers to types +// from other packages. +package main + +import ( + "bytes" + "encoding/json" + "go/ast" + "go/doc" + "go/parser" + "go/token" + "log" + "os" + "path/filepath" + "reflect" + "runtime" + "strings" +) + +type SchemaType string + +const ( + Array SchemaType = "array" + Bool SchemaType = "bool" + Dict SchemaType = "dict" + Number SchemaType = "number" + Object SchemaType = "object" + String SchemaType = "string" + Interface SchemaType = "interface" +) + +const modelImportPath = "github.com/mattermost/mattermost/server/public/model" + +type ObjectProperty struct { + Name string + DocHTML string `json:"DocHTML,omitempty"` + Schema *TypeDocs `json:"Schema,omitempty"` +} + +type TypeDocs struct { + Type SchemaType + DocHTML string `json:"DocHTML,omitempty"` + ObjectProperties []*ObjectProperty `json:"ObjectProperties,omitempty"` + ValueSchema *TypeDocs `json:"ValueSchema,omitempty"` +} + +type Docs struct { + Schema *TypeDocs +} + +var basicTypeKinds = map[string]SchemaType{ + "string": String, + "bool": Bool, + "byte": Number, + "rune": Number, + "int": Number, "int8": Number, "int16": Number, "int32": Number, "int64": Number, + "uint": Number, "uint8": Number, "uint16": Number, "uint32": Number, "uint64": Number, + "float32": Number, "float64": Number, +} + +// fset and filesByPath let namedTypeDocs recover which file (and therefore which imports) a given +// model package type was declared in, so SelectorExpr fields can be resolved against the model +// package's imports rather than by identifier name alone. Populated once in generateDocs. +var ( + fset *token.FileSet + filesByPath map[string]*ast.File +) + +// importAliases maps the local identifier a file uses for an imported package (its alias, or the +// last path segment when unaliased) to that package's full import path. +func importAliases(file *ast.File) map[string]string { + aliases := make(map[string]string) + for _, imp := range file.Imports { + path := strings.Trim(imp.Path.Value, `"`) + alias := path[strings.LastIndex(path, "/")+1:] + if imp.Name != nil { + alias = imp.Name.Name + } + aliases[alias] = path + } + return aliases +} + +func importsForPos(pos token.Pos) map[string]string { + file := filesByPath[fset.Position(pos).Filename] + if file == nil { + return nil + } + return importAliases(file) +} + +func modelPackageDir() string { + _, thisFile, _, ok := runtime.Caller(0) + if !ok { + log.Fatal("unable to determine source file location") + } + repoRoot := filepath.Clean(filepath.Join(filepath.Dir(thisFile), "..", "..", "..", "..")) + return filepath.Join(repoRoot, "server", "public", "model") +} + +func docHTML(text string) string { + buf := &bytes.Buffer{} + doc.ToHTML(buf, text, nil) + return buf.String() +} + +func typeSpecOf(t *doc.Type) *ast.TypeSpec { + for _, spec := range t.Decl.Specs { + if typeSpec, ok := spec.(*ast.TypeSpec); ok { + return typeSpec + } + } + return nil +} + +func namedTypeDocs(t *doc.Type, typesByName map[string]*doc.Type) *TypeDocs { + spec := typeSpecOf(t) + if spec == nil { + return nil + } + ret := exprTypeDocs(spec.Type, typesByName, importsForPos(spec.Pos())) + if ret != nil { + ret.DocHTML = docHTML(t.Doc) + } + return ret +} + +// jsonFieldName returns the field's JSON key, mirroring encoding/json's own rules: unexported +// fields and those tagged `json:"-"` are never included; otherwise the tag's name component wins +// if present (including when a comma-only tag like `json:",omitempty"` leaves it empty, in which +// case the Go field name is used, same as an absent tag). +func jsonFieldName(field *ast.Field) string { + if len(field.Names) == 0 { + // Anonymous (embedded) fields aren't handled by this generator — none exist in the + // reachable model.Manifest schema. + return "" + } + fieldName := field.Names[0].Name + if !ast.IsExported(fieldName) { + return "" + } + + if field.Tag == nil { + return fieldName + } + tagValue := strings.Trim(field.Tag.Value, "`") + jsonTag := reflect.StructTag(tagValue).Get("json") + if jsonTag == "-" { + return "" + } + name := strings.SplitN(jsonTag, ",", 2)[0] + if name == "" { + return fieldName + } + return name +} + +func exprTypeDocs(expr ast.Expr, typesByName map[string]*doc.Type, imports map[string]string) *TypeDocs { + switch x := expr.(type) { + case *ast.StarExpr: + return exprTypeDocs(x.X, typesByName, imports) + case *ast.ArrayType: + return &TypeDocs{ + Type: Array, + ValueSchema: exprTypeDocs(x.Elt, typesByName, imports), + } + case *ast.MapType: + return &TypeDocs{ + Type: Dict, + ValueSchema: exprTypeDocs(x.Value, typesByName, imports), + } + case *ast.StructType: + ret := &TypeDocs{Type: Object} + for _, field := range x.Fields.List { + name := jsonFieldName(field) + if name == "" { + continue + } + ret.ObjectProperties = append(ret.ObjectProperties, &ObjectProperty{ + Name: name, + DocHTML: docHTML(field.Doc.Text()), + Schema: exprTypeDocs(field.Type, typesByName, imports), + }) + } + return ret + case *ast.SelectorExpr: + pkgIdent, ok := x.X.(*ast.Ident) + if !ok || imports[pkgIdent.Name] != modelImportPath { + log.Printf("unrecognized qualified type %v (not a reference to the model package)", x) + return nil + } + // A qualified reference to the model package's own import path (i.e. a self-import + // alias) still names a type declared in this same package, so resolve it the same way + // an unqualified identifier would be. + return exprTypeDocs(x.Sel, typesByName, imports) + case *ast.InterfaceType: + return &TypeDocs{Type: Interface} + case *ast.Ident: + if x.Name == "any" { + return &TypeDocs{Type: Interface} + } + if kind, ok := basicTypeKinds[x.Name]; ok { + return &TypeDocs{Type: kind} + } + if t, ok := typesByName[x.Name]; ok { + return namedTypeDocs(t, typesByName) + } + log.Printf("unrecognized identifier %q (not a builtin or a model package type)", x.Name) + return nil + } + + log.Printf("unrecognized ast.Expr: %T", expr) + return nil +} + +func generateDocs() (*Docs, error) { + modelDir := modelPackageDir() + + fset = token.NewFileSet() + notTest := func(info os.FileInfo) bool { return !strings.HasSuffix(info.Name(), "_test.go") } + pkgs, err := parser.ParseDir(fset, modelDir, notTest, parser.ParseComments) + if err != nil { + return nil, err + } + + modelPkg, ok := pkgs["model"] + if !ok { + return nil, os.ErrNotExist + } + + filesByPath = make(map[string]*ast.File, len(modelPkg.Files)) + for path, file := range modelPkg.Files { + filesByPath[path] = file + } + + godocs := doc.New(modelPkg, "github.com/mattermost/mattermost/server/public/model", doc.Mode(0)) + + typesByName := make(map[string]*doc.Type, len(godocs.Types)) + for _, t := range godocs.Types { + typesByName[t.Name] = t + } + + manifestType, ok := typesByName["Manifest"] + if !ok { + return nil, os.ErrNotExist + } + + return &Docs{ + Schema: namedTypeDocs(manifestType, typesByName), + }, nil +} + +func main() { + docs, err := generateDocs() + if err != nil { + log.Fatal(err) + } + + b, err := json.MarshalIndent(docs, "", " ") + if err != nil { + log.Fatal(err) + } + + if _, err := os.Stdout.Write(b); err != nil { + log.Fatal(err) + } + if _, err := os.Stdout.Write([]byte("\n")); err != nil { + log.Fatal(err) + } +} diff --git a/docs/site/src/components/PluginGoDocs/index.tsx b/docs/site/src/components/PluginGoDocs/index.tsx new file mode 100644 index 000000000000..989539258abe --- /dev/null +++ b/docs/site/src/components/PluginGoDocs/index.tsx @@ -0,0 +1,160 @@ +import React from 'react'; +import CodeBlock from '@theme/CodeBlock'; +// @ts-ignore — generated by `npm run build:plugin-godocs` (from docs/site) from +// server/public/plugin; gitignored build output, see docs/site/.gitignore. +import rawDocs from '@site/data/plugin-godocs.json'; +import type {GoDocs, GoInterfaceDocs} from './types'; +import {signatureText} from './types'; +import styles from './styles.module.css'; + +const docs: GoDocs | undefined = rawDocs && Object.keys(rawDocs).length > 0 ? (rawDocs as GoDocs) : undefined; + +function MissingDataNotice() { + return ( +

+ Run npm run build:plugin-godocs (from docs/site) to generate this + documentation. +

+ ); +} + +function InterfaceTOC({name, iface}: {name: string; iface: GoInterfaceDocs}) { + const methods = iface.Methods ?? []; + const untagged = methods.filter((m) => !m.Tags || m.Tags.length === 0); + const tags = iface.Tags ?? []; + + return ( +
    + {untagged.map((m) => ( +
  • + {signatureText(m)} +
  • + ))} + {tags.map((tag) => ( +
  • + {tag} +
      + {methods + .filter((m) => m.Tags?.includes(tag)) + .map((m) => ( +
    • + {signatureText(m)} +
    • + ))} +
    +
  • + ))} +
+ ); +} + +function InterfaceOverview({name, iface}: {name: string; iface: GoInterfaceDocs}) { + if (!iface.HTML && (!iface.Methods || iface.Methods.length === 0)) return null; + return ( +
+

{name}

+ {iface.HTML &&
} + +
+ ); +} + +function InterfaceMethodDocs({name, iface}: {name: string; iface: GoInterfaceDocs}) { + const methods = iface.Methods ?? []; + if (methods.length === 0) return null; + return ( +
+

{name}

+ {methods.map((m) => ( +
+

+ ({name}) {m.Name} +

+ {signatureText(m)} + {m.HTML &&
} +
+ ))} +
+ ); +} + +function exampleEntries(examples: Record) { + return Object.entries(examples ?? {}).filter(([name]) => name.startsWith('_')); +} + +function ExamplesTOC({examples}: {examples: Record}) { + const entries = exampleEntries(examples); + if (entries.length === 0) return null; + return ( +
+

Examples

+ +
+ ); +} + +function ExamplesDocs({examples}: {examples: Record}) { + const entries = exampleEntries(examples); + if (entries.length === 0) return null; + return ( +
+

Examples

+ {entries.map(([name, example]) => ( +
+

(Example) {displayName(name)}

+ {example.HTML &&
} + {example.Code} +
+ ))} +
+ ); +} + +function displayName(name: string): string { + const stripped = name.replace(/^_/, ''); + return stripped.charAt(0).toUpperCase() + stripped.slice(1); +} + +/** + * Renders the full server plugin SDK reference (API / Hooks interfaces, plus runnable examples) + * generated from `server/public/plugin`'s Go doc comments by `gen-plugin-godocs`. + * + * Method signatures are rendered as plain, syntax-highlighted Go code (via the site's standard + * `CodeBlock`) rather than HTML with inline pkg.go.dev links baked into the signature, for + * consistent theming (including dark mode) and real Prism highlighting. + */ +export default function PluginGoDocs() { + if (!docs) { + return ; + } + + const hasHelpers = (docs.Helpers?.Methods?.length ?? 0) > 0; + + return ( +
+ {docs.HTML &&
} + + + {hasHelpers && } + +
+ +
+ + {hasHelpers && ( + <> +
+ + + )} +
+ +
+ ); +} diff --git a/docs/site/src/components/PluginGoDocs/styles.module.css b/docs/site/src/components/PluginGoDocs/styles.module.css new file mode 100644 index 000000000000..581e039321d8 --- /dev/null +++ b/docs/site/src/components/PluginGoDocs/styles.module.css @@ -0,0 +1,29 @@ +.pluginGoDocs h2 { + margin-top: 2.5rem; + padding-top: 1rem; + border-top: 1px solid var(--mm-border-subtle); +} + +.toc { + columns: 2; + column-gap: 2rem; +} + +.toc li { + break-inside: avoid; +} + +.method { + margin: 1.75rem 0; +} + +.method h3 { + font-family: var(--mm-font-mono); + font-size: 1rem; +} + +@media (max-width: 768px) { + .toc { + columns: 1; + } +} diff --git a/docs/site/src/components/PluginGoDocs/types.ts b/docs/site/src/components/PluginGoDocs/types.ts new file mode 100644 index 000000000000..a4cbf1a9f8a8 --- /dev/null +++ b/docs/site/src/components/PluginGoDocs/types.ts @@ -0,0 +1,82 @@ +// Shape produced by docs/site/scripts/gen-plugin-godocs — kept in sync manually since the +// generator is Go and can't share TS types directly. +export type GoField = { + Names?: string[]; + Type: string; +}; + +export type GoMethodDocs = { + Name: string; + Tags?: string[]; + HTML: string; + Parameters?: GoField[]; + Results?: GoField[]; +}; + +export type GoInterfaceDocs = { + HTML: string; + Tags?: string[] | null; + Methods?: GoMethodDocs[] | null; +}; + +export type GoExampleDocs = { + HTML: string; + Code: string; +}; + +export type GoDocs = { + HTML: string; + API: GoInterfaceDocs; + Hooks: GoInterfaceDocs; + Helpers: GoInterfaceDocs; + Examples: Record; +}; + +// "[]" / "*" / "..." prefixes, and package-qualified names (e.g. +// "github.com/mattermost/mattermost/server/public/model.Manifest"), mirroring the old Hugo +// `TypeString` shortcode define — take the last "/"-delimited segment, keeping the "pkg.Type" +// suffix intact. +export function typeText(type: string): string { + if (type.startsWith('[]')) return '[]' + typeText(type.slice(2)); + if (type.startsWith('*')) return '*' + typeText(type.slice(1)); + if (type.startsWith('...')) return '...' + typeText(type.slice(3)); + if (type.startsWith('map[')) { + let depth = 0; + let i = 4; + for (; i < type.length; i++) { + if (type[i] === '[') depth++; + else if (type[i] === ']') { + if (depth === 0) break; + depth--; + } + } + return `map[${typeText(type.slice(4, i))}]${typeText(type.slice(i + 1))}`; + } + const parts = type.split('/'); + return parts[parts.length - 1]; +} + +export function fieldsText(fields?: GoField[]): string { + if (!fields || fields.length === 0) return ''; + return fields + .map((f) => (f.Names?.length ? `${f.Names.join(', ')} ` : '') + typeText(f.Type)) + .join(', '); +} + +export function resultsText(results?: GoField[]): string { + if (!results || results.length === 0) return ''; + const needsParens = results.length > 1 || Boolean(results[0].Names?.length); + const inner = fieldsText(results); + return needsParens ? `(${inner})` : inner; +} + +export function signatureText(method: GoMethodDocs): string { + const params = fieldsText(method.Parameters); + const results = resultsText(method.Results); + return `${method.Name}(${params})${results ? ' ' + results : ''}`; +} + +export function displayExampleName(name: string): string { + const stripped = name.replace(/^_/, ''); + return stripped.charAt(0).toUpperCase() + stripped.slice(1); +} diff --git a/docs/site/src/components/PluginGoExample/index.tsx b/docs/site/src/components/PluginGoExample/index.tsx new file mode 100644 index 000000000000..2dc7e143b137 --- /dev/null +++ b/docs/site/src/components/PluginGoExample/index.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import CodeBlock from '@theme/CodeBlock'; +// @ts-ignore — generated by `npm run build:plugin-godocs` (from docs/site); gitignored build +// output, see docs/site/.gitignore. +import rawDocs from '@site/data/plugin-godocs.json'; +import type {GoDocs} from '../PluginGoDocs/types'; + +const docs: GoDocs | undefined = rawDocs && Object.keys(rawDocs).length > 0 ? (rawDocs as GoDocs) : undefined; + +/** + * Renders a single Go example's source code, sourced from the same generated data as + * ``, e.g. `` renders the body of + * `Example_helloWorld`. + */ +export default function PluginGoExample({name}: {name: string}) { + const example = docs?.Examples?.[name]; + if (!example) { + return ( +

+ Run npm run build:plugin-godocs (from docs/site) to generate this + example code. +

+ ); + } + return {example.Code}; +} diff --git a/docs/site/src/components/PluginJsDocs/index.tsx b/docs/site/src/components/PluginJsDocs/index.tsx new file mode 100644 index 000000000000..4c9f11174cc5 --- /dev/null +++ b/docs/site/src/components/PluginJsDocs/index.tsx @@ -0,0 +1,61 @@ +import React from 'react'; +import CodeBlock from '@theme/CodeBlock'; +// @ts-ignore — generated by `npm run build:plugin-jsdocs` (from docs/site) from +// webapp/channels/src/plugins/registry.ts; gitignored build output, see docs/site/.gitignore. +import rawDocs from '@site/data/plugin-jsdocs.json'; +import styles from './styles.module.css'; + +type JsMethodDocs = { + Name: string; + Parameters: string[]; + Comments: string[]; +}; + +type JsDocs = { + Interface: { + Methods: JsMethodDocs[]; + }; +}; + +const docs: JsDocs | undefined = rawDocs?.Interface?.Methods?.length > 0 ? (rawDocs as JsDocs) : undefined; + +function signature(method: JsMethodDocs): string { + return `${method.Name}(${method.Parameters.join(', ')})`; +} + +/** + * Renders the web app plugin registry method reference, generated from the JSDoc comments above + * each `PluginRegistry` method/property in `webapp/channels/src/plugins/registry.ts` by + * `gen-plugin-jsdocs`. + */ +export default function PluginJsDocs() { + if (!docs) { + return ( +

+ Run npm run build:plugin-jsdocs (from docs/site) to generate this + documentation. +

+ ); + } + + const methods = docs.Interface.Methods; + + return ( +
+ +
+ {methods.map((m) => ( +
+

{m.Name}

+ {`/**\n${m.Comments.map((c) => ` * ${c}`).join('\n')}\n */\n${signature(m)}`} +
+ ))} +
+ ); +} diff --git a/docs/site/src/components/PluginJsDocs/styles.module.css b/docs/site/src/components/PluginJsDocs/styles.module.css new file mode 100644 index 000000000000..47f3eeb76a8a --- /dev/null +++ b/docs/site/src/components/PluginJsDocs/styles.module.css @@ -0,0 +1,23 @@ +.toc { + columns: 2; + column-gap: 2rem; +} + +.toc li { + break-inside: avoid; +} + +.method { + margin: 1.75rem 0; +} + +.method h3 { + font-family: var(--mm-font-mono); + font-size: 1rem; +} + +@media (max-width: 768px) { + .toc { + columns: 1; + } +} diff --git a/docs/site/src/components/PluginManifestDocs/index.tsx b/docs/site/src/components/PluginManifestDocs/index.tsx new file mode 100644 index 000000000000..106815a1ca86 --- /dev/null +++ b/docs/site/src/components/PluginManifestDocs/index.tsx @@ -0,0 +1,110 @@ +import React from 'react'; +// @ts-ignore — generated by `npm run build:plugin-manifest-docs` (from docs/site) from +// server/public/model's Manifest struct; gitignored build output, see docs/site/.gitignore. +import rawDocs from '@site/data/plugin-manifest-docs.json'; +import styles from './styles.module.css'; + +type SchemaType = 'array' | 'bool' | 'dict' | 'number' | 'object' | 'string' | 'interface'; + +type ObjectProperty = { + Name: string; + DocHTML?: string; + Schema?: TypeDocs; +}; + +type TypeDocs = { + Type: SchemaType; + DocHTML?: string; + ObjectProperties?: ObjectProperty[]; + ValueSchema?: TypeDocs; +}; + +type ManifestDocs = { + Schema: TypeDocs; +}; + +const docs: ManifestDocs | undefined = rawDocs?.Schema ? (rawDocs as ManifestDocs) : undefined; + +function titleCase(type: SchemaType): string { + return type.charAt(0).toUpperCase() + type.slice(1); +} + +// Arrays/dicts have no properties of their own — the ToC/Docs walk passes through to their +// element schema, same as the old Hugo `pluginmanifestdocs` shortcode. +function TOC({schema, prefix}: {schema?: TypeDocs; prefix: string}) { + if (!schema) return null; + if (schema.Type === 'object') { + return ( +
    + {(schema.ObjectProperties ?? []).map((prop) => ( +
  • + + {prop.Name} + + {prop.Schema && ` - ${titleCase(prop.Schema.Type)}`} + {prop.Schema && } +
  • + ))} +
+ ); + } + if (schema.Type === 'array' || schema.Type === 'dict') { + return ; + } + return null; +} + +function Docs({schema, prefix}: {schema?: TypeDocs; prefix: string}) { + if (!schema) return null; + if (schema.Type === 'object') { + return ( +
    + {(schema.ObjectProperties ?? []).map((prop) => ( +
  • +

    + {prop.Name} + {prop.Schema && ` - ${titleCase(prop.Schema.Type)}`} +

    + {prop.DocHTML &&
    } + {prop.Schema?.DocHTML &&
    } + {prop.Schema && } +
  • + ))} +
+ ); + } + if (schema.Type === 'array' || schema.Type === 'dict') { + return ( + <> + {schema.ValueSchema?.DocHTML &&
} + + + ); + } + return null; +} + +/** + * Renders the plugin.json/plugin.yaml manifest field reference, generated from + * `model.Manifest`'s Go doc comments by `gen-plugin-manifest-docs`. + */ +export default function PluginManifestDocs() { + if (!docs) { + return ( +

+ Run npm run build:plugin-manifest-docs (from docs/site) to + generate this documentation. +

+ ); + } + + return ( +
+ {docs.Schema.DocHTML &&
} +

Table of contents

+ +

Documentation

+ +
+ ); +} diff --git a/docs/site/src/components/PluginManifestDocs/styles.module.css b/docs/site/src/components/PluginManifestDocs/styles.module.css new file mode 100644 index 000000000000..cfd5a1946ed4 --- /dev/null +++ b/docs/site/src/components/PluginManifestDocs/styles.module.css @@ -0,0 +1,14 @@ +.docsList { + list-style: none; + padding-left: 0; +} + +.docsList li { + margin: 1.25rem 0; + padding-left: 1rem; + border-left: 2px solid var(--mm-border-subtle); +} + +.docsList code { + font-size: 0.95em; +} diff --git a/docs/site/src/theme/MDXComponents.tsx b/docs/site/src/theme/MDXComponents.tsx index 0f916fe4b82b..2c224eb5440e 100644 --- a/docs/site/src/theme/MDXComponents.tsx +++ b/docs/site/src/theme/MDXComponents.tsx @@ -18,6 +18,10 @@ import StatStrip from '@site/src/components/StatStrip'; import MethodLegend from '@site/src/components/MethodLegend'; import CardGrid from '@site/src/components/CardGrid'; import UpgradeNotesFilter from '@site/src/components/UpgradeNotesFilter'; +import PluginGoDocs from '@site/src/components/PluginGoDocs'; +import PluginGoExample from '@site/src/components/PluginGoExample'; +import PluginJsDocs from '@site/src/components/PluginJsDocs'; +import PluginManifestDocs from '@site/src/components/PluginManifestDocs'; // Globally available so migrated developer docs (Hugo `tabs` shortcode) // can use them without imports. import Tabs from '@theme/Tabs'; @@ -45,6 +49,10 @@ export default { MethodLegend, CardGrid, UpgradeNotesFilter, + PluginGoDocs, + PluginGoExample, + PluginJsDocs, + PluginManifestDocs, Tabs, TabItem, }; diff --git a/docs/site/static/images/oracle/application-information.png b/docs/site/static/images/oracle/application-information.png new file mode 100644 index 000000000000..4f4b06122a9d Binary files /dev/null and b/docs/site/static/images/oracle/application-information.png differ diff --git a/docs/site/static/images/oracle/marketplace-listing.png b/docs/site/static/images/oracle/marketplace-listing.png index 873adf728c2b..5c278414c39d 100644 Binary files a/docs/site/static/images/oracle/marketplace-listing.png and b/docs/site/static/images/oracle/marketplace-listing.png differ diff --git a/docs/site/static/images/oracle/stack-info.png b/docs/site/static/images/oracle/stack-info.png index a6eb1409dc65..fbe4f4229d89 100644 Binary files a/docs/site/static/images/oracle/stack-info.png and b/docs/site/static/images/oracle/stack-info.png differ diff --git a/server/.go-version b/server/.go-version index ea0928cedf0d..ad7c780d0488 100644 --- a/server/.go-version +++ b/server/.go-version @@ -1 +1 @@ -1.26.4 +1.26.7 diff --git a/server/build/Dockerfile.buildenv b/server/build/Dockerfile.buildenv index 75fe3d322ee8..4eb6cbf931c8 100644 --- a/server/build/Dockerfile.buildenv +++ b/server/build/Dockerfile.buildenv @@ -1,4 +1,4 @@ -FROM golang:1.26.4-bookworm@sha256:b305420a68d0f229d91eb3b3ed9e519fcf2cf5461da4bef997bf927e8c0bfd2b +FROM golang:1.26.7-bookworm@sha256:6ef6e30f0ea5c384f6d111cf856e024e3086bbdcb1779da3f3b3fbba0aea53d2 ARG NODE_VERSION=20.11.1 RUN apt-get update && apt-get install -y make git apt-transport-https ca-certificates curl software-properties-common build-essential zip xmlsec1 jq pgloader gnupg diff --git a/server/build/Dockerfile.buildenv-fips b/server/build/Dockerfile.buildenv-fips index c61a4960e0d5..883a85e65ca2 100644 --- a/server/build/Dockerfile.buildenv-fips +++ b/server/build/Dockerfile.buildenv-fips @@ -1,4 +1,4 @@ -FROM cgr.dev/mattermost.com/go-msft-fips:1.26.4.1-dev@sha256:e237532162e2a755fef5944d2fcaff02923752c754a5d7b60836b7a8aa682317 +FROM cgr.dev/mattermost.com/go-msft-fips:1.26.7.1-dev@sha256:ae345a37a612265894a7e7f318be45680663346cb7992613916e196daf38e839 ARG NODE_VERSION=20.11.1 RUN apk add curl ca-certificates mailcap unrtf wv poppler-utils tzdata gpg xmlsec diff --git a/server/build/Dockerfile.fips b/server/build/Dockerfile.fips index 81ba3867573c..281dcaec3956 100644 --- a/server/build/Dockerfile.fips +++ b/server/build/Dockerfile.fips @@ -1,5 +1,5 @@ # First stage - FIPS dev image with dependencies for building -FROM cgr.dev/mattermost.com/glibc-openssl-fips:15-dev@sha256:ab5285209fff77fbe56e58aeed6d7f557cf74c6f90d1d8ee26053003f039b419 AS builder +FROM cgr.dev/mattermost.com/glibc-openssl-fips:16-dev@sha256:e971e3eb6b5ffd227e17d0fa7944e3430d3e8e24e9587d5488a833139629ab0f AS builder # Setting bash as our shell, and enabling pipefail option SHELL ["/bin/bash", "-o", "pipefail", "-c"] @@ -37,7 +37,7 @@ RUN mkdir -p /var/tmp \ && chmod 755 /var/tmp # Final stage using FIPS runtime image -FROM cgr.dev/mattermost.com/glibc-openssl-fips:15@sha256:7947eecc0d82fa3bc661aaca039bcd86d55fdf3ee581c8ecdef1b3c6f63fa83a +FROM cgr.dev/mattermost.com/glibc-openssl-fips:16@sha256:a636adba740bb6a53e55c14f7deb979802bcff2203f4aaecfe6f1d159cdfe3a1 # Some ENV variables ENV PATH="/mattermost/bin:${PATH}" diff --git a/server/go.mod b/server/go.mod index 6efa9947b1dd..ae798c82ade1 100644 --- a/server/go.mod +++ b/server/go.mod @@ -1,6 +1,6 @@ module github.com/mattermost/mattermost/server/v8 -go 1.26.4 +go 1.26.7 require ( code.sajari.com/docconv/v2 v2.0.0-pre.4 diff --git a/server/public/go.mod b/server/public/go.mod index e0dd19cff457..f17df50a05cf 100644 --- a/server/public/go.mod +++ b/server/public/go.mod @@ -1,6 +1,6 @@ module github.com/mattermost/mattermost/server/public -go 1.26.4 +go 1.26.7 require ( github.com/Masterminds/semver/v3 v3.5.0 diff --git a/webapp/channels/src/components/widgets/users/avatar/avatar.scss b/webapp/channels/src/components/widgets/users/avatar/avatar.scss index 4787c936a4d1..f9a416c71f7c 100644 --- a/webapp/channels/src/components/widgets/users/avatar/avatar.scss +++ b/webapp/channels/src/components/widgets/users/avatar/avatar.scss @@ -1,20 +1,12 @@ @use "sass:color"; img.Avatar { - // Hide alt text that deforms the circled shape of the avatars in the thread footer. - // font-size: 0 prevents alt text from expanding the box on broken images. - // min-width: 0 lets width follow the browser's natural broken-image icon size - // so it matches height and border-radius: 50% stays circular. - &.Avatar-xxs, - &.Avatar-xs, - &.Avatar-sm, - &.Avatar-md, - &.Avatar-lg, - &.Avatar-xl, - &.Avatar-xxl { - min-width: 0; - font-size: 0; - } + // A broken is no longer a replaced element, so width/height stop applying and + // the alt text sizes the box. inline-block keeps the Avatar-* size tokens in effect, + // and overflow/color keep the alt text from spilling out of the circle. + display: inline-block; + overflow: hidden; + color: transparent; } .Avatar { diff --git a/webapp/channels/src/sass/components/_post.scss b/webapp/channels/src/sass/components/_post.scss index 9034f697ced7..fea5f2826268 100644 --- a/webapp/channels/src/sass/components/_post.scss +++ b/webapp/channels/src/sass/components/_post.scss @@ -1770,18 +1770,11 @@ .post__img { width: 24px; height: 24px; - flex: 0 0 auto; padding: 0; text-align: left; img.avatar-post-preview { display: block; - - // The shared avatar rules set min-width: 0, which lets the image - // shrink (and look squished) inside constrained flex layouts. - // Pin it to its intended size so it always stays round. - min-width: 24px; - flex-shrink: 0; } }