mirror of
https://github.com/mattermost/mattermost.git
synced 2026-09-19 02:06:37 +08:00
e3823a51ce5ce522f296306dbcb142dd76a5c07e
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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 |
||
|
|
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> |
||
|
|
42f021581f | Tighten CI workflows (#36778) | ||
|
|
800810e880 | [MM-69028] Enable ClassificationMarkings feature flag by default (#36776) | ||
|
|
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>
|
||
|
|
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> |
||
|
|
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> |
||
|
|
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. |
||
|
|
a6e019863e | [MM-68999] Add SchemaVersion to PropertyGroup for group-specific field schema versioning (#36747) | ||
|
|
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> |
||
|
|
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> |
||
|
|
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 |
||
|
|
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> |
||
|
|
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 |
||
|
|
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> |
||
|
|
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> |
||
|
|
41367fa7b1 | Fix missing peer fields in package-lock.json (#36744) | ||
|
|
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>
|
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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
|
||
|
|
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. |
||
|
|
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 |
||
|
|
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 |
||
|
|
b609ec59fc |
chore: Update NOTICE.txt file with updated dependencies (#36729)
Automatic Merge |
||
|
|
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> |
||
|
|
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. |
||
|
|
cfafefe58c | Used short mode of data spillage report card in threads view to fix spacing issue (#36709) | ||
|
|
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> |
||
|
|
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> |
||
|
|
b60ba8b6b4 | chore(ci): allow build-server-image to build and push from release branches (#36716) | ||
|
|
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 |
||
|
|
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> |
||
|
|
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 |
||
|
|
f8e233cc39 | Fix Group Details role dropdown not updating UI when changing role (#36561) | ||
|
|
e8632bd456 |
[MM-68777] Add admin property field permission level (#36558)
|
||
|
|
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> |
||
|
|
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.
|
||
|
|
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> |
||
|
|
efdebec6ad | Fix flaky TestPatchTeam GroupConstrained subtest (#36689) | ||
|
|
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> |
||
|
|
b4aa46a4be |
Bumping version of prepackaged boards plugin (#36701)
Automatic Merge |
||
|
|
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> |
||
|
+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> |
||
|
|
6ee3fb9af1 |
Fix membership policy edit action navigation (#36690)
Automatic Merge |