Skip to content

[pull] master from mattermost:master#402

Open
pull[bot] wants to merge 8033 commits intoDithn:masterfrom
mattermost:master
Open

[pull] master from mattermost:master#402
pull[bot] wants to merge 8033 commits intoDithn:masterfrom
mattermost:master

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Mar 5, 2022

See Commits and Changes for more details.


Created by pull[bot]

Can you help keep this open source service alive? 💖 Please sponsor : )

jgheithcock and others added 28 commits April 5, 2026 15:30
The invite modal's UsersEmailsInput component treated whitespace as a
token delimiter alongside comma and semicolon. This caused typing a
space (e.g., between a first and last name) to split and clear the
input field.

Split the delimiter regex into two: typedInputDelimiter (/[,;]+/) for
interactive typing and pasteDelimiter (/[\s,;]+/) for paste operations
where whitespace-separated values are expected. Added .trim() to split
entries to handle the comma-then-space typing pattern correctly.

Updated onboarding invite description text to reflect the new delimiter
behavior (comma or semicolon instead of space or comma).
* (test): vh1-8+EC enzyme to rtl bulk migration

* address comments
* Added nil checks

* Added test for DM and GM

* Updated operation order
* Fixing issues with browser channels modal

- Fixing "jumping around" issue on hover due to buttons being rendered dynamically
- Added max width for purpose so it doesn't take up the whole screen when long purpose is written

* Fixing modal overflow in mobile screen sizes

* Simplifying join button layout fix

* Fixing styles to be consistent with existing modals
)

* Fix Enterprise Advanced upsell messaging for Enterprise licenses

Update the license settings upsell panel to highlight only Enterprise Advanced-exclusive capabilities so Enterprise customers are not shown features they already have.

Made-with: Cursor

* Update license settings snapshot for Enterprise upsell

Refresh the Enterprise license snapshot so the license settings test matches the new Enterprise Advanced upsell content.

Made-with: Cursor

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
…er service errors (#35949)

* Use multi-level logging for shared channel and remote cluster service errors

  Service-specific log levels (LvlRemoteClusterServiceError, LvlSharedChannelServiceError)
  were hidden from the main log by default, requiring explicit configuration to see them.
  Switch all call sites to use LogM with multi-level combos so each log line is attributed
  to both the standard level (error/warn) and the service-specific level. This surfaces
  errors in the main log while preserving the ability to isolate them into dedicated files.

  Each instance was reviewed and either kept as error (DB failures, security issues, config
  errors, exhausted retries on critical data) or downgraded to warn (transient network
  failures, remote-side reported errors with retry logic, non-critical data like profile
  images, reactions, acknowledgements, and status).
Co-authored-by: unified-ci-app[bot] <121569378+unified-ci-app[bot]@users.noreply.github.com>
* fix mock server response for translations

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
…#35940)

* Update docs-impact workflow to keep stale comment instead of deleting

When a re-run of the docs impact analysis determines that documentation
updates are no longer needed, the previous bot comment was deleted while
the Docs/Needed label was kept. This left the label without context.

Instead of deleting the comment, update it to explain that a previous
analysis had flagged the PR but the latest run found no docs impact.
This preserves the audit trail and gives maintainers context to decide
whether to remove the label.

Made-with: Cursor

* Update .github/workflows/docs-impact-review.yml

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

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Nevyana Angelova <nevyangelova@192.168.100.47>
This stops a warning from Babel which points out that passing a minor version
as a number will have issues because 16.2 is identical to 16.20.
* MM-68179: Run sendLoop workers on all HA nodes

  In HA clusters, sendLoop worker goroutines only ran on the leader node.
  When an API request to send a channel invite landed on a non-leader node,
  SendMsg enqueued the task to a local in-memory channel but no goroutine
  consumed it, silently losing the message. Fix by starting sendLoop workers
  in Start() on all nodes, independent of the leader-only ping lifecycle.

  - Separate sendLoop lifecycle (Start/Shutdown) from ping lifecycle
    (pingStart/pingStop on leader change)
  - Rename resume/pause to pingStart/pingStop for clarity
  - Change Active() to mean "service started" via atomic.Bool
  - Remove SetActive (no longer needed; tests use Start())

* address review comment

* Added idempotency guard to Start()

* Start() and Shutdown(): CompareAndSwap instead of Load/Store — eliminates races where concurrent calls could both proceed. Only the winner of the CAS executes; the loser returns nil
  immediately.

Ping test: replaced time.Sleep with assert.Never/assert.Eventually — no more brittle fixed sleeps. Uses assert.Never to verify no pings fire on non-leader, and assert.Eventually to
  verify pings stop after losing leadership (snapshot-then-compare pattern).

* make unit tests parallel capable

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Log only a 5-character prefix of the password reset token in audit
entries instead of the full 64-character bearer credential (CWE-532).

Co-authored-by: Mattermost Build <build@mattermost.com>
* markdown message preview fixed

* message preview overflow fix

* fix show_more test

* restore package-lock.json

* pull package-lock from master

* package-lock line break

* Fix missing newline at end of package-lock.json

* Update test snapshots

---------

Co-authored-by: David Krauser <david@krauser.org>
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: David Krauser <david@kruser.org>
…35938)

