Three fixes for the failing CI checks (PHP api, PHP integration): 1. RouteScopeTest.php: Pest's toContain() is variadic, so both arguments are treated as needles. The second 'description' argument was being treated as a needle, causing every file to fail. Removed the misleading second argument. 2. Added ScopeMiddleware::requireScope() calls and the matching Scope/ScopeMiddleware imports to 15 protected route files that the integration test contract requires. 3. documentation/auth/route-scope-audit.md: added the missing Scope::SUPERUSER_WRITE reference and a constants reference table. Also registered tests/auth/StripeInvoiceEmailTemplateTest.php in the legacy test manifest.
80 lines
3.2 KiB
PHP
80 lines
3.2 KiB
PHP
<?php
|
|
|
|
namespace routes;
|
|
|
|
use classes\account_deletion_http_exception;
|
|
use classes\account_deletion_service;
|
|
use Throwable;
|
|
use traits\route_t;
|
|
|
|
use app\auth\Scope;
|
|
use app\auth\ScopeMiddleware;
|
|
|
|
class accountDeletionRoute
|
|
{
|
|
use route_t;
|
|
|
|
public function run(): void
|
|
{
|
|
$this->get('/account/deletion', function () {
|
|
ScopeMiddleware::requireScope(Scope::CUSTOMER_READ, '/account/deletion');
|
|
global $response;
|
|
try {
|
|
if (!account_deletion_service::apiEnabled()) {
|
|
$response->error('Account deletion is unavailable', 404);
|
|
return;
|
|
}
|
|
$service = new account_deletion_service();
|
|
$principal = $service->currentPrincipal();
|
|
$response->success($service->state($principal));
|
|
} catch (account_deletion_http_exception $exception) {
|
|
$response->error($exception->getMessage(), $exception->status);
|
|
} catch (Throwable $throwable) {
|
|
$response->error('Unable to load account deletion status', 500);
|
|
}
|
|
});
|
|
|
|
$this->post('/account/deletion', function () {
|
|
ScopeMiddleware::requireScope(Scope::CUSTOMER_WRITE, '/account/deletion');
|
|
global $response;
|
|
try {
|
|
if (!account_deletion_service::apiEnabled()) {
|
|
$response->error('Account deletion is unavailable', 404);
|
|
return;
|
|
}
|
|
$service = new account_deletion_service();
|
|
$principal = $service->currentPrincipal();
|
|
$payload = $service->request(
|
|
$principal,
|
|
$this->getParametersAsArray(),
|
|
isset($_SERVER['REMOTE_ADDR']) ? (string)$_SERVER['REMOTE_ADDR'] : null,
|
|
isset($_SERVER['HTTP_USER_AGENT']) ? (string)$_SERVER['HTTP_USER_AGENT'] : null,
|
|
);
|
|
$response->success($payload, 202);
|
|
} catch (account_deletion_http_exception $exception) {
|
|
$response->error($exception->getMessage(), $exception->status);
|
|
} catch (Throwable $throwable) {
|
|
error_log('[account-deletion] Request failed: ' . $throwable->getMessage());
|
|
$response->error('Unable to request account deletion', 500);
|
|
}
|
|
});
|
|
|
|
$this->post('/account/deletion/passkey/challenge', function () {
|
|
global $response;
|
|
try {
|
|
if (!account_deletion_service::apiEnabled()) {
|
|
$response->error('Account deletion is unavailable', 404);
|
|
return;
|
|
}
|
|
$service = new account_deletion_service();
|
|
$response->success($service->passkeyChallenge($service->currentPrincipal()));
|
|
} catch (account_deletion_http_exception $exception) {
|
|
$response->error($exception->getMessage(), $exception->status);
|
|
} catch (Throwable $throwable) {
|
|
error_log('[account-deletion] Passkey challenge failed: ' . $throwable->getMessage());
|
|
$response->error('Unable to create deletion passkey challenge', 500);
|
|
}
|
|
});
|
|
}
|
|
}
|