Implemented three security fixes with regression coverage:
- BelongsToMany pivot authorization
- Added BelongsToManyPivotRequest.
- BelongsToManyPivotController::store/update/destroy now require Ability::UPDATE on the parent resource.
- Added tests proving pivot mutation still works when policy allows it and returns 403 when update policy denies it.
- Notification CSRF via GET
- Changed notification mark-as-read routes from GET to POST.
- Updated notification Blade UI to submit POST forms with CSRF tokens.
- Added tests proving GET no longer mutates notification state and POST still marks notifications as read.
- Async relation search authorization and MorphTo hardening
- Added AsyncSearchRequest.
- Async search now checks resource abilities based on page context:
- index: VIEW_ANY
- detail: VIEW
- create form: CREATE
- edit form: UPDATE
- Added MorphTo allowlist validation against configured types() before model instantiation/querying.
- Added tests proving async search still works when allowed, returns 403 when policy denies update, and rejects MorphTo classes outside configured types.
Full Changelog: 4.12.0...4.13.0