* Adding watermarking toggle in server
* Update setting to enterprise
* Adding it to mobile security
* Updating experimental section
* Moved back to experimental settings. Added license checks
* Updating tests
---------
Co-authored-by: maria.nunez <maria.nunez@mattermost.com>
* Fixed a bug where user profile popover closed automatically when opened for the first time for a user from channel member list in RHS
* Added tests
* fixed a test
After editing a post, the main textbox now properly regains focus.
The fix uses the stored refocusId to focus the correct textbox element
(post_textbox or reply_textbox) before unsetting edit mode.
Co-authored-by: Mattermost Build <build@mattermost.com>
* MM-67592 - be changes for team admin abac channels (#35353)
* MM-67592 - be changes for team admin abac channels
* Revert team-scoped API routes, keep app layer business logic
* move from config to permission; Add cluster-aware LRU cache for policy team scope lookup
* remove unnecessary references to config value
* local/remote cache invalidation consistency for policy scope
* Replace policy scope cache with store-level team scope query
* rename functions and add comments to query
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
* MM 67594 - policies CUD operations to team settings modal channels ABAC (#35590)
* MM-67592 - be changes for team admin abac channels
* Revert team-scoped API routes, keep app layer business logic
* move from config to permission; Add cluster-aware LRU cache for policy team scope lookup
* remove unnecessary references to config value
* local/remote cache invalidation consistency for policy scope
* Replace policy scope cache with store-level team scope query
* format files correctly
* fix mock expectations for store-query approach in tests
* rename functions and add comments to query
* revert error ids to original to prevent break tests
* adjust translations
* MM-67669 - add tab to team settings modal and basic listing
* adjust tests and fix linter
* use existing search api logic
* fix style and adjust flaky test to clean up and restore orinals
* address ai corabbit feedback and fix linter
* fix unit tests
* MM-67592 - be changes for team admin abac channels (#35353)
* MM-67592 - be changes for team admin abac channels
* fix linter
* fix ts linter for playwright
* Revert team-scoped API routes, keep app layer business logic
* move from config to permission; Add cluster-aware LRU cache for policy team scope lookup
* remove unnecessary references to config value
* local/remote cache invalidation consistency for policy scope
* Replace policy scope cache with store-level team scope query
* format files correctly
* fix mock expectations for store-query approach in tests
* rename functions and add comments to query
* revert error ids to original to prevent break tests
* adjust translations
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
* MM-67594 - support cud operations for team abac BE changes
* create the team settings policy edit section, reuse most components, add basic e2e
* move optional refresh policy list button to list component
* temp get team admins cud policies and sync job
* enhance validation and adjust e2e
* Fix testExpression permission; fix pagination of team policies; add isValidId validation
* adjust styles, handling renaming and add permission migrations
* update the permissions names, use the simple confirmation modal, define the delete modal
* fix policy deletion flow
* fix some linter issues and adjust helper tests
* remove delete from list and fix e2e
* code comments clean up
* remove CEL editor for now, clean styles, enhance e2e
* fix linter, adjust unit test
* fix linter and add missing translation
* fix policy deletion ownership and sanitize test expression
* fixed e2e tests
* rollback orphaned policy on failed channel assignment
* enforce channelless check before last_team_id fallback
* enforce channelless guard on assign fallback too
* add translations missing
* add teamId to audit payload when present
* fix refresh button pagination reset
* fix null safety in channel selector loadChannels
* use responsive width cap for team settings modal and adjust header size
* remove redundant raw term from channel search URL, add showRefreshButton prop to PolicyList component
* handle error when stamping last team ID on channelless policy
* replace Props-based ownership with in-memory LRU cache, disable save on zero channels
* make e2e tests more reliable in CI
* test skip if no license valid found
* add childCount guard to cache-hit paths and reduce TTL to 5s
* fix e2e, adjust translation
* address review feedback: flatten permission checks and separate error types
- Flatten nested permission branching in deleteAccessControlPolicy using
early returns to reduce indentation (review: isacikgoz)
- Validate teamID as input (400) before using it for permission checks (403)
in testExpression and validateExpressionAgainstRequester handlers
- Remove redundant hasSystemPermission check in searchAccessControlPolicies
since system_admin role already includes manage_team_access_rules
- Refactor ValidateTeamAdminPolicyOwnership to return (bool, *model.AppError)
separating "not owned" from "internal error" across all 8 call sites
- Update tests to assert on both return values
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* add persistent team scope to access control policies, replace in-memory cache
* fix translation
* fix case-insensitive policy search and sanitize search term input
* make policies tests have a unique name
* decouple scope/scopeID filter from TeamID in policy store
* Fix authZ bypass searchChannelsForAccessControlPolicy by forcing TeamIds to authorized team
* show unsaved changes on navigator back, and list all private channels on load
* filter already applied channels to a policy
* adjust the styles to dark mode; do not show added channels to the policy in the add channels modal
* fix linter
* MM-67967 add sync status footer to team settings (#35729)
* MM-67967 add sync status footer to team settings
* remove magic numbers and strings and polish the code
* fix linter
* fix linter: replace interface{} with any per gofmt rewrite rule
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refine getJobsByType team-scoped filtering and permissions
* fix sync footer stuck in syncing state on job creation error
* fix team-scoped job pagination in getJobsByType
* Fix authZ bypass searchChannelsForAccessControlPolicy by forcing TeamIds to authorized team
* implement ux feedback, change titles font, fix marging and scroll view jump
* MM-68135 - migrate add channels to policy modal to generic modal (#35907)
* MM-67920 unify e2e team settings tests (#35867)
* MM-67920 - extract duplicated policy editor helpers
* remove duplicate team icon test file
* rename Access Control to Membership Policies in e2e
* replace networkidle with explicit element waits
* fix attribute loading issue
---------
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>
* fix playwright feedback issues and persist filters to the store layer in the no systemconsole path
* Improve policy scope validation and team admin security checks
* Renamed public channels to "AAA Public Channel %03d" and private ones to "ZZZ Private..." so the 55 public channels now fill the 50-result cap
* fix e2e tests and add new unit tests to improve coverage
* Improve e2e test stability: race condition handling and timeout adjustments
* Improve team-scoped ABAC policies: scope preservation, input validation, shared exclusion
* Add comprehensive ABAC test coverage: team admin ops and security validation to reduce flakyness
* Fix team policy editor back button: preserve navigation intent through Undo
* style: format import statements for better readability
* Enhance access control policy creation for team admins: enforce scope stamping from query parameters to prevent unauthorized team assignments
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add PermissionCreateAgent server-side permission definition
Define PermissionCreateAgent in the model layer with system scope,
add to SystemScopedPermissionsMinusSysconsole (feeds AllPermissions),
grant to system_user in MakeDefaultRoles(), and register a permissions
migration for existing installations (system_admin + system_user).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add exhaustive tests for PermissionCreateAgent permission
Model tests: verify create_agent is in AllPermissions, has system scope,
correct i18n fields, present in system_admin and system_user default roles,
and absent from system_guest.
Migration test: verify getAddCreateAgentPermissionMigration adds create_agent
to both system_admin and system_user, and is idempotent on re-run.
Also register the migration key in testlib mock store so server initialization
skips it during test setup.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add webapp permission constants and i18n for create_agent
Add CREATE_AGENT constant to permissions.ts, display strings with
defineMessages in permissions.tsx, and i18n entries in en.json so the
permission appears in System Console Permission Schemes UI.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Clean up tests and minor fixups for create_agent permission
Consolidate role_test.go into table-driven tests, remove redundant comments
in permissions_migrations_test.go, add .planning/ to .gitignore, and
refresh webapp/package-lock.json.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Split create_agent into manage_own_agent and manage_others_agent
Replace PermissionCreateAgent with system-scoped own/others permissions,
update migration and defaults, and wire System Scheme UI for integrations.
Made-with: Cursor
* fixes
* Stabilize autotranslation E2E by pinning mock source language
Set LibreTranslate mock to English before the pre-enable post and Spanish
before the post-enable message so parallel tests cannot leave the mock in
a state where the new message is not translated.
Made-with: Cursor
* Revert package-lock, add more chnages
* Revert "Revert package-lock, add more chnages"
This reverts commit 7f6752c2e0.
* Drop unrelated autotranslation E2E tweak; restore package-lock
The Playwright autotranslation change was not caused by MM-65671. Revert
that test edit and restore webapp/package-lock.json after an accidental
revert of the prior package-lock update.
Made-with: Cursor
* Put package-lock back again
* fixes
* Fix migration tests for manage_own_agent on system_user role
Made-with: Cursor
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
* Add pluggable AI actions menu with rewrite submenu and plugin extension point
* Use cascading hover popover for AI actions submenus
* Fix lint errors in AI actions menu and related files
* Update i18n strings for AI actions menu
* Fix coding guideline violations in AI actions menu and tests
* Fix spacing
* Fix stylelint errors in use_rewrite.scss
* Support ReactNode for AI action menu item text
* Fix empty menu guard, keyboard a11y, and rewrite follow-up placeholder
* Hide rewrite actions while a rewrite is in progress
* Remove subMenuHeader from plugin API and pass isRHS context to plugin components
* Support simple click actions in AI action menu plugin API
* Fix import order in ai_actions_menu tests
* Flip AI actions submenu to open left when insufficient space on right
Adapts the viewport-aware positioning pattern from the existing SubMenu
component so the cascading submenu renders on the side with more space.
* Only flip submenu to left when right space is insufficient
* [MM-68266] Pass through menu props to popout menu item, guard at menu definition to avoid null component blocking keyboard navigation
* fix tests
* Update webapp/channels/src/components/sidebar/sidebar_channel/sidebar_channel_menu/sidebar_channel_menu.test.tsx
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* MM-66937 Remove existing code for handling composition in SuggestionBox
This breaks the ability to autocomplete on Korean characters that haven't been
committed on Firefox. Both the previous and new versions seem to work fine on
Chrome though.
* Add E2E test for SuggestionBox composition in Find Channels modal
* Fix misnamed field
* MM-68235: Rename user-visible "Custom Profile Attributes" to "User Attributes"
Update all English i18n translation values and inline
defaultMessage strings to use the current product name
"User Attributes" instead of the old "Custom Profile
Attributes" / CPA naming.
Add naming-history comments to key CPA source files
(model, app, api4, admin component) explaining that
internal identifiers retain the old naming for backward
compatibility with REST APIs, WebSocket events, and the
Property System Architecture group name. This helps
future developers understand the mapping without needing
to track down the rename history.
* Fix missed lowercase "custom profile attribute" strings
* MM-67505 Add AnalyticsQueryTimeout setting and use when refreshing materialized views
* Fix last minute i18n change
* Disallow 0 values for AnalyticsQueryTimeout
* Fix E2E test config
* Fix post store tests crashing
* Update snapshot and revert accidental changes to it
* MM-63588: Add e2e tests for System Console Custom Profile Attributes
Add Playwright e2e tests for the System Console User Attributes page,
covering CRUD operations for custom profile attribute field definitions.
Tests cover:
- Page navigation and empty state display
- Creating text, select, and multiselect attributes with options
- Editing attribute names
- Deleting attributes (saved and unsaved)
- Duplicating attributes
- Changing attribute types (Text to Phone)
- Configuring visibility (Always show/Hide when empty/Always hide)
- Toggling "Editable by users" setting
- Batch creation (multiple attributes at once)
- Persistence verification after page reload
- Validation warnings (empty name, duplicate names)
Follows the same patterns established in MM-62558 / PR #30722 for
Profile Popup CPA tests, reusing shared helpers for field setup/cleanup.
* Fix 6 failing e2e tests for System Console User Attributes
- Remove .clear() before .fill() to prevent value-based locators from
going stale (edit name, persist after reload tests)
- Hover on visibility submenu instead of click, use force:true to handle
DOM detach during menu animation (visibility test)
- Press Escape to close dot menu before clicking Save, since the
"Editable by users" toggle keeps the menu open (editable test)
- Fix expected validation text: use "Attribute names must be unique."
instead of "Attribute name already taken." (duplicate names test)
- Increase timeout for Save button disabled assertion after deleting
unsaved attribute (delete unsaved test)
* Fix stale locators, flaky save check, and document dirty-state bug
- Use data-testid locators instead of value-based selectors for inputs
that get mutated by fill() (edit name + persist reload tests)
- Wait for Save button to return to disabled after save before API
check to avoid flaky field-not-found failures
- Add test.fail() for Save-stays-enabled bug after deleting an unsaved
row so CI passes today and alerts when the app bug is fixed
- Add LOCATOR NOTE to file header explaining the lazy locator pitfall
* Address CodeRabbit review: save helper, locator fix, test rename
- Add saveAndWaitForSettled() helper and apply to all 11 save paths
for consistent post-save stabilization before API verification
- Fix deptInput locator: use input[value] instead of broken
filter({hasText}) which doesn't match input element children
- Rename "different types" test to "multiple text attributes" to
match actual coverage
* MM-63588: add SystemProperties page object and refactor spec to POM
Extract all UI selectors from user_attributes.spec.ts into a
SystemProperties page object class, eliminating inline selectors
from the test file. Replace coarse networkidle with waitForResponse
on the actual save API endpoint.
* fix playwright e2e test failures
- selectType was failing as 'select' caught both 'select' and 'multi-select'
- Prior behavior where Save button wasn't returning to disabled appears to be working now, removing test.fail()
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
* Remove system_secure_connection_manager role
The dedicated role for delegating secure connection management is no
longer needed. The manage_secure_connections permission remains and
continues to be granted to system admins via AllPermissions.
Removes the role definition, migration, permissions migration, UI
components, i18n strings, and all associated tests across server,
webapp, and e2e-tests.
* Fix interactive dialog bugs: dynamic select lookups, radio values, and field refresh
- Cache sanitized fields in AppsForm to preserve object identity across
renders, preventing AsyncSelect from remounting and re-triggering
dynamic select lookups on every keystroke in any field
- Normalize radio field default values to plain strings in getDefaultValue()
so the value shape is consistent with what RadioSetting.onChange returns
(e.target.value). Accept both string and {label, value} object shapes
downstream for backwards compatibility.
- Fix radio field [object Object] in submission by extracting .value from
AppSelectOption objects in convertAppFormValuesToDialogSubmission
- Include selected_field in refresh submission so plugins know which field
triggered the refresh. Use a shallow copy of accumulatedValues to avoid
permanently contaminating the accumulated state.
- Send empty string for cleared select fields in refresh submissions.
Previously, extractPrimitiveValues skipped null values and the spread
merge never overwrote stale accumulated keys.
* refactor(brand_image_setting): migrate to function component
* test(brand_image_setting): update tests
Migrated tests to React Testing Library.
* refactor(brand_image_setting): wrap functions with useCallback
* test(brand_image_setting): use nock to mock fetch api
* test(brand_image_setting): use findby query instead of getby
* test(brand_image_setting): remove unnecessary scope assertion
* chore(brand_image_setting): split useEffect into two
Also extracted the handleSave function and wrapped it in useCallback.
* test(brand_image_setting): add e2e test for deleting brand image
* test(brand_image_setting): use destructured functions
* chore: delete unnecessary comment
* Revert "test(brand_image_setting): use destructured functions"
This reverts commit 71dc6628ed.
* Fix bad merge
* Fully revert changes to test from merge
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
* Fixed a bug where signup link showed up when signup was disabled
* Removed unused component
* fixed test name
* CI
* fixed a test
* fixed a commit
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
* 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
* 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
* 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.
* 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
* 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>
* 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
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).
* MM-68158: Fix shared channel remote display and add WebSocket notification
Fix getSharedChannelRemotes API handler passing ChannelId instead of
RemoteId to GetRemoteCluster, which always failed the lookup. Add
RemoteId to SharedChannelRemoteStatus model and store query.
Add shared_channel_remote_updated WebSocket event published from the
onInvite callback so the UI refreshes its cached remote names when the
async invite completes, instead of showing the generic "Shared with
trusted organizations" fallback.
* Improved unit tests per review comments
The SupportSettings.AllowDownloadLogs toggle in Site Configuration >
Customization was missing the RESOURCE_KEYS.SITE.CUSTOMIZATION
write-permission guard that all neighboring controls have, allowing
read-only admins to toggle it when they shouldn't be able to.
Co-authored-by: Mattermost Build <build@mattermost.com>
* simplify CODEOWNERS
* dont .gitignore AGENTS.md
* AGENTS.md to document previous CODEOWNERS responsibilities
* update from https://developers.mattermost.com/contribute/more-info/server/schema-migration-guide/
* CREATE INDEX CONCURRENTLY now vetted
* rewrite and move to README.md
* dont limit to 80 chars
* rewrite webapp AGENTS.md and add to README.md
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
* Add CreatedBy and UpdatedBy to the properties fields and values (#34485)
* Add CreatedBy and UpdatedBy to the properties fields and values
* Fix types
---------
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
* Adds ObjectType to the property fields table (#34908)
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
* Update ObjectType migration setting an empty value and marking the column as not null (#34915)
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
* Adds uniqueness mechanisms to the property fields (#35058)
* Adds uniqueness mechanisms to the property fields
After adding ObjectType, this commit ensures that both the PSAv1 and
PSAv2 schemas are supported, and enforces property uniqueness through
both database indexes and a logical check when creating new property
fields.
* Adds uniqueness check to property updates
Updates are covered on this commit and we refactor as well the SQL
code to use the squirrel builder and work better with the conditional
addition of the `existingID` piece of the query.
* Add translations to error messages
* Fixing retrylayer mocks
* Remove retrylayer duplication
* Address review comments
* Fix comment to avoid linter issues
* Address PR comments
* Update server/channels/db/migrations/postgres/000157_add_object_type_to_property_fields.down.sql
Co-authored-by: Alejandro García Montoro <alejandro.garciamontoro@gmail.com>
* Update server/channels/db/migrations/postgres/000157_add_object_type_to_property_fields.up.sql
Co-authored-by: Alejandro García Montoro <alejandro.garciamontoro@gmail.com>
* Update server/channels/db/migrations/postgres/000157_add_object_type_to_property_fields.up.sql
Co-authored-by: Alejandro García Montoro <alejandro.garciamontoro@gmail.com>
* Update field validation to check only for valid target types
* Update migrations to avoid concurrent index creation within a transaction
* Update migrations to make all index ops concurrent
* Update tests to use valid PSAv2 property fields
* Adds a helper for valid PSAv2 TargetTypes
---------
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
Co-authored-by: Alejandro García Montoro <alejandro.garciamontoro@gmail.com>
* Fix property tests (#35388)
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
* Adds Integrated Boards feature flag (#35378)
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
* Adds Integrated Boards MVP API changes (#34822)
This PR includes the necessary changes for channels and posts
endpoints and adds a set of generic endpoints to retrieve and manage
property fields and values following the new Property System approach.
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
Co-authored-by: Mattermost Build <build@mattermost.com>
* Property System Architecture permissions for v2 (#35113)
* Adds uniqueness mechanisms to the property fields
After adding ObjectType, this commit ensures that both the PSAv1 and
PSAv2 schemas are supported, and enforces property uniqueness through
both database indexes and a logical check when creating new property
fields.
* Adds uniqueness check to property updates
Updates are covered on this commit and we refactor as well the SQL
code to use the squirrel builder and work better with the conditional
addition of the `existingID` piece of the query.
* Add translations to error messages
* Add the permissions to the migrations, model and update the store calls
* Adds the property field and property group app layer
* Adds authorization helpers for property fields and values
* Make sure that users cannot lock themselves out of property fields
* Migrate permissions from a JSON column to three normalized columns
* Remove the audit comment
* Use target level constants in authorization
* Log authorization membership failures
* Rename admin to sysadmin
* Fix i18n sorting
---------
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
* Add Views store and app layer (#35361)
* Add Views store and app layer for Integrated Boards
Implements the View entity (model, SQL store, service, app) as described
in the Integrated Boards tech spec. Views are channel-scoped board
configurations with typed props (board, kanban subviews) and soft-delete.
- public/model: View, ViewBoardProps, Subview, ViewPatch types with
PreSave/PreUpdate/IsValid/Patch/Clone/Auditable
- Migration 158: Views table with jsonb Props column and indexes
- SqlViewStore: CRUD with nil-safe Props marshaling (AppendBinaryFlag)
- ViewService: CreateView seeds default kanban subview and links the
boards property field; caches boardPropertyFieldID at startup
- App layer: CreateView/GetView/GetViewsForChannel/UpdateView/DeleteView
with channel-membership permission checks and WebSocket events
(view_created, view_updated, view_deleted)
- doSetupBoardsPropertyField: registers the Boards property group and
board field in NewServer() before ViewService construction
- GetFieldByName now returns store.ErrNotFound instead of raw sql.ErrNoRows
* Move permission checks out of App layer for views
- Remove HasPermissionToChannel calls from all App view methods
- Drop userID params from GetView, GetViewsForChannel, UpdateView, DeleteView
- Fix doSetupBoardsPropertyField to include required TargetType for PSAv2 field
* Make View service generic and enforce board validation in model
- Remove board-specific auto-setup from service and server startup
- Enforce that board views require Props, at least one subview, and at least one linked property in IsValid()
- Move default subview seeding out of app layer; callers must provide valid props
- Call PreSave on subviews during PreUpdate to assign IDs to new subviews
- Update all tests to reflect the new validation requirements
* Restore migrations files to match base branch
* Distinguish ErrNotFound from other errors in view store Get
* Use CONCURRENTLY and nontransactional for index operations in views migration
* Split views index creation into separate nontransactional migrations
* Update migrations.list
* Update i18n translations for views
* Fix makeView helper to include required Props for board view validation
* Rename ctx parameter from c to rctx in OAuthProvider mock
* Remove views service layer, call store directly from app
* Return 500 for unexpected DB errors in GetView, 404 only for not-found
* Harden View model: deep-copy Props, validate linked property IDs
- Add ViewBoardProps.Clone() to deep-copy LinkedProperties and Subviews
- Use it in View.Clone() and View.Patch() to prevent shared-slice aliasing
- Iterate over LinkedProperties in View.IsValid() and reject invalid IDs
with a dedicated i18n key
- Register ViewStore in storetest AssertExpectations so mock expectations
are enforced
- Add tests covering all new behaviours
* Restore autotranslation worker_stopped i18n translation
* Fix view store test IDs and improve error handling in app layer
- Use model.NewId() for linked property IDs in testUpdateView to fix
validation failure (IsValid rejects non-UUID strings)
- Fix import grouping in app/view.go (stdlib imports in one block)
- Return 404 instead of 500 when Update/Delete store calls return
ErrNotFound (e.g. concurrent deletion TOCTOU race)
* Add View store mock to retrylayer test genStore helper
The View store was added to the store interface but the genStore()
helper in retrylayer_test.go was not updated, causing TestRetry to panic.
Also removes the duplicate Recap mock registration.
* Refactor view deletion and websocket event handling; update SQL store methods to use query builder
* revert property field store
* Remove useless migrations
* Add cursor-based pagination to View store GetForChannel
- Add ViewQueryCursor and ViewQueryOpts types with validation
- Return (views, cursor, error) for caller-driven pagination
- PerPage clamping: <=0 defaults to 20, >200 clamps to 200
- Support IncludeDeleted filter
- Add comprehensive store tests for pagination, cursor edge cases,
PerPage clamping, and invalid input rejection
- Add app layer test for empty channelID → 400
- Update interface, retrylayer, timerlayer, and mock signatures
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Refactor test loops in ViewStore tests for improved readability
* change pagination to limit/offset
* Add upper-bound limits on View Subviews and LinkedProperties
Defense-in-depth validation: cap Subviews at 50 and LinkedProperties
at 500 to prevent abuse below the 300KB payload limit.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* MM-67388, MM-66528, MM-67750: Add View REST API endpoints, websocket events, and sort order (#35442)
* Add Views store and app layer for Integrated Boards
Implements the View entity (model, SQL store, service, app) as described
in the Integrated Boards tech spec. Views are channel-scoped board
configurations with typed props (board, kanban subviews) and soft-delete.
- public/model: View, ViewBoardProps, Subview, ViewPatch types with
PreSave/PreUpdate/IsValid/Patch/Clone/Auditable
- Migration 158: Views table with jsonb Props column and indexes
- SqlViewStore: CRUD with nil-safe Props marshaling (AppendBinaryFlag)
- ViewService: CreateView seeds default kanban subview and links the
boards property field; caches boardPropertyFieldID at startup
- App layer: CreateView/GetView/GetViewsForChannel/UpdateView/DeleteView
with channel-membership permission checks and WebSocket events
(view_created, view_updated, view_deleted)
- doSetupBoardsPropertyField: registers the Boards property group and
board field in NewServer() before ViewService construction
- GetFieldByName now returns store.ErrNotFound instead of raw sql.ErrNoRows
* Move permission checks out of App layer for views
- Remove HasPermissionToChannel calls from all App view methods
- Drop userID params from GetView, GetViewsForChannel, UpdateView, DeleteView
- Fix doSetupBoardsPropertyField to include required TargetType for PSAv2 field
* Make View service generic and enforce board validation in model
- Remove board-specific auto-setup from service and server startup
- Enforce that board views require Props, at least one subview, and at least one linked property in IsValid()
- Move default subview seeding out of app layer; callers must provide valid props
- Call PreSave on subviews during PreUpdate to assign IDs to new subviews
- Update all tests to reflect the new validation requirements
* Restore migrations files to match base branch
* Distinguish ErrNotFound from other errors in view store Get
* Use CONCURRENTLY and nontransactional for index operations in views migration
* Split views index creation into separate nontransactional migrations
* Update migrations.list
* Update i18n translations for views
* Fix makeView helper to include required Props for board view validation
* Rename ctx parameter from c to rctx in OAuthProvider mock
* Remove views service layer, call store directly from app
* Return 500 for unexpected DB errors in GetView, 404 only for not-found
* Harden View model: deep-copy Props, validate linked property IDs
- Add ViewBoardProps.Clone() to deep-copy LinkedProperties and Subviews
- Use it in View.Clone() and View.Patch() to prevent shared-slice aliasing
- Iterate over LinkedProperties in View.IsValid() and reject invalid IDs
with a dedicated i18n key
- Register ViewStore in storetest AssertExpectations so mock expectations
are enforced
- Add tests covering all new behaviours
* Restore autotranslation worker_stopped i18n translation
* Fix view store test IDs and improve error handling in app layer
- Use model.NewId() for linked property IDs in testUpdateView to fix
validation failure (IsValid rejects non-UUID strings)
- Fix import grouping in app/view.go (stdlib imports in one block)
- Return 404 instead of 500 when Update/Delete store calls return
ErrNotFound (e.g. concurrent deletion TOCTOU race)
* Add View store mock to retrylayer test genStore helper
The View store was added to the store interface but the genStore()
helper in retrylayer_test.go was not updated, causing TestRetry to panic.
Also removes the duplicate Recap mock registration.
* Refactor view deletion and websocket event handling; update SQL store methods to use query builder
* revert property field store
* Add View API endpoints with OpenAPI spec, client methods, and i18n
Implement REST API for channel views (board-type) behind the
IntegratedBoards feature flag. Adds CRUD endpoints under
/api/v4/channels/{channel_id}/views with permission checks
matching the channel bookmark pattern.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Remove useless migrations
* Add cursor-based pagination to View store GetForChannel
- Add ViewQueryCursor and ViewQueryOpts types with validation
- Return (views, cursor, error) for caller-driven pagination
- PerPage clamping: <=0 defaults to 20, >200 clamps to 200
- Support IncludeDeleted filter
- Add comprehensive store tests for pagination, cursor edge cases,
PerPage clamping, and invalid input rejection
- Add app layer test for empty channelID → 400
- Update interface, retrylayer, timerlayer, and mock signatures
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add cursor-based pagination to View API for channel views
* Enhance cursor handling in getViewsForChannel and update tests for pagination
* Refactor test loops in ViewStore tests for improved readability
* Refactor loop in TestGetViewsForChannel for improved readability
* change pagination to limit/offset
* switch to limit/offset pagination
* Add upper-bound limits on View Subviews and LinkedProperties
Defense-in-depth validation: cap Subviews at 50 and LinkedProperties
at 500 to prevent abuse below the 300KB payload limit.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add view sort order API endpoint
Add POST /api/v4/channels/{channel_id}/views/{view_id}/sort_order
endpoint following the channel bookmarks reorder pattern. Includes
store, app, and API layers with full test coverage at each layer.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add connectionId to view WebSocket events and sort_order API spec
Thread connectionId from request header through all view handlers
(create, update, delete, sort_order) to WebSocket events, matching
the channel bookmarks pattern. Add sort_order endpoint to OpenAPI
spec. Update minimum server version to 11.6.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Remove duplicate View/ViewPatch definitions from definitions.yaml
The merge from integrated-boards-mvp introduced duplicate View and
ViewPatch schema definitions that were already defined earlier in
the file with more detail (including ViewBoardProps ref and enums).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update minimum server version to 11.6 in views API spec
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add missing translations for view sort order error messages
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Merge integrated-boards-mvp into ibmvp_api-views; remove spec files
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix flaky TestViewStore timestamp test on CI
Add sleep before UpdateSortOrder to ensure timestamps differ,
preventing same-millisecond comparisons on fast CI machines.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* remove duplicate views.yaml imclude
* Use c.boolString() for include_deleted query param in GetViewsForChannel
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix views.yaml sort order schema: use integer type and require body
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Refactor view sort order tests to use named IDs instead of array indices
Extract idA/idB/idC from views slice and add BEFORE/AFTER comments
to make stateful subtest ordering easier to follow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Return 404 instead of 403 for view operations on deleted channels
Deleted channels should appear non-existent to callers rather than
revealing their existence via a 403. Detailed error text explains
the context for debugging.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* add missing channel deleteat checks
* Use c.Params.Page instead of manual page query param parsing in getViewsForChannel
c.Params already validates and defaults page/per_page, so the manual
parsing was redundant.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add support for total count in views retrieval
* Add tests for handling deleted views in GetViewsForChannel and GetView
* Short-circuit negative newIndex in UpdateSortOrder before opening transaction
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add per-channel limit on views to bound UpdateSortOrder cost
Without a cap, unbounded view creation makes sort-order updates
increasingly expensive (CASE WHEN per view, row locks). Adds
MaxViewsPerChannel=50 constant and enforces it in the app layer
before saving. Includes API and app layer tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Remove include_deleted support from views API
Soft-deleted views are structural metadata with low risk, but no other
similar endpoint (e.g. channel bookmarks) exposes deleted records without
an admin gate. Rather than adding an admin-only permission check for
consistency, remove the feature entirely since there is no current use case.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update view permissions to require `create_post` instead of channel management permissions
* Remove obsolete view management error messages for direct and group messages
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(migrations): add user tracking and object type to property fields
- Introduced user tracking columns (CreatedBy, UpdatedBy) to PropertyFields and PropertyValues.
- Added ObjectType column to PropertyFields with associated unique indexes for legacy and typed properties.
- Created new migration scripts for adding and dropping these features, including necessary indexes for data integrity.
- Established views for managing property fields with new attributes.
This update enhances the schema to support better tracking and categorization of property fields.
* Add Property System Architecture v2 API endpoints (#35583)
* Adds uniqueness mechanisms to the property fields
After adding ObjectType, this commit ensures that both the PSAv1 and
PSAv2 schemas are supported, and enforces property uniqueness through
both database indexes and a logical check when creating new property
fields.
* Adds uniqueness check to property updates
Updates are covered on this commit and we refactor as well the SQL
code to use the squirrel builder and work better with the conditional
addition of the `existingID` piece of the query.
* Add translations to error messages
* Add the permissions to the migrations, model and update the store calls
* Adds the property field and property group app layer
* Adds authorization helpers for property fields and values
* Make sure that users cannot lock themselves out of property fields
* Migrate permissions from a JSON column to three normalized columns
* Remove the audit comment
* Use target level constants in authorization
* Log authorization membership failures
* Rename admin to sysadmin
* Adds the Property System Architecture v2 API endpoints
* Adds permission checks to the create field endpoint
* Add target access checks to value endpoints
* Add default branches for object_type and target_type and extra guards for cursor client4 methods
* Fix vet API mismatch
* Fix error checks
* Fix linter
* Add merge semantics for property patch logic and API endpoint
* Fix i18n
* Fix duplicated patch elements and early return on bad cursor
* Update docs to use enums
* Fix i18n sorting
* Update app layer to return model.AppError
* Adds a limit to the number of property values that can be patched in the same request
* Require target_type filter when searching property fields
* Add objectType validation as part of field.IsValid()
* Fix linter
* Fix test with bad objecttpye
* Fix test grouping
---------
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
* MM-67968: Flatten view model — remove icon, subviews, typed board props (#35726)
* feat(views): flatten view model by removing icon, subview, and board props
Simplifies the View data model as part of MM-67968: removes Icon, Subview,
and ViewBoardProps types; renames ViewTypeBoard to ViewTypeKanban; replaces
typed Props with StringInterface (map[string]any); adds migration 000167
to drop the Icon column from the Views table.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* feat(api): update views OpenAPI spec to reflect flattened model
Removes ViewBoardProps, Subview, and icon from the View and ViewPatch
schemas. Changes type enum from board to kanban. Replaces typed props
with a free-form StringInterface object. Aligns with MM-67968.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* refactor(views): simplify store by dropping dbView and marshalViewProps
StringInterface already implements driver.Valuer and sql.Scanner, so the
manual JSON marshal/unmarshal and the dbView intermediate struct were
redundant. model.View now scans directly from the database. Also removes
the dead ViewMaxLinkedProperties constant and wraps the Commit() error in
UpdateSortOrder.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* fix(api): allow arbitrary JSON in view props OpenAPI schema
The props field was restricted to string values via
additionalProperties: { type: string }, conflicting with the Go model's
StringInterface (map[string]any). Changed to additionalProperties: true
in View, ViewPatch, and inline POST schemas.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* Adds basic implementation of the generic redux store for PSAv2 (#35512)
* Adds basic implementation of the generic redux store for PSAv2
* Add created_by and updated_by to the test fixtures
* Make target_id, target_type and object_type mandatory
* Wrap getPropertyFieldsByIds and getPropertyValuesForTargetByFieldIds with createSelector
* Address PR comments
---------
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
* Adds websocket messages for the PSAv2 API events (#35696)
* Adds uniqueness mechanisms to the property fields
After adding ObjectType, this commit ensures that both the PSAv1 and
PSAv2 schemas are supported, and enforces property uniqueness through
both database indexes and a logical check when creating new property
fields.
* Adds uniqueness check to property updates
Updates are covered on this commit and we refactor as well the SQL
code to use the squirrel builder and work better with the conditional
addition of the `existingID` piece of the query.
* Add translations to error messages
* Add the permissions to the migrations, model and update the store calls
* Adds the property field and property group app layer
* Adds authorization helpers for property fields and values
* Make sure that users cannot lock themselves out of property fields
* Migrate permissions from a JSON column to three normalized columns
* Remove the audit comment
* Use target level constants in authorization
* Log authorization membership failures
* Rename admin to sysadmin
* Adds the Property System Architecture v2 API endpoints
* Adds permission checks to the create field endpoint
* Add target access checks to value endpoints
* Add default branches for object_type and target_type and extra guards for cursor client4 methods
* Fix vet API mismatch
* Fix error checks
* Fix linter
* Add merge semantics for property patch logic and API endpoint
* Fix i18n
* Fix duplicated patch elements and early return on bad cursor
* Update docs to use enums
* Fix i18n sorting
* Update app layer to return model.AppError
* Adds a limit to the number of property values that can be patched in the same request
* Adds websocket messages for the PSAv2 API events
* Add IsPSAv2 helper to the property field for clarity
* Add guard against nil returns on field deletion
* Add docs to the websocket endpoints
---------
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
* migrations: consolidate views migrations and reorder after master
- Merged 000165 (create Views) with 000167 (drop Icon) since Icon was never needed
- Renumbered branch migrations 159-166 → 160-167 so master's 000159 (deduplicate_policy_names) runs first
- Regenerated migrations.list
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add API endpoint to retrieve posts for a specific view (#35604)
Automatic Merge
* Apply fixes after merge
* Return a more specific error from getting multiple fields
* Prevent getting broadcast params on field deletion if not needed
* Remove duplicated migration code
* Update property conflict code to always use master
* Adds nil guard when iterating on property fields
* Check that permission level is valid before getting rejected by the database
* Validate correctness on TargetID for PSAv2 fields
* Avoid PSAv1 using permissions or protected
* Fix test data after validation change
* Fix flaky search test
* Adds more posts for filter use cases to properly test exclusions
---------
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
Co-authored-by: Alejandro García Montoro <alejandro.garciamontoro@gmail.com>
Co-authored-by: Julien Tant <julien@craftyx.fr>
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Julien Tant <785518+JulienTant@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>