diff --git a/.gitattributes b/.gitattributes index 67c2e50d..1ad43602 100644 --- a/.gitattributes +++ b/.gitattributes @@ -20,3 +20,9 @@ /rector.php export-ignore /testbench.yaml export-ignore /tests export-ignore +# Pollora harness (QA-06): development files stay out of the archive Composer downloads +/.gitignore export-ignore +/.harness.json export-ignore +/AGENTS.md export-ignore +/api-surface.json export-ignore +/composer-dependency-analyser.php export-ignore diff --git a/.github/workflows/harness.yml b/.github/workflows/harness.yml index 906de845..bcacc6be 100644 --- a/.github/workflows/harness.yml +++ b/.github/workflows/harness.yml @@ -14,6 +14,6 @@ permissions: {} jobs: harness: - uses: Pollora/harness/.github/workflows/php-package.yml@v0.1.8 + uses: Pollora/harness/.github/workflows/php-package.yml@v0.1.15 permissions: contents: read diff --git a/CHANGELOG.md b/CHANGELOG.md index 76fbd06c..35691cb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,13 @@ All notable changes to the Pollora framework will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased](https://github.com/Pollora/framework/compare/v13.39.2...develop) +## [Unreleased](https://github.com/Pollora/framework/compare/v13.39.3...develop) + +## [v13.39.3](https://github.com/Pollora/framework/compare/v13.39.2...v13.39.3) - 2026-11-02 + +### 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` +- The development files (`.harness.json`, `AGENTS.md`, `api-surface.json`, `composer-dependency-analyser.php`, `.gitignore`) are kept out of the distribution archive, and `pollora/harness` is required at `^0.1.15` ## [v13.39.2](https://github.com/Pollora/framework/compare/v13.39.1...v13.39.2) - 2026-10-30 diff --git a/composer.json b/composer.json index f81ed322..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", @@ -125,7 +125,7 @@ "wp-cli/wp-cli": "^2.12", "larastan/larastan": "^3.13", "orchestra/testbench": "^11.3.0", - "pollora/harness": "^0.1.13" + "pollora/harness": "^0.1.15" }, "autoload-dev": { "psr-4": { 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/package-lock.json b/tests/e2e/package-lock.json index 7aef148b..354b0881 100644 --- a/tests/e2e/package-lock.json +++ b/tests/e2e/package-lock.json @@ -7,7 +7,7 @@ "name": "pollora-framework-e2e", "devDependencies": { "@playwright/test": "1.64.1", - "@types/node": "22.20.4", + "@types/node": "22.20.5", "@wordpress/e2e-test-utils-playwright": "3.1.0" }, "engines": { @@ -528,9 +528,9 @@ } }, "node_modules/@types/node": { - "version": "22.20.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.4.tgz", - "integrity": "sha512-zJRE40jpHtKqE/C4fgHrAKQLJuSpzEnP9ff9Y7YtoR3Wd2pwqzlekDeEuUQXjRd+QCYnVnNwuJYmhdk9XV8gvA==", + "version": "22.20.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.5.tgz", + "integrity": "sha512-U2+DNr+wSjpsTS/wZGYHq7GcwfuSmKiKvoPvK22zwTlRhU91yOniN4qRR5KhIjvif7ysw/dz/hKmfDH0Ris4aA==", "dev": true, "license": "MIT", "dependencies": { diff --git a/tests/e2e/package.json b/tests/e2e/package.json index 2d31a624..6700bc2c 100644 --- a/tests/e2e/package.json +++ b/tests/e2e/package.json @@ -11,7 +11,7 @@ }, "devDependencies": { "@playwright/test": "1.64.1", - "@types/node": "22.20.4", + "@types/node": "22.20.5", "@wordpress/e2e-test-utils-playwright": "3.1.0" } } 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'));