* MM-64330 - filter abac users in channel invite
* implement cursor functionality for abac user filtering
* remove unnecessary comments
* refactor the backend implementation simplifying the functions
* refactor api to use opts as parameters, rename function
* add missing translation
* remove unnecesary test code
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
The function was trying to use 'opts.TeamID' but 'opts' was not defined in the function scope. Changed it to use the 'teamId' parameter which is properly defined in the function signature.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Claude <noreply@anthropic.com>
* move category permissions to api
In https://github.com/mattermost/mattermost/pull/21038, we changed the
behaviour of the channel category store to filter out deleted teams and
teams for which the user was not a member. This was necessary in part
due to querying multiple teams via GraphQL.
With GraphQL no longer supported, let's move the permissions to the
API instead and remove the `JOIN` to filter out teams in the store.
Note that we /don't/ prevent access to deleted teams. For better or
worse, deleted teams remain largely accessible via other API endpoints
anyway.
* remove ExcludeTeam / GraphQL support
As part of https://github.com/mattermost/mattermost/pull/20353, we added
`ExcludeTeam` and the associated logic to support a GraphQL API.
With GraphQL no longer supported, let's simplify this logic and remove
the filtering and associated complexity.
* Fix shadow variable declaration in channel_store_categories.go
Fixed golangci-lint error by reusing existing err variable rather than shadowing it.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix build issue
* Remove SidebarCategorySearchOpts and simplify API to use teamID string
Per code review feedback, this change removes the SidebarCategorySearchOpts
struct entirely since the Type field was never used in the store implementation.
All methods now accept a simple teamID string parameter instead of the struct,
which simplifies the API and makes the code clearer.
Changes:
- Remove SidebarCategorySearchOpts struct from store.go
- Update CreateInitialSidebarCategories and GetSidebarCategories signatures
- Update all implementations (sqlstore, retrylayer, timerlayer, mocks)
- Update all callers to pass teamID string directly
- Clean up unused imports
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Remove redundant sidebar tests from TestChannelStore
* MM-63725 Refactor to split out getOrphanedSidebarChannels
* MM-63725 Populate multiple sidebar categories at once whenever possible
* Fix shadowing
* feat: Replace 5% grace period with configurable ExtraUsers field
- Rename ExtraSeats to ExtraUsers in license Features struct
- Remove fixed 5% grace period and minimum 1 extra user logic
- Add configurable ExtraUsers field that allows exact control over additional seats
- Update calculateGraceLimit() to use extraUsers parameter directly
- When ExtraUsers is nil, defaults to 0 (hard cap with no overage)
- Special case maintained: zero user licenses always return 0 grace limit
- Update all tests to use new ExtraUsers functionality
Closes#31628
Co-authored-by: Jesse Hallam <lieut-data@users.noreply.github.com>
* feat: eliminate calculateGraceLimit function, use inline baseLimit + extraUsers
- Remove calculateGraceLimit function and replace with inline calculation
- Allow extraUsers even when baseLimit is 0 (behavioral change)
- Update tests to reflect new behavior
- Remove TestCalculateGraceLimit since function no longer exists
Co-authored-by: Jesse Hallam <lieut-data@users.noreply.github.com>
* feat: move ExtraUsers field to top level License struct
Move ExtraUsers field from Features struct to the top level License struct
for better organization and direct access. Update all references in limits.go
and limits_test.go to use the new field location.
Co-authored-by: Jesse Hallam <lieut-data@users.noreply.github.com>
* feat: use model.NewPointer for creating integer pointers in tests
Replace inline function declarations with model.NewPointer calls for cleaner code.
Co-authored-by: Jesse Hallam <lieut-data@users.noreply.github.com>
* feat: reorder ExtraUsers field to be after IsSeatCountEnforced
Co-authored-by: Jesse Hallam <lieut-data@users.noreply.github.com>
* fix: format Go files with gofmt
- Remove extra blank line in limits.go
- Align struct fields in limits_test.go table test
Co-authored-by: Jesse Hallam <lieut-data@users.noreply.github.com>
* Fix user limits tests and document ExtraUsers field
- Fix TestCreateUserOrGuestSeatCountEnforcement to use ExtraUsers instead of old grace period
- Add documentation to ExtraUsers field explaining it as a grace mechanism
- Update test comments to reflect hard limit terminology
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Co-authored-by: Jesse Hallam <lieut-data@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
When a user disconnects from the hub, we would spawn off a goroutine
which would make a cluster request, and then update the user status
as offline in the DB.
This was another case of unbounded concurrency where the number of
goroutines spawned was user controlled. Therefore, we would see
a clear spike in DB connections on master when a lot of users
would suddenly disconnect.
To fix this, we implement concurrency control in two areas:
1. In making the cluster request. We implement a counting semaphore
per-hub to avoid making unbounded cluster requests.
2. We use a buffered channel with a periodic flusher to process
status updates.
We also add a new store method to upsert multiple statuses
in a single query. The statusUpdateThreshold is set to 32, which means
no more than 32 rows will be upserted at one time, keeping the
SQL query load reasonable.
https://mattermost.atlassian.net/browse/MM-64298
```release-note
We improve DB connection spikes on user disconnect
by processing status updates in batches.
```
* [MM-63717] LDAP Wizard skeleton (#31029)
* add ldap_wizard component to render its admin components
* i18n
* test adjustment
* keys and props fixes
* title fix
* fix placeholders
* fix value initialization
* linting
* remove all ...props (except custom component); any->unknown
* fix i18n (temp, will be changed in later PR)
* better return; simplify function checking/calling
* [MM-64259] Sections sidebar and navigation (#31059)
* initial sections list sidebar
* sidebar highlighting and scroll on click
* some tidying up
* add custom section titles for section sidebar
* i18n
* updating border on sections
* scss style lint
* color -> border-color
* simplify activeSectionKey initialization; remove trailing newline
* add useSectionNavigation; clean up ldap_wizard and scss; PR comments
* extract section of code into renderSidebar()
---------
Co-authored-by: Asaad Mahmood <asaadmahmood@users.noreply.github.com>
* [MM-64296] Add test connection for connection settings panel (#31190)
* button -> ldap test connect api
* fix console error by sanitizing value in text component
* return detailed error as error; adjust button -> primary, flushLeft
* middle of redesigning how we do hover text, first button
* add hover text to bools and file uploads
* i18n
* add LdapSettings as api type; add new endpoint to api yaml
* allow testing without first enabling LDAP and saving config
* i18n id changes
* improve TestLdapConnection to current standards
* PR comments
* safeDereference; cleaner returns
* remove hover markdown; formatting and typing simplification
* use button for "More Info"; i18n
* finish renaming help_text_hover -> help_text_more_info
* fix error output
* only send bindpassword if it has been changed
* fix: don't send blank bindPassword when it is still *****
* merge conflict
* [MM-64480] Refactor Admin Definition (#31280)
* move ldap definition to its own file for simplicity & context
* refactor admin_definition to eliminate circular dependencies
* merge conflicts
* before: buggy userHasReadPermissinOnSomeResources; after: fix incorrect snapshot
* merge conflict: new bindPasssword definition was left behind; fixed.
* merge conflict
* [MM-63765] LDAP Wizard: User filter expandable section (#31286)
* add "more info" hover to user filter help texts; make wider
* add expandable_setting type and component
* use Dislosure show/hide pattern for accessibility
* fix tooltip scss selectors
* fix hover -> more_info; make sure translation files are correct
* use join('\n\n') instead of the eslint disable line
* Revert "use join('\n\n') instead of the eslint disable line"
This reverts commit 274667e875b34703f14fee0706cd28b0125cefc9.
* [MM-64482] LDAP Wizard - Test User filters (#31312)
* initial cut at UI and backend for test filters
* api definitions; mocks
* clean up to current standards
* [MM-64512] - Test user filters UI (#31355)
* result_count -> total_count
* json cannot marshal error, returning error as string as god intended
* render errors with icon, hover text, and better feedback texts
* gather the settings that may be in expandable sections
* remove success, use error == "" to indicate success
* [MM-64536] LDAP Wizard: Test user attributes (#31373)
* LdapFilterTestResult -> LdapDiagnosticResult; FilterName -> TestName
* implement test_attributes endpoint and limited frontend (first step)
* adding EntriesWithValue
* [MM-64550] LDAP Wizard: Test user attributes UI (#31374)
* [MM-64551] LDAP Wizard: Test group attributes (#31375)
* remove Test LDAP button (not needed); reused helptext for other btn
* implement test_group_attributes endpoint; button/client-side paths
* [MM-64552] LDAP Wizard: Test group attributes UI (#31376)
* implement Test Group Attributes button
* simplify helper functions (improves useCallback dependencies)
* show the default filter that was used on the backend in the tooltip
* show the icon when there's an error (e.g. required filter/attribute)
* fix infinite rerendering
* fix error after failed save; fix navigation unlocked after save
* empty
* Adjust message feedback given we don't test the schema anymore
* improve css; don't use inline styles
* removed unneccesary pointer indirection
* improved i18n strings and logic
* combining filters/attributes/group attributes endpoints
improve types
* improve help text for User Filter (it's tricky)
* AvailableAttrs -> AvailableAttributes
* fix for e2e tests (renamed title)
* more e2e fixes
* skip broken e2e test
---------
Co-authored-by: Asaad Mahmood <asaadmahmood@users.noreply.github.com>
* enforce License.IsSeatCountEnforced if set
If a license sets `IsSeatCountEnforced`, enforce the user limit therein
as a hard cap.
Fixes: https://mattermost.atlassian.net/browse/CLD-9260
* remove duplicate tests
* Improve user limit error messages and display
- Add separate error messages for licensed vs unlicensed servers
- Licensed servers: "Server exceeds maximum licensed users. ERROR_LICENSED_USERS_LIMITS"
- Unlicensed servers: "Server exceeds safe user limit. ERROR_SAFETY_LIMITS_EXCEEDED"
- Remove redundant "Contact administrator" text from activation errors shown to admins
- Fix system console to display actual server error messages instead of generic "Failed to activate user"
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Add license nil check and test coverage
- Add license != nil check in GetServerLimits to prevent panic
- Add test case to verify graceful handling of license being set to nil
- Ensures fallback to hard-coded limits when license becomes nil
Co-authored-by: lieut-data <lieut-data@users.noreply.github.com>
* Fix user limits tests to expect license-specific error IDs
Update test expectations to use the new license-specific error IDs:
- app.user.update_active.license_user_limit.exceeded for licensed server user activation
- api.user.create_user.license_user_limits.exceeded for licensed server user creation
Also update frontend to show actual server error messages instead of generic ones in system console.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Remove redundant license nil test
The test couldn't meaningfully verify nil license behavior since it relied on
hard-coded constants that can't be modified in the test.
Co-authored-by: lieut-data <lieut-data@users.noreply.github.com>
* Fix whitespace issue in limits_test.go
Remove unnecessary trailing newline to pass style checks.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* updated i18n
* s/ERROR_LICENSED_USERS_LIMITS/ERROR_LICENSED_USERS_LIMIT_EXCEEDED/, expand warning log
* Add 5% grace period for licensed user limits
- Add calculateGraceLimit() function with 5% or +1 minimum grace
- Apply grace period only to licensed servers with seat count enforcement
- Handle zero user licenses by returning zero grace limit
- Add comprehensive test coverage for grace period scenarios
- Unlicensed servers maintain existing hard-coded limits without grace
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix TestCreateUserOrGuestSeatCountEnforcement to account for 5% grace period
The test was failing because it expected user creation to fail at exactly
the license limit, but the implementation now includes a 5% grace period
before enforcement kicks in.
Changes:
- Update test cases to create users up to the grace limit (6 for a 5-user license)
- Add comments explaining the grace period calculation
- Both regular user and guest user creation tests now properly validate
enforcement at the grace limit rather than the base license limit
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix TestUpdateActiveWithUserLimits to account for 5% grace period
Update test expectations to match the new grace period behavior:
- At base limit (100) but below grace limit (105): should succeed
- At grace limit (105): should fail
- Above grace limit (106): should fail
This aligns the tests with the license enforcement implementation
that includes a 5% grace period above the licensed user count.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Co-authored-by: lieut-data <lieut-data@users.noreply.github.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
* Adds support for GMs in shared channels
* Fix linter
* Remove creatorID from slack call
---------
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
* Upgrade Go to 1.24.3
Updates the following files:
- server/.go-version: 1.23.9 → 1.24.3
- server/build/Dockerfile.buildenv: golang:1.23.9-bullseye → golang:1.24.3-bullseye
- server/go.mod: go 1.23.0 → go 1.24.3, toolchain go1.23.9 → go1.24.3
- server/public/go.mod: go 1.23.0 → go 1.24.3, toolchain go1.23.9 → go1.24.3
Also fixes non-constant format string errors introduced by Go 1.24.3's stricter format string checking:
- Added response() helper function in slashcommands/util.go for simple string responses
- Removed unused responsef() function from slashcommands/util.go
- Replaced responsef() with response() for translated strings that don't need formatting
- Fixed fmt.Errorf and fmt.Fprintf calls to use proper format verbs instead of string concatenation
- Updated marketplace buildURL to handle format strings conditionally
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Update generated mocks for Go 1.24.3
Regenerated mocks using mockery v2.53.4 to ensure compatibility with Go 1.24.3.
This addresses mock generation failures that occurred with the Go upgrade.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Update to bookworm and fix non-existent sha
Signed-off-by: Stavros Foteinopoulos <stafot@gmail.com>
* fix non-constant format string
---------
Signed-off-by: Stavros Foteinopoulos <stafot@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Stavros Foteinopoulos <stafot@gmail.com>
Fix support packet caching issue by adding no-cache headers
Added Cache-Control headers to prevent browser caching when downloading support packets.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* add video type
* add video mime-type
* combine MIME type maps and update tests
* correct MIME type detection for video files
* format code
* lint fix
* simplified mimeType
* change avi mime type
* add avi type