diff --git a/CHANGELOG.md b/CHANGELOG.md index 76fbd06c..eede3023 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://github.com/Pollora/framework/compare/v13.39.2...develop) +### Changed +- **`pollora/wp-rest` 2.0 is accepted, and `composer update` installs it: a REST route that declares no permission is refused** (`rest_forbidden`, 401 for a visitor, 403 for a logged-in user), where it used to stay public. Before updating, declare `permissionCallback: Everyone::class` on the routes that are public on purpose, or a permission such as `IsLoggedIn`. To keep the old behaviour for a while, return `false` from the `pollora/wp-rest/private_by_default` filter: WordPress then tells, with `WP_DEBUG`, which route to fix. To stay on the previous version, require `"pollora/wp-rest": "^0.2"` (there is no 1.x). The framework accepts `^0.1 || ^0.2 || ^1.0 || ^2.0` + ## [v13.39.2](https://github.com/Pollora/framework/compare/v13.39.1...v13.39.2) - 2026-10-30 ### Added diff --git a/composer.json b/composer.json index d442968c..72f0cf3f 100644 --- a/composer.json +++ b/composer.json @@ -43,7 +43,7 @@ "pollora/roles": "^0.2", "pollora/schedule": "^1.0", "pollora/wp-cli": "^0.1 || ^1.0", - "pollora/wp-rest": "^0.1 || ^0.2 || ^1.0", + "pollora/wp-rest": "^0.1 || ^0.2 || ^1.0 || ^2.0", "watson/rememberable": "^7.1", "cweagans/composer-patches": "^2.0", "pollora/colt": "^11.0", diff --git a/tests/e2e/fixtures/plugins/e2e-features/app/Endpoints/Undeclared.php b/tests/e2e/fixtures/plugins/e2e-features/app/Endpoints/Undeclared.php new file mode 100644 index 00000000..418ec241 --- /dev/null +++ b/tests/e2e/fixtures/plugins/e2e-features/app/Endpoints/Undeclared.php @@ -0,0 +1,22 @@ + 'undeclared']; + } +} diff --git a/tests/e2e/specs/features.spec.ts b/tests/e2e/specs/features.spec.ts index 009e739c..284d0073 100644 --- a/tests/e2e/specs/features.spec.ts +++ b/tests/e2e/specs/features.spec.ts @@ -72,6 +72,15 @@ test.describe('REST routes declared by #[WpRestRoute]', () => { await context.dispose(); }); + test('a route with no permission is refused', async () => { + const context = await visitor(); + const response = await context.get(homeUrl('/wp-json/e2e/v1/undeclared')); + + expect(response.status()).toBe(401); + expect((await response.json()).code).toBe('rest_forbidden'); + await context.dispose(); + }); + test('an IsAdmin route refuses a visitor', async () => { const context = await visitor(); const response = await context.get(homeUrl('/wp-json/e2e/v1/admin/7'));