Commit Graph
22594 Commits
Author SHA1 Message Date
e3823a51ce Fix flaky TestScheduleOnceSequential (#36805)
The subtest used a fixed sleep before asserting callback counts, but
job.run waits until runAt plus up to scheduleOnceJitter. Under the race
detector or loaded CI that window can elapse after the sleep, so
newCount3 is still 0 and the assertion flakes.

Poll with require.Eventually (same approach as the paging subtest in
#35891) so the test waits for the scheduled callback without weakening
assertions.

Tests-only change. Verified with:
go test -run '^TestScheduleOnceSequential$/adding_two_callback_works' \
  -race -count=100 ./pluginapi/cluster/... (from server/public)

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
2026-05-29 12:39:07 +02:00
Pablo VélezandMattermost Build 495fbc8437 MM-68978 - Harden ABAC masking guards and fix sentinel detection (#36740)
* MM-68978 - Harden ABAC masking guards and fix sentinel detection

* address pr feedback

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-05-29 11:49:58 +02:00
5ad66d3f76 Fix flaky TestUpdatePropertyValues_WriteAccessControl (#36784)
* Fix flaky TestUpdatePropertyValues_WriteAccessControl

GetPropertyValues delegates to PropertyValueStore.GetMany, which does not
preserve the caller's ID slice order. Subtests asserted on retrieved[0] and
retrieved[1] by position, so a planner that returns rows sorted by ID or
UpdateAt (e.g. with idx_propertyvalues_groupid_updateat_id) could swap
values and fail intermittently.

Look up returned values by ID before comparing JSON payloads.

Tests-only change. Verified with `go test -run '^TestUpdatePropertyValues_WriteAccessControl$' -race -count=100` locally.

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Refactor property value test helper

Co-authored-by: Miguel de la Cruz <mgdelacroix@users.noreply.github.com>

* Remove redundant property test nil checks

Co-authored-by: Miguel de la Cruz <mgdelacroix@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
Co-authored-by: Miguel de la Cruz <mgdelacroix@users.noreply.github.com>
2026-05-29 08:53:34 +00:00
Harrison Healey 8c8f28f943 MM-69042 Add user setting to experimentally enable concurrent React (#36785)
* MM-69042 Add user setting to experimentally enable concurrent React

* Change collapsed label to always use store value
2026-05-28 21:02:25 -04:00
0d0dd16d40 Fix classification modal save state (#36693)
* Fix classification modal save state

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Align classification modal regression test

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Reset save panel on classification edits

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Wait for classification sync before clearing edits

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Use realistic classified channel in reset test

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Strengthen classification banner regression test

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Refactored fix to be simpler, added E2E test suite to prevent regressions

* Applied prettier fix to playwright test

* Fixing failed E2E test

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
Co-authored-by: avasconcelos114 <andre.onogoro@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-05-28 20:45:24 +03:00
edgarbellot 42f021581f Tighten CI workflows (#36778) 2026-05-28 18:21:13 +02:00
David Krauser 800810e880 [MM-69028] Enable ClassificationMarkings feature flag by default (#36776) 2026-05-28 10:42:49 -04:00
Maria A NunezandCursor 1379beae98 MM-68840: Apply team sanitization on scheme teams endpoint (#36640)
* MM-68840: Apply team sanitization on scheme teams endpoint

Align GET /api/v4/schemes/{scheme_id}/teams with the team-returning
handlers in server/channels/api4/team.go by calling
App.SanitizeTeams before marshaling the response.

Adds a regression test that locks in the sanitized response for
non-admin callers and a positive control for system admins.

Co-authored-by: Cursor <cursoragent@cursor.com>

* MM-68840: Drop descriptive comments from regression test

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 08:43:16 -04:00
Maria A NunezandCursor bf39b41ca8 MM-68845: Tighten authorization on /share-channel autocomplete (#36662)
* MM-68845: Tighten authorization on /share-channel autocomplete

Require manage_shared_channels for the /share-channel slash command's
dynamic autocomplete suggestions, matching the equivalent gate already
enforced by /secure-connection autocomplete and by /share-channel
command execution.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Clean up test comments and naming on /share-channel autocomplete tests

Drop verbose test docstrings, rename helpers and subtests to neutral
behavior-contract phrasing.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 08:41:37 -04:00
23d83b74d2 MM-65723 Validate user auth update requests (#36749)
* MM-65723 validate user auth updates

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* MM-65723 assert auth update persistence

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* MM-65723 move auth service allowlist into model

Extracts the allowlist used by isValidUpdateUserAuthRequest into a new
model.IsValidUserAuthService helper next to IsSSOUser/IsOAuthUser so the
auth service list lives next to its constants. Adds a unit test for the
helper.

* go mod tidy

Drops stale github.com/bep/imagemeta v0.12.0 entry left in go.sum.

* Address PR feedback: 2 items resolved, 1 declined

* Address PR feedback: 1 items resolved, 1 declined

* Address PR feedback: 1 items resolved, 3 declined

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Julien Tant <julien@craftyx.fr>
2026-05-28 09:30:44 +00:00
Ben Schumacher b632c9ed1c Stop logging email subject when sending mail (#36765)
The "sending mail" Info log includes the subject line, which for DM and
mention notifications contains the sender's name and other PII visible
to anyone with log access. The "to" address is enough operational
signal to confirm that a notification fired.
2026-05-28 09:14:12 +02:00
David Krauser a6e019863e [MM-68999] Add SchemaVersion to PropertyGroup for group-specific field schema versioning (#36747) 2026-05-27 14:27:16 -04:00
David KrauserandClaude Sonnet 4.6 159ed5ad96 Return error when plugins use deprecated custom_profile_attributes group name (#36748)
The plugin API was silently redirecting calls using the old
"custom_profile_attributes" group name to the new "access_control" group.
Replace the silent alias with an explicit error so plugin developers get
a clear message telling them what to change.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 12:24:01 -04:00
5984d7d6e3 MM-68938 Fix clipped policy editor tooltips (#36684)
* MM-68938 Keep tooltips within viewport

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* MM-68938 Let CEL editor tooltips overflow

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Fix BuildAccessControlSubject call in channel join request evaluation

Pass channel.Id as the channelID argument so evaluateChannelMembership
compiles after the BuildAccessControlSubject signature gained a fourth
parameter.

Co-authored-by: mattermost-code <matty-code@mattermost.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-05-27 10:32:01 -04:00
Harshil Sharma 88e48a0e79 Fixed a bug where deleted post was broadcasted by the server and rest… (#36646)
* Fixed a bug where deleted post was broadcasted by the server and restored posts weren't visible

* i18n fix

* Handled a possible undefined dereference

* Undeleted post in-place instead of fetching from database

* i18n fix

* Added currrent channel check
2026-05-27 19:02:31 +05:30
Alejandro García MontoroandMattermost Build 472e4a01d2 MM-68664: Microsoft Entra ID / Default Credential authentication for Azure Blob Storage (#36733)
* Add DefaultAzureCredential authentication for Azure Blob Storage

Adds a second authentication mode for the Azure filestore backend
alongside the existing shared-key path. The new "default credential"
mode constructs azidentity.NewDefaultAzureCredential, which discovers
managed identity, workload identity, service principal env vars, and
az login in that order at runtime - the standard Microsoft pattern for
host-provided identities.

The credential type is configured via FileSettings.AzureAuthMode (and
ExportAzureAuthMode for the dedicated export store). Both default to
shared_key so existing deployments are unaffected. The access-key field
is only required under shared_key; default_credential reads identity
from the host environment and needs no per-mode config.

------
AI assisted commit

* Add Azure authentication selector to the System Console

Adds an "Azure Authentication" dropdown to both the primary file-storage
panel and the dedicated export-store panel. Two options: "Shared key"
(the existing default) and "Default credential (Microsoft Entra ID)".
The Azure Storage Account Key field is hidden when default credential
is selected; it has no role in that auth mode.

The Cypress spec is extended to cover the new dropdown's visibility
toggling.

------
AI assisted commit

* Use fmt.Errorf instead of pkg/errors

* Do not support empty AzureAuthModeSharedKey

There is no need to support legacy settings when a feature is not yet
released.

* Bring in master's Azure Blob Storage Cypress spec and scroll the access key into view

Two related changes:

- The merge commit just before this one missed master's MM-68787 updates
  to the Azure Blob Storage Cypress spec (the AzureClouddropdown
  visibility, the disabled -> not.exist tightening when S3 driver is
  selected, and the new "shows the custom endpoint only for the Custom
  cloud" test). This commit pulls those in.
- The new "hides the access key when the authentication mode is default
  credential" spec asserts the access key field is visible immediately
  after selecting the Azure driver. With the AzureAuthMode and (now
  landed) AzureCloud dropdowns above it, the field sits below the
  visible area of the System Console scroll container, and Cypress's
  strict be.visible check fails on overflow clipping. scrollIntoView
  mirrors what the Test Connection spec already does for the same
  reason.

------
AI assisted commit

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-05-27 10:57:26 +02:00
Harshil Sharma d563fdd5ac Data spillage report api use available data (#36699)
* Read available value when viable

* Added tests

* Restored package lock

* CI

* Used saved actor details when available

* i18n fix

* Updated data in log
2026-05-27 12:26:02 +05:30
Ben SchumacherandClaude Opus 4.7 8a957afce2 [MM-68458] Improve diagnostics.yaml readability: reorder server fields and add inline YAML comments (#36703)
* MM-68458: Improve diagnostics.yaml readability — reorder server fields and add inline comments

Regroup the SupportPacketDiagnostics.Server fields into Machine /
Capacity / Process lifecycle / Software clusters (declaration order
determines YAML emit order in goccy/go-yaml), and emit YAML head /
line comments at marshal time via yaml.MarshalWithOptions +
yaml.WithComment.

Comments cover the non-obvious cases support engineers hit during
triage: host RAM vs cgroup quota, omitempty fields that silently
disappear when no container limit is set, sql.DBStats counters that
are cumulative-since-process-start, and PostgreSQL-only fields that
vanish on MySQL. file_store: local-driver-only fields are similarly
annotated.

No struct reorder outside server:; no public-API or JSON shape
changes; no new dependencies (goccy/go-yaml already supports
WithComment).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* gofmt: realign diagnosticsYAMLComments map literal

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 08:43:42 +02:00
fc7b5c78a5 MM-68943 Wrap data spillage RHS action buttons (#36682)
* MM-68943 Wrap data spillage action buttons

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* MM-68943 Satisfy data spillage action stylelint

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Fix BuildAccessControlSubject call in channel join request ABAC

Pass an empty channel ID when evaluating channel membership so the
server build matches the updated BuildAccessControlSubject signature.

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Re-trigger CI after postgres shard flake

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Fix data spillage action button spacing

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
2026-05-27 09:52:26 +05:30
Harrison Healey 41367fa7b1 Fix missing peer fields in package-lock.json (#36744) 2026-05-26 12:52:34 -04:00
Alejandro García MontoroandMattermost Build ecd72f79bd MM-68787: Support sovereign-cloud endpoints for Azure Blob Storage (#36732)
* Support sovereign-cloud endpoints in the Azure Blob Storage backend

Adds an AzureCloud enum to FileBackendSettings and the matching
FileSettings / ExportFileSettings entries, defaulting to commercial.
The supported values pick the service URL the SDK signs against:

  - commercial: vhost-style against blob.core.windows.net, exactly
    the existing default. Only the storage account name is needed.
  - government: vhost-style against blob.core.usgovcloudapi.net, no
    user-supplied endpoint. Only the storage account name is needed.
  - custom: the admin-provided AzureEndpoint is the full service URL,
    scheme and storage account included, and Mattermost passes it to
    the SDK unchanged. Covers Azurite, reverse proxies, Azure China,
    and any future Azure cloud Mattermost has not codified a preset
    for.

Wires the new field through NewFileBackendSettingsFromConfig,
NewExportFileBackendSettingsFromConfig, ConfigToFileBackendSettings,
SetDefaults, the System Console (File Storage and Export Storage
panels) with matching i18n strings, and a dedicated Cypress spec.
Azurite test settings switch to AzureCloud=custom with the full
http://host:port/account/ URL so the existing integration suites
keep driving Azurite without any conditional URL plumbing inside the
driver. buildAzureServiceURL is now total: it returns an error for
custom-without-endpoint and for unknown enum values rather than
producing a malformed URL.

------
AI assisted commit

* Hide S3 File Storage fields when a different driver is selected

Match the existing Azure-field behavior: when the selected file storage
driver is not Amazon S3, hide the S3-only fields entirely instead of
just disabling them. Both driver groups already use this hide-when-
inactive pattern in the dedicated export storage section.

The Cypress assertion in azure_blob_storage_spec.js that codified the
old disable-only behavior is updated to expect not.exist.

------
AI assisted commit

* Address review feedback on AzureCloud validation and config-test endpoints

- Switch FileSettings.isValid AzureCloud / ExportAzureCloud value
  checks from slices.Contains to a switch statement, matching the
  closed-enum style used a few lines above for DriverName.
- Revert the io.EOF suppression in testFileStore and testEmail. The
  suppression was bot-suggested log-noise polish; reviewer prefers
  to keep the original error handling for those endpoints.
- Drop the redundant "http(s)" qualifier from the scheme check comment
  in buildAzureServiceURL.

------
AI assisted commit

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-05-26 16:34:48 +00:00
d9c1388461 [MM-68649] Add Session Attributes from user agent for use in Permission Policies (#36511)
* [MM-68649] Add Session Attributes from user agent for use in Permission Policies

* Update server/channels/app/session_attributes.go

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Fix test

* fix i18n

* Allow session attributes for permission policies when no user attributes are configured

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: maria.nunez <maria.nunez@mattermost.com>
2026-05-26 11:24:03 -04:00
16c8f9d6e3 MM-68955 Offset onboarding checklist above bottom classification banner (#36691)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
2026-05-26 09:22:27 -04:00
1e98d75e80 MM-68944 Fix data spillage report affordances (#36685)
* MM-68944 Fix data spillage report affordances

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* MM-68944 Cover non-clickable post preview rendering

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Assert preview attachment has no role attribute

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Fix BuildAccessControlSubject call in channel join request ABAC

Pass channel.Id as the scoped channel argument so evaluateChannelMembership
compiles against the updated BuildAccessControlSubject signature.

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Address PR feedback: 1 item resolved, 0 declined

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-05-26 11:21:17 +05:30
Harrison HealeyandMattermost Build 099a18b84e Remove some leftover code related to removed notify admin feature (#36680)
* Remove unused NotificationFromMembersModal and AtSumMembers

* Remove unused AtPlanMention

* Remove unused channelIsShared props

I think these were left over from a previous version of some logic
around shared channels where we had to pass it around since I can't find
anywhere that these are used.

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-05-25 21:49:03 +00:00
Jesse Hallam 67b49ad5c0 MM-68154: Upgrade imagemeta to v0.17.2 (#36588)
* MM-68154: Upgrade imagemeta to v0.17.2

* MM-68154: Add test coverage for GetImageOrientation edge cases

Cover MIME-type format strings ("image/jpeg") and unsupported formats.

* fixup! MM-68154: Upgrade imagemeta to v0.17.2
server/public/v0.4.1
2026-05-25 21:05:10 +02:00
Doug Lauder e1189a3005 MM-68914 - Fix DM/GM channel member import defaulting SchemeUser to false (#36661)
* Fix DM/GM channel member import defaulting SchemeUser to false

  The direct-channel participant import path only assigned scheme flags
  when the import data carried them, so imports that omitted those
  fields (notably mmetl's Slack export) produced channel members with
  no effective role. The web client then routed those channels to the
  "missing channel role" loading state and the message input never
  loaded. A customer reported 444 affected channel member rows for a
  single user.

  Default SchemeGuest and SchemeUser from the resolved user before the
  existing nil-checked overrides, matching the regular user-channel
  import path at lines 1273-1275. Explicit values in the import data
  still win. Adds regression tests for both DM and GM channels.

  Fixes MM-68914.

* Use fresh users in SchemeUser regression tests

  The new subtests added in the previous commit reused BasicUser,
  BasicUser2, and user3, which already had channels created by earlier
  subtests in TestImportImportDirectChannel with non-zero LastViewedAt.
  The freshness guard in importDirectChannel then skipped the
  participants and the assertions ran against pre-existing channel
  members rather than the import path. As a result the tests passed
  regardless of whether the fix was present.

  Switch to fresh users created via th.CreateUser so there is no
  pre-existing channel, no LastViewedAt mismatch, and
  UpdateMultipleMembers actually runs with the import-built members.
  Verified by reverting the fix in import_functions.go: both subtests
  now fail without the fix and pass with it.
2026-05-25 14:30:43 -04:00
Jesse Hallam 462f34ac6c Generate default_roles_permissions.js from a live server snapshot (#36698)
* Generate default_roles_permissions.js from a live server snapshot

Replace the hand-maintained default_roles_permissions.js with a
generated file. The generator (scripts/default_permissions_generator/)
boots a real app.NewServer() against a temporary database created by
storetest.MakeSqlSettings, lets all schema and app-level migrations run
naturally, then snapshots the resulting Roles table into the JS file.

This eliminates the drift risk of the previous hand-maintained map:
new migrations are picked up automatically because the same server
initialization path is used here as in production.

The CI job gets a postgres service and sets IS_CI=true so the generator
uses the same host-switching logic as the rest of the test suite.
Locally, make start-docker provides the postgres instance.

* Address CodeRabbit feedback: pin checkout SHA, add permissions, add .PHONY entries
2026-05-25 15:03:11 -03:00
Harrison Healey 25bf5edc4f MM-68773 Fix bug with HTML encoding in proxied image URL (#36555)
* MM-68773 Fix bug with HTML encoding in proxied image URL

* Remove some now-unneeded hasImageProxy props
2026-05-25 09:14:14 -04:00
unified-ci-app[bot] b609ec59fc chore: Update NOTICE.txt file with updated dependencies (#36729)
Automatic Merge
2026-05-25 13:54:05 +02:00
Alejandro García MontoroandMattermost Build c6b59cc9a7 MM-68663: Admin console support and Test Connection generalization for Azure Blob Storage (#36583)
* Generalize the file storage Test Connection endpoint

Replaces the S3-only /api/v4/file/s3_test handler with a backend-agnostic
POST /api/v4/file/test that validates mandatory fields per driver and
runs a write/read/delete probe against the configured backend. The
legacy /file/s3_test route stays as a thin wrapper so existing clients
keep working.

The driver switch validates S3 and Azure mandatory fields explicitly,
treats Local as a no-op (no required credentials), and rejects unknown
or empty driver names with a 400 and a specific error code so admins
get a useful message instead of a generic backend failure.

Reuses config.Desanitize (renamed from the package-private desanitize)
so the FakeSetting placeholder swap for secrets is shared with the
PUT /api/v4/config save path. Adding a new driver-secret in the future
only requires touching config.Desanitize once. Desanitize is also made
nil-safe on every pointer dereference so callers can hand it a partial
config without first running SetDefaults().

Mattermost-redux and the webapp client gain a corresponding
TestFileStoreConnection method that the admin console action layer
calls instead of the deprecated S3-specific method.

------
AI assisted commit

* Wire Azure Blob Storage into the file storage admin console

Adds the Azure Blob Storage option to the File Storage panel in the
System Console. Selecting it enables Azure-specific fields for the
storage account name, container, optional path prefix, shared key,
optional endpoint override, secure-connections toggle, and request
timeout. The fields are hidden and disabled when the driver is set to
Local or S3, matching the existing pattern.

Help text and placeholders are added in the webapp i18n catalog so
admins see the same field labels documented in the admin guide.

The same set of fields is repeated for the Files Export panel when
DedicatedExportStore is enabled, keeping the export backend
configurable independently of the primary file store.

------
AI assisted commit

* Document /api/v4/file/test in the OpenAPI spec

Adds the new backend-agnostic file storage Test Connection endpoint to
the public OpenAPI surface. The request body is optional: callers that
omit it test the running server configuration, callers that include a
full AdminConfig test the supplied configuration without persisting
anything. The deprecated /api/v4/file/s3_test endpoint is left
unchanged in the spec for the existing S3-only flow.

------
AI assisted commit

* Add UI-only Cypress coverage for the Azure file storage panel

Adds a Cypress spec that drives the System Console File Storage panel,
switches the driver to Azure Blob Storage, fills in the Azure fields,
and asserts the expected fields appear (and S3 fields are hidden). The
spec is UI-only and does not depend on an Azure backend or Azurite, so
it can run in CI without external infrastructure.

Updates the existing environment_spec.js so it tolerates the new Azure
option in the driver dropdown.

------
AI assisted commit

* Nil-guard file storage mandatory-field checks

CheckMandatoryS3Fields and CheckMandatoryAzureFields built a
FileBackendSettings via NewFileBackendSettingsFromConfig before
validating, but that constructor dereferences pointers
unconditionally and would panic if a caller skipped the api
handler's reflective nil check. Validate the required pointers
directly against FileSettings instead, dropping the throwaway
constructor call so the methods are safe to call from any path.

------
AI assisted commit

* Check permission before validating file settings

The /file/test handler ran checkHasNilFields before
SessionHasPermissionTo, so an unauthorized caller posting a partial
config got a 400, leaking config shape, rather than a 403. Swap the two
blocks so the permission decision happens first.

------
AI assisted commit

* Preserve FakeSetting when desanitize has no actual

The Azure access key, export Azure access key, and S3 secret access key
branches in Desanitize reassigned target to actual without checking
actual for nil. When the running config had no value, the FakeSetting
placeholder in target was replaced with nil, dropping the field from the
round-trip. Guard the assignment so the placeholder stays in place when
actual is unset.

------
AI assisted commit

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-05-25 11:36:02 +00:00
Felipe Martin 4d8c25f040 [MM-68736] Reconcile partial GM membership in bulk import (#36542)
* [MM-68736] Reconcile partial GM membership in bulk import

importDirectChannel failed with "ChannelMember not found" when the
group channel hash already existed in Channels but one or more
participants were missing from ChannelMembers (concurrent import
workers, a prior import that crashed mid SaveMember loop, or a
pre-existing GM whose membership has drifted).

The function only used existingMembers to compare LastViewedAt and
still appended absent participants to UpdateMultipleMembers, whose
UPDATE-then-SELECT returns sql.ErrNoRows for the missing row.

Insert the missing ChannelMembers row via SaveMember (logging the
join event) before the UPDATE path. ErrConflict is treated as benign
so concurrent workers racing on the same MPIM hash do not fail each
other.

* [MM-68736] Add missing i18n key for new bulk import error

The save_member.error key was added in the importDirectChannel fix but
not registered in i18n/en.json.

* [MM-68736] Address review feedback

- Broaden the save_member.error translation to also cover DM imports,
  since importDirectChannel runs the same SaveMember reconciliation
  path for both 2-participant DMs and 3+-participant GMs.
- In the idempotent re-import test, assert that
  ChannelMemberHistory.GetMembershipChanges returns no rows after the
  second import. LogJoinEvent is only invoked when the missing-member
  branch runs, so an empty result proves SaveMember was not called
  for any already-present participant.
2026-05-25 12:17:08 +02:00
Harshil Sharma cfafefe58c Used short mode of data spillage report card in threads view to fix spacing issue (#36709) 2026-05-25 09:36:01 +05:30
508f1551e3 Fix flaky TestScrubPost (#36686)
The should_preserve_non-content_fields subtest asserted UpdateAt was
unchanged after scrubPost, but scrubPost refreshes UpdateAt via
model.GetMillis(). When the scrub runs in a later millisecond than the
fixture setup, the strict equality fails intermittently.

Align the assertion with scrubPost behavior (UpdateAt >= pre-scrub value).

Tests-only change. Verified with `go test -run '^TestScrubPost$' -race
-count=100` and 10000 runs of the subtest locally.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
2026-05-25 09:13:25 +05:30
7e75035cb6 Add Data Spillage discovery page (#36697)
* Add Data Spillage feature discovery page

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Strengthen Data Spillage discovery tests

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Fix Data Spillage discovery precommit issues

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Address PR feedback: 1 items resolved, 0 declined

* Remove Entry SKU hide condition for content flagging discovery

* Update Data Spillage discovery illustration

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Replace Data Spillage discovery illustration

Co-authored-by: mattermost-code <matty-code@mattermost.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
2026-05-22 14:44:44 -04:00
Jesse Hallam b60ba8b6b4 chore(ci): allow build-server-image to build and push from release branches (#36716) 2026-05-22 14:15:23 -04:00
Jesse Hallam 44ba06ee3c MM-68248: Handle missing OpenSearch indexes gracefully before reindex (#36712)
* MM-68248: Handle missing indexes gracefully before reindex

OpenSearch v3 rejects _update_by_query and _delete_by_query with no index
argument (405), and returns index_not_found_exception (404) when querying
an exact index name that hasn't been created yet. Both arise before any
reindex has run, since indexes are created on first document write.

Return nil/empty instead of an error from all affected operations, and add
test coverage for each in the no-indexes state.

* MM-68248: Fix copy-paste operation names in DeleteFilesBatch

* MM-68248: Add i18n string for delete_files_batch error

* MM-68248: Also check error type in isIndexNotFound
2026-05-22 16:05:03 +00:00
Pablo VélezandMattermost Build b0185d9817 update packages to Fix npm audit vulnerabilities (#35810)
* Fix npm audit vulnerabilities and replace image-webpack-loader with sharp

* remove dead webp config and restore SVG optimization via svgoMinify

* fix import order

* removed unused gif from testing, and add missing peer dependency

* make sure only svgs are parsed

* scope svgoMinify to src- SVGs via loader rule

* remove redundant npm overrides per review feedback

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-05-22 17:57:53 +02:00
Jesse Hallam 834a86b5e3 MM-68248: Support OpenSearch v3 (#36617)
* Remove build-opensearch-image.yml -- the published image is unused

* MM-68248: Support OpenSearch v3

* MM-68248: Add CI job to test OpenSearch v2 backwards compatibility

* MM-68248: Handle missing indexes gracefully before reindex

OpenSearch v3 rejects _update_by_query and _delete_by_query with no index
argument (405), and returns index_not_found_exception (404) when querying
an exact index name that hasn't been created yet. Both arise before any
reindex has run, since indexes are created on first document write.

Return nil/empty instead of an error from all affected operations, and add
test coverage for each in the no-indexes state.

* MM-68248: Fix copy-paste operation names in DeleteFilesBatch

* MM-68248: Add i18n string for delete_files_batch error

* Revert "MM-68248: Add i18n string for delete_files_batch error"

This reverts commit e885678088.

* Revert "MM-68248: Fix copy-paste operation names in DeleteFilesBatch"

This reverts commit 4b7caacf59.

* Revert "MM-68248: Handle missing indexes gracefully before reindex"

This reverts commit 2d2d522f86.
2026-05-22 15:37:50 +00:00
Ben Cooke f8e233cc39 Fix Group Details role dropdown not updating UI when changing role (#36561) 2026-05-22 11:07:10 -04:00
David Krauser e8632bd456 [MM-68777] Add admin property field permission level (#36558) 2026-05-22 11:01:41 -04:00
4e01dae534 Fix flaky TestPreparePostForClient/files (#36631)
The files subtest polled for post file metadata with assert.Eventually
using only a one-second total wait. Under CI load, PreparePostForClient
can take longer than that to see persisted file rows, causing intermittent
timeouts while the final assert would still pass if given time.

Tests-only change. Verified with go test -run
'^TestPreparePostForClient$/^files$' -race -count=100 locally.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>
2026-05-22 10:40:49 -04:00
Doug Lauder c63154598c MM-66162: harden GET /sharedchannels/{id}/remotes error path and add WS guard (#36696)
* MM-66162: harden GET /sharedchannels/{id}/remotes error path and add WS guard

  Two small follow-ups on top of the existing fix that returns 200 with an
  empty list when a channel is not shared.

  Server: getSharedChannelRemotes built its 500 AppError with nil params,
  so the i18n template "Could not fetch status for secure connections:
  {{.Error}}." rendered as "<no value>" in logs and response bodies when a
  genuinely unexpected error occurred. Pass map[string]any{"Error":
  err.Error()} so the underlying error surfaces, matching the pattern
  already used by the slash command caller in
  channels/app/slashcommands/command_share.go.

  Webapp: handleSharedChannelRemoteUpdatedEvent dispatched
  fetchChannelRemotes unconditionally on every shared_channel_remote_updated
  WS event, including for channels the local state already knows are not
  shared. The server publishes this event from the onInvite callback after
  a remote accepts a channel invitation, by which point the channel has
  already been flipped to shared and the channel_updated event that did so
  has already fired, so the local channel should reflect shared=true when
  this event arrives. If it does not, the event is not actionable and we
  skip the fetch.

  Adds jest coverage for the four cases of the new guard.

* add regression test for stale shared channel state

  Pins the DB inconsistency scenario suggested in the original ticket
  investigation: Channel.shared is true and a SharedChannelRemote row
  exists, but the SharedChannels row is missing. The endpoint should
  return 200 with an empty list rather than surfacing the stale state
  as an internal server error. Also tightens the existing
  TestGetSharedChannelRemotes by asserting the status code on the
  success path.
2026-05-22 09:59:15 -04:00
27d144226f Fix inactive team icon active styling (#36683)
Prevent decorative team icons from showing the active sidebar highlight when clicked, and pass the channel ID needed by the access-control subject builder so the current checkout can build.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-05-22 18:31:23 +05:30
cursor[bot] efdebec6ad Fix flaky TestPatchTeam GroupConstrained subtest (#36689) 2026-05-22 08:38:27 -04:00
182049583b Skip flaky TestGetLogs (MM-68910) (#36659)
* Skip flaky TestGetLogs

Skipping while the root cause is investigated under MM-68910.

Tests-only change.

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Address PR feedback: 2 items resolved, 0 declined

* Address PR feedback: 2 items resolved, 0 declined

* Address PR feedback: 2 items resolved, 0 declined

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
2026-05-22 12:50:24 +02:00
Andre Vasconcelos b4aa46a4be Bumping version of prepackaged boards plugin (#36701)
Automatic Merge
2026-05-22 10:53:37 +02:00
209606f15b MM-68419: Add expires_at to PAT data model and enforce expiry at token validation (#36243)
* Add expires_at to PAT data model and enforce expiry at token validation

Adds an ExpiresAt field (int64 millis, 0 = never expires) to the
UserAccessToken model and DB table, enforces expiry when a PAT is used
to create a session, clamps the resulting session's ExpiresAt to the
token's expiry so cached sessions also honor it, ships a background job
(cleanup_expired_access_tokens) that periodically deletes expired
tokens along with any sessions minted from them, and emits audit events
for rejected and reaped expired tokens.

Refs: MM-68419

Co-authored-by: Ben Schumacher <hanzei@users.noreply.github.com>

* Fix govet shadow warnings in DeleteExpired

Co-authored-by: Ben Schumacher <hanzei@users.noreply.github.com>

* Stabilize expired PAT test by persisting an already-expired token

The previous variant created a live token, used it to mint a session,
then backdated the row and revoked the cached session to force a
re-validation. That flow was race-prone under parallel test execution
and was flagged as flaky in CI. Replace it with a direct store write
that persists the PAT with ExpiresAt already in the past, so
createSessionForUserAccessToken is exercised deterministically on the
first HTTP call and no session cache races are possible.

Co-authored-by: Ben Schumacher <hanzei@users.noreply.github.com>

* Address PR review: batched cleanup, consistent filters, audit ordering

- server.go: initialize s.Audit before initJobs() so the cleanup worker
  never captures a nil audit logger.

- Replace DeleteExpired(cutoff) with DeleteByIds([]string) on
  UserAccessTokenStore. The worker now fetches a batch via
  GetExpiredBefore, emits one audit record per token, then deletes
  exactly that batch by id — guaranteeing 1:1 audit/delete pairing
  and eliminating the IsActive-filter mismatch between reads and
  deletes. The worker loops up to maxBatches (=1000) x batchLimit
  (=1000) rows per run and stops when GetExpiredBefore returns less
  than batchLimit or zero rows.

- GetExpiredBefore now selects an explicit column set that omits the
  secret Token column, so the PAT secret never travels from DB to app.

- DeleteByIds surfaces an error from RowsAffected instead of silently
  returning 0.

- Remove dead job.Data initialization in the worker.

- api4 test: set IsActive: true explicitly, walk the AppError chain
  and assert the specific Id app.user_access_token.expired so future
  401 regressions are caught.

Co-authored-by: Ben Schumacher <hanzei@users.noreply.github.com>

* Use named returns in DeleteByIds and clean up expired fixture in test

- DeleteByIds now declares (deleted int64, err error) and uses bare
  returns on every error path so finalizeTransactionX can append a
  rollback failure to the returned error via merror.Append. Previously
  early returns short-circuited the deferred rollback's error
  contribution.
- Add the expired token to the test cleanup so all three fixtures are
  removed even on early test exit.

Co-authored-by: Ben Schumacher <hanzei@users.noreply.github.com>

* Guard GetExpiredBefore against non-positive limit + tighten store test

- GetExpiredBefore now short-circuits when limit <= 0 and returns an
  empty slice without hitting the DB. This prevents the int -> uint64
  cast on a negative value from wrapping into an effectively unbounded
  query.
- Store test now asserts row.Token is empty for every row returned by
  GetExpiredBefore (not just the matched one) to catch any future
  query change that accidentally re-introduces the secret column.
- Added store-level coverage for the limit=0 and limit<0 short-circuit
  contract.

Co-authored-by: Ben Schumacher <hanzei@users.noreply.github.com>

* Add session-clamping and worker tests; bump migration to 172

Address PR test-coverage analysis (issuecomment-4336010565):

- api4/user_test.go: add two subtests covering session.ExpiresAt
  behavior — clamped to token.ExpiresAt when the PAT has a non-zero
  ExpiresAt, and untouched (long-lived) when the PAT has no expiry.
- cleanup_expired_access_tokens/worker.go: extract the batching/audit/
  error orchestration into a package-private cleanupExpired() taking
  small interfaces (expiredTokenStore, auditRecorder) so it can be
  unit-tested without spinning up a job server.
- cleanup_expired_access_tokens/worker_test.go (new): seven unit tests
  cover happy path, empty result, full-batch -> next iteration,
  maxIter cap, GetExpiredBefore error propagation, DeleteByIds error
  propagation, and nil auditLogger guard.
- Bump migration 000170_add_expiresat_to_user_access_tokens to 000172
  to slot in behind the master-side 000170 (property_groups_version)
  and 000171 (drop_property_fields_protected_index).

Co-authored-by: Ben Schumacher <hanzei@users.noreply.github.com>

* Fix PAT expiry audit ordering and cleanup scheduler gate

- Move IsExpired() check after EnableUserAccessTokens gate in
  createSessionForUserAccessToken so the AuditEventRejectExpiredUserAccessToken
  event only fires when PATs are active for the user, not when the feature
  is globally disabled.
- Tie the cleanup_expired_access_tokens scheduler to EnableUserAccessTokens
  so the hourly job does not schedule on servers where PATs are disabled.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Remove per-token audit logging from expired PAT cleanup job

Background system jobs do not emit audit events in this codebase —
only user/admin-initiated actions do. The cleanup worker's per-token
AuditEventExpireUserAccessToken records were inconsistent with that
pattern (cleanup_desktop_tokens and other session jobs log nothing).

Also removes the early s.Audit init in NewServer that existed solely
to supply a non-nil logger to the worker.

The AuditEventRejectExpiredUserAccessToken event (emitted by
createSessionForUserAccessToken when a live request is rejected) is
unchanged — that is an auth gate firing in response to a request and
warrants auditing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Replace hand-rolled IN-clause helpers with squirrel query builder

Remove placeholders() and idsToArgs() from DeleteByIds — squirrel's
sq.Eq{"column": slice} generates the IN clause and argument list
automatically, matching the pattern used throughout the sqlstore package.

Also restructures the sessions delete from a PostgreSQL-specific
USING join to a portable subquery, keeping both statements expressible
via the query builder.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Drop redundant logger.Error calls in cleanup worker

SimpleWorker already logs any error returned from execute at the
Error level (base_workers.go:86). The extra logger.Error calls before
return were double-logging every failure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Use mlog.CreateConsoleTestLogger in cleanup worker tests

Replaces the hand-rolled newTestLogger helper with the established
mlog.CreateConsoleTestLogger(t) pattern used by other job tests in
this package (jobs_test.go, recap/worker_test.go). It wires cleanup
and test-runner output automatically.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Consolidate cleanup worker tests into subtests

Groups the six top-level TestCleanupExpiredXxx functions under a single
TestCleanupExpired parent with t.Run subtests. One shared logger is
created at the parent level; each subtest gets its own fakeStore.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Revert incidental configureAudit restructure in server.go

The separation of s.Audit init from configureAudit was an unintended
side effect of an earlier commit. Restore the original pattern where
configureAudit is only called when s.Audit was nil at startup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Remove api4 PAT expiry tests until API endpoint exists

The three tests (expired token rejected, session clamped, no-expiry
default) bypass the API to inject ExpiresAt via the store directly,
since no API endpoint exists yet to create tokens with an expiry.
They belong in the PR that adds that endpoint.

The same behaviors are covered at the appropriate layer by
storetest/user_access_token_store.go and model/user_access_token_test.go.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Prevent ExtendSessionExpiryIfNeeded from overriding PAT session expiry

PAT-authenticated sessions have their ExpiresAt clamped to the token's
ExpiresAt in createSessionForUserAccessToken. However, ExtendSessionExpiryIfNeeded
was resetting that expiry to now+SessionLengthWebInHours on the first
subsequent request, effectively bypassing PAT expiry for cached sessions.

Guard the extension to skip SessionTypeUserAccessToken sessions until
GetSessionLengthInMillis learns to return a length bounded by token.ExpiresAt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Strip ExpiresAt in create-token handler until API officially supports it

The JSON decoder populates the full accessToken struct from the request body,
and only UserId and Token were being overwritten before the store call. This
allowed clients to set an arbitrary expires_at (including 0 for non-expiring)
through the existing endpoint, contradicting the PR description.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Clear session cache for affected users after DeleteByIds in cleanup worker

DeleteByIds removes sessions from the DB but did not invalidate the in-memory
session cache. This left stale sessions readable from cache until eviction,
inconsistent with the RevokeSession path.

Thread a clearSessionCache callback through MakeWorker and cleanupExpired.
After each successful batch delete, call it for each unique UserId in the
batch. The callback is deduplicated per batch to avoid redundant cache
invalidations when a user has multiple expired tokens.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Add partial index on useraccesstokens.expiresat

The cleanup job queries expiresat on every scheduled run (hourly). Without an
index this is a full sequential scan. Add a partial index WHERE expiresat > 0
to match the query's filter, keeping the index small since most tokens have no
expiry set. Mirrors the idx_sessions_expires_at pattern on the sessions table.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Register JobTypeCleanupExpiredAccessTokens in job permission switches

Without entries in SessionHasPermissionToReadJob, SessionHasPermissionToCreateJob,
and SessionHasPermissionToManageJob, the job type falls through to (false, nil),
which API handlers treat as HTTP 400. This made the cleanup job invisible to
System Console and unmanageable via API (list, cancel, manual trigger all 400).

Add the job type to the PermissionManageJobs / PermissionReadJobs groups in
all three switches, matching how other internal jobs like JobTypeMigrations
are handled.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Teach GetSessionLengthInMillis to honor PAT ExpiresAt

Replace the blunt guard in ExtendSessionExpiryIfNeeded with proper logic in
GetSessionLengthInMillis: for PAT sessions with a fixed ExpiresAt, return the
remaining lifetime instead of the configured web-session hours.

This means newExpiry = now + (ExpiresAt - now) = ExpiresAt, so extension never
pushes the session past the token's own expiry. The elapsed threshold
collapses to zero for such sessions, so no spurious DB writes occur either.

Non-expiring PAT sessions (ExpiresAt == 0) continue to use normal web-session
extension, which is correct behavior.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Split expiresat index into separate non-transactional migration (000175)

CREATE INDEX CONCURRENTLY cannot run inside a transaction block. The morph
migration runner wraps each file in a transaction by default, causing the
combined migration to fail.

Split the index creation out of 000174 into a new 000175 migration file
with the -- morph:nontransactional directive, following the same pattern
used by 000135, 000155, 000173 and others. The 174 down migration no longer
needs to drop the index since 175 owns it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update Beginx call to renamed Begin (sqlx wrapper API change on master)

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Ben Schumacher <hanzei@users.noreply.github.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 10:30:30 +02:00
+11 b0d2f83620 Translations update from Mattermost Weblate (#36695)
* Translated using Weblate (Lithuanian)

Currently translated at 62.6% (4601 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/lt/

* Translated using Weblate (Lithuanian)

Currently translated at 62.6% (4601 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/lt/

* Translated using Weblate (Estonian)

Currently translated at 0.4% (31 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/et/

* Translated using Weblate (Estonian)

Currently translated at 0.4% (31 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/et/

* Translated using Weblate (Danish)

Currently translated at 8.1% (266 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/da/

* Translated using Weblate (Danish)

Currently translated at 8.1% (266 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/da/

* Translated using Weblate (Italian)

Currently translated at 44.6% (3281 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/it/

* Translated using Weblate (Italian)

Currently translated at 44.6% (3281 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/it/

* Translated using Weblate (Belarusian)

Currently translated at 88.6% (6509 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/be/

* Translated using Weblate (Khmer (Central))

Currently translated at 0.6% (48 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/km/

* Translated using Weblate (Khmer (Central))

Currently translated at 0.6% (48 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/km/

* Translated using Weblate (Latin)

Currently translated at 0.0% (0 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/la/

* Translated using Weblate (Latin)

Currently translated at 0.0% (0 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/la/

* Translated using Weblate (Latin)

Currently translated at 0.0% (0 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/la/

* Translated using Weblate (Persian)

Currently translated at 54.5% (4006 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fa/

* Translated using Weblate (Persian)

Currently translated at 54.5% (4006 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fa/

* Translated using Weblate (Portuguese)

Currently translated at 27.1% (1993 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pt/

* Translated using Weblate (Portuguese)

Currently translated at 27.1% (1993 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pt/

* Translated using Weblate (Albanian)

Currently translated at 3.1% (228 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sq/

* Translated using Weblate (Albanian)

Currently translated at 3.1% (228 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sq/

* Translated using Weblate (Catalan)

Currently translated at 33.3% (1089 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/ca/

* Translated using Weblate (Lao)

Currently translated at 0.1% (1 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/lo/

* Translated using Weblate (Macedonian)

Currently translated at 1.7% (126 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/mk/

* Translated using Weblate (Macedonian)

Currently translated at 1.7% (126 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/mk/

* Translated using Weblate (Hungarian)

Currently translated at 62.9% (2058 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/hu/

* Translated using Weblate (Estonian)

Currently translated at 0.5% (19 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/et/

* Translated using Weblate (Georgian)

Currently translated at 7.1% (525 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ka/

* Translated using Weblate (Georgian)

Currently translated at 7.1% (525 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ka/

* Translated using Weblate (Georgian)

Currently translated at 7.1% (525 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ka/

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 4.4% (147 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nb_NO/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 99.4% (7304 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/zh_Hans/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 99.4% (7304 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/zh_Hans/

* Translated using Weblate (Nepali)

Currently translated at 0.1% (6 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/ne/

* Translated using Weblate (Malayalam)

Currently translated at 3.7% (272 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ml/

* Translated using Weblate (Malayalam)

Currently translated at 3.7% (272 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ml/

* Translated using Weblate (Mongolian)

Currently translated at 0.6% (21 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/mn/

* Translated using Weblate (French)

Currently translated at 65.2% (4788 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fr/

* Translated using Weblate (French)

Currently translated at 65.2% (4788 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fr/

* Translated using Weblate (Swedish)

Currently translated at 83.6% (2733 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sv/

* Translated using Weblate (Japanese)

Currently translated at 91.4% (6715 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ja/

* Translated using Weblate (Japanese)

Currently translated at 91.4% (6715 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ja/

* Translated using Weblate (Croatian)

Currently translated at 25.8% (1896 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/hr/

* Translated using Weblate (Croatian)

Currently translated at 25.8% (1896 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/hr/

* Translated using Weblate (Filipino)

Currently translated at 0.0% (0 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fil/

* Translated using Weblate (Filipino)

Currently translated at 0.0% (0 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fil/

* Translated using Weblate (Filipino)

Currently translated at 0.0% (0 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fil/

* Translated using Weblate (Romanian)

Currently translated at 48.3% (3551 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ro/

* Translated using Weblate (Romanian)

Currently translated at 48.3% (3551 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ro/

* Translated using Weblate (Amharic)

Currently translated at 0.1% (4 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/am/

* Translated using Weblate (Amharic)

Currently translated at 0.1% (4 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/am/

* Translated using Weblate (Sinhala)

Currently translated at 0.3% (12 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/si/

* Translated using Weblate (French)

Currently translated at 65.1% (2129 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/fr/

* Translated using Weblate (Bengali)

Currently translated at 0.9% (70 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/bn/

* Translated using Weblate (Bengali)

Currently translated at 0.9% (70 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/bn/

* Translated using Weblate (Bengali)

Currently translated at 0.9% (70 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/bn/

* Translated using Weblate (Georgian)

Currently translated at 3.6% (120 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/ka/

* Translated using Weblate (Georgian)

Currently translated at 3.6% (120 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/ka/

* Translated using Weblate (Romanian)

Currently translated at 58.0% (1897 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/ro/

* Translated using Weblate (Frisian)

Currently translated at 56.6% (4161 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fy/

* Translated using Weblate (Frisian)

Currently translated at 56.6% (4161 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fy/

* Translated using Weblate (Frisian)

Currently translated at 56.6% (4161 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fy/

* Translated using Weblate (Russian)

Currently translated at 80.7% (2638 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/ru/

* Translated using Weblate (Kazakh)

Currently translated at 12.7% (938 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/kk/

* Translated using Weblate (Kazakh)

Currently translated at 12.7% (938 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/kk/

* Translated using Weblate (Kazakh)

Currently translated at 12.7% (938 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/kk/

* Translated using Weblate (English (Australia))

Currently translated at 88.0% (2875 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/en_AU/

* Translated using Weblate (English (Australia))

Currently translated at 88.0% (2875 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/en_AU/

* Translated using Weblate (Hindi)

Currently translated at 26.7% (1961 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/hi/

* Translated using Weblate (Hindi)

Currently translated at 26.7% (1961 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/hi/

* Translated using Weblate (Dutch)

Currently translated at 98.4% (7230 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/

* Translated using Weblate (Dutch)

Currently translated at 98.4% (7230 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/

* Translated using Weblate (Galician)

Currently translated at 19.8% (1458 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/gl/

* Translated using Weblate (Galician)

Currently translated at 19.8% (1458 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/gl/

* Translated using Weblate (Swedish)

Currently translated at 88.4% (6497 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/

* Translated using Weblate (Swedish)

Currently translated at 88.4% (6497 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/

* Translated using Weblate (Arabic)

Currently translated at 0.1% (7 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ar/

* Translated using Weblate (Arabic)

Currently translated at 0.1% (7 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ar/

* Translated using Weblate (Albanian)

Currently translated at 0.9% (32 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sq/

* Translated using Weblate (Vietnamese)

Currently translated at 66.5% (2174 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/vi/

* Translated using Weblate (German)

Currently translated at 90.6% (2962 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/de/

* Translated using Weblate (German)

Currently translated at 90.6% (2962 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/de/

* Translated using Weblate (Latvian)

Currently translated at 0.3% (24 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/lv/

* Translated using Weblate (Latvian)

Currently translated at 0.3% (24 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/lv/

* Translated using Weblate (Latvian)

Currently translated at 0.3% (24 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/lv/

* Translated using Weblate (Thai)

Currently translated at 1.0% (77 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/th/

* Translated using Weblate (Thai)

Currently translated at 1.0% (77 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/th/

* Translated using Weblate (English (Australia))

Currently translated at 94.2% (6922 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/en_AU/

* Translated using Weblate (Serbian)

Currently translated at 8.4% (275 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sr/

* Translated using Weblate (Turkish)

Currently translated at 83.4% (2725 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/tr/

* Translated using Weblate (Turkish)

Currently translated at 83.4% (2725 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/tr/

* Translated using Weblate (Portuguese)

Currently translated at 6.3% (207 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pt/

* Translated using Weblate (Greek)

Currently translated at 25.3% (829 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/el/

* Translated using Weblate (Gujarati)

Currently translated at 0.1% (9 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/gu/

* Translated using Weblate (Gujarati)

Currently translated at 0.1% (9 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/gu/

* Translated using Weblate (Arabic (Saudi Arabia))

Currently translated at 0.0% (0 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ar_SA/

* Translated using Weblate (Arabic (Saudi Arabia))

Currently translated at 0.0% (0 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ar_SA/

* Translated using Weblate (English (Pirate))

Currently translated at 0.1% (2 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/en@pirate/

* Translated using Weblate (English (Pirate))

Currently translated at 0.1% (2 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/en@pirate/

* Translated using Weblate (English (Pirate))

Currently translated at 0.1% (2 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/en@pirate/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 98.1% (3208 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/zh_Hans/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 98.1% (3208 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/zh_Hans/

* Translated using Weblate (Bulgarian)

Currently translated at 61.5% (2011 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/bg/

* Translated using Weblate (Bulgarian)

Currently translated at 61.5% (2011 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/bg/

* Translated using Weblate (Korean)

Currently translated at 79.5% (2600 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/ko/

* Translated using Weblate (Korean)

Currently translated at 79.5% (2600 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/ko/

* Translated using Weblate (Indonesian)

Currently translated at 27.0% (883 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/id/

* Translated using Weblate (Basque)

Currently translated at 1.3% (43 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/eu/

* Translated using Weblate (Slovenian)

Currently translated at 13.8% (1015 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sl/

* Translated using Weblate (Slovenian)

Currently translated at 13.8% (1015 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sl/

* Translated using Weblate (Arabic (Saudi Arabia))

Currently translated at 0.0% (0 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/ar_SA/

* Translated using Weblate (Breton)

Currently translated at 0.1% (7 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/br/

* Translated using Weblate (Breton)

Currently translated at 0.1% (7 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/br/

* Translated using Weblate (Bulgarian)

Currently translated at 59.0% (4335 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/bg/

* Translated using Weblate (Bulgarian)

Currently translated at 59.0% (4335 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/bg/

* Translated using Weblate (Amharic)

Currently translated at 3.0% (101 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/am/

* Translated using Weblate (Thai)

Currently translated at 0.7% (23 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/th/

* Translated using Weblate (Polish)

Currently translated at 99.4% (7304 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/

* Translated using Weblate (Polish)

Currently translated at 99.4% (7304 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/

* Translated using Weblate (Korean)

Currently translated at 84.1% (6179 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ko/

* Translated using Weblate (Korean)

Currently translated at 84.1% (6179 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ko/

* Translated using Weblate (Slovenian)

Currently translated at 33.4% (1092 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sl/

* Translated using Weblate (Slovenian)

Currently translated at 33.4% (1092 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sl/

* Translated using Weblate (Chinese (Traditional Han script))

Currently translated at 75.3% (5535 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/zh_Hant/

* Translated using Weblate (Chinese (Traditional Han script))

Currently translated at 75.3% (5535 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/zh_Hant/

* Translated using Weblate (Finnish)

Currently translated at 38.2% (1249 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/fi/

* Translated using Weblate (Japanese)

Currently translated at 81.5% (2665 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/ja/

* Translated using Weblate (Japanese)

Currently translated at 81.5% (2665 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/ja/

* Translated using Weblate (Catalan)

Currently translated at 1.6% (121 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ca/

* Translated using Weblate (Catalan)

Currently translated at 1.6% (121 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ca/

* Translated using Weblate (Mongolian)

Currently translated at 1.6% (124 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/mn/

* Translated using Weblate (Mongolian)

Currently translated at 1.6% (124 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/mn/

* Translated using Weblate (Polish)

Currently translated at 96.6% (3159 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pl/

* Translated using Weblate (Polish)

Currently translated at 96.6% (3159 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pl/

* Translated using Weblate (Hebrew)

Currently translated at 0.6% (50 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/he/

* Translated using Weblate (Hebrew)

Currently translated at 0.6% (50 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/he/

* Translated using Weblate (Belarusian)

Currently translated at 85.6% (2799 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/be/

* Translated using Weblate (Belarusian)

Currently translated at 85.6% (2799 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/be/

* Translated using Weblate (Turkish)

Currently translated at 91.8% (6747 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/tr/

* Translated using Weblate (Turkish)

Currently translated at 91.8% (6747 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/tr/

* Translated using Weblate (Turkish)

Currently translated at 91.8% (6747 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/tr/

* Translated using Weblate (Italian)

Currently translated at 62.0% (2026 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/it/

* Translated using Weblate (Spanish)

Currently translated at 60.2% (4426 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/es/

* Translated using Weblate (Spanish)

Currently translated at 60.2% (4426 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/es/

* Translated using Weblate (Basque)

Currently translated at 0.1% (11 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/eu/

* Translated using Weblate (Basque)

Currently translated at 0.1% (11 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/eu/

* Translated using Weblate (Vietnamese)

Currently translated at 62.1% (4562 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/vi/

* Translated using Weblate (Vietnamese)

Currently translated at 62.1% (4562 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/vi/

* Translated using Weblate (Czech)

Currently translated at 82.2% (6037 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/cs/

* Translated using Weblate (Czech)

Currently translated at 82.2% (6037 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/cs/

* Translated using Weblate (Icelandic)

Currently translated at 0.0% (0 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/is/

* Translated using Weblate (Icelandic)

Currently translated at 0.0% (0 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/is/

* Translated using Weblate (Icelandic)

Currently translated at 0.0% (0 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/is/

* Translated using Weblate (Danish)

Currently translated at 8.9% (659 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/da/

* Translated using Weblate (Danish)

Currently translated at 8.9% (659 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/da/

* Translated using Weblate (Serbian)

Currently translated at 7.6% (559 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sr/

* Translated using Weblate (Serbian)

Currently translated at 7.6% (559 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sr/

* Translated using Weblate (Breton)

Currently translated at 0.8% (29 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/br/

* Translated using Weblate (German)

Currently translated at 96.2% (7071 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/

* Translated using Weblate (German)

Currently translated at 96.2% (7071 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/

* Translated using Weblate (Indonesian)

Currently translated at 2.6% (191 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/id/

* Translated using Weblate (Indonesian)

Currently translated at 2.6% (191 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/id/

* Translated using Weblate (Chinese (Traditional Han script))

Currently translated at 73.3% (2396 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/zh_Hant/

* Translated using Weblate (Arabic)

Currently translated at 0.5% (18 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/ar/

* Translated using Weblate (Kazakh (Latin script))

Currently translated at 3.2% (235 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/kk_Latn/

* Translated using Weblate (Kazakh (Latin script))

Currently translated at 3.2% (235 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/kk_Latn/

* Translated using Weblate (Kazakh (Latin script))

Currently translated at 3.2% (235 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/kk_Latn/

* Translated using Weblate (Gujarati)

Currently translated at 0.5% (19 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/gu/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 74.5% (2436 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pt_BR/

* Translated using Weblate (Czech)

Currently translated at 81.7% (2670 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/cs/

* Translated using Weblate (Czech)

Currently translated at 81.7% (2670 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/cs/

* Translated using Weblate (Persian)

Currently translated at 60.0% (1963 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/fa/

* Translated using Weblate (Hungarian)

Currently translated at 59.6% (4383 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/hu/

* Translated using Weblate (Hungarian)

Currently translated at 59.6% (4383 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/hu/

* Translated using Weblate (Hungarian)

Currently translated at 59.6% (4383 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/hu/

* Translated using Weblate (Hebrew)

Currently translated at 1.1% (39 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/he/

* Translated using Weblate (Finnish)

Currently translated at 20.9% (1538 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fi/

* Translated using Weblate (Finnish)

Currently translated at 20.9% (1538 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fi/

* Translated using Weblate (Croatian)

Currently translated at 8.0% (264 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/hr/

* Translated using Weblate (Sinhala)

Currently translated at 0.1% (10 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/si/

* Translated using Weblate (Sinhala)

Currently translated at 0.1% (10 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/si/

* Translated using Weblate (Greek)

Currently translated at 6.5% (482 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/el/

* Translated using Weblate (Greek)

Currently translated at 6.5% (482 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/el/

* Translated using Weblate (Malayalam)

Currently translated at 8.9% (292 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/ml/

* Translated using Weblate (Galician)

Currently translated at 1.7% (58 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/gl/

* Translated using Weblate (Ukrainian)

Currently translated at 80.4% (5905 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/uk/

* Translated using Weblate (Ukrainian)

Currently translated at 80.4% (5905 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/uk/

* Translated using Weblate (Nepali)

Currently translated at 5.7% (424 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ne/

* Translated using Weblate (Nepali)

Currently translated at 5.7% (424 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ne/

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 76.4% (5613 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 76.4% (5613 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 76.4% (5613 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/

* Translated using Weblate (Hindi)

Currently translated at 58.5% (1913 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/hi/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 62.0% (4557 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pt_BR/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 62.0% (4557 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pt_BR/

* Translated using Weblate (Khmer (Central))

Currently translated at 0.7% (26 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/km/

* Translated using Weblate (Lithuanian)

Currently translated at 6.7% (221 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/lt/

* Translated using Weblate (Ukrainian)

Currently translated at 78.5% (2567 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/uk/

* Translated using Weblate (Ukrainian)

Currently translated at 78.5% (2567 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/uk/

* Translated using Weblate (Spanish)

Currently translated at 67.0% (2191 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/es/

* Translated using Weblate (Spanish)

Currently translated at 67.0% (2191 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/es/

* Translated using Weblate (Spanish)

Currently translated at 67.0% (2191 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/es/

* Translated using Weblate (Dutch)

Currently translated at 95.8% (3131 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nl/

* Translated using Weblate (Macedonian)

Currently translated at 6.7% (221 of 3267 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/mk/

* Translated using Weblate (Lao)

Currently translated at 3.9% (290 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/lo/

* Translated using Weblate (Lao)

Currently translated at 3.9% (290 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/lo/

* Translated using Weblate (Russian)

Currently translated at 76.7% (5636 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ru/

* Translated using Weblate (Russian)

Currently translated at 76.7% (5636 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ru/

* Translated using Weblate (Russian)

Currently translated at 76.7% (5636 of 7343 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ru/

* Update translation files

Updated by "Remove blank strings" hook in Weblate.

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/

* Update translation files

Updated by "Remove blank strings" hook in Weblate.

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/

---------

Co-authored-by: jprusch <rs@schaeferbarthold.de>
Co-authored-by: Martin Popp Fredslund (SektorCERT) <martin@sektorcert.dk>
Co-authored-by: Tom De Moor <tom@controlaltdieliet.be>
Co-authored-by: Ekaterine Papava <papava.e@gtu.ge>
Co-authored-by: Sharuru <mave@foxmail.com>
Co-authored-by: Matthew Williams <Matthew.Williams@outlook.com.au>
Co-authored-by: Kristoffer Grundström <swedishsailfishosuser@tutanota.com>
Co-authored-by: Kaya Zeren <kayazeren@gmail.com>
Co-authored-by: Nikolai Zahariev <nikolaiz@yahoo.com>
Co-authored-by: master7 <marcin.karkosz@rajska.info>
Co-authored-by: DeepL <noreply-mt-deepl@weblate.org>
Co-authored-by: Takayuki Maruyama <bis5.wsys@gmail.com>
Co-authored-by: Vadim Asadchi <vadim.asadchi@codex-soft.com>
Co-authored-by: Martin Mičuda <micuda@rematiptop.cz>
Co-authored-by: ritchierope <ritchierope@users.noreply.translate.mattermost.com>
Co-authored-by: Frank Paul Silye <frankps@gmail.com>
Co-authored-by: Serhii Khomiuk <sergiy.khomiuk@gmail.com>
Co-authored-by: Ricardo Obregón <robregonm@gmail.com>
Co-authored-by: Carloswaldo <waldosaurio@gmail.com>
Co-authored-by: Dmitriy Q <krotesk@mail.ru>
2026-05-22 01:47:43 +00:00
cursor[bot] 6ee3fb9af1 Fix membership policy edit action navigation (#36690)
Automatic Merge
2026-05-22 01:23:39 +02:00