When a channel is shared between two instances, the sender was including
  membership changes for users that originated from the target remote.
  On the receiver those users are local (RemoteID=""), causing the
  RemoteID check to fail with "remoteID mismatch", creating log noise.
  Fix both sides: sender now skips users belonging to the target remote, and receiver
  silently skips local users instead of logging an error.
* Add demo plugin E2E tests for hook toggle and crash recovery

- Add selectSlashCommandFromAutocomplete() to post_create lib component
- Extract shared setupDemoPlugin() helper to reduce duplication
- Rename crash.spec.ts to plugin_crash.spec.ts for clearer CI output
- Add demo_plugin_hook_toggle.spec.ts: verifies /demo_plugin true/false
  slash command enables/disables hooks, confirmed via sidebar indicator
  and ChannelHasBeenCreated event presence/absence

* Fix lint errors in demo plugin helpers and crash spec

* Fix prettier formatting in post_create.ts

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
* MM-67945 Added entity decoding to message attachments

- Separated markdown utility to decode special characters with testing suite
- Applied it to remove_markdown utility and used it in

* Ensuring escaping uses RegExp.escape

* Removing footer decoding tests

* Added E2E tests for message attachment decoding

* Fixing linter errors
…x convention (#35944)

* Rename shared_channel_manager and secure_connection_manager roles to use system_ prefix

  The new roles added in PR #35354 broke the naming convention that all
  system-level roles stored in Users.Roles are prefixed with "system_".
  Client-side code (role.includes('system')) and server-side code (explicit
  switch cases in applyMultiRoleFilters) relied on this convention, causing
  users assigned to these roles to not appear in the System Console.

  Also adds both roles to the applyMultiRoleFilters switch statement in
  user_store.go, which was missing them entirely.
* Fix a bug in decomposeKorean that caused it to only decompose the first character

* MM-66887 Fix Invite To Team modal suggesting users one key press behind

* Cherry-pick updates to ime.ts from another branch

* And cherry-pick another bit

* Remove broken and unnecessary onBlur method from UsersEmailsInput

See https://github.com/mattermost/mattermost/pull/35936/changes#r3047500882 for more information
…m web app (#35954)

* Remove unneeded references to PropTypes in TS code

* Add type definition file for SuggestionBox

* Fixed type definitions for SuggestionBoxProps and fixed usage of those props in other places

* Remove babel-plugin-typescript-to-proptypes

* Fix circular type reference and incorrect non-null assertion
* feat(test analysis): using reusable workflow

* address comment

* pin to main during initial rollout

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
…or FIPS, shard CI, fix FIPS builds (#35905)

* Replace hardcoded test passwords with model.NewTestPassword()

Add model.NewTestPassword() utility that generates 14+ character
passwords meeting complexity requirements for FIPS compliance. Replace
all short hardcoded test passwords across the test suite with calls to
this function.

* Enforce FIPS compliance for passwords and HMAC keys

FIPS OpenSSL requires HMAC keys to be at least 14 bytes. PBKDF2 uses
the password as the HMAC key internally, so short passwords cause
PKCS5_PBKDF2_HMAC to fail.

- Add FIPSEnabled and PasswordFIPSMinimumLength build-tag constants
- Raise the password minimum length floor to 14 when compiled with
  requirefips, applied in SetDefaults only when unset and validated
  independently in IsValid
- Return ErrMismatchedHashAndPassword for too-short passwords in
  PBKDF2 CompareHashAndPassword rather than a cryptic OpenSSL error
- Validate atmos/camo HMAC key length under FIPS and lengthen test
  keys accordingly
- Adjust password validation tests to use PasswordFIPSMinimumLength
  so they work under both FIPS and non-FIPS builds

* CI: shard FIPS test suite and extract merge template

Run FIPS tests on PRs that touch go.mod or have 'fips' in the branch
name. Shard FIPS tests across 4 runners matching the normal Postgres
suite. Extract the test result merge logic into a reusable workflow
template to deduplicate the normal and FIPS merge jobs.

* more

* Fix email test helper to respect FIPS minimum password length

* Fix test helpers to respect FIPS minimum password length

* Remove unnecessary "disable strict password requirements" blocks from test helpers

* Fix CodeRabbit review comments on PR #35905

- Add server-test-merge-template.yml to server-ci.yml pull_request.paths
  so changes to the reusable merge workflow trigger Server CI validation
- Skip merge-postgres-fips-test-results job when test-postgres-normal-fips
  was skipped, preventing failures due to missing artifacts
- Set guest.Password on returned guest in CreateGuestAndClient helper
  to keep contract consistent with CreateUserWithClient
- Use shared LowercaseLetters/UppercaseLetters/NUMBERS/PasswordFIPSMinimumLength
  constants in NewTestPassword() to avoid drift if FIPS floor changes

https://claude.ai/code/session_01HmE9QkZM3cAoXn2J7XrK2f

* Rename FIPS test artifact to match server-ci-report pattern

The server-ci-report job searches for artifacts matching "*-test-logs",
so rename from postgres-server-test-logs-fips to
postgres-server-fips-test-logs to be included in the report.

---------

Co-authored-by: Claude <noreply@anthropic.com>
hmhealey and others added 30 commits May 6, 2026 09:38
* Add initial version of Button

* Use Button in ConfirmModal

* Use Button in easy places that use className='btn btn-primary'

This is everywhere that I could just replace `<button className='btn
btn-primary'>` with `<Button emphasis='primary'>` (and some other
emphasis versions) without any additional changes. There's still more
places where this could be used which require more in-depth changes that
will be in a following commit.

* Use Button in place of divs with className='btn btn-primary'

This is a minor functional change because these elements are now
accessible.

* Use Button in SpinnerButton

This is removing some usage of a save-button CSS class
that doesn't seem to affect these components.

* Replace RB Button with our Button

There's a small functional change here because the copy button in the
header of the FullLogEventModal is now styled when it wasn't before.

* Use Button in many places which used btn-secondary, btn-tertiary, and btn-danger

This removes some CSS classes from some different elements, but as
elsewhere, those CSS classes don't actually do anything. I think some
might have had a purpose once, but there seems to be quite a few that
were copied around during previous, possibly AI-assisted refactors.

* Use Button in many places in System Console

Notably, this includes:
1. Cleaning up some complicated logic in PurchaseLink/RenewalLink for
   determining their styling.
2. Making some minor functional changes in ChannelProfile/TeamProfile
   because they didn't use standard CSS classes previously. The styles
   mostly match a secondary button, but they had slightly different
   padding and colours previously.
3. I also removed a workaround for an old issue with OverlayTrigger and
   disabled buttons in favour of just using the disabled attribute. For
   more information on the previous code, see
   mattermost/mattermost-webapp#10387. Based on
   some brief testing, that's no longer needed.

* Use Button in MultiSelect and remove unneeded backButtonClass prop

Everything that used that prop either passed the tertiary class that
was the default or passed a class that didn't exist.

* Use Button in more places that used btn-primary/secondary/tertiary/quaternary

* Use Button in more places that used btn-danger

* Use Button for all buttons with a className starting with 'btn btn-...'

* Migrate anchors that really should've been buttons to Buttons

All of these are anchors with click handlers and the btn class, so
they'd appear as buttons anyway.

* Migrate SettingItemMax and SettingPicture to Button

* Use Button in BrowseChannels

* Use Button in TourTip

* Migrate GenericModal to Button

There's a minor UX change due to the old `delete` class having a slightly
different colour from `btn-danger`, but I think that was from an older
version of the default themes.

Ideally, we'd remove the `GenericModal__button`, `confirm`, and `delete`
classes from the buttons on that modal, but doing that would require
changes to a large number of E2E tests that I'd rather not do now.

* Change order of building packages in postinstall

* Fix move_thread E2E tests

* Coderabbit feedback

* Address feedback

* Add JSDoc comments and remove width prop

I don't think we need this since this should be set by a parent with
`display: flex`, so I'm not going to add it to the Button.

* Share Button with plugins
* Update interdependency between packages to 11.8.0

* Fix bad merge upstream
* Translated using Weblate (Polish)

Currently translated at 100.0% (3191 of 3191 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (7243 of 7243 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 91.5% (6634 of 7243 strings)

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

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

Currently translated at 99.9% (7239 of 7243 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 100.0% (3191 of 3191 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 100.0% (7243 of 7243 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 100.0% (7243 of 7243 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 100.0% (3191 of 3191 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 100.0% (7243 of 7243 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 100.0% (3191 of 3191 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 100.0% (7243 of 7243 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 93.3% (6763 of 7243 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (7243 of 7243 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (7243 of 7243 strings)

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

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

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

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 76.9% (5617 of 7303 strings)

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

---------

Co-authored-by: master7 <marcin.karkosz@rajska.info>
Co-authored-by: Kaya Zeren <kayazeren@gmail.com>
Co-authored-by: Sharuru <mave@foxmail.com>
Co-authored-by: ThrRip <coding@thrrip.space>
Co-authored-by: Frank Paul Silye <frankps@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
* MM-68397 Add shared package to STYLE_GUIDE.md and CLAUDE.OPTIONAL.md

* Add webapp/AGENTS.md
…3363)

* feat(color_input): migrate ColorInput to function component

* test(color_input): migrate tests from enzyme to react testing library

* test(color_input): remove obsolete snapshots

* test(color_input): update snapshots

* test(color_input): update test

* refactor(color_input): remove unnecessary state update in function body

* Revert "refactor(color_input): remove unnecessary state update in function body"

This reverts commit 2c7647a.

* Fix ColorInput tests

* Simplify click outside handler

By changing the button to always show the picker instead of toggling it
and making it so that the click outside handler checks for clicks
outside of the whole ColorInput, we can get rid of the setTimeout and
the very specific timing needed for the click outside handler.

* Wrap handleColorChange in useCallback

* Update snapshot

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
* Lower default test console log level from stdlog to debug

Suppresses trace-level log spam (e.g. MlvlNotificationTrace) that
flooded CI output. MM_LOGSETTINGS_CONSOLELEVEL still overrides for
local debugging.

* Fix TestEnvironmentVariableHandling to expect debug default

Updates the assertion to match the new default console log level.
* Add Button to Component Library

* Fix key warnings in Component Library

* Add grid of Buttons to match Figma

* Fix trailingIcon default
…'t (#36328)

* Split out buttonClassNames utility and use for most places Button isn't

* Update StartTrialBtn to use buttonClassNames

Ideally, we'd:
1. Use Button, but that requires sorting out the one case that overrides
   btnClass entirely.
2. Use a button for all of these since none of these should have a link
   role, but that's outside of the scope of this ticket.

* Update another new button to use Button
… loading (#36400)

* docs: import server/AGENTS.md from platform/AGENTS.md to ensure eager loading

* docs: use sentence format for AGENTS.md import comment
* Add root id to webhooks

* Address feedback

* Address coderabbit comment

* Error if root post is not really a root post

* Fix test

* Address nitpick
…vocation (#36332)

* MM-68543 Invalidate active WebConn session cache on global session revocation

Mirrors the per-user revocation pattern (ClearUserSessionCache ->
ClearSessionCacheForUserSkipClusterSend -> hub fan-out) for the global
revocation path so that ClearAllUsersSessionCache invokes the same
local-side primitive on the originating node as the cluster handler
runs on remote nodes. Also covers single-node deployments where the
cluster broadcast was previously the only trigger of the WebConn
invalidation.

Adds a Hub.InvalidateAll fan-out primitive on the websocket hub and
two contract tests covering the SkipClusterSend variant and the
production RevokeSessionsFromAllUsers entry point.

Made-with: Cursor

* MM-68543 Restore error propagation on ClearAllUsersSessionCache

The previous commit moved the local-side work into
ClearSessionCacheForAllUsersSkipClusterSend, which returned no error,
so ClearAllUsersSessionCache started always returning nil even when the
underlying session-cache purge failed.

Make the helper return the cache-purge error and propagate it back
through ClearAllUsersSessionCache, restoring the historical error
contract for callers (RevokeSessionsFromAllUsers,
App.ClearSessionCacheForAllUsers, TestCache). The hub fan-out and the
cluster broadcast still run unconditionally so security invalidation
happens even on local-purge failure.

Made-with: Cursor

* MM-68543 Trim comments and fix unchecked errcheck on App wrapper

Address review feedback: trim verbose comments across the touched
files and check the error returned by ClearSessionCacheForAllUsersSkipClusterSend
in the App-level wrapper to fix the golangci-lint errcheck failure
introduced when the helper started returning an error.

Made-with: Cursor

* MM-68543 Wipe channel routing index instead of rebuilding it on global revoke

Rebuilding byChannelID per user via InvalidateCMCacheForUser issues a
GetAllChannelMembersForUser DB query for every user with a live conn
on the hub, which is wasted work when those conns have just been
invalidated. Replace it with a single clear() of byChannelID, hidden
behind a small clearChannels() helper. Index entries repopulate
naturally as conns re-handshake or fully reconnect.

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

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Nevyana Angelova <nevyangelova@192.168.100.47>
GetPreferencesForUser returns default preferences in non-deterministic order
under the race detector and Postgres, but the test asserted fixed slice
indices. Look up each default preference by category instead.

Tests-only change. Verified with go test -run '^TestPluginAPIUpdateUserPreferences$' -race -count=100 ./channels/app.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>
…ame to UI for channel creation and settings (#36289)

* [MM-68496] Feature flag Managed Categories, expose Default Category Name to UI for Channels

* PR feedback

* PR feedback

* Fix i18n

* Fix test

* Fix E2E

* Merge'd

* Add tests

* Re-add old tests (skipped)

* Add IncrementVersion to PropertyGroup store, increment version on managed category group

* Fix lint

* Fix mock

* Fix prettier

* Add tests

* Fixed issue when moving from existing category to existing category

* Fix e2e

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
* MM-67904 Fix inflated count in search results Messages tab

The "Messages" counter in the search results RHS was rendering
`results.length`, but `results` is the array produced by
`makeAddDateSeparatorsForSearchResults`, which interleaves
date-line strings between posts (one per date group). A search
returning a single post therefore showed "2", and N posts spread
across D dates showed N+D.

Filter date-line strings out of `results` before computing the
counter so it reflects only the actual matching posts. File
results are unaffected.

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

* Address review feedback: simplify count predicate, drop unnecessary type casts in tests

- Count non-string entries in results directly. The Props type already
  declares results as Array<Post | string>, so any string entry is a
  separator; this is clearer than checking isDateLine and is more
  defensive against future marker strings.
- Drop the as any casts on the new test results props. The literals are
  assignable to Array<Post | string>, so the casts only suppressed
  type checking.

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>
…36466)

When navigator.sendBeacon() is called with a plain string body, the
browser defaults to Content-Type: text/plain;charset=UTF-8. This
causes legitimate WAF alerts because the payload is JSON, not plain
text. Many deployments have been blocking users because of this
mismatch (MM-61530 / #29101).

Fix: wrap the JSON string in a Blob with type 'application/json'
before passing it to sendBeacon. Also add the matching
Content-Type: application/json header to the fallback fetch call
that fires when sendBeacon returns false.

Tests: add three new focused tests in the
PerformanceReporter.sendReport content-type suite that verify:
1. sendBeacon receives a Blob with type application/json
2. The Blob's text content is valid JSON matching the report
3. The fallback fetch includes Content-Type: application/json
Also update the existing (currently skipped) tests to parse the
Blob body via FileReader instead of JSON.parse(string).

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Miguel de la Cruz <mgdelacroix@users.noreply.github.com>
…ttachments (#36468)

Set ReqFileId on the UploadSession created in
  ReceiveSharedChannelAttachmentSyncMsg so the attachment is persisted
  under the sender's file ID. Without this, the receiving server stored
  the bytes under a freshly generated ID while the synced post's FileIds
  still referenced the sender's ID, leaving the attachment invisible in
  the UI even though the file and FileInfo row existed on disk.

  Mirrors the existing cluster-to-cluster path in
  platform/services/sharedchannel/attachment.go.

  Also tightens TestPluginAPIReceiveSharedChannelAttachmentSyncMsg to
  pass a sender-side fi.Id and assert the saved FileInfo keeps it. The
  prior assertion only checked that some ID was assigned, which the
  buggy code also satisfied.
* change retry to 1, fixed and disabled failed tests

* add v2 templates for Cypress and Playwright E2E tests with test system io integration

* add commenting to pr

* identify more playwrights to fix separately

* disable deletion-report.spec for separate fix

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
* api4: block user managers from toggling bot active status without bot permissions

The PUT /api/v4/users/{id}/active endpoint only checked for
PermissionSysconsoleWriteUserManagementUsers and a special-case for system
admins, but had no equivalent guard for bot accounts.

This meant a User Manager with edit access to users but no access to
Integrations could deactivate (or reactivate) bot accounts — causing the
bot's sessions to be revoked and its tokens invalidated — even though every
dedicated bot endpoint (/api/v4/bots/{id}/disable, /enable, PATCH, etc.)
requires the caller to pass SessionHasPermissionToManageBot.

Fix: after fetching the target user and running the system-admin guard, add
an equivalent check for IsBot that delegates to the same
SessionHasPermissionToManageBot helper used by all other bot endpoints.

Fixes MM-68686

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

* api4: assert bot is inactive after deactivation in test

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

* api4: pin bot-deactivation test assertion to 404 and clarify comment

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

* api4: use require.Zero for DeleteAt assertion in bot test

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

* api4: fix err shadow in updateUserActive bot permission check

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>
Co-authored-by: Mattermost Build <build@mattermost.com>
* Fix modal title line-height regression introduced in MM-66442

The current inflated value for the modal's line-height causes
multi-line modal titles to overflow or be clipped. Restores the
original value and adds an e2e test to prevent future regressions.

* Improvements

---------

Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
* Added base fr report generation

* WIP

* Refactoring and cleanup

* lint fixes, added new tests

* test fix

* Several improvements

* Addressed some security enhancements

* Created zip writer entery later

* Improved a test to check for file content

* Improved error handling

* Made a geneeric function

* accepting comment in report API

* Removed an unnecessary check

* Made a geneeric function

* Made the comment body not required and updated API docs
…36213)

* MM-68433 - Fix DM/GM menu gating and header save in Channel Settings

* fix linter

* Avoid global role mutation in autotranslation DM e2e tests

* adjust menu item display based on config

* fix e2e tests

* Stabilize DM autotranslation Playwright menu/settings tests

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
…n RHS (#36467)

* Fix compact mode: consecutive bot reply header floating incorrectly in RHS

MM-67419: In compact display mode, when a bot sends consecutive replies in
the RHS thread view, the .post__header floats incorrectly because the
global CSS rule in _post.scss gains higher specificity (7 classes) than
the ThreadViewer override (6 classes) when the post also carries .post--bot
and .same--user classes.

Fix: add an explicit .same--user.post--bot sub-selector inside the
.post-right__container / .ThreadViewer compact-reply block, raising the
override specificity to 8 classes so it correctly beats the global rule
and resets float to none.

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

* Remove redundant height/margin declarations from bot post-header override

The enclosing .post__header rule already sets height: auto and margin-left: 0;
the only property the global compact bot rule overrides is float: left, so
the new sub-selector only needs float: none to win the specificity contest.

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>
* Fix autocomplete clipping beside RHS

Co-authored-by: Nick Misasi <nick13misasi@gmail.com>

* Address Copilot autocomplete findings

Co-authored-by: Nick Misasi <nick13misasi@gmail.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
…ttachments (#36486)

* MM-68705 - Make ReceiveSharedChannelAttachmentSyncMsg order tolerant

  Allow plugin remotes to invoke ReceiveSharedChannelAttachmentSyncMsg
  and ReceiveSharedChannelSyncMsg in either order without losing the
  post/file binding, and make repeat deliveries of the same file id
  idempotent.

  Two localised changes inside ReceiveSharedChannelAttachmentSyncMsg:

  - Idempotency check before CreateUploadSession. If a FileInfo with
    the sender's id already exists for the same channel and creator,
    return it instead of inserting a duplicate (which would violate
    the FileInfo PK and force the caller to retry indefinitely after
    any transient ack failure). A mismatched channel or creator on the
    same id is rejected.

  - Lazy bind to post after UploadData. When the matching post is
    already present (post-then-file ordering), CreatePost will have
    stripped the unmatched file id from Post.FileIds; AttachToPost
    plus Post.Overwrite restore the binding. When the post is not
    yet present (file-then-post ordering), the FileInfo is left
    unbound so the eventual post arrival's CreatePost path binds it.
    The post is fetched first because AttachToPost is a blind UPDATE
    that does not validate post existence, so calling it before the
    post exists would orphan the FileInfo.

  No other paths change. Cluster (non-plugin) shared-channel attachments,
  ReceiveSharedChannelProfileImageSyncMsg, and UI uploads are unaffected.

  New tests in shared_channel_test.go cover both orderings, repeated
  receive success and rejection on channel/creator mismatch, and the
  empty-PostId no-op.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.