Skip to content

[pull] master from mattermost:master#402

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

[pull] master from mattermost:master#402
pull[bot] wants to merge 7930 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 : )

nickmisasi and others added 28 commits March 15, 2026 12:05
* Restore manage oauth permission

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

* Fix migration test lint assertion

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

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* Translated using Weblate (German)

Currently translated at 100.0% (2986 of 2986 strings)

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

* Translated using Weblate (Russian)

Currently translated at 84.2% (2517 of 2986 strings)

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

* Translated using Weblate (German)

Currently translated at 97.7% (6902 of 7059 strings)

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

* Translated using Weblate (Russian)

Currently translated at 76.5% (5406 of 7059 strings)

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

* Translated using Weblate (Russian)

Currently translated at 76.5% (5407 of 7059 strings)

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

* Translated using Weblate (Polish)

Currently translated at 96.5% (6814 of 7059 strings)

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

* Translated using Weblate (Russian)

Currently translated at 77.1% (5447 of 7059 strings)

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

* Translated using Weblate (Russian)

Currently translated at 84.4% (2523 of 2986 strings)

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

* Translated using Weblate (Russian)

Currently translated at 77.4% (5469 of 7059 strings)

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

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 76.7% (5429 of 7072 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (7072 of 7072 strings)

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

* Translated using Weblate (Polish)

Currently translated at 96.7% (6845 of 7072 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (7083 of 7083 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 76.8% (5440 of 7083 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.8% (5444 of 7083 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 98.7% (6996 of 7083 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 100.0% (2993 of 2993 strings)

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

* Translated using Weblate (Polish)

Currently translated at 97.9% (2933 of 2993 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 100.0% (7083 of 7083 strings)

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

* Translated using Weblate (Polish)

Currently translated at 96.8% (6861 of 7083 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/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/

---------

Co-authored-by: jprusch <rs@schaeferbarthold.de>
Co-authored-by: Dmitriy Q <krotesk@mail.ru>
Co-authored-by: master7 <marcin.karkosz@rajska.info>
Co-authored-by: Frank Paul Silye <frankps@gmail.com>
Co-authored-by: Tom De Moor <tom@controlaltdieliet.be>
)

With this change, we now scope role_updated websocket events to users that need to receive them. Built-in and unowned role broadcast globally, team-scheme roles emit one event per team using the role, channel-scheme roles emit one event per channel using the role.

To efficiently find a role's owning scheme, a schemeid column is added to the roles table. The ID is set when the scheme creates its related roles.
…35462)

This commit fixes a crash in the webapp when native link URLs are malformed. Now we catch the exception instead of crashing, and we also validate URLs on the server side to avoid malformed URLs in the first place.
* Include footer and author name in indexed fields.
* Improves the Property System Architecture groups

The group creation for builtin property groups is moved from behaving
like a singleton in the app layer (first call creates the group) to
register groups and making sure they're present at server startup
time.

At the same time, it adds a groups cache as a sync map in the property
service, to avoid having individual caches per feature as package
variables, making the group caching part of the system.

* Fix i18n

* Fix test and calls after updating the branch

* Avoid panics by controlling the errors

* Adjust translations after merge

---------

Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
Co-authored-by: Mattermost Build <build@mattermost.com>
* Translated using Weblate (Norwegian Bokmål)

Currently translated at 77.0% (5458 of 7087 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (2996 of 2996 strings)

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

* Translated using Weblate (Swedish)

Currently translated at 91.5% (2742 of 2996 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (7087 of 7087 strings)

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

* Translated using Weblate (Swedish)

Currently translated at 91.2% (6465 of 7087 strings)

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

* Translated using Weblate (Swedish)

Currently translated at 91.2% (6465 of 7087 strings)

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

* Translated using Weblate (Russian)

Currently translated at 85.3% (2556 of 2996 strings)

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

---------

Co-authored-by: Frank Paul Silye <frankps@gmail.com>
Co-authored-by: jprusch <rs@schaeferbarthold.de>
Co-authored-by: MArtin Johnson <martinjohnson@bahnhof.se>
Co-authored-by: Kevin Vikström <kevv@redpill-linpro.com>
Co-authored-by: Dmitriy Q <krotesk@mail.ru>
…ks (#35219)

* Fix: Angle brackets display as HTML entities in inline code blocks

When using markdown in dialog introduction text (apps_form) or other
components using the Markdown component, angle brackets inside inline
code blocks (backticks) were being double-escaped and displayed as
"&lt;" and "&gt;" instead of "<" and ">".
…#35556)

* [MM-67886] Remove height cap on Feature Flags table in System Console

The Feature Flags page is entirely dedicated to the table, so the
max-height restriction is unnecessary and leaves excessive blank space.
Add a --full-height modifier class to remove the cap on this page only.

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

* [MM-67886] Fix scrolling header on Feature Flags and Server Logs pages

Replace wrapper--admin with wrapper--fixed so the admin header stays
fixed while content scrolls, matching all other System Console pages.
Rework the logs CSS to use flex-based sizing instead of fixed heights
so only the innermost container (DataGrid_rows / log__panel) scrolls,
preventing double scrollbars.

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

* [MM-67886] Fix CSS property order lint errors

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Indusha Semba <indusha@Indushas-MacBook-Pro.local>
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
)

* 🐛 fix: normalize Unicode filenames in import attachment lookup

Fix import failures for files with Japanese dakuten/handakuten characters
(e.g., ガ, パ, べ) on macOS.

macOS stores filenames in NFD (decomposed) form while Linux/Windows use
NFC (composed) form. This mismatch caused attachment lookup failures
when zip filenames and JSONL paths used different normalization forms.

Changes:
- Add NormalizeFilename utility function using golang.org/x/text/unicode/norm
- Normalize filenames when building attachment maps from zip files
- Normalize paths when looking up attachments in maps
- Apply fixes to both server (import.go) and mmctl (validate.go)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* avoid duplicating normalizeFilename

* add coverage for Korean filenames

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Jesse Hallam <jesse@mattermost.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
* Add unit tests for ScheduledPost model

Cover all methods: BaseIsValid, IsValid, PreSave, PreUpdate, ToPost,
Auditable, RestoreNonUpdatableFields, SanitizeInput, and GetPriority.
Includes validation branch coverage through Draft delegation chain.

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

* Address review findings for ScheduledPost tests

- Use require.Nil on valid-path validation checks (match post_test.go)
- Use require.Error/require.Nil on error-path ToPost subtests
- Add require.NotNil guards for inner pointer fields before dereference
- Add ToPost test for non-nil Metadata with empty Priority

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

* Fix typo in ScheduledPost.ToPost comment

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

* Seed real metadata fields in ToPost preservation tests

Populate Embeds in both metadata subtests and assert they survive
ToPost(), catching any replacement of the metadata struct.

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

* Improve ScheduledPost Auditable metadata test to verify content preservation

Seed a real PostMetadata with an emoji and assert the auditable output
matches metadata.Auditable() instead of just checking non-nil.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…e bottom (#35680)

* MM-67518 Increase amount that the post list is considered to be at the bottom

* Update tests to account for new BUFFER_TO_BE_CONSIDERED_BOTTOM
* Run docs-impact-review as regular CI instead of slash command

Switch the Documentation Impact Review workflow from a `/docs-review`
slash command trigger to running automatically on pull_request events.
The analysis posts a sticky PR comment and inline comments, and adds a
`docs/needed` label when documentation changes are needed.

Made-with: Cursor

* Address review feedback: harden docs-impact-review workflow

- Remove invalid `direct_prompt` input not recognized by the pinned
  claude-code-action version (auto-detects mode from event type).
- Guard Claude step with secret availability check so fork and
  Dependabot PRs skip gracefully instead of failing.
- Move label management out of the LLM into a deterministic
  github-script step that parses the sticky comment, eliminating
  prompt-injection and excessive-agency risks.

Made-with: Cursor

* Fix secret check: use job-level env var instead of secrets context in step if

The secrets context is not available in step-level if expressions.
Evaluate it as a job-level env var and reference that instead.

Made-with: Cursor

* Use paginated API call to fetch all PR comments

Prevents missing the bot comment on busy PRs with more than 30 comments.

Made-with: Cursor

* Address review: add issues:write permission, remove auto-label-removal

- Upgrade issues permission from read to write (required for addLabels API)
- Remove automatic docs/needed label removal to avoid stripping the label
  prematurely when the analysis comment hasn't been posted yet

Made-with: Cursor
* Fix typos in webapp/channels: receivedStatus and separately

* Revert formatting changes and keep typo fix

---------

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

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
#34657)

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
* Refactoring image proxy

* Improving resilience of peeking mechanism

* Moving should304 check

* Replacing functions with text encoding library
pavelzeman and others added 30 commits April 21, 2026 12:22
* ci: fix startup_failure in nightly race and weekly workflows

Add id-token: write permission to both server-ci-nightly-race.yml and
server-ci-weekly.yml. The reusable server-test-template.yml declares
id-token: write in its permissions block (needed for FIPS Docker Hub
login via OIDC). GitHub requires that caller workflows grant at least
the permissions declared by any reusable workflow they invoke —
regardless of whether the steps using those permissions are skipped at
runtime. Both new workflows only declared contents: read, causing
immediate startup_failure with zero jobs created.

Release Note
```release-note
NONE
```

Co-authored-by: Claude <claude@anthropic.com>

* ci: remove unused id-token: write from server-test-template

The template declared id-token: write but nothing in the workflow uses
OIDC token exchange — the FIPS Docker Hub login uses plain secrets
(DOCKERHUB_USERNAME/DOCKERHUB_TOKEN), not an OIDC identity token.

Removing it from the template means caller workflows (nightly race,
weekly, and the main server-ci) no longer need to grant id-token: write
either, following the principle of least privilege.

This is the actual root cause fix: the previous commit added id-token
to the callers as a workaround, but the real issue was the template
requesting a permission it never uses.

Co-authored-by: Claude <claude@anthropic.com>

---------

Co-authored-by: Claude <claude@anthropic.com>
* Update docs-impact-review.yml

* Update docs-impact-review.yml
* Update Agents plugin to v2.0.0-rc4

* Update Agents plugin to v2.0.0-rc5
* Fix bot import panic when user exists without bot record

The original importBot error handler re-declared `var appErr *model.AppError`
inside the CreateBot failure block, shadowing the outer appErr with a typed nil
pointer. When errors.As received this (*model.AppError)(nil), it was a non-nil
interface — so instead of returning false, it called AppError.Unwrap() on the
nil receiver, causing a panic.

This commit:
- Fixes the variable shadowing that caused the panic
- Adds recovery logic: when CreateBot fails because the username is taken,
  look up the existing user and create/update just the bot record
- Fixes pre-existing silent error swallowing in Bot().GetByUsername — now
  distinguishes store.ErrNotFound from real database errors
- Fixes pre-existing bug where DisplayName changes on re-import were lost
  because DisplayName is stored in Users.FirstName, not the Bots table
- Adds logging at every step of the recovery path (Info for normal flow,
  Warn for fallback/error paths)
- Uses distinct variable names (saveErr/updateErr) in the Save→Update
  fallback to avoid the same class of variable-reuse hazard
- Adds comprehensive test suite (11 subtests) covering dry-run, apply,
  re-import, recovery, regression/panic guard, idempotency, DisplayName
  update, and plugin-owner edge cases

* Address review findings: tighten assertions, fix error ID, add coverage

- Use require.ErrorAs for store.ErrNotFound instead of generic require.Error
  in the dry-run test, so it catches only not-found rather than any store error
- Add time.Sleep before idempotent re-import to ensure any real write would
  produce a different UpdateAt timestamp at millisecond resolution
- Fix misleading error ID "app.bot.createbot.internal_error" to
  "app.bot.update.internal_error" in the Update fallback path
- Add test for non-username CreateBot failure (email conflict) to cover
  the error passthrough at line 907-908

* Add missing i18n translations for bot import error strings

Add translation entries for app.bot.update.internal_error,
app.import.import_bot.lookup_error, and
app.import.import_bot.user_not_found.error to fix enterprise CI
i18n check failure.
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
…endpoint (#34678)

* gather plugin metrics and serve on /metrics

* tests

* fix recent conflicts from master

* fix linting

* address review feedback: feature flag, route guard, and unit tests for plugin metrics

- Add PluginMetricsCollection feature flag (default true) to allow disabling plugin metric collection without a deploy
- Only wrap the /metrics handler with plugin metric collection (not arbitrary plugin routes, which would cause double-listing)
- Extract wrapping logic into wrapMetricsHandler for clarity
- Add unit tests for addPluginLabelToMetrics covering no-label, existing-label, comments, empty lines, and multiple metrics cases

* fix integration tests to use /metrics route so wrapMetricsHandler runs

* switch addPluginLabelToMetrics to use expfmt for correct label injection

Replace string manipulation with expfmt parse→mutate→re-encode, which
correctly handles all metric types, timestamps, and malformed input.
Output is normalized: blank lines are dropped and TYPE headers are
injected for undeclared metrics. Update unit tests accordingly.

* refine addPluginLabelToMetrics: log warnings, drop sort, use assert.Contains

- Log a warning (instead of silently discarding) on parse or encode errors,
  returning empty string in both cases
- Remove name sorting — metric family order is irrelevant to Prometheus scrapers
- Switch unit test assertions to assert.Contains per line so tests are
  order-independent

* replace strPtr helper with model.NewPointer

* fix gofmt: remove extra blank line

* replace existing plugin_id label instead of appending a duplicate

If a plugin already exports a plugin_id label, overwrite it rather than
appending a second one, which would produce invalid Prometheus output.
Add test coverage for the replace path.

* add missing test coverage per mattermost-build feedback

- Unit test: malformed input returns empty string without panicking
- Integration: PluginMetricsCollection=false excludes plugin metrics
- Integration: plugin returning non-200 status excluded from response
- Integration: plugin returning empty body excluded from response

* rename PluginMetricsCollection to AggregatePluginMetrics, default false

---------

Co-authored-by: Jesse Hallam <jesse@mattermost.com>
* docs: document enterprise.pin workflow in root AGENTS.md

* docs: add bash language tag to fenced code block in AGENTS.md
…e job (#36216)

The Coverage job ran the same tests as Postgres with only ENABLE_COVERAGE=true
and a Codecov upload as differences. Enable coverage directly on the Postgres
job under the same release-branch skip condition, eliminating 4x 8-core runner
hours per PR.
Error: Action failed with error: HttpError: Resource not accessible by integration
#36178
…logs (#36214)

* Surface ws_event type in oversized cluster publish message logs

When a best-effort UDP gossip send fails with "message too long", the log
only shows event: publish with no further context. Tag the ClusterMessage
with the originating WebSocket event type so it appears in the error log.

* Update enterprise.pin to latest after enterprise PR #2133 merged

https://claude.ai/code/session_01Y1Abg1eDjKQBJvy7XhCtG6

* Bump

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Claude <noreply@anthropic.com>
* Default template property field permissions to sysadmin

Templates define the schema that linked fields inherit, so their
permission levels should default to sysadmin rather than member. This
aligns the create handler with TestLinkedProperties expectations.

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

* Require sysadmin for template property field creation

The target_type-based scope check lets team admins create template
fields with target_type=team, which would then inherit sysadmin-level
permission defaults and lock the creator out. Enforce manage_system for
any template creation so the permission gate matches the intent of the
"create template field as non-admin fails" test.

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

---------

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

* MM-67975: Add container CPU and memory limits to support packet diagnostics

Add two new optional fields to SupportPacketDiagnostics.Server:
- container_cpu_limit (float64): effective CPU limit in CPUs (e.g. 0.5, 2.0)
- container_memory_limit_mb (uint64): memory limit in MB

Both fields are populated from cgroups v2 (/sys/fs/cgroup/memory.max and
/sys/fs/cgroup/cpu.max) on Linux. Fields use omitempty so they are absent
from the output on bare metal or when no container limits are configured,
preserving backwards compatibility.

Non-Linux builds compile and produce no output for these fields via a
container_limits_other.go stub, following the existing memory_linux.go /
memory_other.go pattern.

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

* Fix golangci-lint errors: govet shadow and gofmt formatting

- Fix govet shadow: use var memBytes uint64 + err = instead of memBytes, err :=
  to avoid shadowing the outer err variable (which is reused after this block)
- Fix gofmt: add extra space before // 512 MB comment to align with
  the longer v2CPUMax line in the same assignment block

* fix(platform): ceil memory MB conversion and return zero-values for missing cgroup files

- Use ceiling division for MemoryLimitMB so sub-1MB limits map to 1 instead
  of 0 (which omitempty would silently drop)
- Absorb os.ErrNotExist in getContainerLimits so non-v2/bare-metal hosts
  return ContainerLimits{}, nil as the function comment promises
- Update test: missing cgroup file now asserts zero-values, not an error

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

* test(platform): add subtest locking ceil-to-MB behavior for sub-MB memory limits

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

* test(platform): add subtest for missing cpu.max returning zero values

Locks in the os.ErrNotExist branch for cpu.max (lines 57-60 in
container_limits_linux.go), which was previously unreachable via the
existing missing-memory test since that test returns early before
reading cpu.max.

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

---------

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

* fix(mmctl): prevent nil pointer panic in websocket command on connection failure

When the WebSocket connection fails immediately, Listen() closes EventChannel
via defer. Reading from a closed channel with a plain receive returns nil,
causing a panic in ToJSON(). Switch to range so the loop exits cleanly,
add a nil guard, and surface ListenError to the caller.

Fixes MM-68351

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

* test(mmctl): add unit tests for websocket nil event and ListenError handling

Extracts the event-processing loop into processWebSocketEvents to enable
unit testing, and adds tests covering the nil-event skip and error surfacing.

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

* test(mmctl): add happy-path subtest for processWebSocketEvents

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* MM-67352 Prevent composer scroll jumps on formatting click

Keep formatting controls from stealing textarea focus on mousedown so long drafts stay in place when markdown buttons are clicked. Add a regression test for the formatting bar interaction.

Made-with: Cursor

* Update webapp/channels/src/components/advanced_text_editor/formatting_bar/formatting_icon.tsx

Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>

---------

Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
* MM-66082: Fix invite modal paste by reading text/plain from clipboard

UsersEmailsInput always called preventDefault on paste but read clipboard
data with the legacy 'Text' type, which is empty in modern browsers.
That blocked default paste while adding nothing. Read text/plain first,
fall back to Text, skip custom handling when there is no meaningful
content, and only preventDefault when handling pasted text.

Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>

* Fix ESLint no-void in UsersEmailsInput paste handler

Replace void promise with .catch(() => undefined) so async paste
processing satisfies the no-void rule.

Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>

* MM-66082: Keep arbitrary pasted invite text as draft

Only treat obvious list pastes (comma, semicolon, newline) as bulk
invite input. Let arbitrary pasted text remain in the input so the
existing search and no-match UX can handle it, and keep space-delimited
text as draft rather than splitting it into invite tokens.

Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>

* MM-66082: Restore space-delimited email paste handling

Treat space-separated paste as bulk invite input only when every token
is a valid email. Keep mixed or free-form space-separated paste as draft
text so the existing no-match search UX still applies.

Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>

* MM-66082: Fix invite paste parsing in modal input

Treat pasted input as bulk invite tokens only when it is a single valid
email, an obvious comma/semicolon/newline list, or a space-separated list
of valid emails. Leave mixed or arbitrary pasted text as draft so the
existing no-match search UX still applies. Add focused widget and invite
view regression coverage for the affected paste paths.

Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>

* tests: use example invite paste fixtures

Replace product-specific test data with example.com values, restore the
space-paste length assertion, rename the invalid-word fixture, and remove
extra clipboard MIME lookups that were not needed for the supported paste
path.

Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>

* MM-66082: Fix invite input typing regressions

Fix premature chip creation while typing valid emails by using the paste
classifier only when it returns bulk mode, keep the valid address default
message wired correctly, and add regression coverage for typing and blur
behavior in both UsersEmailsInput and InviteView.

Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
The react-select input uses classNamePrefix ManagedCategory, so it did not
inherit the global react-select__input theme color. Set color to
var(--center-channel-color) on the input and input-container to match
placeholder and single-value styling.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Devin Binnie <devinbinnie@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* Introduce model.SanitizeFilename and model.IsValidFilename, and
apply them in genFileInfoFromReader and FileInfo.IsValid. The
sanitizer uses filepath.Base, NFC-normalizes Unicode, strips ASCII
control characters, collapses backslashes to forward slashes, and
truncates to the VARCHAR(256) fileinfo.name column width.
* Fix invite modal input text clipping and modal width overflow

Root cause: react-select v5 auto-sizes the input container using a CSS
grid with data-value attribute, which grows the grid columns based on
input text width. This caused the control, modal-content, and the
dropdown menu to exceed the modal-dialog's 600px width.

Changes:

1. invitation_modal.scss: Add max-width:100% and overflow:hidden on
   .modal-content to prevent it from overflowing the 600px modal-dialog.

2. users_emails_input.tsx: Override react-select's styles:
   - input.gridTemplateColumns: '0 minmax(0, 1fr)' prevents the sizer
     column from auto-expanding based on typed text width.
   - valueContainer.gridTemplateColumns: 'minmax(0, 1fr)' prevents the
     value-container grid from auto-sizing columns beyond the container.
   - Remove old display:flex and width:100% overrides that fought with
     react-select v5's inline-grid layout.

3. users_emails_input.scss:
   - Remove legacy width:1px on react-select input wrapper.
   - Add min-width:0 and max-width:100% on value-container and
     input-container for proper flex/grid containment.
   - Constrain dropdown menu to max-width:100%.
   - Allow no-match text and menu notices to wrap with overflow-wrap
     and word-break. Use min-height instead of fixed height so wrapped
     text fits.

Fixes: MM-68461

Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>

* Fix stylelint property order in invitation_modal.scss

Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>

* Update snapshot for react-select style changes

Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>

* Add min-width: 0 to input-container to prevent shrink/overflow regressions

Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
sqlstore's TestMain calls sqlstore.InitTest (which opens postgres and
drops tables) before mainHelper.Main, so the -test.list bailout added
in #36222 never fired and shard-split discovery failed on the GitHub
host. Bail out at the top of TestMain instead, and restore HEAVY_MS
so sqlstore can still be treated as whole.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
* Adds version to the property group model

* Ensures that the REST API rejects v1 group calls

* Ensures field version and group version match

* Simplify property groups on app layer tests

* Add GetByID to PropertyGroupStore and enforce field/group version match on update

* Simplify bits of the code

* Fix i18n and add generic errors

* Fix PropertyGroupStore mock to return stable IDs and default zero version to V1

* Fix tests that were using nonexistent group IDs

* Fix rigidness on valid group names

* Update group not found slug

* Temporary allow to use tempaltes with v1

* Explicitly including tempaltes in the IsPSAv1 check for conflict check

* Return 404 on group not found and template explicit inclusion on patch API endpoint

* Fix CPA test that would use fields from unregistered groups

---------

Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
* [MM-68231] Tighten post info authorization

Align post info channel access with the standard read path while preserving expected public-channel discoverability. Add regression coverage for guest and compliance-mode access checks.

Made-with: Cursor

* [MM-68231] Strengthen post info test coverage

Tighten the new post info regression coverage so the guest denial case proves its setup and the compliance case asserts the expected non-compliance behavior first.

Made-with: Cursor

* [MM-68231] Expand post info authorization coverage

Add focused regression coverage for invite-team access, compliance behavior on open teams, private-channel permission boundaries, and outsider denial for DM and GM post info.

Made-with: Cursor
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.