The Create_WithNonExistentContentType test expected ArgumentException but
ContentCrudService correctly throws generic Exception to match the original
ContentService behavior (behavioral parity).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements IContentCrudService with full CRUD operations:
- Create: 6 overloads matching IContentService
- Read: GetById, GetByIds, GetRootContent, GetParent
- Save: Single and batch with notifications
- Delete: Cascade deletion with notifications
All methods maintain exact behavioral parity with ContentService.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Establishes shared infrastructure for content services:
- Common dependencies (DocumentRepository, AuditService, UserIdKeyResolver)
- Audit helper methods (sync and async)
- Inherits from RepositoryService for scope/query support
- Adds ContentServiceConstants for shared constants (batch page size)
Updated tracking test to look for correct assembly location.
Tracking test now fails (expected) - signals class exists for future work.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Adds unit test file for ContentServiceBase with documented test cases.
Tests are commented out until ContentServiceBase is created in Phase 1:
- 2 audit helper method tests
- 2 scope provider access pattern tests
- 2 logger injection tests
- 1 repository access test
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Only validate segment values for cultures they are defined for.
* Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Integration test suppressions.
* Remove previous implementation using ISegmentService and rely on values provided in the model to determine segments with cultures.
* Omit null culture and remove passing but unrealistic tests.
* Fixed nullability error.
* Apply suggestions from code review
Co-authored-by: Kenn Jacobsen <kja@umbraco.dk>
* Relocated function following code review.
* Reset unchanged files.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Kenn Jacobsen <kja@umbraco.dk>
* Fix preview showing published version when Save and Preview is clicked multiple times
Fixes#20981
When clicking "Save and Preview" multiple times, the preview tab would show the published version instead of the latest saved version. This occurred because:
1. Each "Save and Preview" creates a new preview session with a new token
2. The preview window is reused (via named window target)
3. Without a URL change, the browser doesn't reload and misses the new session token
4. The stale page gets redirected to the published URL
Solution: Add a cache-busting parameter (?rnd=timestamp) to the preview URL, forcing the browser to reload and pick up the new preview session token. This aligns with how SignalR refreshes work.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Improve Save and Preview to avoid full page reloads when preview is already open
When clicking "Save and Preview" multiple times with a preview tab already open, the entire preview tab would reload. This enhancement makes it behave like the "Save" button - only the iframe reloads, not the entire preview wrapper.
Changes:
- Store reference to preview window when opened
- Check if preview window is still open before creating new session
- If open, just focus it and let SignalR handle the iframe refresh
- If closed, create new preview session and open new window
This provides a smoother UX where subsequent saves don't cause the preview frame and controls to reload, only the content iframe refreshes via SignalR.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Close preview window when ending preview session
Changes the "End Preview" behavior to close the preview tab instead of navigating to the published URL. This provides a cleaner UX and ensures subsequent "Save and Preview" actions will always create a fresh preview session.
Benefits:
- Eliminates edge case where preview window remains open but is no longer in preview mode
- Simpler behavior - preview session ends and window closes
- Users can use "Preview website" button if they want to view published page
Also removes unnecessary await on SignalR connection.stop() to prevent blocking if the connection cleanup hangs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix preview cookie expiration and add proper error handling
This commit addresses cookie management issues in the preview system:
1. **Cookie Expiration API Enhancement**
- Added `ExpireCookie` overload with security parameters (httpOnly, secure, sameSiteMode)
- Added `SetCookieValue` overload with optional expires parameter
- Marked old methods as obsolete for removal in Umbraco 19
- Ensures cookies are expired with matching security attributes
2. **PreviewService Cookie Handling**
- Changed to use new `ExpireCookie` method with explicit security attributes
- Maintains `Secure=true` and `SameSite=None` for cross-site scenarios
- Uses new `SetCookieValue` overload with explicit expires parameter
- Properly expires preview cookies when ending preview session
3. **Frontend Error Handling**
- Added try-catch around preview window reference checks
- Handles stale window references gracefully
- Prevents potential errors from accessing closed window properties
These changes ensure preview cookies are properly managed throughout their
lifecycle and support both same-site and cross-site scenarios (e.g., when
the backoffice is on a different domain/port during development).
Fixes#20981🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Track document ID for preview window to prevent reusing window across different documents
When navigating from one document to another in the backoffice, the preview window reference was being reused even though it was showing a different document. This meant clicking "Save and Preview" would just focus the existing window without updating it to show the new document.
Now we track which document the preview window is showing and only reuse the window if:
1. The window is still open
2. The window is showing the same document
This ensures each document gets its own preview session while still avoiding unnecessary full page reloads when repeatedly previewing the same document.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Remove updates to ICookieManager and use Cookies.Delete to remove cookie.
* Fix file not found on click to save and preview.
* Removed further currently unnecessary updates to the cookie manager interface and implementation.
* Fixed failing unit test.
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Andy Butland <abutland73@gmail.com>
* Preserve existing Examine FieldDefinitionCollection if it already exists (#20267)
* Fix missing bracket
* Minor tidy/addition of comments; addition of unit tests.
---------
Co-authored-by: Andy Butland <abutland73@gmail.com>
Handles rich text blocks created with TinyMCE in convert local links migration.
Refreshes internal datatype cache following migration requiring cache rebuild.
* configure max chars for textbox
* min 1
* Adds server-side check for text box min and max character validation.
* Applied suggestion from code review.
* Bumped version of test helper
* Fixed test that was creating a text string data type with too large a maximum characters setting.
---------
Co-authored-by: Andy Butland <abutland73@gmail.com>
Co-authored-by: Nhu Dinh <hnd@umbraco.dk>
* Add MoveFile it IFileSystem and implement on file systems.
* Rename media file on move to recycle bin.
* Rename file on restore from recycle bin.
* Add configuration to enabled recycle bin media protection.
* Expose backoffice authentication as cookie for non-backoffice usage.
Protected requests for media in recycle bin.
* Display protected image when viewing image cropper in the backoffice media recycle bin.
* Code tidy and comments.
* Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Introduced helper class to DRY up repeated code between image cropper and file upload notification handlers.
* Reverted client-side and management API updates.
* Moved update of path to media file in recycle bin with deleted suffix to the server.
* Separate integration tests for add and remove.
* Use interpolated strings.
* Renamed variable.
* Move EnableMediaRecycleBinProtection to ContentSettings.
* Tidied up comments.
* Added TODO for 18.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Added request cache to content and media lookups in mult URL picker.
* Allow property editors to cache referenced entities from block data.
* Update src/Umbraco.Infrastructure/PropertyEditors/MultiUrlPickerValueEditor.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add obsoletions.
* Minor spellcheck
* Ensure request cache is available before relying on it.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: kjac <kja@umbraco.dk>
* Added request cache to content and media lookups in mult URL picker.
* Allow property editors to cache referenced entities from block data.
* Update src/Umbraco.Infrastructure/PropertyEditors/MultiUrlPickerValueEditor.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add obsoletions.
* Minor spellcheck
* Ensure request cache is available before relying on it.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: kjac <kja@umbraco.dk>
* change property value to an object
* add const for picker data source type
* Add value editor and converter server-side
* register schema for property editor + move settings ui
---------
Co-authored-by: kjac <kja@umbraco.dk>
Co-authored-by: Niels Lyngsø <nsl@umbraco.dk>
* Be consistent in use of GetOrCreateAsync overload in exists and retrieval.
Ensure nullability of ContentCacheNode is consistent in exists and retrieval.
* Applied suggestion from code review.
* Move seeding to Umbraco application starting rather than started, ensuring an initial request is served.
* Tighten up hybrid cache exists check with locking around check and remove, and use of cancellation token.
(cherry picked from commit 81a8a0c191)
* Store local time zone as UTC and do not throw validation error when stored time zone is different
* Additional fixes when switching between date time editors with and without time zone
* Additional fixes
* Ensure that an update is triggered when the expected value does not match the stored value
This will happen when switching between editors (with and without time zone) or switching between a specific time zone to the editor's local time zone.
* Fix inconsistencies with null and undefined
* Fix inconsistencies between date/time provided to the client and returned in the value converter (when switching between editors)
* Fix unit tests and small bug
* Adjust integration test
* Small improvement
* Update test data
* Adjust logic so that time zone offsets are updated every time the date value changes
* Do not pre-select time zone when switching between unspecified and time zone editors
* Added unique color checker to color picker.
* Added Unittest for duplicates
* optimized for codescene
* removed the bump and simplified the function
* Fixed behaviour for duplicate checks so unit test passes.
A little refactoring.
* Adds continue so invalid colors aren't checked for duplicates.
---------
Co-authored-by: Andy Butland <abutland73@gmail.com>
* Adjust the `JsonBlockValueConverter` to handle conflicts with 'values' property (due to old data schema)
* Simplify code
* Add unit test to verify change.
---------
Co-authored-by: Andy Butland <abutland73@gmail.com>
* Adjust the `JsonBlockValueConverter` to handle conflicts with 'values' property (due to old data schema)
* Simplify code
* Add unit test to verify change.
---------
Co-authored-by: Andy Butland <abutland73@gmail.com>
* V16: Cache Version Mechanism (#19747)
* Add RepositoryCacheVersion table
* Add repository
* Add Cache version lock
* Add GetAll method to repository
* Add RepositoryCacheVersionService
* Remember to add lock in data creator
* Work my way out of constructor hell
This is why we use DI folks. 🤦
* Add checks to specific cache policies
* Fix migration
* Add to schema creator
* Fix database access
* Initialize the cache version on in memory miss
* Make cache version service internal
* Add tests
* Apply suggestions from code review
Co-authored-by: Andy Butland <abutland73@gmail.com>
* Add missing obsoletions
* Prefer full name
---------
Co-authored-by: Andy Butland <abutland73@gmail.com>
* fixed merge
* V16/feature/move last synced id to db (#19884)
* Foundation work for moving last synced id
* register manager and repo in dependency injection
* Fixing to make tests work
* Replacing the use of the old LastSyncedFileManager.cs with the new LastSyncedManager.cs
* Testing to delete out of sync id and old entries
* changing some stuff to please the reviewer.
* Inverted saving methods id check and fixed documentation mishaps
* Loadbalancing: Add Cache Sync service to allow us to roll forward isolated caches when backoffice is load balanced. (#20398)
* Split cache refreshers into internal and external caches
* Add obsolete constructor for CacheInstructionsPruningJob
* Add xml docs
* Move lastID management into CacheInstructionService
* Cache last synced ids in memory
* Lock when processing instructions
* Sync caches when out of sync
* Fix constructors for ICacheSyncService
* Cache version on request
* Register caches as synced when instructions are processed
* Rename CacheVersionAccessor to IRepositoryCacheVersionAccessor
* Set caches as synced before actually syncing the caches
* Set caches as synced before syncing, within scope, this should also lock the cache version from being written to whilst updating caches
* Only check version for backoffice requests
* Clear request cache when caches are syned
* Default to using NOOP cache version service
* Don't generate local identity in database server messenger anymore
* Fix ambiguous constructor
* Add helper method to switch to load balanced isolated caches
* Fix LastSyncedManagerTests
* Fix RepositoryCacheVersionServiceTests
* Fix DefaultCachePolicyTests
* Use correct constructor in FullDataSetRepositoryCachePolicy
* Minor cleanup
* Add XML docs
* Add more xml docs
* Apply suggestions from code review
Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
---------
Co-authored-by: Zeegaan <skrivdetud@gmail.com>
Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
* Fix migration plan
* fix tests
* Fix integration tests
* Fix changes from github review
* Move premigrations to v17
* Make lock constantws sequential
* Fix comment
* Make IRepositoryCacheVersionService and ICacheSyncService protected on EntityRepositoryBase
---------
Co-authored-by: Andy Butland <abutland73@gmail.com>
Co-authored-by: Nicklas Kramer <nik@umbraco.dk>
Co-authored-by: NillasKA <kramernicklas@gmail.com>
Co-authored-by: Zeegaan <skrivdetud@gmail.com>
Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
* Serverside generated preview URLs
* Add URL provider notation to UrlInfo
* Change preview URL generation to happen at preview time based on provider alias
* Update XML docs
* Always add culture (if available) to preview URL
* Do not log user input (security vulnerability)
* Fix typo
* Re-generate TypeScript client
from Management API
* Deprecated `UmbDocumentPreviewRepository.enter()` (for v19)
Fixed TS errors
Added temp stub for `getPreviewUrl`
* Adds `previewOption` extension-type
* Adds "default" `previewOption` kind
* Relocated "Save and Preview" workspace action
reworked using the "default" `previewOption` kind.
* Added stub for "urlProvider" `previewOption` kind
* Renamed "workspace-action-default-kind.element.ts"
to a more suitable filename.
Exported element so can be reused in other packages,
e.g. documents, for the new "save and preview" feature.
* Refactored "Save and Preview" button
to work with first action's manifest/API.
* Reverted `previewOption` extension-type
Re-engineered to make a "urlProvider" kind for `workspaceActionMenuItem`.
This is to simplify the extension point and surrounding logic.
* Modified `saveAndPreview` Document Workspace Context
to accept a URL Provider Alias.
* Refactored "Save and Preview" button
to extend `UmbWorkspaceActionElement`.
This did mean exposing certain methods/properties to be overridable.
* Used `umbPeekError` to surface any errors to the user
* Renamed `urlProvider` kind to `previewOption`
* Relocated `urlProviderAlias` inside the `meta` property
* also throw an error
* Added missing `await`
* Fix build errors after forward merge
---------
Co-authored-by: leekelleher <leekelleher@gmail.com>
Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
Co-authored-by: Laura Neto <12862535+lauraneto@users.noreply.github.com>
* Start work
* Introduce dto
* Start making repository
* Add migrations
* Implement fetchable first job
* Fix up to also finish tasks
* Refactor jobs to distributed background jobs
* Filter jobs correctly on LastRun
* Hardcode delay
* Add settings to configure delay and period
* Fix formatting
* Add default data
* Add update on startup, which will update periods on startup
* Refactor service to return job directly
* Update src/Umbraco.Infrastructure/Services/Implement/DistributedJobService.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update src/Umbraco.Infrastructure/BackgroundJobs/DistributedBackgroundJobHostedService.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update src/Umbraco.Infrastructure/BackgroundJobs/DistributedBackgroundJobHostedService.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Remove unused
* Move jobs and make internal
* make OpenIddictCleanupJob.cs public, as it is used elsewhere
* Minor docstring changes
* Update src/Umbraco.Core/Persistence/Constants-Locks.cs
Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>
* ´Throw correct exceptions
* Update xml doc
* Remove business logic from repository
* Remove more business logic from repository into service
* Remove adding jobs from migration
* fix creation
* Rename to ExecuteAsync
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: mole <nikolajlauridsen@protonmail.ch>
* Started the implementation of the new date time property editor
* Display picked time in local and UTC
* Adjustments to the way the timezones are displayed and the picker is configured
* Filter out `Etc/` (offset) timezones from the list
* Additional adjustments
* Introduced date format and time zone options (all, local or custom)
* Adjustments to the property editor configuration and value converter
* Use UUICombobox instead of UUISelect for displaying time zone options. Display UTC offset instead of short offset name in label.
* Allow searching by offset
* Ignore case when searching for time zone
* Store dates consistently (always same format)
* Add custom PropertyIndexValueFactory for the new property editor
* Adjustments when switching between time zone modes
* Small fixes and cleanup
* Started improving time zone config selection
* Small adjustments
* Remove selected time zones from the list + display label instead of value
* Localizing labels
* Remove unwanted character
* Fix incorrect order of custom time zones list
* Small fixes (mostly validation)
* Rename input time zone component
* Small adjustments
* Using model for stored value
* Save examine value as ISO format
* Adjusting class names for consistency
* Small fixes
* Add default data type configuration
* Rename `TimeZone` to `UmbTimeZone`
* Fix failing tests
* Started adding unit tests for DateWithTimeZonePropertyEditor
* Additional tests
* Additional tests
* Additional tests
* Fixed searches with regex special characters throwing errors
* Remove offset from generic UmbTimeZone type and added new type specific for the property editor
* Adjust property editor to show error when selected time zone is no longer available, instead of pre-selecting another one
* Do not preselect a time zone if a date is stored without time zone
This most likely means that the configuration of the editor changed to add time zone support. In this case we want to force the editor to select the applicable time zone.
* Fix failing backoffice build
* Added tests for DateTimeWithTimeZonePropertyIndexValueFactory
* Improved picker validation
* Remove unused code
* Move models to their corresponding places
* Renaming `DateTimeWithTimeZone` to `DateTime2`
* Fix data type count tests
* Simplifying code + adjusting value converter to support old picker value
* Adjustments to property editor unit tests
* Fix validation issue
* Fix default configuration for 'Date Time (Unspecified)'
* Rename validator
* Fix comment
* Adjust database creator default DateTime2 data types
* Update tests after adjusting default data types
* Add integration test for DateTime2 returned value type
* Apply suggestions from code review
Co-authored-by: Andy Butland <abutland73@gmail.com>
* Aligning DateTime2Validator with other JSON validators. Added new model for API.
* Removed unused code and updated tests
* Fix validation error message
* Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Splitting the new date time editor into multiple (per output type)
* Adjust tests in DateTime2PropertyIndexValueFactoryTest
* Update value converter tests
* Group the new date time tests
* Adjust new property editor tests
* Adjust property editor integration tests
* Update data editor count tests
* Naming adjustments
* Small fixes
* Cleanup
- Remove unused files
- Remove 'None' option from configuration and update all the tests
* Update luxon depedencies
* Move GetValueFromSource to the value converter
* Add new property editor examples to mock data
* Re-organizing the code
* Adjustments from code review
* Place the date time property index value factories in their own files
* Small adjustments for code consistency
* Small adjustments
* Minor adjustment
* Small fix from copilot review
* Completed the set of XML header comments.
* use already existing query property
* fail is form control element is null or undefined
* using lit ref for querying and form control registration
* state for timeZonePickerValue and remove _disableAddButton
* Adjustments to form control registration
* Remove unused declaration
---------
Co-authored-by: Andy Butland <abutland73@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Niels Lyngsø <nsl@umbraco.dk>
Co-authored-by: Niels Lyngsø <niels.lyngso@gmail.com>
* PropertyType constructor sets the DataTypeKey if passed IDataType has identity
* Updated unit tests to verify behaviour.
---------
Co-authored-by: Andy Butland <abutland73@gmail.com>
* Display the latest update date in document collection view
* Don't consider "" as a missing option when initializing the drop down list.
* Don't flag "" as a missing option when validatng server-side.
---------
Co-authored-by: Laura Neto <12862535+lauraneto@users.noreply.github.com>