Commit graph

22569 commits

Author SHA1 Message Date
Harshil Sharma
8f6a7f5093 i18n fix 2026-05-26 13:35:07 +05:30
Harshil Sharma
94b52978eb fix test 2026-05-26 13:06:03 +05:30
Harshil Sharma
d3cd57507b Some improvements 2026-05-26 12:29:08 +05:30
Harshil Sharma
3586e21ad0 Optimisation 2026-05-26 11:49:35 +05:30
Harshil Sharma
6a76833148 Added tracking 2026-05-26 07:56:05 +05:30
Harshil Sharma
6b7d9ec905 Renamed storage 2026-05-26 06:52:32 +05:30
Harshil Sharma
4ff072e4e0 WIP 2026-05-25 11:31:44 +05:30
Harshil Sharma
cfafefe58c
Used short mode of data spillage report card in threads view to fix spacing issue (#36709)
Some checks are pending
Server CI / Postgres (shard 0) (push) Blocked by required conditions
Server CI / Postgres (shard 1) (push) Blocked by required conditions
Server CI / Postgres (shard 2) (push) Blocked by required conditions
Server CI / Postgres (shard 3) (push) Blocked by required conditions
Server CI / Merge Postgres Test Results (push) Blocked by required conditions
Server CI / Elasticsearch v8 Compatibility (push) Blocked by required conditions
Server CI / OpenSearch v2 Compatibility (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 0) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 1) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 2) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 3) (push) Blocked by required conditions
Server CI / Merge Postgres FIPS Test Results (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Tools CI / check-style (mattermost-govet) (push) Waiting to run
Tools CI / Test (mattermost-govet) (push) Waiting to run
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-external-links (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
YAML Lint / yamllint (push) Waiting to run
2026-05-25 09:36:01 +05:30
cursor[bot]
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
cursor[bot]
7e75035cb6
Add Data Spillage discovery page (#36697)
Some checks failed
Server CI / Check migration files (push) Has been cancelled
Server CI / Generate email templates (push) Has been cancelled
Server CI / Check store layers (push) Has been cancelled
Server CI / Check mmctl docs (push) Has been cancelled
Server CI / Postgres (shard 0) (push) Has been cancelled
Server CI / Postgres (shard 1) (push) Has been cancelled
Server CI / Postgres (shard 2) (push) Has been cancelled
Server CI / Postgres (shard 3) (push) Has been cancelled
Server CI / Merge Postgres Test Results (push) Has been cancelled
Server CI / Elasticsearch v8 Compatibility (push) Has been cancelled
Server CI / OpenSearch v2 Compatibility (push) Has been cancelled
Server CI / Postgres FIPS (shard 0) (push) Has been cancelled
Server CI / Postgres FIPS (shard 1) (push) Has been cancelled
Server CI / Postgres FIPS (shard 2) (push) Has been cancelled
Server CI / Postgres FIPS (shard 3) (push) Has been cancelled
Server CI / Merge Postgres FIPS Test Results (push) Has been cancelled
Server CI / Run mmctl tests (push) Has been cancelled
Server CI / Run mmctl tests (FIPS) (push) Has been cancelled
Server CI / Build mattermost server app (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
* 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élez
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
cursor[bot]
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)
Some checks are pending
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres (shard 0) (push) Blocked by required conditions
Server CI / Postgres (shard 1) (push) Blocked by required conditions
Server CI / Postgres (shard 2) (push) Blocked by required conditions
Server CI / Postgres (shard 3) (push) Blocked by required conditions
Server CI / Merge Postgres Test Results (push) Blocked by required conditions
Server CI / Elasticsearch v8 Compatibility (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 0) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 1) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 2) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 3) (push) Blocked by required conditions
Server CI / Merge Postgres FIPS Test Results (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Tools CI / check-style (mattermost-govet) (push) Waiting to run
Tools CI / Test (mattermost-govet) (push) Waiting to run
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-external-links (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
YAML Lint / yamllint (push) Waiting to run
* 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
cursor[bot]
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
cursor[bot]
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
Ben Schumacher
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
Weblate (bot)
b0d2f83620
Translations update from Mattermost Weblate (#36695)
Some checks are pending
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres (shard 0) (push) Blocked by required conditions
Server CI / Postgres (shard 1) (push) Blocked by required conditions
Server CI / Postgres (shard 2) (push) Blocked by required conditions
Server CI / Postgres (shard 3) (push) Blocked by required conditions
Server CI / Merge Postgres Test Results (push) Blocked by required conditions
Server CI / Elasticsearch v8 Compatibility (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 0) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 1) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 2) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 3) (push) Blocked by required conditions
Server CI / Merge Postgres FIPS Test Results (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Tools CI / check-style (mattermost-govet) (push) Waiting to run
Tools CI / Test (mattermost-govet) (push) Waiting to run
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-external-links (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
YAML Lint / yamllint (push) Waiting to run
* 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
Nick Misasi
3570814ddd
MM-68316: add mattermost db ping subcommand (#36406)
Some checks are pending
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres (shard 0) (push) Blocked by required conditions
Server CI / Postgres (shard 1) (push) Blocked by required conditions
Server CI / Postgres (shard 2) (push) Blocked by required conditions
Server CI / Postgres (shard 3) (push) Blocked by required conditions
Server CI / Merge Postgres Test Results (push) Blocked by required conditions
Server CI / Elasticsearch v8 Compatibility (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 0) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 1) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 2) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 3) (push) Blocked by required conditions
Server CI / Merge Postgres FIPS Test Results (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Tools CI / check-style (mattermost-govet) (push) Waiting to run
Tools CI / Test (mattermost-govet) (push) Waiting to run
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-external-links (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
YAML Lint / yamllint (push) Waiting to run
* MM-68316: add `mattermost db ping` subcommand

Adds a one-shot DB-readiness CLI that opens a connection to the
configured PostgreSQL DSN and exits 0 when reachable. Honours
--timeout (default 5m) and --retry-interval (default 2s); reads the
DSN from --config / MM_CONFIG / MM_SQLSETTINGS_DATASOURCE matching
the existing `db init`/`db migrate` semantics.

Intended primarily as an init-container readiness check for the
mattermost-operator, removing its dependency on a separate
postgres:13 image (relevant for air-gapped deployments).

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

* MM-68316: address PR feedback (sanitize ping retry log)

Drop mlog.Err(err) from the per-attempt "Waiting for database" log line in
pingWithRetry: lib/pq error strings can echo DSN fragments back at operators
when DSN parsing fails. Replace with a non-sensitive status field. Also
clarifies the TestDBPingInvalidDSN comment to reflect actual lib/pq behavior
(parse error surfaces at PingContext, not Open, so the retry loop treats it
as transient — desired for a readiness probe).

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

* MM-68316 Preserve safe db ping DSN errors

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-05-21 18:46:52 +00:00
Christopher Poile
03f2eaaa0b
[MM-68400] Four plugin hooks and ChannelGuard enforcement (#36152)
* allow workflow_dispatch trigger for Server CI (for plugins CI)

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

* [MM-68402] MBE Phase 2: declare four generic plugin hooks (#36291)

* new hooks-only phase 2

* remove ChannelWillBeMoved

* remove RecapWillBeProcessed and MessageWillBeRewrittenByAI

Drop the AI/recap hooks from the new-hook surface; AI-LLM paths
remain uncovered in tech preview and are documented as residuals.

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

* [MM-68403] MBE Phase 3: ChannelGuards primitive (storage + cache + plugin API) (#36365)

* phase 3

* phase 3: register ChannelGuard mock in test setup helper

NewChannels' startup-time call to reloadGuardCache invokes
s.ChannelGuard().GetAll(); without an expectation on the mock store,
every test that sets up the server with GetMockStoreForSetupFunctions
panics during init.

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

* phase 3: register ChannelGuard mock in retrylayer test

retrylayer.New walks every store getter to wrap it; without the mock
expectation on ChannelGuard, TestRetry panics during layer construction.

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

* use rctx properly in the store methods

* phase 3: match rctx arg in testlib ChannelGuard mock

GetAll now takes request.CTX, so the testify expectation must include
mock.Anything; otherwise the call panics under the mocked store.

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

* phase 3: set api.ctx in TestChannelGuardLowercaseNormalization

The test constructs PluginAPI directly without a ctx, which used to
work when App.RegisterChannelGuard built its own EmptyContext. Now
that the App methods take rctx from the caller, the nil ctx panics
inside RequestContextWithMaster.

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

* [MM-68404] MBE Phase 4: App-layer plugin hook wiring (#36407)

* phase 4

* Fix nil rctx in TestChannelGuardLowercaseNormalization

The PluginAPI struct literal was missing ctx: rctx after a refactor
moved the rctx declaration below the struct construction, leaving
api.ctx as nil. This caused a nil pointer dereference in reloadGuardCache
when RegisterChannelGuard called store.RequestContextWithMaster(nil).

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

* Remove ChannelWillBeMoved hook call from MoveChannel (phase 4)

The hook and its ID were removed from mbe-phase-2 but the call site in
MoveChannel and its i18n string were not cleaned up during the rebase.

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

* remove channel will be moved test

* Remove RecapWillBeProcessed and MessageWillBeRewrittenByAI hook calls (phase 4)

The hooks and their IDs were removed from mbe-phase-2 but the call sites
in ProcessRecapChannel and RewriteMessage, their i18n strings, and their
tests were not cleaned up during the rebase.

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

* Revert channel_id plumbing on rewrite endpoint (phase 4)

The channel_id field on RewriteRequest was added in phase 4 to feed the
synthetic post passed to MessageWillBeRewrittenByAI. With that hook
removed from mbe-phase-2, channel_id has no consumer; revert the field,
the api4 validation, the app.RewriteMessage parameter, and the
corresponding webapp client + hook plumbing.

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

* [MM-68555] MBE Phase 5: Channel-guard enforcement + two-phase dispatch (#36473)

* phase 5

* Bake plugin counter-file paths into source instead of env vars

t.Setenv panics when an ancestor test calls t.Parallel, so the two
channel-guard tests broke under ENABLE_FULLY_PARALLEL_TESTS in CI.
Build each plugin source per-subtest with its temp file path embedded
as a Go literal — same pattern as TestPluginUploadsAPI.

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

* Remove guarded helpers and tests for dropped hooks (phase 5)

The runGuardedRecapWillBeProcessed and runGuardedMessageWillBeRewrittenByAI
helpers were never wired (their app-layer call sites were already removed
in the phase-4 cleanup), and the corresponding sub-tests across panic /
allow / reject / partial plugins reference hooks that no longer exist.

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

* [MM-68405] MBE Phase 6: fire MessagesWillBeConsumed on the edit path (#36475)

---------

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

---------

Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

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

---------

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

* rebase onto master

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-21 18:16:05 +00:00
Jesse Hallam
b9e8d5ce82
MM-68763: fix BuildAccessControlSubject call missing channelID argument (#36681) 2026-05-21 19:18:30 +02:00
Ibrahim Serdar Acikgoz
e6c59693af
MM-68763: Discoverable Private Channels — Server feature complete (visibility, ABAC, queue API) (#36580) 2026-05-21 17:10:51 +02:00
Sven Hüster
29fe2789a0
Exclude webhook posts from thread participation check (#36673)
Some checks are pending
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres (shard 0) (push) Blocked by required conditions
Server CI / Postgres (shard 1) (push) Blocked by required conditions
Server CI / Postgres (shard 2) (push) Blocked by required conditions
Server CI / Postgres (shard 3) (push) Blocked by required conditions
Server CI / Merge Postgres Test Results (push) Blocked by required conditions
Server CI / Elasticsearch v8 Compatibility (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 0) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 1) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 2) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 3) (push) Blocked by required conditions
Server CI / Merge Postgres FIPS Test Results (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Tools CI / check-style (mattermost-govet) (push) Waiting to run
Tools CI / Test (mattermost-govet) (push) Waiting to run
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-external-links (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
YAML Lint / yamllint (push) Waiting to run
* Exclude webhook posts from thread participation check

When determining if the current user has replied to a thread for
comment mention notifications, ignore posts made by webhooks even if
they use the owning user's user_id.

Co-authored-by: Sven Hüster <svelle@users.noreply.github.com>

* Add missing isFromWebhook import in posts selector

Co-authored-by: Sven Hüster <svelle@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Sven Hüster <svelle@users.noreply.github.com>
2026-05-21 15:22:43 +02:00
Asaad Mahmood
eeb3c1ec04
MM-67237 - Open file preview modal when clicking draft attachment thumbnails. (#36590)
* Open file preview modal when clicking draft attachment thumbnails.

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

* Document draft thumbnail preview handler for CodeRabbit/doc checks.

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

* Fix ESLint import/order in FilePreview connector and tests.

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

* Add tests for archived and deleted draft attachment preview guards.

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

* Enable draft attachment preview for all file types.

Draft thumbnails were only clickable for images and SVGs; other attachments now open the standard file preview modal like post attachments do.

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

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 18:12:25 +05:00
Ibrahim Serdar Acikgoz
ba1cec51a5
[MM-68693] Resource level permission policies and new simulation (#36472) 2026-05-21 14:40:05 +02:00
Ben Schumacher
7739b349a0
[MM-68578] Add support packet DB performance diagnostics (#36324)
* Add support packet DB diagnostics for pool and pg_stat

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

* Fix support packet mock store for new DB diagnostics

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

* Add context timeouts to support packet pg diagnostics

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

* Move support packet DB diagnostics queries into sqlstore

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

* Fix support packet diagnostics lint and partial data handling

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

* Stabilize support packet pool idle assertion

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

* Relax live support packet DB counter assertions

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

* Fix deterministic pool diagnostics test wiring

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

* Mock support packet diagnostics in app test store

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

* Move SupportPacketDatabaseDiagnostics out of public model

The struct is an internal store→platform transport (no yaml tags, never
serialized directly) so it doesn't belong in server/public/model where
it would form a public API contract for plugins. Move it into the store
package as the natural return type of GetSupportPacketDatabaseDiagnostics.

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

* Describe SupportPacketDatabaseDiagnostics by content, not history

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

* wording

* Align store diagnostics with sqlstore conventions

- Rename Store.GetSupportPacketDatabaseDiagnostics to Store.GetDiagnostics
  and rename the holding files to diagnostics{,_test}.go.
- Drop the queryRowScanner / rowScanner / sqlQueryRowScanner test seam.
  The collectors now use the sqlxDBWrapper master handle and bind result
  rows into local structs via sqlx GetContext, matching how the rest of
  the sqlstore package talks to Postgres.
- Replace the hand-rolled mock-based unit tests for the Postgres
  collector with an integration test driven through StoreTest, the
  pattern used by the other sqlstore tests (e.g. schema_dump_test.go).
  The pure pool-stats unit test (TestApplyDBPoolStats) is kept.

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

* Drop MasterDBStats/ReplicaDBStats from the Store interface

After GetDiagnostics moved into the store layer, no caller outside the
sqlstore package itself reads MasterDBStats/ReplicaDBStats through the
Store interface — the diagnostics collector calls them on the concrete
*SqlStore receiver. Remove them from the interface, the retry/timer
layer wrappers, the storetest fake, and the generated mock; drop the
now-redundant fixedDBStatsStore shim methods and mock setups in the
support packet tests.

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

* Rename SupportPacketDatabaseDiagnostics to DatabaseDiagnostics

Now that the type lives in the store package and is returned by
Store.GetDiagnostics, the SupportPacket prefix is just legacy framing —
support packets are one consumer of the data, not its identity. Rename
to store.DatabaseDiagnostics for consistency with the package and method
name.

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

* Inline diagnostics SQL into the collector functions

Each pg_stat query has a single caller, so a package-level constant just
adds indirection between the function and the SQL it owns. Move the
query strings to local consts inside the collectors that use them.

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

* Fix Connectios typo to Connections

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

* Fix sqlstore diagnostics build: call GetMaster().DB() method

The recent rebase brought in a change that turned the SqlStore DB
field into a method, so passing ss.GetMaster().DB to
collectPostgresDatabaseDiagnostics (which expects *sqlx.DB) no longer
compiles. Call the method instead.

* Fix gofmt alignment in SupportPacketDiagnostics

The post-merge struct had extra spaces on MasterConnections /
ReplicaConnections that broke gofmt alignment.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Ben Schumacher <hanzei@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 12:45:18 +02:00
cursor[bot]
bc757c5c54
Fix content flagging update for unloaded posts (#36504)
* Fix content flagging update for unloaded posts

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

* Strengthen content flagging reducer tests

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

* Guard content flagging reducer updates

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

* Add non-array content flagging reducer test

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-21 15:14:16 +05:30
Ben Schumacher
2ab07701b5
[MM-68577] Add OAuth2/OpenID Connect provider status to support packet (#36451)
* [MM-68577] Add OAuth2/OpenID Connect provider status to support packet

Probe configured GitLab, Google, Office365, and OpenID providers and report
their connectivity status in the support packet diagnostics. For providers
with a DiscoveryEndpoint, the probe verifies a valid OIDC discovery document
(JSON with an "issuer" field) is returned; otherwise it probes the
TokenEndpoint host, treating any HTTP response as reachable since token
endpoints reject GETs.

Disabled providers report status: disabled, enabled providers report ok or
fail with the underlying error. No secrets are read or transmitted; only
public endpoint URLs are probed.

* [MM-68577] Drain response body in probeOAuthTokenEndpoint

Closing resp.Body without first reading it leaves unread bytes on the wire,
which prevents net/http from returning the underlying TCP connection to the
idle pool for keep-alive reuse. Drain with io.Copy + io.LimitReader (1MB
cap to bound a misbehaving server) and use defer for the close.

* [MM-68577] Extract drainAndCloseBody helper for HTTP probe responses

Three call sites in this file (probeOIDCDiscovery, probeOAuthTokenEndpoint,
testPushProxyConnection) now share the same drain-then-close idiom needed
to keep TCP connections eligible for keep-alive reuse. Replace the inline
copies with a single drainAndCloseBody helper that bounds the discard at
1 MiB to limit exposure to a misbehaving server.

Also fixes the same un-drained Close() bug in the pre-existing
testPushProxyConnection while we're here.

* Add comment explaining 1 MiB discovery response size cap

Addresses review feedback asking for clarity on the 1<<20 limit.
2026-05-21 09:09:20 +00:00
Miguel de la Cruz
6b20092e7a
Fix MM-57406: prevent IPv6 hex segments from parsing as emoji (#36541)
* Fix MM-57406: prevent IPv6 hex segments from parsing as emoji

Add word-boundary lookbehind and lookahead to EMOJI_PATTERN so a
:name: token is only matched when neither side abuts an
alphanumeric/underscore. Without this, hex runs in IPv6
addresses (e.g. :beef: in 2001:18:1:beef::/64) were tokenized and
rendered as custom emoji. The new semantics align with the server
parser at server/public/shared/markdown/emoji.go.

Bump the webapp babel safari target from 16.2 to 16.4 since regex
lookbehind is a syntax feature and is not lowered by
@babel/preset-env. The actual supported minimum is well above 16.4, so
the previous target was stale.

Add regression tests for the IPv6 case and guardrail tests for
back-to-back, paren-wrapped, and punctuation-terminated emoji.  Update
the existing asdf🐐asdf💨asdf test to reflect the
new (server-aligned) semantics.

* Dedupe word-char class in EMOJI_PATTERN

Use \w in the lookarounds and inside the name matcher ([\w+-])
so the word-char set is expressed once instead of being repeated
as two slightly different literal character classes. Same set,
same semantics; addresses review feedback on PR #36541.

---------

Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
2026-05-21 10:34:30 +02:00
Miguel de la Cruz
02bae8c3a1
Fix: Global Threads view shows only 1 quick reaction emoji instead of 3 (MM-68681) (#36512)
* Fix: Global Threads shows 1 quick reaction emoji instead of 3 (MM-68681)

When posts are viewed in the Global Threads full-width view, the hover
toolbar was incorrectly showing only 1 quick reaction emoji instead of 3.

Root cause: In post/index.tsx, the isExpanded prop (which controls whether
the toolbar shows 3 or 1 emojis) was derived only from
state.views.rhs.isSidebarExpanded. When navigating to Global Threads,
suppressRHS is dispatched (setting state.views.rhsSuppressed = true), but
isSidebarExpanded remains false. Since posts in the thread viewer use
RHS_ROOT/RHS_COMMENT locations (not CENTER), and the #sidebar-right element
is suppressed (width = 0), the showMoreReactions check in post_options.tsx
always fell through to showing only 1 emoji.

Fix: Include state.views.rhsSuppressed in the isExpanded computation so that
when the RHS is suppressed (i.e., we are in a full-width context like Global
Threads or Drafts), the toolbar correctly renders 3 quick reaction emojis.

Tests: Added post_options.test.tsx with 4 unit tests verifying:
- CENTER location → 3 emojis (existing behavior)
- RHS_ROOT + isExpanded=false → 1 emoji (narrow RHS, existing behavior)
- RHS_ROOT + isExpanded=true → 3 emojis (expanded RHS or Global Threads)
- RHS_COMMENT + isExpanded=true → 3 emojis

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

* Refactor: use getIsGlobalThreadsView selector instead of rhsSuppressed (MM-68681)

Replace the broad state.views.rhsSuppressed check (which also fires for the
Drafts view) with a precise getIsGlobalThreadsView() selector that reads the
already-existing state.views.lhs.currentStaticPageId field.

When global_threads.tsx mounts it dispatches selectLhsItem(LhsItemType.Page,
LhsPage.Threads) which sets currentStaticPageId to LhsPage.Threads ('threads').
This is the existing, canonical signal that the Global Threads full-width view
is active; the selector wraps it with a name that conveys intent directly.

Changes:
- selectors/lhs.ts: add getIsGlobalThreadsView() — returns true iff
  state.views.lhs.currentStaticPageId === LhsPage.Threads
- selectors/lhs.test.ts: 3 new tests covering Threads, Drafts, and empty page
- post/index.tsx: import getIsGlobalThreadsView and use it in isExpanded
- post_options.test.tsx: update test description to match new mechanism

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

* Fix tests: use renderWithContext + real component tree, not jest.mock

The previous post_options.test.tsx used jest.mock() to replace
PostRecentReactions, DotMenu, and several other components. That pattern
is not established in this codebase — post_component.test.tsx and
post_reaction.test.tsx both exercise the real connected component tree
via renderWithContext with a partial Redux state.

Rewrite to match:
- Drop all jest.mock() calls for child components.
- Provide minimal Redux state (roles with ADD_REACTION + user with
  system_user role) so that ChannelPermissionGate lets the emoji
  buttons render — the same pattern used in post_reaction.test.tsx.
- Use proper SystemEmoji shaped objects (with short_name) as
  recentEmojis so that getEmojiName() does not crash.
- Assert on the real rendered emoji buttons (data-testid=
  'post-menu__item_emoji') rather than a mocked prop capture.

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

* Remove selector comment; add e2e test for Global Threads quick reactions (MM-68681)

- selectors/lhs.ts: remove JSDoc block from getIsGlobalThreadsView; the
  name is self-explanatory and the comment was narrating the code.

- emoji_recently_used_spec.js:
  * Add group tag @collapsed_reply_threads (test now requires CRT config).
  * Add MM-T4261_3: verifies that hovering a post in the Global Threads
    full-width panel shows 3 quick reaction emojis, matching the center
    channel and unlike the narrow RHS sidebar which shows 1.
  * Add GLOBAL_THREADS case to validateQuickReactions helper (uses
    rhsPost id prefix, numReactions=3).

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

* Fix lint: correct import order in post_options.test.tsx and post/index.tsx

- post_options.test.tsx: move @mattermost/types/emojis type import before
  mattermost-redux/constants; add missing blank line between import groups.
- post/index.tsx: move selectors/lhs import before selectors/posts
  (alphabetical order within the selectors/* group).

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

* Fix types: use correct EmojiCategory value 'people-body' not 'people'

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

* Remove dead RHS_EXPANDED branch from validateQuickReactions helper

No call site ever passes 'RHS_EXPANDED' to validateQuickReactions — the
branch was unreachable. Keep only the 'GLOBAL_THREADS' case that the new
MM-T4261_3 test actually exercises.

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

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Miguel de la Cruz <mgdelacroix@users.noreply.github.com>
2026-05-21 10:33:56 +02:00
Eva Sarafianou
5cacd26776
Fix config-change-checker to use merge-base for per-file diffs (#36670)
Automatic Merge
2026-05-21 10:23:44 +02:00
Ben Schumacher
a7ef484fee
[MM-68576] Add SAML connectivity status to support packet diagnostics (#36321)
* Add SAML connectivity status to support packet diagnostics

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

* Fix SAML diagnostics tests for config validation

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

* Add enterprise SAML diagnostics hook for support packet

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

* Cleanup

* Fix SAML support packet tests to use enterprise mock interface

Tests were expecting the platform layer to perform HTTP metadata URL
checks directly, but that logic belongs in the enterprise SAML
diagnostic implementation. Updated tests to install a mock enterprise
interface (matching the existing pattern in the override test) instead
of relying on bare HTTP calls that only work without the enterprise
interface registered.

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

* Simplify SamlDiagnosticInterface to return error instead of (string, string)

The status return was always either StatusOk or StatusFail, which maps
directly to nil/non-nil error. Removing the redundant status string
makes the interface idiomatic Go and lets the call site derive status
from error presence.

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

* lint fix

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Ben Schumacher <hanzei@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 10:21:34 +02:00
cursor[bot]
981e5341ca
Fix flaky TestUserHasJoinedChannel (#36660)
Some checks are pending
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres (shard 0) (push) Blocked by required conditions
Server CI / Postgres (shard 1) (push) Blocked by required conditions
Server CI / Postgres (shard 2) (push) Blocked by required conditions
Server CI / Postgres (shard 3) (push) Blocked by required conditions
Server CI / Merge Postgres Test Results (push) Blocked by required conditions
Server CI / Elasticsearch v8 Compatibility (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 0) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 1) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 2) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 3) (push) Blocked by required conditions
Server CI / Merge Postgres FIPS Test Results (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Tools CI / check-style (mattermost-govet) (push) Waiting to run
Tools CI / Test (mattermost-govet) (push) Waiting to run
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-external-links (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
YAML Lint / yamllint (push) Waiting to run
* Fix flaky TestUserHasJoinedChannel

The UserHasJoinedChannel plugin hook is invoked from AddChannelMember via
Srv().Go, so the hook post can appear after the join system post. Under CI
load the 5s Eventually window was sometimes too short. Confirm the plugin
is active before triggering the hook, poll posts in channel order like the
sibling subtest, and extend the wait to 10s.

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

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

* test: add plugin activation assertion messages

* test: deduplicate plugin hook post assertion

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
2026-05-20 22:19:54 +00:00
Jesse Hallam
77f9ecdfde
Upgrade Go to 1.26.3 and update deps in tool modules (#36658) 2026-05-20 17:25:49 -04:00
Maria A Nunez
c4b36dee16
Add user attribute validation banners (#36595)
Some checks failed
Server CI / Postgres (shard 1) (push) Blocked by required conditions
Server CI / Postgres (shard 2) (push) Blocked by required conditions
Server CI / Postgres (shard 3) (push) Blocked by required conditions
Server CI / Merge Postgres Test Results (push) Blocked by required conditions
Server CI / Elasticsearch v8 Compatibility (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 0) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 1) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 2) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 3) (push) Blocked by required conditions
Server CI / Merge Postgres FIPS Test Results (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Tools CI / check-style (mattermost-govet) (push) Waiting to run
Tools CI / Test (mattermost-govet) (push) Waiting to run
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-external-links (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
YAML Lint / yamllint (push) Waiting to run
BuildEnv Docker Image / build-image (push) Has been cancelled
BuildEnv Docker Image / build-image-fips (push) Has been cancelled
* Add user attribute validation banners

Add row-level and banner validation coverage for user attribute names so admins get clearer feedback before saving invalid attributes.

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

* UX Feedback

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-05-20 17:23:18 -04:00
Jesse Hallam
2c925ccf88
MM-68151: Update server dependencies (#36571) 2026-05-20 18:20:19 -03:00
Scott Bishel
448a642835
Add inline action buttons for bot-posted markdown (#36219)
* Add inline action buttons for bot-posted markdown

Bots, webhooks, and plugins can now embed clickable action buttons
inside markdown (including table cells) using mmaction://actionId
links, with row-specific parameters forwarded to the integration on
click. This enables use cases like a per-row "Mx Plan" button in a
fleet-status table that opens a dialog scoped to the clicked row.

Design
- New post prop inline_actions maps actionId (alphanumeric) to a
  PostActionIntegration {URL, Context}, capped at 50 entries.
- Markdown link with scheme mmaction:// emits a placeholder span that
  messageHtmlToComponent converts to the InlineActionButton component.
- Click POSTs inline_context (parsed from the URL query string) to the
  existing /posts/{id}/actions/{action_id} endpoint; the server merges
  it into the integration request as context.inline_params while
  preserving the post-level context.
- Only bot, webhook, and plugin posts render the button; non-integration
  posts have inline_actions stripped on create, update, and ephemeral
  broadcast. Hardened-mode also covers the new prop.
- Reuses the existing PostAction dialog pipeline: plugin handlers reply
  with a trigger_id and call /actions/dialogs/open as before.

Security
- InlineContext capped at 50 entries / 128-char keys / 2 KB values.
- Integration Context cloned per click so per-click inline_params and
  selected_option cannot leak into the cached post for other clickers.
- Plugin response updates cannot add inline_actions to a post that did
  not already have them; invalid entries are dropped with a warn log.
- Label content and data attributes are escaped; labels are flattened
  to plain text (tags stripped, entities decoded, then escaped).
- Malformed JSON request bodies now return 400 instead of falling
  through with an empty inline_context.

Tests
- Model: validators, normalization, GetInlineAction, strip, fallback.
- App: create strip, update guard (4 subtests including
  AllowInlineActionsUpdate bypass), ephemeral strip, inline_params
  merge, context-map isolation, plugin-response guards, from_bot and
  from_plugin retention across plugin updates.
- API: inline_context validation (size bounds + error id),
  omitempty backward compat, malformed JSON 400.
- Webapp: renderer scheme handling, allow/deny flags, size caps,
  HTML escape, tag strip, entity decode, attribute-injection defense;
  component click dispatch, double-click race guard, unmount safety,
  error-result recovery, aria state.

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

* lint fix

* i18n-extract

* Review fixes for inline action buttons

- renderer: preserve actionId case; reject opaque mmaction: URI
- app: require bot AND integration session to preserve inline_actions
- app: restore original inline_actions when plugin response is invalid
- i18n: rename key to ...app_error to match convention

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

* Tighten UpdatePost inline_actions guard; fix test seeds

- app: UpdatePost now requires AllowInlineActionsUpdate to modify
  inline_actions. Integration session alone is insufficient — a
  PAT-wielding user could otherwise inject inline_actions on any
  post they could edit.
- tests: seed bot posts with inline_actions via an integration
  session (intSeedCtx) so they survive the create-time strip.
- renderer: lint fix (blank line before comment block).

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

* Reject malformed inline-action authorities at render time

- renderer: enforce ^[A-Za-z0-9]+$ on actionId, mirroring the server
  regex. Authorities like mmaction://plan:443 or mmaction://user@plan
  now fall through to plain text instead of rendering a dead button.
- post: clarify in the strip comment that webhooks and plugins bypass
  CreatePostAsUser entirely (they call CreatePost / CreatePostMissingChannel
  directly), so the strip block does not apply to them.

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

* Tighten inline-action renderer tests

- Replace oversized-params test with boundary pair (at-cap and over-cap)
  to lock in the > vs >= behavior of the size-limit check.
- Add a "surrounding text survives" assertion for the tag-strip path so
  a future swap from regex strip to a DOM sanitizer won't silently
  drop legitimate content along with tags.

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

* Inline action buttons via mmaction:// markdown links

Adds inline action buttons rendered from mmaction:// links in markdown,
with the click pipeline reusing the existing post-action infrastructure.
Aligned with the broader mm_blocks_actions framework (Daniel's PR).

* fix lint, DoS hardening, fix and rename test

* Address review feedback

* lint fix

* Reject percent-encoded path traversal in validateIntegrationURL (e.g. %2e%2e%2f) by parsing the URL and checking the decoded path.

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-05-20 13:34:44 -06:00
Scott Bishel
a84941bec1
Remove Legacy Interactive Dialog code (#35874) 2026-05-20 13:34:13 -06:00
Ben Cooke
6189a3f54a
[MM-66489] Pull and populate certificate from metadata endpoint (#36557) 2026-05-20 14:51:24 -04:00
Jesse Hallam
0790fc7281
Upgrade Go to 1.26.3 (#36656) 2026-05-20 13:21:14 -03:00
Jesse Hallam
c74e51f35e
chore(ci): upgrade Go to 1.26.3 in build container Dockerfiles (#36648) 2026-05-20 17:56:19 +03:00
Jesse Hallam
51c6d5219f
Fix config Sanitize fields missing from desanitize, causing FakeSetting to be persisted (#36619)
Some checks are pending
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres (shard 0) (push) Blocked by required conditions
Server CI / Postgres (shard 1) (push) Blocked by required conditions
Server CI / Postgres (shard 2) (push) Blocked by required conditions
Server CI / Postgres (shard 3) (push) Blocked by required conditions
Server CI / Merge Postgres Test Results (push) Blocked by required conditions
Server CI / Elasticsearch v8 Compatibility (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 0) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 1) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 2) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 3) (push) Blocked by required conditions
Server CI / Merge Postgres FIPS Test Results (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Tools CI / check-style (mattermost-govet) (push) Waiting to run
Tools CI / Test (mattermost-govet) (push) Waiting to run
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-external-links (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
YAML Lint / yamllint (push) Waiting to run
* Add TestDesanitizeRemovesAllFakeSettings to catch future omissions

Walks every string field in the config after a Sanitize+desanitize
round-trip and fails if any still holds FakeSetting. This catches the
case where a field is added to Sanitize without a corresponding
desanitize entry.

* Fix ElasticsearchSettings.ClientKey being incorrectly masked as a secret

ClientKey is a file path, not a secret value. Masking it caused the
asterisk string to be persisted to the database on config writes, which
broke TLS client auth on restart.

* Fix desanitize missing entries for fields added in 504fb96fdd

504fb96fdd masked five fields in Sanitize without adding the
corresponding desanitize entries, meaning a config save through the
API would permanently overwrite those fields with FakeSetting:

- FileSettings.ExportAmazonS3SecretAccessKey
- ServiceSettings.GoogleDeveloperKey
- ServiceSettings.GiphySdkKey
- CacheSettings.RedisPassword
- AutoTranslationSettings.LibreTranslate.APIKey

* fixup! Add TestDesanitizeRemovesAllFakeSettings to catch future omissions

* fixup! Fix desanitize missing entries for fields added in 504fb96fdd

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-05-20 10:04:21 +00:00
Jesse Hallam
41f3b22679
Fix flaky E2E tests (Cypress + Playwright) (#36637)
Some checks are pending
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres (shard 0) (push) Blocked by required conditions
Server CI / Postgres (shard 1) (push) Blocked by required conditions
Server CI / Postgres (shard 2) (push) Blocked by required conditions
Server CI / Postgres (shard 3) (push) Blocked by required conditions
Server CI / Merge Postgres Test Results (push) Blocked by required conditions
Server CI / Elasticsearch v8 Compatibility (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 0) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 1) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 2) (push) Blocked by required conditions
Server CI / Postgres FIPS (shard 3) (push) Blocked by required conditions
Server CI / Merge Postgres FIPS Test Results (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Tools CI / check-style (mattermost-govet) (push) Waiting to run
Tools CI / Test (mattermost-govet) (push) Waiting to run
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-external-links (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
YAML Lint / yamllint (push) Waiting to run
* Fix flaky email sort test by ignoring punctuation in localeCompare

PostgreSQL's en_US.UTF-8 collation ignores hyphens at the primary sort
level, but JS localeCompare() on a C-locale CI runner uses byte order,
causing the expected and actual sort orders to diverge for emails
containing hyphens. Passing ignorePunctuation:true aligns JS collation
with Postgres behavior.

* E2E/Cypress: re-enable CYPRESS_* env var overrides

allowCypressEnv: false was introduced in the v15.13 upgrade (PR #36091)
but broke the existing CYPRESS_adminUsername / CYPRESS_adminPassword
override mechanism that local and CI runners depend on.

* E2E/Cypress: fix MM-T1508 accessibility image test flakiness

The test was failing because the admin user could have a stale
compact display mode preference from a previous spec, causing
post avatars to render with pointer-events: none and blocking
the .status-wrapper click.

Two fixes:
- resetUserPreference() now resets message_display to 'clean'
  so compact mode doesn't leak across spec files
- accessibility_image_spec before() now runs as a fresh user
  with default preferences rather than the shared admin account
2026-05-20 10:46:17 +08:00