Fix route permission instance calls (#344)

## Root cause

`route_t::hasPermission()` and `requirePermission()` are instance
methods. Route code was invoking them with `self::`; the new XL Vask
hall-scope helper made that call from a genuinely static context,
causing PHP to throw:

`Non-static method routes\\xlvaskUsageLogsRoute::hasPermission() cannot
be called statically`

## Changes

- Invoke route permission methods through `$this` across all 273
executable legacy calls in 45 route classes.
- Make `xlvaskUsageLogsRoute::allowedHallIdsForUser()` an instance
helper and update all 13 callers.
- Preserve the existing all-scope and own-scope hall selection rules.
- Add a token-aware regression test that rejects executable
`self::hasPermission()` and `self::requirePermission()` calls, while
ignoring comments.
- Add focused XL Vask tests for global scanner hall scope and
group-limited own scope.
- Update affected route contract assertions to the instance-call form.

## Verification

- PHP lint: all 53 changed PHP files
- Focused PHPStan: changed XL Vask route and both new regression tests —
clean
- Focused regression slice: 58 passed, 748 assertions
- Full local unit suite: 1,300 passed, 9,442 assertions (1 unrelated
existing warning, 1 environment skip)
- Full local API suite: 285 passed, 11,704 assertions
- Exact-SHA GitHub Tests workflow: all 7 jobs passed (unit, API,
integration, legacy, edge gateway, and supporting checks)
- Independent exact-SHA QA gate: PASS, no findings
- Independent exact-SHA security gate: PASS, no findings
- Independent exact-SHA reviewer gate: PASS, no findings
- Remote comparison: exactly one commit ahead of
`40b104abed7723a7d1b7028190ecda0e7aeef829`; all 53 remote blob hashes
matched the reviewed worktree

## Delivery state

Draft only for human review. No merge or deployment is included. Qodana
is skipped while the PR remains draft and is therefore not represented
as a passed gate.
This commit is contained in:
Jeppe B
2026-08-04 16:04:41 +02:00
committed by GitHub
parent 40b104abed
commit ab6c3ba5b6
53 changed files with 486 additions and 297 deletions
@@ -42,7 +42,7 @@ class birdControlPlaneRoute
{ {
$this->get('/bird/health', function (): void { $this->get('/bird/health', function (): void {
global $response; global $response;
self::requirePermission('modules_bird_health_read'); $this->requirePermission('modules_bird_health_read');
$client = new bird(); $client = new bird();
$workspaceId = $this->getConfiguredWorkspaceId($client); $workspaceId = $this->getConfiguredWorkspaceId($client);
@@ -16,7 +16,7 @@ class birdNumbersRoute
$this->get('/bird/numbers', function () { $this->get('/bird/numbers', function () {
global $response; global $response;
// Permission: list numbers via Bird // Permission: list numbers via Bird
self::requirePermission('modules_bird_numbers_list'); $this->requirePermission('modules_bird_numbers_list');
$client = new bird(); $client = new bird();
$ws = $this->normalizeOptionalString($this->fromQuery('workspaceId')); $ws = $this->normalizeOptionalString($this->fromQuery('workspaceId'));
if ($ws === '') { if ($ws === '') {
@@ -36,7 +36,7 @@ class birdNumbersRoute
// Get a specific number by ID // Get a specific number by ID
$this->get('/bird/numbers/{id}', function () { $this->get('/bird/numbers/{id}', function () {
global $response; global $response;
self::requirePermission('modules_bird_numbers_get'); $this->requirePermission('modules_bird_numbers_get');
$id = (string)$this->fromRoute('id'); $id = (string)$this->fromRoute('id');
if ($id === '') { if ($id === '') {
$response->error('Missing id', 400); $response->error('Missing id', 400);
@@ -58,7 +58,7 @@ class birdNumbersRoute
// Release/delete a number by ID (if supported in your Bird account) // Release/delete a number by ID (if supported in your Bird account)
$this->delete('/bird/numbers/{id}', function () { $this->delete('/bird/numbers/{id}', function () {
global $response; global $response;
self::requirePermission('modules_bird_numbers_delete'); $this->requirePermission('modules_bird_numbers_delete');
$id = (string)$this->fromRoute('id'); $id = (string)$this->fromRoute('id');
if ($id === '') { if ($id === '') {
$response->error('Missing id', 400); $response->error('Missing id', 400);
@@ -39,7 +39,7 @@ class birdVoiceCallsRoute
// List workspace call log // List workspace call log
$this->get('/bird/voice/calls/log', function () { $this->get('/bird/voice/calls/log', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_calls_log_list'); $this->requirePermission('modules_bird_voice_calls_log_list');
$client = new bird(); $client = new bird();
$workspaceId = $this->birdResolveWorkspaceId($client); $workspaceId = $this->birdResolveWorkspaceId($client);
@@ -59,7 +59,7 @@ class birdVoiceCallsRoute
// Create a voice call // Create a voice call
$this->post('/bird/voice/calls', function () { $this->post('/bird/voice/calls', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_calls_create'); $this->requirePermission('modules_bird_voice_calls_create');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -77,7 +77,7 @@ class birdVoiceCallsRoute
// List voice calls // List voice calls
$this->get('/bird/voice/calls', function () { $this->get('/bird/voice/calls', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_calls_list'); $this->requirePermission('modules_bird_voice_calls_list');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -96,7 +96,7 @@ class birdVoiceCallsRoute
// Get a voice call by ID // Get a voice call by ID
$this->get('/bird/voice/calls/{id}', function () { $this->get('/bird/voice/calls/{id}', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_calls_get'); $this->requirePermission('modules_bird_voice_calls_get');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -111,7 +111,7 @@ class birdVoiceCallsRoute
// Update a voice call by ID // Update a voice call by ID
$this->patch('/bird/voice/calls/{id}', function () { $this->patch('/bird/voice/calls/{id}', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_calls_update'); $this->requirePermission('modules_bird_voice_calls_update');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -130,7 +130,7 @@ class birdVoiceCallsRoute
// Answer an incoming call by ID // Answer an incoming call by ID
$this->post('/bird/voice/calls/{id}/answer', function () { $this->post('/bird/voice/calls/{id}/answer', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_calls_answer'); $this->requirePermission('modules_bird_voice_calls_answer');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -149,7 +149,7 @@ class birdVoiceCallsRoute
// Mark call as ringing by ID // Mark call as ringing by ID
$this->post('/bird/voice/calls/{id}/ringing', function () { $this->post('/bird/voice/calls/{id}/ringing', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_calls_ringing'); $this->requirePermission('modules_bird_voice_calls_ringing');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -168,7 +168,7 @@ class birdVoiceCallsRoute
// Hang up an active call by ID // Hang up an active call by ID
$this->post('/bird/voice/calls/{id}/hangup', function () { $this->post('/bird/voice/calls/{id}/hangup', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_calls_hangup'); $this->requirePermission('modules_bird_voice_calls_hangup');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -187,7 +187,7 @@ class birdVoiceCallsRoute
// Playback media on an active call by ID // Playback media on an active call by ID
$this->post('/bird/voice/calls/{id}/playback', function () { $this->post('/bird/voice/calls/{id}/playback', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_calls_playback'); $this->requirePermission('modules_bird_voice_calls_playback');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -206,7 +206,7 @@ class birdVoiceCallsRoute
// Say a message on an active call // Say a message on an active call
$this->post('/bird/voice/calls/{id}/say', function () { $this->post('/bird/voice/calls/{id}/say', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_calls_say'); $this->requirePermission('modules_bird_voice_calls_say');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -225,7 +225,7 @@ class birdVoiceCallsRoute
// Gather input on an active call // Gather input on an active call
$this->post('/bird/voice/calls/{id}/gather', function () { $this->post('/bird/voice/calls/{id}/gather', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_calls_gather'); $this->requirePermission('modules_bird_voice_calls_gather');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -244,7 +244,7 @@ class birdVoiceCallsRoute
// Bridge current call to another destination // Bridge current call to another destination
$this->post('/bird/voice/calls/{id}/bridge', function () { $this->post('/bird/voice/calls/{id}/bridge', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_calls_bridge'); $this->requirePermission('modules_bird_voice_calls_bridge');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -263,7 +263,7 @@ class birdVoiceCallsRoute
// Record call command endpoint // Record call command endpoint
$this->post('/bird/voice/calls/{id}/record', function () { $this->post('/bird/voice/calls/{id}/record', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_calls_record'); $this->requirePermission('modules_bird_voice_calls_record');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -282,7 +282,7 @@ class birdVoiceCallsRoute
// Start call recording session // Start call recording session
$this->post('/bird/voice/calls/{id}/recordings', function () { $this->post('/bird/voice/calls/{id}/recordings', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_calls_recordings_create'); $this->requirePermission('modules_bird_voice_calls_recordings_create');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -301,7 +301,7 @@ class birdVoiceCallsRoute
// List call recordings // List call recordings
$this->get('/bird/voice/calls/{id}/recordings', function () { $this->get('/bird/voice/calls/{id}/recordings', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_calls_recordings_list'); $this->requirePermission('modules_bird_voice_calls_recordings_list');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -320,7 +320,7 @@ class birdVoiceCallsRoute
// Get single call recording // Get single call recording
$this->get('/bird/voice/calls/{id}/recordings/{recordingId}', function () { $this->get('/bird/voice/calls/{id}/recordings/{recordingId}', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_calls_recordings_get'); $this->requirePermission('modules_bird_voice_calls_recordings_get');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -336,7 +336,7 @@ class birdVoiceCallsRoute
// Update single call recording // Update single call recording
$this->patch('/bird/voice/calls/{id}/recordings/{recordingId}', function () { $this->patch('/bird/voice/calls/{id}/recordings/{recordingId}', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_calls_recordings_update'); $this->requirePermission('modules_bird_voice_calls_recordings_update');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -356,7 +356,7 @@ class birdVoiceCallsRoute
// Get call insights // Get call insights
$this->get('/bird/voice/calls/{id}/insights', function () { $this->get('/bird/voice/calls/{id}/insights', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_calls_insights_get'); $this->requirePermission('modules_bird_voice_calls_insights_get');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -371,7 +371,7 @@ class birdVoiceCallsRoute
// Place test outbound call and hang up when accepted // Place test outbound call and hang up when accepted
$this->post('/bird/voice/calls/test-outbound', function () { $this->post('/bird/voice/calls/test-outbound', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_calls_test_outbound'); $this->requirePermission('modules_bird_voice_calls_test_outbound');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -28,7 +28,7 @@ class birdVoiceFlashCallsRoute
// Create a flash call // Create a flash call
$this->post('/bird/voice/flash-calls', function () { $this->post('/bird/voice/flash-calls', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_flash_calls_create'); $this->requirePermission('modules_bird_voice_flash_calls_create');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -46,7 +46,7 @@ class birdVoiceFlashCallsRoute
// List flash calls // List flash calls
$this->get('/bird/voice/flash-calls', function () { $this->get('/bird/voice/flash-calls', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_flash_calls_list'); $this->requirePermission('modules_bird_voice_flash_calls_list');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -64,7 +64,7 @@ class birdVoiceFlashCallsRoute
// Get a specific flash call by ID // Get a specific flash call by ID
$this->get('/bird/voice/flash-calls/{id}', function () { $this->get('/bird/voice/flash-calls/{id}', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_flash_calls_get'); $this->requirePermission('modules_bird_voice_flash_calls_get');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -79,7 +79,7 @@ class birdVoiceFlashCallsRoute
// Complete/end a flash call by ID // Complete/end a flash call by ID
$this->post('/bird/voice/flash-calls/{id}', function () { $this->post('/bird/voice/flash-calls/{id}', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_flash_calls_end'); $this->requirePermission('modules_bird_voice_flash_calls_end');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -98,7 +98,7 @@ class birdVoiceFlashCallsRoute
// Hang up flash calls by payload // Hang up flash calls by payload
$this->post('/bird/voice/flash-calls/hangup', function () { $this->post('/bird/voice/flash-calls/hangup', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_flash_calls_hangup'); $this->requirePermission('modules_bird_voice_flash_calls_hangup');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -116,7 +116,7 @@ class birdVoiceFlashCallsRoute
// Compatibility alias for flash hangup endpoint // Compatibility alias for flash hangup endpoint
$this->post('/bird/voice/flash-calls/end', function () { $this->post('/bird/voice/flash-calls/end', function () {
global $response; global $response;
self::requirePermission('modules_bird_voice_flash_calls_end_by_numbers'); $this->requirePermission('modules_bird_voice_flash_calls_end_by_numbers');
$client = new bird(); $client = new bird();
[$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client); [$workspaceId, $channelId] = $this->birdResolveWorkspaceAndChannelIds($client);
@@ -38,7 +38,7 @@ class birdVoiceWebhooksRoute
$this->post('/bird/voice/calls/webhook/inbound', function (): void { $this->post('/bird/voice/calls/webhook/inbound', function (): void {
global $response; global $response;
self::requirePermission('modules_bird_voice_call_webhooks_trigger'); $this->requirePermission('modules_bird_voice_call_webhooks_trigger');
$client = $this->resolveBirdClient(); $client = $this->resolveBirdClient();
$payload = $this->readInboundWebhookPayload(); $payload = $this->readInboundWebhookPayload();
@@ -16,7 +16,7 @@ class callbackMicrosoftRoute
$this->post('/callback/microsoft/token', function () { $this->post('/callback/microsoft/token', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('callback_microsoft_token'); $this->requirePermission('callback_microsoft_token');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
// Check if the request was successful // Check if the request was successful
if (!$user) { if (!$user) {
@@ -18,7 +18,7 @@ class customerDefaultDepartmentRoute
$this->get('/customer/department/default', function () { $this->get('/customer/department/default', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('get_customer_default_department'); $this->requirePermission('get_customer_default_department');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
(new logs_o())->add('customer_default_department', 'global', 0, $user->id, 'CUSTOMER_GET_DEFAULT_DEPARTMENT', 'User not logged in'); (new logs_o())->add('customer_default_department', 'global', 0, $user->id, 'CUSTOMER_GET_DEFAULT_DEPARTMENT', 'User not logged in');
@@ -28,7 +28,7 @@ class customerDefaultDepartmentRoute
$customer_number = (int)$this->getCustomerNumberFromParameterOrUser($user); $customer_number = (int)$this->getCustomerNumberFromParameterOrUser($user);
// Check if the customer is its own customer number // Check if the customer is its own customer number
if ($customer_number !== (int)$user->customer_number->value()) { if ($customer_number !== (int)$user->customer_number->value()) {
self::requirePermission('get_customer_default_department_other'); $this->requirePermission('get_customer_default_department_other');
} }
// Check if the customer number exists // Check if the customer number exists
$customer = (new users_o())->getUserByCustomerNumber((int)$customer_number); $customer = (new users_o())->getUserByCustomerNumber((int)$customer_number);
@@ -59,7 +59,7 @@ class customerDefaultDepartmentRoute
$this->post('/customer/department/default', function () { $this->post('/customer/department/default', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('add_customer_default_department'); $this->requirePermission('add_customer_default_department');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
(new logs_o())->add('customer_default_department', 'global', 0, $user->id, 'CUSTOMER_ADD_DEFAULT_DEPARTMENT', 'User not logged in'); (new logs_o())->add('customer_default_department', 'global', 0, $user->id, 'CUSTOMER_ADD_DEFAULT_DEPARTMENT', 'User not logged in');
@@ -71,7 +71,7 @@ class customerDefaultDepartmentRoute
$customer_number = $this->getCustomerNumberFromParameterOrUser($user); $customer_number = $this->getCustomerNumberFromParameterOrUser($user);
// Check if the customer is its own customer number // Check if the customer is its own customer number
if ($customer_number !== (int)$user->customer_number->value()) { if ($customer_number !== (int)$user->customer_number->value()) {
self::requirePermission('add_customer_default_department_other'); $this->requirePermission('add_customer_default_department_other');
} }
// Check if the department is valid // Check if the department is valid
$department = (int)self::getParameter('department'); $department = (int)self::getParameter('department');
@@ -115,7 +115,7 @@ class customerDefaultDepartmentRoute
$this->delete('/customer/department/default', function () { $this->delete('/customer/department/default', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('delete_customer_default_department'); $this->requirePermission('delete_customer_default_department');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
(new logs_o())->add('customer_default_department', 'global', 0, $user->id, 'CUSTOMER_DELETE_DEFAULT_DEPARTMENT', 'User not logged in'); (new logs_o())->add('customer_default_department', 'global', 0, $user->id, 'CUSTOMER_DELETE_DEFAULT_DEPARTMENT', 'User not logged in');
@@ -125,7 +125,7 @@ class customerDefaultDepartmentRoute
$customer_number = $this->getCustomerNumberFromParameterOrUser($user); $customer_number = $this->getCustomerNumberFromParameterOrUser($user);
// Check if the customer is its own customer number // Check if the customer is its own customer number
if ($customer_number !== (int)$user->customer_number->value()) { if ($customer_number !== (int)$user->customer_number->value()) {
self::requirePermission('delete_customer_default_department_other'); $this->requirePermission('delete_customer_default_department_other');
} }
// Check if the customer number exists // Check if the customer number exists
$customer = (new users_o())->getUserByCustomerNumber((int)$customer_number); $customer = (new users_o())->getUserByCustomerNumber((int)$customer_number);
@@ -18,7 +18,7 @@ class customerFixedPricingRoute
$this->get('/customer/pricing/fixed', function () { $this->get('/customer/pricing/fixed', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('get_customer_fixed_pricing'); $this->requirePermission('get_customer_fixed_pricing');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
(new logs_o())->add('customer_fixed_pricing', 'global', 0, $user->id, 'CUSTOMER_GET_FIXED_PRICING', 'User not logged in'); (new logs_o())->add('customer_fixed_pricing', 'global', 0, $user->id, 'CUSTOMER_GET_FIXED_PRICING', 'User not logged in');
@@ -59,7 +59,7 @@ class customerFixedPricingRoute
$this->post('/customer/pricing/fixed', function () { $this->post('/customer/pricing/fixed', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('add_customer_fixed_pricing'); $this->requirePermission('add_customer_fixed_pricing');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
(new logs_o())->add('customer_fixed_pricing', 'global', 0, $user->id, 'CUSTOMER_ADD_FIXED_PRICING', 'User not logged in'); (new logs_o())->add('customer_fixed_pricing', 'global', 0, $user->id, 'CUSTOMER_ADD_FIXED_PRICING', 'User not logged in');
@@ -137,7 +137,7 @@ class customerFixedPricingRoute
$this->delete('/customer/pricing/fixed', function () { $this->delete('/customer/pricing/fixed', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('delete_customer_fixed_pricing'); $this->requirePermission('delete_customer_fixed_pricing');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
(new logs_o())->add('customer_fixed_pricing', 'global', 0, $user->id, 'CUSTOMER_DELETE_FIXED_PRICING', 'User not logged in'); (new logs_o())->add('customer_fixed_pricing', 'global', 0, $user->id, 'CUSTOMER_DELETE_FIXED_PRICING', 'User not logged in');
@@ -58,7 +58,7 @@ class customerSearchRoute
self::get('/customers', function () { self::get('/customers', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('search_customers'); $this->requirePermission('search_customers');
// Get the user object // Get the user object
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
// Check if the request was successful // Check if the request was successful
@@ -830,7 +830,7 @@ class departmentDailyReportsRoute
[$department_id], [$department_id],
(string)self::getParameter('date'), (string)self::getParameter('date'),
$date_to, $date_to,
self::hasPermission(self::SET_PRODUCT_TARGET_PERMISSION) $this->hasPermission(self::SET_PRODUCT_TARGET_PERMISSION)
), ),
]); ]);
}, },
@@ -874,7 +874,7 @@ class departmentDailyReportsRoute
$department_ids, $department_ids,
(string)self::getParameter('date'), (string)self::getParameter('date'),
$date_to, $date_to,
self::hasPermission(self::SET_PRODUCT_TARGET_PERMISSION) $this->hasPermission(self::SET_PRODUCT_TARGET_PERMISSION)
) )
); );
}, },
@@ -23,7 +23,7 @@ class departmentNotificationSmsRoute
/** Department Notification SMS -> Get */ /** Department Notification SMS -> Get */
$this->get('/department/notification/sms', function () { $this->get('/department/notification/sms', function () {
global $response; global $response;
self::requirePermission('department_notification_sms_get'); $this->requirePermission('department_notification_sms_get');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
$department_notification_sms = new department_notification_sms_o(); $department_notification_sms = new department_notification_sms_o();
@@ -61,7 +61,7 @@ class departmentNotificationSmsRoute
/** Department Notification SMS -> Add */ /** Department Notification SMS -> Add */
$this->post('/department/notification/sms', function () { $this->post('/department/notification/sms', function () {
global $response; global $response;
self::requirePermission('department_notification_sms_add'); $this->requirePermission('department_notification_sms_add');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
self::requireParameters([ self::requireParameters([
@@ -77,7 +77,7 @@ class departmentNotificationSmsRoute
self::requireMinValue((int)self::getParameter('phone_country_code'), 1); self::requireMinValue((int)self::getParameter('phone_country_code'), 1);
self::requireType(self::getParameter('phone'), self::type_int()); self::requireType(self::getParameter('phone'), self::type_int());
self::requireMinValue((int)self::getParameter('phone'), 1); self::requireMinValue((int)self::getParameter('phone'), 1);
self::requirePermission('department_notification_sms_add'); $this->requirePermission('department_notification_sms_add');
self::requireDepartmentAccess((int)self::getParameter('department')); self::requireDepartmentAccess((int)self::getParameter('department'));
$department_notification_sms = new department_notification_sms_o(); $department_notification_sms = new department_notification_sms_o();
@@ -104,7 +104,7 @@ class departmentNotificationSmsRoute
/** Department Notification SMS -> Update */ /** Department Notification SMS -> Update */
$this->put('/department/notification/sms', function () { $this->put('/department/notification/sms', function () {
global $response; global $response;
self::requirePermission('department_notification_sms_update'); $this->requirePermission('department_notification_sms_update');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
self::requireParameters([ self::requireParameters([
@@ -131,7 +131,7 @@ class departmentNotificationSmsRoute
self::requireType(self::getParameter('enabled'), self::type_bool()); self::requireType(self::getParameter('enabled'), self::type_bool());
$data['enabled'] = self::getParameter('enabled') ? 1 : 0; $data['enabled'] = self::getParameter('enabled') ? 1 : 0;
} }
self::requirePermission('department_notification_sms_update'); $this->requirePermission('department_notification_sms_update');
$department_notification_sms = new department_notification_sms_o(); $department_notification_sms = new department_notification_sms_o();
$department_notification_sms->select((int)self::getParameter('id')); $department_notification_sms->select((int)self::getParameter('id'));
self::requireDepartmentAccess((int)$department_notification_sms->department->value()); self::requireDepartmentAccess((int)$department_notification_sms->department->value());
@@ -158,7 +158,7 @@ class departmentNotificationSmsRoute
/** Department Notification SMS -> Delete */ /** Department Notification SMS -> Delete */
$this->delete('/department/notification/sms', function () { $this->delete('/department/notification/sms', function () {
global $response; global $response;
self::requirePermission('department_notification_sms_delete'); $this->requirePermission('department_notification_sms_delete');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
self::requireParameters([ self::requireParameters([
@@ -167,7 +167,7 @@ class departmentNotificationSmsRoute
self::requireType((int)self::getParameter('id'), self::type_int()); self::requireType((int)self::getParameter('id'), self::type_int());
self::requireSameLength(self::getParameter('id'), (int)self::getParameter('id')); self::requireSameLength(self::getParameter('id'), (int)self::getParameter('id'));
self::requireMinValue((int)self::getParameter('id'), 1); self::requireMinValue((int)self::getParameter('id'), 1);
self::requirePermission('department_notification_sms_delete'); $this->requirePermission('department_notification_sms_delete');
$department_notification_sms = new department_notification_sms_o(); $department_notification_sms = new department_notification_sms_o();
$department_notification_sms->select((int)self::getParameter('id')); $department_notification_sms->select((int)self::getParameter('id'));
self::requireDepartmentAccess((int)$department_notification_sms->department->value()); self::requireDepartmentAccess((int)$department_notification_sms->department->value());
@@ -26,7 +26,7 @@ class departmentTimeBookingsRoute
/** Department Time Bookings -> List */ /** Department Time Bookings -> List */
$this->get('/department/timebookings/opening-hours', function () { $this->get('/department/timebookings/opening-hours', function () {
global $response; global $response;
self::requirePermission('department_timebookings_opening_hours_get'); $this->requirePermission('department_timebookings_opening_hours_get');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
$specific_department = null; $specific_department = null;
@@ -75,7 +75,7 @@ class departmentTimeBookingsRoute
/** Department Time Bookings -> Update */ /** Department Time Bookings -> Update */
$this->put('/department/timebookings/opening-hours', function () { $this->put('/department/timebookings/opening-hours', function () {
global $response; global $response;
self::requirePermission('department_timebookings_opening_hours_put'); $this->requirePermission('department_timebookings_opening_hours_put');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
self::requireParameters(['id']); self::requireParameters(['id']);
@@ -125,7 +125,7 @@ class departmentTimeBookingsRoute
/** Department Time Bookings -> Types */ /** Department Time Bookings -> Types */
$this->get('/department/timebookings/types', function () { $this->get('/department/timebookings/types', function () {
global $response; global $response;
self::requirePermission('department_timebookings_types_get'); $this->requirePermission('department_timebookings_types_get');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
$specific_department = null; $specific_department = null;
@@ -170,7 +170,7 @@ class departmentTimeBookingsRoute
/** Department Time Bookings -> Types -> Add */ /** Department Time Bookings -> Types -> Add */
$this->post('/department/timebookings/types', function () { $this->post('/department/timebookings/types', function () {
global $response; global $response;
self::requirePermission('department_timebookings_types_post'); $this->requirePermission('department_timebookings_types_post');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
self::requireParameters(['department', 'product']); self::requireParameters(['department', 'product']);
@@ -205,7 +205,7 @@ class departmentTimeBookingsRoute
/** Department Time Bookings -> Types -> Update */ /** Department Time Bookings -> Types -> Update */
$this->put('/department/timebookings/types', function () { $this->put('/department/timebookings/types', function () {
global $response; global $response;
self::requirePermission('department_timebookings_types_put'); $this->requirePermission('department_timebookings_types_put');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
self::requireParameters(['id']); self::requireParameters(['id']);
@@ -240,7 +240,7 @@ class departmentTimeBookingsRoute
/** Department Time Bookings -> Types -> Delete */ /** Department Time Bookings -> Types -> Delete */
$this->delete('/department/timebookings/types', function () { $this->delete('/department/timebookings/types', function () {
global $response; global $response;
self::requirePermission('department_timebookings_types_delete'); $this->requirePermission('department_timebookings_types_delete');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
self::requireParameters(['id']); self::requireParameters(['id']);
@@ -270,7 +270,7 @@ class departmentTimeBookingsRoute
/** Department Time Bookings -> Entries */ /** Department Time Bookings -> Entries */
$this->get('/department/timebookings/entries', function () { $this->get('/department/timebookings/entries', function () {
global $response; global $response;
self::requirePermission('department_timebookings_entries_get'); $this->requirePermission('department_timebookings_entries_get');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
$specific_department = null; $specific_department = null;
@@ -325,7 +325,7 @@ class departmentTimeBookingsRoute
/** Department Time Bookings -> Entries -> Add */ /** Department Time Bookings -> Entries -> Add */
$this->post('/department/timebookings/entries', function () { $this->post('/department/timebookings/entries', function () {
global $response; global $response;
self::requirePermission('department_timebookings_entries_post'); $this->requirePermission('department_timebookings_entries_post');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
self::requireParameters(['department', 'type', 'start']); self::requireParameters(['department', 'type', 'start']);
@@ -211,7 +211,7 @@ class departmentsRoute
$this->put('/departments', function () { $this->put('/departments', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('edit_department'); $this->requirePermission('edit_department');
// Get the user object // Get the user object
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
// Check if the request was successful // Check if the request was successful
@@ -272,8 +272,8 @@ class departmentsRoute
$subuser = $auth->get_subuser(); $subuser = $auth->get_subuser();
// Check if the request was successful // Check if the request was successful
if ($user || $subuser) { if ($user || $subuser) {
$isCustomerBookingSession = ($user && self::hasPermission('user')) || $subuser; $isCustomerBookingSession = ($user && $this->hasPermission('user')) || $subuser;
if (!$isCustomerBookingSession && !self::hasPermission('list_department_categories')) { if (!$isCustomerBookingSession && !$this->hasPermission('list_department_categories')) {
$this->emitForbidden(['list_department_categories']); $this->emitForbidden(['list_department_categories']);
} }
@@ -325,7 +325,7 @@ class departmentsRoute
$this->get('/departments/self-serve/enabled', function () { $this->get('/departments/self-serve/enabled', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('view_department_selfserve_enabled'); $this->requirePermission('view_department_selfserve_enabled');
// Get the user object // Get the user object
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
// Check if the request was successful // Check if the request was successful
@@ -364,7 +364,7 @@ class departmentsRoute
$this->put('/departments/self-serve/enabled', function () { $this->put('/departments/self-serve/enabled', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('edit_department_selfserve_enabled'); $this->requirePermission('edit_department_selfserve_enabled');
// Get the user object // Get the user object
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
// Check if the request was successful // Check if the request was successful
@@ -415,7 +415,7 @@ class departmentsRoute
$this->post('/departments/categories', function () { $this->post('/departments/categories', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('add_department_category'); $this->requirePermission('add_department_category');
// Get the user object // Get the user object
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
// Check if the request was successful // Check if the request was successful
@@ -467,7 +467,7 @@ class departmentsRoute
$this->delete('/departments/categories', function () { $this->delete('/departments/categories', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('delete_department_category'); $this->requirePermission('delete_department_category');
// Get the user object // Get the user object
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
// Check if the request was successful // Check if the request was successful
@@ -505,7 +505,7 @@ class departmentsRoute
self::get('/departments/order/recommended', function () { self::get('/departments/order/recommended', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('list_department_order_recommended'); $this->requirePermission('list_department_order_recommended');
// Get the user object // Get the user object
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
// Check if the request was successful // Check if the request was successful
@@ -541,7 +541,7 @@ class departmentsRoute
self::get('/departments/weekly-results', function () { self::get('/departments/weekly-results', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('view_department_weekly_results'); $this->requirePermission('view_department_weekly_results');
// Get the user object // Get the user object
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
// Check if the request was successful // Check if the request was successful
@@ -16,7 +16,7 @@ class moduleActionLogsRoute
/** Modules > Action Logs > List */ /** Modules > Action Logs > List */
$this->get('/modules/action-logs', function () { $this->get('/modules/action-logs', function () {
global $response; global $response;
self::requirePermission('modules_action_logs_view'); $this->requirePermission('modules_action_logs_view');
// Get the user object // Get the user object
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
@@ -23,7 +23,7 @@ class moduleEconomicCustomerRoute
/** Modules > Economic > Customer > Get customer */ /** Modules > Economic > Customer > Get customer */
$this->get('/modules/economic/customer', function () { $this->get('/modules/economic/customer', function () {
global $response; global $response;
self::requirePermission('modules_economic_customer_get'); $this->requirePermission('modules_economic_customer_get');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
self::requireParameters(['customer_number']); self::requireParameters(['customer_number']);
@@ -46,7 +46,7 @@ class moduleEconomicCustomerRoute
/** Modules > Economic > Customer > Create customer */ /** Modules > Economic > Customer > Create customer */
$this->post('/modules/economic/customer', function () { $this->post('/modules/economic/customer', function () {
global $response; global $response;
self::requirePermission('modules_economic_customer_create'); $this->requirePermission('modules_economic_customer_create');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user || true) { if ($user || true) {
self::requireParameters(['customer_number', 'cvr', 'email', 'phone', 'name']); self::requireParameters(['customer_number', 'cvr', 'email', 'phone', 'name']);
@@ -68,7 +68,7 @@ class moduleEconomicRoute
// Require permission // Require permission
global /** @var response $response */ global /** @var response $response */
$response; $response;
self::requirePermission('economic_departments_get'); $this->requirePermission('economic_departments_get');
// Get the user // Get the user
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
// Check if the user is valid // Check if the user is valid
@@ -104,7 +104,7 @@ class moduleEconomicRoute
// Require permission // Require permission
global /** @var response $response */ global /** @var response $response */
$response; $response;
self::requirePermission('economic_products_get'); $this->requirePermission('economic_products_get');
// Get the user // Get the user
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
// Check if the user is valid // Check if the user is valid
@@ -22,7 +22,7 @@ class moduleEntraRoute
/** Modules > Entra > Users > GET */ /** Modules > Entra > Users > GET */
$this->get('/modules/entra/users', function () { $this->get('/modules/entra/users', function () {
global $response; global $response;
self::requirePermission('modules_entra_users'); $this->requirePermission('modules_entra_users');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
$result = (new \classes\entra())->get_users(); $result = (new \classes\entra())->get_users();
@@ -24,7 +24,7 @@ class moduleFxRatesAPIRoute
/** Modules > FXRatesAPI > conversion rate > GET */ /** Modules > FXRatesAPI > conversion rate > GET */
$this->get('/modules/fxratesapi/rate', function () { $this->get('/modules/fxratesapi/rate', function () {
global $response; global $response;
self::requirePermission('modules_fxratesapi_rate'); $this->requirePermission('modules_fxratesapi_rate');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
self::requireParameters(['base', 'target']); self::requireParameters(['base', 'target']);
@@ -64,7 +64,7 @@ class moduleFxRatesAPIRoute
/** Modules > FXRatesAPI > conversion rates > GET */ /** Modules > FXRatesAPI > conversion rates > GET */
$this->get('/modules/fxratesapi/rates', function () { $this->get('/modules/fxratesapi/rates', function () {
global $response; global $response;
self::requirePermission('modules_fxratesapi_rates'); $this->requirePermission('modules_fxratesapi_rates');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('modules_fxratesapi', 'global', 1, $user->id, 'MODULES_FXRATESAPI', 'User accessed the conversion rate'); (new logs_o())->add('modules_fxratesapi', 'global', 1, $user->id, 'MODULES_FXRATESAPI', 'User accessed the conversion rate');
@@ -22,7 +22,7 @@ class moduleLimbleRoute
$this->post('/modules/limble/webhook/task', function () { $this->post('/modules/limble/webhook/task', function () {
global $response; global $response;
$slack = new slack(); $slack = new slack();
self::requirePermission('modules_limble_webhooks_task'); $this->requirePermission('modules_limble_webhooks_task');
// Check if the module is enabled // Check if the module is enabled
$limble = new limble(); $limble = new limble();
$limble->requireModuleEnabled(); $limble->requireModuleEnabled();
@@ -44,7 +44,7 @@ class moduleLimbleRoute
global $response; global $response;
$slack = new slack(); $slack = new slack();
$slack->send_message('Limble Tasks Endpoint Triggered', 'Limble Tasks'); $slack->send_message('Limble Tasks Endpoint Triggered', 'Limble Tasks');
self::requirePermission('modules_limble_tasks'); $this->requirePermission('modules_limble_tasks');
// Check if the module is enabled // Check if the module is enabled
$limble = new limble(); $limble = new limble();
$limble->requireModuleEnabled(); $limble->requireModuleEnabled();
@@ -23,7 +23,7 @@ class moduleMotorAPIRoute
/** Modules > MotorAPI > Lookup > GET */ /** Modules > MotorAPI > Lookup > GET */
$this->get('/modules/motorapi/lookup', function () { $this->get('/modules/motorapi/lookup', function () {
global $response; global $response;
self::requirePermission('modules_motorapi_lookup'); $this->requirePermission('modules_motorapi_lookup');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
self::requireParameters(['license_plate']); self::requireParameters(['license_plate']);
+11 -11
View File
@@ -22,7 +22,7 @@ class moduleN8nRoute
$this->get('/modules/n8n/workflows', function () { $this->get('/modules/n8n/workflows', function () {
global $response; global $response;
self::requirePermission('modules_n8n_workflows_view'); $this->requirePermission('modules_n8n_workflows_view');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -47,7 +47,7 @@ class moduleN8nRoute
$this->get('/modules/n8n/workflows/{id}', function () { $this->get('/modules/n8n/workflows/{id}', function () {
global $response; global $response;
self::requirePermission('modules_n8n_workflows_view'); $this->requirePermission('modules_n8n_workflows_view');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -63,7 +63,7 @@ class moduleN8nRoute
$this->post('/modules/n8n/workflows', function () { $this->post('/modules/n8n/workflows', function () {
global $response; global $response;
self::requirePermission('modules_n8n_workflows_manage'); $this->requirePermission('modules_n8n_workflows_manage');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -81,7 +81,7 @@ class moduleN8nRoute
$this->put('/modules/n8n/workflows/{id}', function () { $this->put('/modules/n8n/workflows/{id}', function () {
global $response; global $response;
self::requirePermission('modules_n8n_workflows_manage'); $this->requirePermission('modules_n8n_workflows_manage');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -99,7 +99,7 @@ class moduleN8nRoute
$this->post('/modules/n8n/workflows/{id}/publish', function () { $this->post('/modules/n8n/workflows/{id}/publish', function () {
global $response; global $response;
self::requirePermission('modules_n8n_workflows_manage'); $this->requirePermission('modules_n8n_workflows_manage');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -117,7 +117,7 @@ class moduleN8nRoute
$this->post('/modules/n8n/workflows/{id}/deactivate', function () { $this->post('/modules/n8n/workflows/{id}/deactivate', function () {
global $response; global $response;
self::requirePermission('modules_n8n_workflows_manage'); $this->requirePermission('modules_n8n_workflows_manage');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -132,7 +132,7 @@ class moduleN8nRoute
$this->post('/modules/n8n/webhooks/trigger', function () { $this->post('/modules/n8n/webhooks/trigger', function () {
global $response; global $response;
self::requirePermission('modules_n8n_workflows_run'); $this->requirePermission('modules_n8n_workflows_run');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -153,7 +153,7 @@ class moduleN8nRoute
$this->get('/modules/n8n/executions', function () { $this->get('/modules/n8n/executions', function () {
global $response; global $response;
self::requirePermission('modules_n8n_executions_view'); $this->requirePermission('modules_n8n_executions_view');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -177,7 +177,7 @@ class moduleN8nRoute
$this->get('/modules/n8n/executions/{id}', function () { $this->get('/modules/n8n/executions/{id}', function () {
global $response; global $response;
self::requirePermission('modules_n8n_executions_view'); $this->requirePermission('modules_n8n_executions_view');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -192,7 +192,7 @@ class moduleN8nRoute
$this->post('/modules/n8n/executions/{id}/retry', function () { $this->post('/modules/n8n/executions/{id}/retry', function () {
global $response; global $response;
self::requirePermission('modules_n8n_workflows_run'); $this->requirePermission('modules_n8n_workflows_run');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -212,7 +212,7 @@ class moduleN8nRoute
$this->post('/modules/n8n/executions/{id}/stop', function () { $this->post('/modules/n8n/executions/{id}/stop', function () {
global $response; global $response;
self::requirePermission('modules_n8n_workflows_manage'); $this->requirePermission('modules_n8n_workflows_manage');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -51,7 +51,7 @@ class moduleSelfServeRoute
/** Modules > Self Serve > Lane > Status */ /** Modules > Self Serve > Lane > Status */
$this->get('/modules/self-serve/lane/status', function () { $this->get('/modules/self-serve/lane/status', function () {
global $response; global $response;
self::requirePermission('modules_selfserve_lane_status_view'); $this->requirePermission('modules_selfserve_lane_status_view');
$selfserve = new selfserve(); $selfserve = new selfserve();
$lane_id = self::isParametersSet(['lane_id']) ? (int)self::getParameter('lane_id') : 1; $lane_id = self::isParametersSet(['lane_id']) ? (int)self::getParameter('lane_id') : 1;
$lane = $selfserve->lane($lane_id); $lane = $selfserve->lane($lane_id);
@@ -74,7 +74,7 @@ class moduleSelfServeRoute
$this->put('/modules/self-serve/lane/status', function () { $this->put('/modules/self-serve/lane/status', function () {
global $response; global $response;
self::requirePermission('modules_selfserve_lane_status_set'); $this->requirePermission('modules_selfserve_lane_status_set');
self::requireParameters(['lane_id', 'enabled']); self::requireParameters(['lane_id', 'enabled']);
$lane_id = (int)self::getParameter('lane_id'); $lane_id = (int)self::getParameter('lane_id');
self::requireType($lane_id, self::type_int()); self::requireType($lane_id, self::type_int());
@@ -368,7 +368,7 @@ class moduleSelfServeRoute
/** Modules > Self Serve > Sessions */ /** Modules > Self Serve > Sessions */
$this->get('/modules/self-serve/sessions', function () { $this->get('/modules/self-serve/sessions', function () {
global $response; global $response;
self::requirePermission('modules_selfserve_sessions_view'); $this->requirePermission('modules_selfserve_sessions_view');
$sessions = new selfserve_wash_sessions_o(); $sessions = new selfserve_wash_sessions_o();
$sessions->setSearchableFields([ $sessions->setSearchableFields([
@@ -421,7 +421,7 @@ class moduleSelfServeRoute
/** Modules > Self Serve > Session detail */ /** Modules > Self Serve > Session detail */
$this->get('/modules/self-serve/sessions/{id}', function () { $this->get('/modules/self-serve/sessions/{id}', function () {
global $response; global $response;
self::requirePermission('modules_selfserve_sessions_view'); $this->requirePermission('modules_selfserve_sessions_view');
$session_id = (int)$this->fromRoute('id'); $session_id = (int)$this->fromRoute('id');
self::requireType($session_id, self::type_int()); self::requireType($session_id, self::type_int());
self::requireMinValue($session_id, 1); self::requireMinValue($session_id, 1);
@@ -440,7 +440,7 @@ class moduleSelfServeRoute
/** Modules > Self Serve > Lane > Force > Stop */ /** Modules > Self Serve > Lane > Force > Stop */
$this->post('/modules/self-serve/lane/force/stop', function () { $this->post('/modules/self-serve/lane/force/stop', function () {
global $response; global $response;
self::requirePermission('modules_selfserve_sessions_force_stop'); $this->requirePermission('modules_selfserve_sessions_force_stop');
self::requireParameters(['lane_id', 'bill']); self::requireParameters(['lane_id', 'bill']);
$lane_id = (int)$this->getParameter('lane_id'); $lane_id = (int)$this->getParameter('lane_id');
@@ -456,7 +456,7 @@ class moduleSelfServeRoute
$bill = $this->requestedBoolean('bill'); $bill = $this->requestedBoolean('bill');
if ($bill) { if ($bill) {
self::requirePermission('modules_selfserve_sessions_force_stop_bill'); $this->requirePermission('modules_selfserve_sessions_force_stop_bill');
} }
$reason = null; $reason = null;
if ($this->isParametersSet(['reason'])) { if ($this->isParametersSet(['reason'])) {
@@ -518,7 +518,7 @@ class moduleSelfServeRoute
$allow_department_active_wash $allow_department_active_wash
); );
// If the user has the bypass permission, set the lane to bypass customer number validation // If the user has the bypass permission, set the lane to bypass customer number validation
if (self::hasPermission('modules_selfserve_lane_command_bypass_customer_number_validation')) { if ($this->hasPermission('modules_selfserve_lane_command_bypass_customer_number_validation')) {
$lane->setBypassCustomerNumberValidation(true); $lane->setBypassCustomerNumberValidation(true);
} }
// Require permissions for specific commands // Require permissions for specific commands
@@ -757,7 +757,7 @@ class moduleSelfServeRoute
/** Modules > Self Serve > Lane > Gate > Open (ENTRANCE/EXIT) */ /** Modules > Self Serve > Lane > Gate > Open (ENTRANCE/EXIT) */
$this->post('/modules/self-serve/lane/gate/open', function () { $this->post('/modules/self-serve/lane/gate/open', function () {
global $response; global $response;
self::requirePermission('modules_selfserve_lane_gate_open'); $this->requirePermission('modules_selfserve_lane_gate_open');
$selfserve = new selfserve(); $selfserve = new selfserve();
self::requireParameters(['lane_id', 'gate']); self::requireParameters(['lane_id', 'gate']);
$lane_id = (int)$this->getParameter('lane_id'); $lane_id = (int)$this->getParameter('lane_id');
@@ -870,7 +870,7 @@ class moduleSelfServeRoute
/** Modules > Self Serve > Lane > Hardware > Batch poll */ /** Modules > Self Serve > Lane > Hardware > Batch poll */
$this->get('/modules/self-serve/lane/hardware/batch/{batch_id}', function () { $this->get('/modules/self-serve/lane/hardware/batch/{batch_id}', function () {
global $response; global $response;
self::requirePermission('modules_selfserve_lane_relay_machine_status_view'); $this->requirePermission('modules_selfserve_lane_relay_machine_status_view');
try { try {
$response->success((new edge_gateway_manager())->relayBatchStatus((string)$this->fromRoute('batch_id'))); $response->success((new edge_gateway_manager())->relayBatchStatus((string)$this->fromRoute('batch_id')));
} catch (\Exception $e) { } catch (\Exception $e) {
@@ -883,7 +883,7 @@ class moduleSelfServeRoute
/** Modules > Self Serve > Lane > Relay > MACHINE_PROGRAM_PICKER status */ /** Modules > Self Serve > Lane > Relay > MACHINE_PROGRAM_PICKER status */
$this->get('/modules/self-serve/lane/relay/machine_program_picker/status', function () { $this->get('/modules/self-serve/lane/relay/machine_program_picker/status', function () {
global $response; global $response;
self::requirePermission('modules_selfserve_lane_relay_machine_program_picker_status_view'); $this->requirePermission('modules_selfserve_lane_relay_machine_program_picker_status_view');
$selfserve = new selfserve(); $selfserve = new selfserve();
self::requireParameters(['lane_id']); self::requireParameters(['lane_id']);
$lane_id = (int)$this->getParameter('lane_id'); $lane_id = (int)$this->getParameter('lane_id');
@@ -905,7 +905,7 @@ class moduleSelfServeRoute
/** Modules > Self Serve > Lane > Relay > MACHINE_PROGRAM_PICKER set on/off */ /** Modules > Self Serve > Lane > Relay > MACHINE_PROGRAM_PICKER set on/off */
$this->post('/modules/self-serve/lane/relay/machine_program_picker/set', function () { $this->post('/modules/self-serve/lane/relay/machine_program_picker/set', function () {
global $response; global $response;
self::requirePermission('modules_selfserve_lane_relay_machine_program_picker_status_set'); $this->requirePermission('modules_selfserve_lane_relay_machine_program_picker_status_set');
$selfserve = new selfserve(); $selfserve = new selfserve();
self::requireParameters(['lane_id', 'on']); self::requireParameters(['lane_id', 'on']);
$lane_id = (int)$this->getParameter('lane_id'); $lane_id = (int)$this->getParameter('lane_id');
@@ -936,7 +936,7 @@ class moduleSelfServeRoute
/** Modules > Self Serve > Lane > Relay > MACHINE_CLEANER status */ /** Modules > Self Serve > Lane > Relay > MACHINE_CLEANER status */
$this->get('/modules/self-serve/lane/relay/machine_cleaner/status', function () { $this->get('/modules/self-serve/lane/relay/machine_cleaner/status', function () {
global $response; global $response;
self::requirePermission('modules_selfserve_lane_relay_machine_cleaner_status_view'); $this->requirePermission('modules_selfserve_lane_relay_machine_cleaner_status_view');
$selfserve = new selfserve(); $selfserve = new selfserve();
self::requireParameters(['lane_id']); self::requireParameters(['lane_id']);
$lane_id = (int)$this->getParameter('lane_id'); $lane_id = (int)$this->getParameter('lane_id');
@@ -958,7 +958,7 @@ class moduleSelfServeRoute
/** Modules > Self Serve > Lane > Relay > MACHINE_CLEANER set on/off */ /** Modules > Self Serve > Lane > Relay > MACHINE_CLEANER set on/off */
$this->post('/modules/self-serve/lane/relay/machine_cleaner/set', function () { $this->post('/modules/self-serve/lane/relay/machine_cleaner/set', function () {
global $response; global $response;
self::requirePermission('modules_selfserve_lane_relay_machine_cleaner_status_set'); $this->requirePermission('modules_selfserve_lane_relay_machine_cleaner_status_set');
$selfserve = new selfserve(); $selfserve = new selfserve();
self::requireParameters(['lane_id', 'on']); self::requireParameters(['lane_id', 'on']);
$lane_id = (int)$this->getParameter('lane_id'); $lane_id = (int)$this->getParameter('lane_id');
@@ -989,7 +989,7 @@ class moduleSelfServeRoute
/** Modules > Self Serve > Lane > Relay > MACHINE status */ /** Modules > Self Serve > Lane > Relay > MACHINE status */
$this->get('/modules/self-serve/lane/relay/machine/status', function () { $this->get('/modules/self-serve/lane/relay/machine/status', function () {
global $response; global $response;
self::requirePermission('modules_selfserve_lane_relay_machine_status_view'); $this->requirePermission('modules_selfserve_lane_relay_machine_status_view');
$selfserve = new selfserve(); $selfserve = new selfserve();
self::requireParameters(['lane_id']); self::requireParameters(['lane_id']);
$lane_id = (int)$this->getParameter('lane_id'); $lane_id = (int)$this->getParameter('lane_id');
@@ -1011,7 +1011,7 @@ class moduleSelfServeRoute
/** Modules > Self Serve > Lane > Relay > MACHINE set on/off */ /** Modules > Self Serve > Lane > Relay > MACHINE set on/off */
$this->post('/modules/self-serve/lane/relay/machine/set', function () { $this->post('/modules/self-serve/lane/relay/machine/set', function () {
global $response; global $response;
self::requirePermission('modules_selfserve_lane_relay_machine_status_set'); $this->requirePermission('modules_selfserve_lane_relay_machine_status_set');
$selfserve = new selfserve(); $selfserve = new selfserve();
self::requireParameters(['lane_id', 'on']); self::requireParameters(['lane_id', 'on']);
$lane_id = (int)$this->getParameter('lane_id'); $lane_id = (int)$this->getParameter('lane_id');
@@ -1059,7 +1059,7 @@ class moduleSelfServeRoute
/** Modules > Self Serve > Lane > Relay > Enable MACHINE_PROGRAM_PICKER (manual) */ /** Modules > Self Serve > Lane > Relay > Enable MACHINE_PROGRAM_PICKER (manual) */
$this->post('/modules/self-serve/lane/relay/machine_program_picker/enable', function () { $this->post('/modules/self-serve/lane/relay/machine_program_picker/enable', function () {
global $response; global $response;
self::requirePermission('modules_selfserve_lane_relay_enable_machine_program_picker'); $this->requirePermission('modules_selfserve_lane_relay_enable_machine_program_picker');
$selfserve = new selfserve(); $selfserve = new selfserve();
// Validate parameters // Validate parameters
self::requireParameters(['lane_id']); self::requireParameters(['lane_id']);
@@ -1092,7 +1092,7 @@ class moduleSelfServeRoute
/** Modules > Self Serve > Lane > Relay > Enable MACHINE_CLEANER (manual) */ /** Modules > Self Serve > Lane > Relay > Enable MACHINE_CLEANER (manual) */
$this->post('/modules/self-serve/lane/relay/machine_cleaner/enable', function () { $this->post('/modules/self-serve/lane/relay/machine_cleaner/enable', function () {
global $response; global $response;
self::requirePermission('modules_selfserve_lane_relay_enable_machine_cleaner'); $this->requirePermission('modules_selfserve_lane_relay_enable_machine_cleaner');
$selfserve = new selfserve(); $selfserve = new selfserve();
// Validate parameters // Validate parameters
self::requireParameters(['lane_id']); self::requireParameters(['lane_id']);
@@ -1138,7 +1138,7 @@ class moduleSelfServeRoute
} }
$lane = $selfserve->lane($lane_id); $lane = $selfserve->lane($lane_id);
$customer_number = $this->resolveEffectiveCustomerNumber(); $customer_number = $this->resolveEffectiveCustomerNumber();
self::requirePermission('modules_selfserve_lane_relay_enable_machine'); $this->requirePermission('modules_selfserve_lane_relay_enable_machine');
try { try {
$this->applyShellyTransportOverride($lane); $this->applyShellyTransportOverride($lane);
$lane->turnOnRelay(selfserve_lane_relay::MACHINE, $duration); $lane->turnOnRelay(selfserve_lane_relay::MACHINE, $duration);
@@ -1174,7 +1174,7 @@ class moduleSelfServeRoute
/** Modules > Self Serve > Lane > Force > MACHINE_PROGRAM_PICKER enable */ /** Modules > Self Serve > Lane > Force > MACHINE_PROGRAM_PICKER enable */
$this->post('/modules/self-serve/lane/force/machine_program_picker/enable', function () { $this->post('/modules/self-serve/lane/force/machine_program_picker/enable', function () {
global $response; global $response;
self::requirePermission('modules_selfserve_lane_force_machine_program_picker_enable'); $this->requirePermission('modules_selfserve_lane_force_machine_program_picker_enable');
$selfserve = new selfserve(); $selfserve = new selfserve();
// Validate parameters // Validate parameters
self::requireParameters(['lane_id']); self::requireParameters(['lane_id']);
@@ -1207,7 +1207,7 @@ class moduleSelfServeRoute
/** Modules > Self Serve > Lane > Force > MACHINE_PROGRAM_PICKER disable */ /** Modules > Self Serve > Lane > Force > MACHINE_PROGRAM_PICKER disable */
$this->post('/modules/self-serve/lane/force/machine_program_picker/disable', function () { $this->post('/modules/self-serve/lane/force/machine_program_picker/disable', function () {
global $response; global $response;
self::requirePermission('modules_selfserve_lane_force_machine_program_picker_disable'); $this->requirePermission('modules_selfserve_lane_force_machine_program_picker_disable');
$selfserve = new selfserve(); $selfserve = new selfserve();
// Validate parameters // Validate parameters
self::requireParameters(['lane_id']); self::requireParameters(['lane_id']);
@@ -1234,7 +1234,7 @@ class moduleSelfServeRoute
/** Modules > Self Serve > Lane > Force > MACHINE_CLEANER enable */ /** Modules > Self Serve > Lane > Force > MACHINE_CLEANER enable */
$this->post('/modules/self-serve/lane/force/machine_cleaner/enable', function () { $this->post('/modules/self-serve/lane/force/machine_cleaner/enable', function () {
global $response; global $response;
self::requirePermission('modules_selfserve_lane_force_machine_cleaner_enable'); $this->requirePermission('modules_selfserve_lane_force_machine_cleaner_enable');
$selfserve = new selfserve(); $selfserve = new selfserve();
// Validate parameters // Validate parameters
self::requireParameters(['lane_id']); self::requireParameters(['lane_id']);
@@ -1267,7 +1267,7 @@ class moduleSelfServeRoute
/** Modules > Self Serve > Lane > Force > MACHINE_CLEANER disable */ /** Modules > Self Serve > Lane > Force > MACHINE_CLEANER disable */
$this->post('/modules/self-serve/lane/force/machine_cleaner/disable', function () { $this->post('/modules/self-serve/lane/force/machine_cleaner/disable', function () {
global $response; global $response;
self::requirePermission('modules_selfserve_lane_force_machine_cleaner_disable'); $this->requirePermission('modules_selfserve_lane_force_machine_cleaner_disable');
$selfserve = new selfserve(); $selfserve = new selfserve();
// Validate parameters // Validate parameters
self::requireParameters(['lane_id']); self::requireParameters(['lane_id']);
@@ -1294,7 +1294,7 @@ class moduleSelfServeRoute
/** Modules > Self Serve > Lane > Force > MACHINE enable (simulate started wash) */ /** Modules > Self Serve > Lane > Force > MACHINE enable (simulate started wash) */
$this->post('/modules/self-serve/lane/force/machine/enable', function () { $this->post('/modules/self-serve/lane/force/machine/enable', function () {
global $response; global $response;
self::requirePermission('modules_selfserve_lane_force_machine_enable'); $this->requirePermission('modules_selfserve_lane_force_machine_enable');
$selfserve = new selfserve(); $selfserve = new selfserve();
// Validate parameters // Validate parameters
self::requireParameters(['lane_id']); self::requireParameters(['lane_id']);
@@ -1368,7 +1368,7 @@ class moduleSelfServeRoute
/** Modules > Self Serve > Lane > Force > MACHINE disable (simulate started wash without machine) */ /** Modules > Self Serve > Lane > Force > MACHINE disable (simulate started wash without machine) */
$this->post('/modules/self-serve/lane/force/machine/disable', function () { $this->post('/modules/self-serve/lane/force/machine/disable', function () {
global $response; global $response;
self::requirePermission('modules_selfserve_lane_force_machine_disable'); $this->requirePermission('modules_selfserve_lane_force_machine_disable');
$selfserve = new selfserve(); $selfserve = new selfserve();
// Validate parameters // Validate parameters
self::requireParameters(['lane_id']); self::requireParameters(['lane_id']);
@@ -1442,7 +1442,7 @@ class moduleSelfServeRoute
$response->error('Authentication failed. Invalid or missing token.', 401); $response->error('Authentication failed. Invalid or missing token.', 401);
} }
if (self::hasPermission('modules_selfserve_lane_wash_in_progress_view')) { if ($this->hasPermission('modules_selfserve_lane_wash_in_progress_view')) {
$department_lane = (new department_lanes_o())->select($lane_id); $department_lane = (new department_lanes_o())->select($lane_id);
if (!$department_lane->exists()) { if (!$department_lane->exists()) {
$response->error('Department lane not found', 404); $response->error('Department lane not found', 404);
@@ -1455,7 +1455,7 @@ class moduleSelfServeRoute
if ( if (
$customer_number !== null $customer_number !== null
&& $customer_number > 0 && $customer_number > 0
&& self::hasPermission($this->customerSelfServeUsePermission(), $customer_number) && $this->hasPermission($this->customerSelfServeUsePermission(), $customer_number)
) { ) {
return [ return [
'customer_number' => (int)$customer_number, 'customer_number' => (int)$customer_number,
@@ -1576,7 +1576,7 @@ class moduleSelfServeRoute
} }
$customer_number = $this->resolveEffectiveCustomerNumber(); $customer_number = $this->resolveEffectiveCustomerNumber();
if (!self::hasPermission($this->customerSelfServeUsePermission(), $customer_number)) { if (!$this->hasPermission($this->customerSelfServeUsePermission(), $customer_number)) {
$this->emitForbidden([$this->customerSelfServeUsePermission()]); $this->emitForbidden([$this->customerSelfServeUsePermission()]);
} }
@@ -2128,10 +2128,10 @@ class moduleSelfServeRoute
private function requireLaneHardwareStatusPermission(string $target): void private function requireLaneHardwareStatusPermission(string $target): void
{ {
match ($target) { match ($target) {
'MACHINE' => self::requirePermission('modules_selfserve_lane_relay_machine_status_view'), 'MACHINE' => $this->requirePermission('modules_selfserve_lane_relay_machine_status_view'),
'PROGRAM_PICKER', 'MACHINE_PROGRAM_PICKER' => self::requirePermission('modules_selfserve_lane_relay_machine_program_picker_status_view'), 'PROGRAM_PICKER', 'MACHINE_PROGRAM_PICKER' => $this->requirePermission('modules_selfserve_lane_relay_machine_program_picker_status_view'),
'CLEANER', 'MACHINE_CLEANER' => self::requirePermission('modules_selfserve_lane_relay_machine_cleaner_status_view'), 'CLEANER', 'MACHINE_CLEANER' => $this->requirePermission('modules_selfserve_lane_relay_machine_cleaner_status_view'),
'ENTRANCE', 'EXIT' => self::requirePermission('modules_selfserve_lane_gate_open'), 'ENTRANCE', 'EXIT' => $this->requirePermission('modules_selfserve_lane_gate_open'),
default => throw new \Exception('Unsupported lane hardware target: ' . $target), default => throw new \Exception('Unsupported lane hardware target: ' . $target),
}; };
} }
@@ -2139,10 +2139,10 @@ class moduleSelfServeRoute
private function requireLaneHardwareMutationPermission(string $target): void private function requireLaneHardwareMutationPermission(string $target): void
{ {
match ($target) { match ($target) {
'MACHINE' => self::requirePermission('modules_selfserve_lane_relay_machine_status_set'), 'MACHINE' => $this->requirePermission('modules_selfserve_lane_relay_machine_status_set'),
'PROGRAM_PICKER', 'MACHINE_PROGRAM_PICKER' => self::requirePermission('modules_selfserve_lane_relay_machine_program_picker_status_set'), 'PROGRAM_PICKER', 'MACHINE_PROGRAM_PICKER' => $this->requirePermission('modules_selfserve_lane_relay_machine_program_picker_status_set'),
'CLEANER', 'MACHINE_CLEANER' => self::requirePermission('modules_selfserve_lane_relay_machine_cleaner_status_set'), 'CLEANER', 'MACHINE_CLEANER' => $this->requirePermission('modules_selfserve_lane_relay_machine_cleaner_status_set'),
'ENTRANCE', 'EXIT' => self::requirePermission('modules_selfserve_lane_gate_open'), 'ENTRANCE', 'EXIT' => $this->requirePermission('modules_selfserve_lane_gate_open'),
default => throw new \Exception('Unsupported lane hardware target: ' . $target), default => throw new \Exception('Unsupported lane hardware target: ' . $target),
}; };
} }
@@ -2314,8 +2314,8 @@ class moduleSelfServeRoute
} }
self::requireDepartmentAccess((string)$lane->department_lane->department->value()); self::requireDepartmentAccess((string)$lane->department_lane->department->value());
self::requirePermission('modules_selfserve_lane_command_execute'); $this->requirePermission('modules_selfserve_lane_command_execute');
self::requirePermission($command_permission); $this->requirePermission($command_permission);
} }
private function requirePropertyGateCommandPermission(string $permission, selfserve_lane $lane, int $customer_number): void private function requirePropertyGateCommandPermission(string $permission, selfserve_lane $lane, int $customer_number): void
+10 -10
View File
@@ -25,7 +25,7 @@ class moduleStripeRoute
/** Modules > Stripe > Customers > List */ /** Modules > Stripe > Customers > List */
$this->get('/modules/stripe/customers', function () { $this->get('/modules/stripe/customers', function () {
global $response; global $response;
self::requirePermission('modules_stripe_customers_list'); $this->requirePermission('modules_stripe_customers_list');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('modules_stripe', 'global', 1, 0, 'MODULES_STRIPE', 'User accessed the customers list'); (new logs_o())->add('modules_stripe', 'global', 1, 0, 'MODULES_STRIPE', 'User accessed the customers list');
@@ -44,7 +44,7 @@ class moduleStripeRoute
/** Modules > Stripe > Products > List */ /** Modules > Stripe > Products > List */
$this->get('/modules/stripe/products', function () { $this->get('/modules/stripe/products', function () {
global $response; global $response;
self::requirePermission('modules_stripe_products_list'); $this->requirePermission('modules_stripe_products_list');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('modules_stripe', 'global', 1, 0, 'MODULES_STRIPE', 'User accessed the products list'); (new logs_o())->add('modules_stripe', 'global', 1, 0, 'MODULES_STRIPE', 'User accessed the products list');
@@ -63,7 +63,7 @@ class moduleStripeRoute
/** Modules > Stripe > Prices > List */ /** Modules > Stripe > Prices > List */
$this->get('/modules/stripe/prices', function () { $this->get('/modules/stripe/prices', function () {
global $response; global $response;
self::requirePermission('modules_stripe_prices_list'); $this->requirePermission('modules_stripe_prices_list');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('modules_stripe', 'global', 1, 0, 'MODULES_STRIPE', 'User accessed the prices list'); (new logs_o())->add('modules_stripe', 'global', 1, 0, 'MODULES_STRIPE', 'User accessed the prices list');
@@ -82,7 +82,7 @@ class moduleStripeRoute
/** Modules > Stripe > Retired direct payment-link creation */ /** Modules > Stripe > Retired direct payment-link creation */
$this->post('/modules/stripe/invoice', function () { $this->post('/modules/stripe/invoice', function () {
global $response; global $response;
self::requirePermission('modules_stripe_invoice_send'); $this->requirePermission('modules_stripe_invoice_send');
$response->error([ $response->error([
'message' => 'Direct Stripe payment links by email are no longer available. Use card payment instead.', 'message' => 'Direct Stripe payment links by email are no longer available. Use card payment instead.',
'code' => 'stripe_email_payment_disabled', 'code' => 'stripe_email_payment_disabled',
@@ -96,7 +96,7 @@ class moduleStripeRoute
/** Modules > Stripe > Cancel Invoice */ /** Modules > Stripe > Cancel Invoice */
$this->delete('/modules/stripe/invoice', function () { $this->delete('/modules/stripe/invoice', function () {
global $response; global $response;
self::requirePermission('modules_stripe_invoice_send'); $this->requirePermission('modules_stripe_invoice_send');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
(new logs_o())->add('modules_stripe', 'global', 0, 0, 'MODULES_STRIPE', 'User tried to cancel a Stripe invoice without a valid session'); (new logs_o())->add('modules_stripe', 'global', 0, 0, 'MODULES_STRIPE', 'User tried to cancel a Stripe invoice without a valid session');
@@ -149,7 +149,7 @@ class moduleStripeRoute
self::get('/modules/stripe/terminal/readers', function () { self::get('/modules/stripe/terminal/readers', function () {
global $response; global $response;
self::requirePermission('modules_stripe_terminal_readers_list'); $this->requirePermission('modules_stripe_terminal_readers_list');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('modules_stripe', 'global', 1, 0, 'MODULES_STRIPE', 'User accessed the readers list'); (new logs_o())->add('modules_stripe', 'global', 1, 0, 'MODULES_STRIPE', 'User accessed the readers list');
@@ -167,7 +167,7 @@ class moduleStripeRoute
self::get('/modules/stripe/terminal/locations', function () { self::get('/modules/stripe/terminal/locations', function () {
global $response; global $response;
self::requirePermission('modules_stripe_terminal_locations_list'); $this->requirePermission('modules_stripe_terminal_locations_list');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('modules_stripe', 'global', 1, 0, 'MODULES_STRIPE', 'User accessed the terminal locations list'); (new logs_o())->add('modules_stripe', 'global', 1, 0, 'MODULES_STRIPE', 'User accessed the terminal locations list');
@@ -186,7 +186,7 @@ class moduleStripeRoute
self::get('/modules/stripe/department/terminal/location', self::get('/modules/stripe/department/terminal/location',
function () { function () {
global $response; global $response;
self::requirePermission('modules_stripe_department_terminal_location_list'); $this->requirePermission('modules_stripe_department_terminal_location_list');
self::requireParameters(['id']); self::requireParameters(['id']);
self::requireType((int)self::fromRequest('id'), self::TYPE_INT()); self::requireType((int)self::fromRequest('id'), self::TYPE_INT());
// Require the id to be above 0 // Require the id to be above 0
@@ -225,7 +225,7 @@ class moduleStripeRoute
self::post('/modules/stripe/department/terminal/location', self::post('/modules/stripe/department/terminal/location',
function () { function () {
global $response; global $response;
self::requirePermission('modules_stripe_department_terminal_location_set'); $this->requirePermission('modules_stripe_department_terminal_location_set');
self::requireParameters(['id', 'location']); self::requireParameters(['id', 'location']);
self::requireType((int)self::fromRequest('id'), self::TYPE_INT()); self::requireType((int)self::fromRequest('id'), self::TYPE_INT());
self::requireType((string)self::fromRequest('location'), 'string'); self::requireType((string)self::fromRequest('location'), 'string');
@@ -263,7 +263,7 @@ class moduleStripeRoute
self::get('/modules/stripe/department/terminal/readers', self::get('/modules/stripe/department/terminal/readers',
function () { function () {
global $response; global $response;
self::requirePermission('modules_stripe_department_terminal_readers_list'); $this->requirePermission('modules_stripe_department_terminal_readers_list');
self::requireParameters(['id']); self::requireParameters(['id']);
self::requireType((int)self::fromRequest('id'), self::TYPE_INT()); self::requireType((int)self::fromRequest('id'), self::TYPE_INT());
// Require the id to be above 0 // Require the id to be above 0
@@ -25,7 +25,7 @@ class moduleVirkDataRoute
/** Modules > VirkData > search > GET */ /** Modules > VirkData > search > GET */
$this->get('/modules/virkdata/search', function () { $this->get('/modules/virkdata/search', function () {
global $response; global $response;
self::requirePermission('modules_virkdata_search'); $this->requirePermission('modules_virkdata_search');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
self::requireParameters(['search']); self::requireParameters(['search']);
@@ -47,7 +47,7 @@ class moduleWeatherAPIRoute
$this->get('/modules/weatherapi/current', function () { $this->get('/modules/weatherapi/current', function () {
global $response; global $response;
self::requirePermission('modules_weatherapi_current'); $this->requirePermission('modules_weatherapi_current');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -64,7 +64,7 @@ class moduleWeatherAPIRoute
$this->get('/modules/weatherapi/forecast', function () { $this->get('/modules/weatherapi/forecast', function () {
global $response; global $response;
self::requirePermission('modules_weatherapi_forecast'); $this->requirePermission('modules_weatherapi_forecast');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -82,7 +82,7 @@ class moduleWeatherAPIRoute
$this->get('/modules/weatherapi/search', function () { $this->get('/modules/weatherapi/search', function () {
global $response; global $response;
self::requirePermission('modules_weatherapi_search'); $this->requirePermission('modules_weatherapi_search');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -99,7 +99,7 @@ class moduleWeatherAPIRoute
$this->get('/departments/weather', function () { $this->get('/departments/weather', function () {
global $response; global $response;
self::requirePermission('departments_weather_get'); $this->requirePermission('departments_weather_get');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -155,7 +155,7 @@ class moduleWeatherAPIRoute
$this->get('/departments/weather/hours/details', function () { $this->get('/departments/weather/hours/details', function () {
global $response; global $response;
self::requirePermission('departments_weather_get'); $this->requirePermission('departments_weather_get');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -190,7 +190,7 @@ class moduleWeatherAPIRoute
$this->get('/departments/weather/targets', function () { $this->get('/departments/weather/targets', function () {
global $response; global $response;
self::requirePermission('departments_weather_targets_get'); $this->requirePermission('departments_weather_targets_get');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -220,7 +220,7 @@ class moduleWeatherAPIRoute
$this->put('/departments/weather/targets', function () { $this->put('/departments/weather/targets', function () {
global $response; global $response;
self::requirePermission('departments_weather_targets_manage'); $this->requirePermission('departments_weather_targets_manage');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -21,7 +21,7 @@ class moduleWorkfeedRoute
$this->get('/modules/workfeed/employees', function () { $this->get('/modules/workfeed/employees', function () {
global $response; global $response;
self::requirePermission('modules_workfeed_employees_view'); $this->requirePermission('modules_workfeed_employees_view');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -36,7 +36,7 @@ class moduleWorkfeedRoute
$this->get('/modules/workfeed/employees/{id}', function () { $this->get('/modules/workfeed/employees/{id}', function () {
global $response; global $response;
self::requirePermission('modules_workfeed_employees_view'); $this->requirePermission('modules_workfeed_employees_view');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -51,7 +51,7 @@ class moduleWorkfeedRoute
$this->get('/modules/workfeed/shifts', function () { $this->get('/modules/workfeed/shifts', function () {
global $response; global $response;
self::requirePermission('modules_workfeed_shifts_view'); $this->requirePermission('modules_workfeed_shifts_view');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -95,7 +95,7 @@ class moduleWorkfeedRoute
$this->get('/modules/workfeed/shifts/{id}', function () { $this->get('/modules/workfeed/shifts/{id}', function () {
global $response; global $response;
self::requirePermission('modules_workfeed_shifts_view'); $this->requirePermission('modules_workfeed_shifts_view');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -110,7 +110,7 @@ class moduleWorkfeedRoute
$this->get('/modules/workfeed/departments', function () { $this->get('/modules/workfeed/departments', function () {
global $response; global $response;
self::requirePermission('modules_workfeed_departments_view'); $this->requirePermission('modules_workfeed_departments_view');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
+11 -11
View File
@@ -25,7 +25,7 @@ class moduleXLVaskRoute
$router, $response; $router, $response;
$this->get('/modules/xlvask/usageLog', function () { $this->get('/modules/xlvask/usageLog', function () {
global $response; global $response;
self::requirePermission('modules_xlvask_usageLog'); $this->requirePermission('modules_xlvask_usageLog');
$params = [ $params = [
'dateFrom' => null, 'dateFrom' => null,
'regNr' => null, 'regNr' => null,
@@ -53,7 +53,7 @@ class moduleXLVaskRoute
$this->get('/modules/xlvask/vehicles', function () { $this->get('/modules/xlvask/vehicles', function () {
global $response; global $response;
self::requirePermission('modules_xlvask_vehicles'); $this->requirePermission('modules_xlvask_vehicles');
$params = [ $params = [
'customerId' => null, 'customerId' => null,
'vehicleId' => null, 'vehicleId' => null,
@@ -79,7 +79,7 @@ class moduleXLVaskRoute
$this->get('/modules/xlvask/customers', function () { $this->get('/modules/xlvask/customers', function () {
global $response; global $response;
self::requirePermission('modules_xlvask_customers'); $this->requirePermission('modules_xlvask_customers');
$params = [ $params = [
'customerId' => null, 'customerId' => null,
'customerName' => null, 'customerName' => null,
@@ -107,7 +107,7 @@ class moduleXLVaskRoute
$this->get('/modules/xlvask/internal/vehicle-types', function () { $this->get('/modules/xlvask/internal/vehicle-types', function () {
global $response; global $response;
self::requirePermission('modules_xlvask_internal_vehicle_types'); $this->requirePermission('modules_xlvask_internal_vehicle_types');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
$xlvask_vehicle_types = new \objects\xlvask_vehicle_types_o(); $xlvask_vehicle_types = new \objects\xlvask_vehicle_types_o();
$result = $xlvask_vehicle_types->listObjectsWithPaginationIfSet( $result = $xlvask_vehicle_types->listObjectsWithPaginationIfSet(
@@ -127,7 +127,7 @@ class moduleXLVaskRoute
$this->get('/modules/xlvask/related-orders', function () { $this->get('/modules/xlvask/related-orders', function () {
global $response; global $response;
self::requirePermission('modules_xlvask_related_orders'); $this->requirePermission('modules_xlvask_related_orders');
self::requireParameters(['washIds']); self::requireParameters(['washIds']);
$washIds = self::getParameter('washIds'); $washIds = self::getParameter('washIds');
// Check if the washIds is an array // Check if the washIds is an array
@@ -161,7 +161,7 @@ class moduleXLVaskRoute
$this->get('/modules/xlvask/tasks/sync-users', function () { $this->get('/modules/xlvask/tasks/sync-users', function () {
global $response; global $response;
self::requirePermission('modules_xlvask_sync_users'); $this->requirePermission('modules_xlvask_sync_users');
// Create the xlvask tasks object // Create the xlvask tasks object
$xlvask = new xlvask(); $xlvask = new xlvask();
// Run the sync users task // Run the sync users task
@@ -179,7 +179,7 @@ class moduleXLVaskRoute
$this->get('/modules/xlvask/tasks/sync-usage', function () { $this->get('/modules/xlvask/tasks/sync-usage', function () {
global $response; global $response;
self::requirePermission('modules_xlvask_sync_usage'); $this->requirePermission('modules_xlvask_sync_usage');
// Remove the memory limit // Remove the memory limit
// ini_set('memory_limit', '-1'); // ini_set('memory_limit', '-1');
// Remove the execution time limit // Remove the execution time limit
@@ -201,7 +201,7 @@ class moduleXLVaskRoute
$this->get('/modules/xlvask/tasks/debug', function () { $this->get('/modules/xlvask/tasks/debug', function () {
global $response; global $response;
self::requirePermission('modules_xlvask_sync_usage'); $this->requirePermission('modules_xlvask_sync_usage');
// Create the xlvask tasks object // Create the xlvask tasks object
$xlvask = new xlvask(); $xlvask = new xlvask();
$user = new users_o(); $user = new users_o();
@@ -222,7 +222,7 @@ class moduleXLVaskRoute
$this->get('/modules/xlvask/tasks/import-customers', function () { $this->get('/modules/xlvask/tasks/import-customers', function () {
global $response; global $response;
self::requirePermission('modules_xlvask_import_customers'); $this->requirePermission('modules_xlvask_import_customers');
// Create the xlvask_customers_o object // Create the xlvask_customers_o object
$xlvask_customers_o = new xlvask_customers_o(); $xlvask_customers_o = new xlvask_customers_o();
$xlvask_customers_o->importCustomers(); $xlvask_customers_o->importCustomers();
@@ -238,7 +238,7 @@ class moduleXLVaskRoute
$this->get('/modules/xlvask/tasks/import-vehicles', function () { $this->get('/modules/xlvask/tasks/import-vehicles', function () {
global $response; global $response;
self::requirePermission('modules_xlvask_import_vehicles'); $this->requirePermission('modules_xlvask_import_vehicles');
// Create the xlvask_vehicles_o object // Create the xlvask_vehicles_o object
$xlvask_vehicles_o = new \objects\xlvask_vehicles_o(); $xlvask_vehicles_o = new \objects\xlvask_vehicles_o();
$xlvask_vehicles_o->importVehicles(); $xlvask_vehicles_o->importVehicles();
@@ -254,7 +254,7 @@ class moduleXLVaskRoute
$this->get('/modules/xlvask/tasks/import-usage', function () { $this->get('/modules/xlvask/tasks/import-usage', function () {
global $response; global $response;
self::requirePermission('modules_xlvask_import_usage'); $this->requirePermission('modules_xlvask_import_usage');
$response->error('Deprecated state-changing GET. Use POST /modules/xlvask/services/usage/autopilot-runs.', 410); $response->error('Deprecated state-changing GET. Use POST /modules/xlvask/services/usage/autopilot-runs.', 410);
}, },
[ [
@@ -18,7 +18,7 @@ class notificationsRoute
global $response; global $response;
$this->requirePermission('list_notifications'); $this->requirePermission('list_notifications');
// Check if the user has permission to list all notifications // Check if the user has permission to list all notifications
if (self::hasPermission('list_all_notifications')) { if ($this->hasPermission('list_all_notifications')) {
$this->requirePermission('list_all_notifications'); $this->requirePermission('list_all_notifications');
} else { } else {
$this->requirePermission('list_own_notifications'); $this->requirePermission('list_own_notifications');
@@ -79,7 +79,7 @@ class notificationsRoute
$this->post('/notifications', function () { $this->post('/notifications', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('add_notification'); $this->requirePermission('add_notification');
// Get the user object // Get the user object
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
// Check if the request was successful // Check if the request was successful
@@ -132,7 +132,7 @@ class notificationsRoute
$this->delete('/notifications', function () { $this->delete('/notifications', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('delete_own_notifications'); $this->requirePermission('delete_own_notifications');
// Get the user object // Get the user object
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
// Check if the request was successful // Check if the request was successful
+11 -11
View File
@@ -120,7 +120,7 @@ class orderBookingRoute
*/ */
$permission_own = self::definePermission('list_own_bookings', subusers_permission_node_key::BOOKINGS_LIST); $permission_own = self::definePermission('list_own_bookings', subusers_permission_node_key::BOOKINGS_LIST);
$permission_other = self::definePermission('list_bookings'); $permission_other = self::definePermission('list_bookings');
$has_permission_other = self::hasPermission($permission_other); $has_permission_other = $this->hasPermission($permission_other);
$targetCustomer = !empty($object) ? (int)$object->customer_number->value() : null; $targetCustomer = !empty($object) ? (int)$object->customer_number->value() : null;
$deptId = !empty($object) ? (int)$object->department->value() : null; $deptId = !empty($object) ? (int)$object->department->value() : null;
self::allowOwnOrDepartmentAccess( self::allowOwnOrDepartmentAccess(
@@ -190,8 +190,8 @@ class orderBookingRoute
$permission_own = self::definePermission('list_own_bookings', subusers_permission_node_key::BOOKINGS_LIST); $permission_own = self::definePermission('list_own_bookings', subusers_permission_node_key::BOOKINGS_LIST);
$permission_other = self::definePermission('list_bookings'); $permission_other = self::definePermission('list_bookings');
$hasPermissionOwn = self::hasPermission($permission_own); $hasPermissionOwn = $this->hasPermission($permission_own);
$hasPermissionOther = self::hasPermission($permission_other); $hasPermissionOther = $this->hasPermission($permission_other);
if (!$hasPermissionOwn && !$hasPermissionOther) { if (!$hasPermissionOwn && !$hasPermissionOther) {
$this->emitForbidden([$permission_own, $permission_other]); $this->emitForbidden([$permission_own, $permission_other]);
@@ -283,7 +283,7 @@ class orderBookingRoute
} }
$permission_own = self::definePermission('edit_own_bookings', subusers_permission_node_key::BOOKINGS_EDIT); $permission_own = self::definePermission('edit_own_bookings', subusers_permission_node_key::BOOKINGS_EDIT);
$permission_other = self::definePermission('edit_bookings'); $permission_other = self::definePermission('edit_bookings');
$has_permission_other = self::hasPermission($permission_other); $has_permission_other = $this->hasPermission($permission_other);
$ownGuard = function () use ($has_permission_other, $object) { $ownGuard = function () use ($has_permission_other, $object) {
// Block own edits when a transaction exists, unless admin/department permission is present // Block own edits when a transaction exists, unless admin/department permission is present
return $has_permission_other || !$object->hasTransaction(); return $has_permission_other || !$object->hasTransaction();
@@ -306,7 +306,7 @@ class orderBookingRoute
*/ */
$previous_order_id = (int)($object->order_id->value() ?? 0); $previous_order_id = (int)($object->order_id->value() ?? 0);
$data = [ $data = [
...(self::hasPermission($permission_other) && !empty($customer_number) ? [ ...($this->hasPermission($permission_other) && !empty($customer_number) ? [
'customer_number' => (int)$customer_number->customer_number->value(), 'customer_number' => (int)$customer_number->customer_number->value(),
] : []), ] : []),
...(isset($department) ? ['department' => $department->id] : []), ...(isset($department) ? ['department' => $department->id] : []),
@@ -385,7 +385,7 @@ class orderBookingRoute
$response->error('Order booking does not exist.', 400); $response->error('Order booking does not exist.', 400);
} }
self::requirePermission('resend_booking_confirmations'); $this->requirePermission('resend_booking_confirmations');
self::requireDepartmentAccess((int)$object->department->value()); self::requireDepartmentAccess((int)$object->department->value());
(new email())->sendOrderBookingConfirmationEmail($object); (new email())->sendOrderBookingConfirmationEmail($object);
@@ -408,7 +408,7 @@ class orderBookingRoute
$response->error('Order booking does not exist.', 400); $response->error('Order booking does not exist.', 400);
} }
self::requirePermission('complete_bookings'); $this->requirePermission('complete_bookings');
self::requireDepartmentAccess((int)$object->department->value()); self::requireDepartmentAccess((int)$object->department->value());
if (!$object->hasTransaction()) { if (!$object->hasTransaction()) {
@@ -673,7 +673,7 @@ class orderBookingRoute
if ($auth->get_subuser() !== false && $this->isOwnCustomerContext($targetCustomerNumber)) { if ($auth->get_subuser() !== false && $this->isOwnCustomerContext($targetCustomerNumber)) {
$permissionOwn = self::definePermission('add_own_bookings', subusers_permission_node_key::BOOKINGS_ADD); $permissionOwn = self::definePermission('add_own_bookings', subusers_permission_node_key::BOOKINGS_ADD);
if (!self::hasPermission($permissionOwn, $targetCustomerNumber)) { if (!$this->hasPermission($permissionOwn, $targetCustomerNumber)) {
$this->emitForbidden([$permissionOwn]); $this->emitForbidden([$permissionOwn]);
} }
return; return;
@@ -681,14 +681,14 @@ class orderBookingRoute
if ( if (
$auth->get_user() !== false $auth->get_user() !== false
&& self::hasPermission('user') && $this->hasPermission('user')
&& $this->isOwnCustomerContext($targetCustomerNumber) && $this->isOwnCustomerContext($targetCustomerNumber)
) { ) {
return; return;
} }
$permissionOther = self::definePermission('add_bookings'); $permissionOther = self::definePermission('add_bookings');
if (!self::hasPermission($permissionOther)) { if (!$this->hasPermission($permissionOther)) {
$this->emitForbidden([$permissionOther]); $this->emitForbidden([$permissionOther]);
} }
@@ -703,7 +703,7 @@ class orderBookingRoute
return true; return true;
} }
return $auth->get_user() !== false && self::hasPermission('user'); return $auth->get_user() !== false && $this->hasPermission('user');
} catch (Exception) { } catch (Exception) {
return false; return false;
} }
@@ -38,7 +38,7 @@ class orderInvoicesRoute
/** Collected order invoices > GET */ /** Collected order invoices > GET */
$this->get('/collected-invoices', function () { $this->get('/collected-invoices', function () {
global $response; global $response;
self::requirePermission('list_collected_invoices'); $this->requirePermission('list_collected_invoices');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'LIST_COLLECTED_INVOICES', 'User accessed the list of collected order invoices'); (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'LIST_COLLECTED_INVOICES', 'User accessed the list of collected order invoices');
@@ -143,7 +143,7 @@ class orderInvoicesRoute
/** Collected order invoices > Compare with E-conomic > GET */ /** Collected order invoices > Compare with E-conomic > GET */
$this->get('/collected-invoices/economic/compare', function () { $this->get('/collected-invoices/economic/compare', function () {
global $response; global $response;
self::requirePermission('compare_collected_invoice_economic'); $this->requirePermission('compare_collected_invoice_economic');
//$user = (new authentication())->get_user(); //$user = (new authentication())->get_user();
self::requireParameters(['collected_invoice_id']); self::requireParameters(['collected_invoice_id']);
self::requireType((int)self::getParameter('collected_invoice_id'), self::type_int()); self::requireType((int)self::getParameter('collected_invoice_id'), self::type_int());
@@ -242,7 +242,7 @@ class orderInvoicesRoute
/** Collected order invoices > E-conomic V2 details > GET */ /** Collected order invoices > E-conomic V2 details > GET */
$this->get('/collected-invoices/economic/v2/details', function () { $this->get('/collected-invoices/economic/v2/details', function () {
global $response; global $response;
self::requirePermission('view_collected_invoice_economic_v2_details'); $this->requirePermission('view_collected_invoice_economic_v2_details');
$collected_invoice_id = $this->requireCollectedInvoiceId(); $collected_invoice_id = $this->requireCollectedInvoiceId();
$payload = $this->buildEconomicV2DetailsPayload($collected_invoice_id); $payload = $this->buildEconomicV2DetailsPayload($collected_invoice_id);
@@ -256,7 +256,7 @@ class orderInvoicesRoute
/** Collected order invoices > E-conomic PDF > GET */ /** Collected order invoices > E-conomic PDF > GET */
$this->get('/collected-invoices/economic/pdf', function () { $this->get('/collected-invoices/economic/pdf', function () {
global $response; global $response;
self::requirePermission('download_collected_invoice_economic_pdf'); $this->requirePermission('download_collected_invoice_economic_pdf');
$collected_invoice_id = $this->requireCollectedInvoiceId(); $collected_invoice_id = $this->requireCollectedInvoiceId();
self::requireParameters(['type']); self::requireParameters(['type']);
@@ -276,7 +276,7 @@ class orderInvoicesRoute
/** Collected order invoices > E-conomic V2 compare > GET */ /** Collected order invoices > E-conomic V2 compare > GET */
$this->get('/collected-invoices/economic/v2/compare', function () { $this->get('/collected-invoices/economic/v2/compare', function () {
global $response; global $response;
self::requirePermission('compare_collected_invoice_economic_v2'); $this->requirePermission('compare_collected_invoice_economic_v2');
$collected_invoice_id = $this->requireCollectedInvoiceId(); $collected_invoice_id = $this->requireCollectedInvoiceId();
$details = $this->buildEconomicV2DetailsPayload($collected_invoice_id); $details = $this->buildEconomicV2DetailsPayload($collected_invoice_id);
@@ -304,7 +304,7 @@ class orderInvoicesRoute
/** Collected order invoices > E-conomic V2 compare bulk > POST */ /** Collected order invoices > E-conomic V2 compare bulk > POST */
$this->post('/collected-invoices/economic/v2/compare/bulk', function () { $this->post('/collected-invoices/economic/v2/compare/bulk', function () {
global $response; global $response;
self::requirePermission('compare_collected_invoice_economic_v2_bulk'); $this->requirePermission('compare_collected_invoice_economic_v2_bulk');
self::requireParameters(['collected_invoice_ids']); self::requireParameters(['collected_invoice_ids']);
$collected_invoice_ids = self::getParameter('collected_invoice_ids'); $collected_invoice_ids = self::getParameter('collected_invoice_ids');
@@ -371,7 +371,7 @@ class orderInvoicesRoute
/** Collected order invoices > E-conomic V2 revenue statistics > GET */ /** Collected order invoices > E-conomic V2 revenue statistics > GET */
$this->get('/collected-invoices/economic/v2/revenue-statistics', function () { $this->get('/collected-invoices/economic/v2/revenue-statistics', function () {
global $response; global $response;
self::requirePermission('view_collected_invoice_economic_v2_revenue_statistics'); $this->requirePermission('view_collected_invoice_economic_v2_revenue_statistics');
$dateFrom = (string)(self::fromRequest('dateFrom') ?? date('Y-m-01')); $dateFrom = (string)(self::fromRequest('dateFrom') ?? date('Y-m-01'));
$dateTo = (string)(self::fromRequest('dateTo') ?? date('Y-m-d')); $dateTo = (string)(self::fromRequest('dateTo') ?? date('Y-m-d'));
@@ -414,7 +414,7 @@ class orderInvoicesRoute
/** Collected order invoices > Ready to invoice > GET */ /** Collected order invoices > Ready to invoice > GET */
$this->get('/collected-invoices/ready-to-invoice', function () { $this->get('/collected-invoices/ready-to-invoice', function () {
global $response; global $response;
self::requirePermission('list_collected_invoices'); $this->requirePermission('list_collected_invoices');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'LIST_COLLECTED_INVOICES_READY_TO_INVOICE', 'User accessed the list of collected order invoices ready to invoice'); (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'LIST_COLLECTED_INVOICES_READY_TO_INVOICE', 'User accessed the list of collected order invoices ready to invoice');
@@ -450,7 +450,7 @@ class orderInvoicesRoute
/** Collected order invoices > POST */ /** Collected order invoices > POST */
$this->post('/collected-invoices', function () { $this->post('/collected-invoices', function () {
global $response; global $response;
self::requirePermission('add_collected_invoice'); $this->requirePermission('add_collected_invoice');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'ADD_COLLECTED_INVOICE', 'User added a collected order invoice'); (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'ADD_COLLECTED_INVOICE', 'User added a collected order invoice');
@@ -524,7 +524,7 @@ class orderInvoicesRoute
/** Collected order invoices > Move to customer > POST */ /** Collected order invoices > Move to customer > POST */
$this->post('/collected-invoices/move-to-customer', function () { $this->post('/collected-invoices/move-to-customer', function () {
global $response; global $response;
self::requirePermission('move_collected_invoice_customer'); $this->requirePermission('move_collected_invoice_customer');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
(new logs_o())->add('orderInvoices', 'global', 0, 0, 'MOVE_COLLECTED_INVOICE_CUSTOMER', 'User tried to move a collected order invoice without a valid session'); (new logs_o())->add('orderInvoices', 'global', 0, 0, 'MOVE_COLLECTED_INVOICE_CUSTOMER', 'User tried to move a collected order invoice without a valid session');
@@ -567,7 +567,7 @@ class orderInvoicesRoute
/** Collected order invoices > Split > POST */ /** Collected order invoices > Split > POST */
$this->post('/collected-invoices/split', function () { $this->post('/collected-invoices/split', function () {
global $response; global $response;
self::requirePermission('split_collected_invoice'); $this->requirePermission('split_collected_invoice');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'SPLIT_COLLECTED_INVOICE', 'User split a collected order invoice'); (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'SPLIT_COLLECTED_INVOICE', 'User split a collected order invoice');
@@ -597,7 +597,7 @@ class orderInvoicesRoute
/** Collected order invoices > Split by month > POST */ /** Collected order invoices > Split by month > POST */
$this->post('/collected-invoices/split-by-month', function () { $this->post('/collected-invoices/split-by-month', function () {
global $response, $db; global $response, $db;
self::requirePermission('split_collected_invoice'); $this->requirePermission('split_collected_invoice');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
self::requireParameters(['dateFrom', 'dateTo']); self::requireParameters(['dateFrom', 'dateTo']);
@@ -861,7 +861,7 @@ class orderInvoicesRoute
$this->post('/superuser/invoicing/period/tree-actions/preview', function () { $this->post('/superuser/invoicing/period/tree-actions/preview', function () {
global $response; global $response;
self::requirePermission('superuser_invoicing_period'); $this->requirePermission('superuser_invoicing_period');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -916,7 +916,7 @@ class orderInvoicesRoute
$this->post('/superuser/invoicing/period/tree-actions/apply', function () { $this->post('/superuser/invoicing/period/tree-actions/apply', function () {
global $response; global $response;
self::requirePermission('superuser_invoicing_period'); $this->requirePermission('superuser_invoicing_period');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -956,7 +956,7 @@ class orderInvoicesRoute
/** Collected order invoices > E-Conomic > POST (queued) */ /** Collected order invoices > E-Conomic > POST (queued) */
$this->post('/collected-invoices/economic', function () { $this->post('/collected-invoices/economic', function () {
global $response; global $response;
self::requirePermission('add_collected_invoice_economic'); $this->requirePermission('add_collected_invoice_economic');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
self::requireParameters(['id']); self::requireParameters(['id']);
@@ -1050,7 +1050,7 @@ class orderInvoicesRoute
$this->get('/collected-invoices/economic/queue', function () { $this->get('/collected-invoices/economic/queue', function () {
global $response; global $response;
self::requirePermission('add_collected_invoice_economic'); $this->requirePermission('add_collected_invoice_economic');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -1087,7 +1087,7 @@ class orderInvoicesRoute
$this->get('/collected-invoices/economic/queue/status', function () { $this->get('/collected-invoices/economic/queue/status', function () {
global $response; global $response;
self::requirePermission('add_collected_invoice_economic'); $this->requirePermission('add_collected_invoice_economic');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -1106,7 +1106,7 @@ class orderInvoicesRoute
$this->get('/collected-invoices/economic/queue/monitor', function () { $this->get('/collected-invoices/economic/queue/monitor', function () {
global $response; global $response;
self::requirePermission('add_collected_invoice_economic'); $this->requirePermission('add_collected_invoice_economic');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -1129,7 +1129,7 @@ class orderInvoicesRoute
$this->post('/collected-invoices/economic/queue/retry', function () { $this->post('/collected-invoices/economic/queue/retry', function () {
global $response; global $response;
self::requirePermission('add_collected_invoice_economic'); $this->requirePermission('add_collected_invoice_economic');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -1163,7 +1163,7 @@ class orderInvoicesRoute
$this->post('/collected-invoices/economic/queue/dismiss', function () { $this->post('/collected-invoices/economic/queue/dismiss', function () {
global $response; global $response;
self::requirePermission('add_collected_invoice_economic'); $this->requirePermission('add_collected_invoice_economic');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -1199,7 +1199,7 @@ class orderInvoicesRoute
$this->post('/collected-invoices/economic/queue/dismiss-terminal', function () { $this->post('/collected-invoices/economic/queue/dismiss-terminal', function () {
global $response; global $response;
self::requirePermission('add_collected_invoice_economic'); $this->requirePermission('add_collected_invoice_economic');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -1224,7 +1224,7 @@ class orderInvoicesRoute
$this->post('/collected-invoices/economic/queue/run', function () { $this->post('/collected-invoices/economic/queue/run', function () {
global $response; global $response;
self::requirePermission('add_collected_invoice_economic'); $this->requirePermission('add_collected_invoice_economic');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -1266,7 +1266,7 @@ class orderInvoicesRoute
/** Collected order invoices > Move multiple > Registration numbers > POST */ /** Collected order invoices > Move multiple > Registration numbers > POST */
$this->post('/collected-invoices/move-multiple/registration-numbers', function () { $this->post('/collected-invoices/move-multiple/registration-numbers', function () {
global $response; global $response;
self::requirePermission('move_collected_invoice'); $this->requirePermission('move_collected_invoice');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -1341,7 +1341,7 @@ class orderInvoicesRoute
$this->post('/collected-invoices/move-multiple', function () { $this->post('/collected-invoices/move-multiple', function () {
// Used to move multiple orders, to a new collected order invoice, in one request, instead of having to move each order one by one // Used to move multiple orders, to a new collected order invoice, in one request, instead of having to move each order one by one
global $response; global $response;
self::requirePermission('move_collected_invoice'); $this->requirePermission('move_collected_invoice');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
@@ -1403,7 +1403,7 @@ class orderInvoicesRoute
/** Collected order invoices > E-Conomic > Unlink and clear cached data > POST */ /** Collected order invoices > E-Conomic > Unlink and clear cached data > POST */
$this->post('/collected-invoices/economic/unlink', function () { $this->post('/collected-invoices/economic/unlink', function () {
global $response; global $response;
self::requirePermission('unlink_collected_invoice_economic'); $this->requirePermission('unlink_collected_invoice_economic');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'UNLINK_COLLECTED_INVOICE_ECONOMIC', 'User unlinked a collected order invoice from E-Conomic'); (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'UNLINK_COLLECTED_INVOICE_ECONOMIC', 'User unlinked a collected order invoice from E-Conomic');
@@ -1434,7 +1434,7 @@ class orderInvoicesRoute
/** Collected order invoices > E-Conomic > Remove special arrangements, and set all items to be included in the invoice > POST */ /** Collected order invoices > E-Conomic > Remove special arrangements, and set all items to be included in the invoice > POST */
$this->post('/collected-invoices/remove-special-arrangements', function () { $this->post('/collected-invoices/remove-special-arrangements', function () {
global $response; global $response;
self::requirePermission('reset_collected_invoice_economic'); $this->requirePermission('reset_collected_invoice_economic');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'RESET_COLLECTED_INVOICE_ECONOMIC', 'User reset a collected order invoice in E-Conomic'); (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'RESET_COLLECTED_INVOICE_ECONOMIC', 'User reset a collected order invoice in E-Conomic');
@@ -1467,7 +1467,7 @@ class orderInvoicesRoute
/** Collected order invoices > E-Conomic > Reset prices of items not included in the invoice > POST */ /** Collected order invoices > E-Conomic > Reset prices of items not included in the invoice > POST */
$this->post('/collected-invoices/reset-prices-of-items-not-included-in-invoice', function () { $this->post('/collected-invoices/reset-prices-of-items-not-included-in-invoice', function () {
global $response; global $response;
self::requirePermission('reset_collected_invoice_economic'); $this->requirePermission('reset_collected_invoice_economic');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'RESET_COLLECTED_INVOICE_ECONOMIC', 'User reset a collected order invoice in E-Conomic'); (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'RESET_COLLECTED_INVOICE_ECONOMIC', 'User reset a collected order invoice in E-Conomic');
@@ -1499,7 +1499,7 @@ class orderInvoicesRoute
/** Collected order invoices > Stripe > BOOK > POST */ /** Collected order invoices > Stripe > BOOK > POST */
$this->post('/collected-invoices/stripe/book', function () { $this->post('/collected-invoices/stripe/book', function () {
global $response; global $response;
self::requirePermission('add_collected_invoice_stripe'); $this->requirePermission('add_collected_invoice_stripe');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'ADD_COLLECTED_INVOICE_STRIPE', 'User added a collected order invoice to Stripe'); (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'ADD_COLLECTED_INVOICE_STRIPE', 'User added a collected order invoice to Stripe');
@@ -1581,7 +1581,7 @@ class orderInvoicesRoute
/** Collected order invoices > Vehicle subscriptions > POST */ /** Collected order invoices > Vehicle subscriptions > POST */
$this->post('/collected-invoices/vehicle-subscriptions', function () { $this->post('/collected-invoices/vehicle-subscriptions', function () {
global $response; global $response;
self::requirePermission('add_collected_invoice_vehicle_subscriptions'); $this->requirePermission('add_collected_invoice_vehicle_subscriptions');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'ADD_COLLECTED_INVOICE_VEHICLE_SUBSCRIPTIONS', 'User added a collected order invoice for vehicle subscriptions'); (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'ADD_COLLECTED_INVOICE_VEHICLE_SUBSCRIPTIONS', 'User added a collected order invoice for vehicle subscriptions');
@@ -1612,7 +1612,7 @@ class orderInvoicesRoute
/** Collected order invoices > Vehicle subscriptions > POST */ /** Collected order invoices > Vehicle subscriptions > POST */
$this->post('/collected-invoices/fixed-price', function () { $this->post('/collected-invoices/fixed-price', function () {
global $response; global $response;
self::requirePermission('add_collected_invoice_fixed_price'); $this->requirePermission('add_collected_invoice_fixed_price');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'ADD_COLLECTED_INVOICE_FIXED_PRICE', 'User added a collected order invoice fixed price modifications'); (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'ADD_COLLECTED_INVOICE_FIXED_PRICE', 'User added a collected order invoice fixed price modifications');
@@ -1652,7 +1652,7 @@ class orderInvoicesRoute
/** Collected order invoices > Vehicle subscriptions > POST */ /** Collected order invoices > Vehicle subscriptions > POST */
$this->post('/collected-invoices/vehicle-subscriptions/custom', function () { $this->post('/collected-invoices/vehicle-subscriptions/custom', function () {
global $response; global $response;
self::requirePermission('add_collected_invoice_vehicle_subscriptions'); $this->requirePermission('add_collected_invoice_vehicle_subscriptions');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'ADD_COLLECTED_INVOICE_VEHICLE_SUBSCRIPTIONS', 'User added a collected order invoice for vehicle subscriptions'); (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'ADD_COLLECTED_INVOICE_VEHICLE_SUBSCRIPTIONS', 'User added a collected order invoice for vehicle subscriptions');
@@ -1718,7 +1718,7 @@ class orderInvoicesRoute
/** Collected order invoices > Open > GET Customers */ /** Collected order invoices > Open > GET Customers */
$this->get('/collected-invoices/customers', function () { $this->get('/collected-invoices/customers', function () {
global $response; global $response;
self::requirePermission('list_collected_invoices'); $this->requirePermission('list_collected_invoices');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'LIST_COLLECTED_INVOICES_CUSTOMERS', 'User accessed the list of collected order invoices customers'); (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'LIST_COLLECTED_INVOICES_CUSTOMERS', 'User accessed the list of collected order invoices customers');
@@ -1800,7 +1800,7 @@ class orderInvoicesRoute
$this->get('/collected-invoices/customers/invoicePerOrder', function () { $this->get('/collected-invoices/customers/invoicePerOrder', function () {
global $response; global $response;
self::requirePermission('list_collected_invoices'); $this->requirePermission('list_collected_invoices');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'LIST_COLLECTED_INVOICES_CUSTOMERS_INVOICE_PER_ORDER', 'User accessed the list of collected order invoices customers with invoice per order'); (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'LIST_COLLECTED_INVOICES_CUSTOMERS_INVOICE_PER_ORDER', 'User accessed the list of collected order invoices customers with invoice per order');
@@ -1843,7 +1843,7 @@ class orderInvoicesRoute
$this->get('/collected-invoices/customers/invoicePerMonth', function () { $this->get('/collected-invoices/customers/invoicePerMonth', function () {
global $response; global $response;
self::requirePermission('list_collected_invoices'); $this->requirePermission('list_collected_invoices');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'LIST_COLLECTED_INVOICES_CUSTOMERS_INVOICE_PER_MONTH', 'User accessed the list of collected order invoices customers with invoice per month'); (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'LIST_COLLECTED_INVOICES_CUSTOMERS_INVOICE_PER_MONTH', 'User accessed the list of collected order invoices customers with invoice per month');
@@ -1888,7 +1888,7 @@ class orderInvoicesRoute
$this->post('/collected-invoices/customers/invoiceTotals', function () { $this->post('/collected-invoices/customers/invoiceTotals', function () {
// This is a superuser-only route // This is a superuser-only route
global $response; global $response;
self::requirePermission('list_collected_invoices'); $this->requirePermission('list_collected_invoices');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'LIST_COLLECTED_INVOICES_CUSTOMERS_INVOICE_TOTALS', 'User accessed the list of collected order invoices customers with invoice totals'); (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'LIST_COLLECTED_INVOICES_CUSTOMERS_INVOICE_TOTALS', 'User accessed the list of collected order invoices customers with invoice totals');
@@ -1974,7 +1974,7 @@ class orderInvoicesRoute
$this->get('/collected-invoices/economic/overview', function () { $this->get('/collected-invoices/economic/overview', function () {
global $response; global $response;
self::requirePermission('list_collected_invoices_economic_overview'); $this->requirePermission('list_collected_invoices_economic_overview');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
// Get the economic module // Get the economic module
@@ -2055,7 +2055,7 @@ class orderInvoicesRoute
$this->post('/collected-invoices/economic/run/check-drafts', function () { $this->post('/collected-invoices/economic/run/check-drafts', function () {
global $response; global $response;
self::requirePermission('module_economic_run_check_drafts'); $this->requirePermission('module_economic_run_check_drafts');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'RUN_CHECK_DRAFTS', 'User ran the check drafts'); (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'RUN_CHECK_DRAFTS', 'User ran the check drafts');
@@ -2083,7 +2083,7 @@ class orderInvoicesRoute
$this->post('/collected-invoices/economic/run/check-errors', function () { $this->post('/collected-invoices/economic/run/check-errors', function () {
global $response; global $response;
self::requirePermission('module_economic_run_check_errors'); $this->requirePermission('module_economic_run_check_errors');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'RUN_CHECK_ERRORS', 'User ran the check errors'); (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'RUN_CHECK_ERRORS', 'User ran the check errors');
@@ -2871,7 +2871,7 @@ class orderInvoicesRoute
default => throw new Exception('Invalid invoice collection bulk action.'), default => throw new Exception('Invalid invoice collection bulk action.'),
}; };
self::requirePermission($permission); $this->requirePermission($permission);
} }
/** /**
+9 -9
View File
@@ -94,7 +94,7 @@ class ordersRoute
/** Permissions (subuser-aware) */ /** Permissions (subuser-aware) */
$permission_own = self::definePermission('list_own_orders', subusers_permission_node_key::ORDERS_LIST); $permission_own = self::definePermission('list_own_orders', subusers_permission_node_key::ORDERS_LIST);
$permission_other = self::definePermission('list_orders'); $permission_other = self::definePermission('list_orders');
$has_permission_other = self::hasPermission($permission_other); $has_permission_other = $this->hasPermission($permission_other);
$targetCustomerNumber = self::resolveEffectiveCustomerNumber(); $targetCustomerNumber = self::resolveEffectiveCustomerNumber();
self::allowOwnOrDepartmentAccess( self::allowOwnOrDepartmentAccess(
$permission_own, $permission_own,
@@ -428,9 +428,9 @@ class ordersRoute
// Permissions (subuser-aware) // Permissions (subuser-aware)
$permission_own = self::definePermission('list_own_order_attachments', subusers_permission_node_key::ORDERS_LIST); $permission_own = self::definePermission('list_own_order_attachments', subusers_permission_node_key::ORDERS_LIST);
$permission_other = self::definePermission('list_order_attachments'); $permission_other = self::definePermission('list_order_attachments');
$has_permission_other = self::hasPermission($permission_other); $has_permission_other = $this->hasPermission($permission_other);
if (!$has_permission_other) { if (!$has_permission_other) {
self::requirePermission($permission_own); $this->requirePermission($permission_own);
$effectiveCustomer = self::resolveEffectiveCustomerNumber(); $effectiveCustomer = self::resolveEffectiveCustomerNumber();
if ($effectiveCustomer === null || (int)$order->customer_id->value() !== (int)$effectiveCustomer) { if ($effectiveCustomer === null || (int)$order->customer_id->value() !== (int)$effectiveCustomer) {
$response->forbidden([$permission_other->permission]); $response->forbidden([$permission_other->permission]);
@@ -1344,15 +1344,15 @@ class ordersRoute
$user = $auth->get_user(); $user = $auth->get_user();
$permission_own = self::definePermission('edit_own_orders', subusers_permission_node_key::ORDERS_EDIT); $permission_own = self::definePermission('edit_own_orders', subusers_permission_node_key::ORDERS_EDIT);
$permission_other = self::definePermission('edit_order'); $permission_other = self::definePermission('edit_order');
$has_permission_other = self::hasPermission($permission_other); $has_permission_other = $this->hasPermission($permission_other);
// Classic user own-edit path (legacy behaviour) // Classic user own-edit path (legacy behaviour)
$classic_own_path = ($user !== false && $user->hasPermission('user') && !$has_permission_other); $classic_own_path = ($user !== false && $user->hasPermission('user') && !$has_permission_other);
// Subuser own-edit path via node ORDERS_EDIT // Subuser own-edit path via node ORDERS_EDIT
$subuser_own_path = (!$has_permission_other && self::hasPermission($permission_own)); $subuser_own_path = (!$has_permission_other && $this->hasPermission($permission_own));
$isOwnPath = $classic_own_path || $subuser_own_path; $isOwnPath = $classic_own_path || $subuser_own_path;
if (!$isOwnPath && !$has_permission_other) { if (!$isOwnPath && !$has_permission_other) {
// Neither own nor admin permission — deny via admin requirement to unify error shape // Neither own nor admin permission — deny via admin requirement to unify error shape
self::requirePermission($permission_other); $this->requirePermission($permission_other);
} }
// Check if the request was successful // Check if the request was successful
if ($user) { if ($user) {
@@ -1450,7 +1450,7 @@ class ordersRoute
$response->success($order->asArray()); $response->success($order->asArray());
} }
// Admin/department path (requires edit_order) // Admin/department path (requires edit_order)
self::requirePermission($permission_other); $this->requirePermission($permission_other);
/** Departmental access — user must have access to the order's current department */ /** Departmental access — user must have access to the order's current department */
self::requireDepartmentAccess((string)(int)$order->department_id->value()); self::requireDepartmentAccess((string)(int)$order->department_id->value());
$originalCustomerNumber = (int)$order->customer_id->value(); $originalCustomerNumber = (int)$order->customer_id->value();
@@ -1999,9 +1999,9 @@ class ordersRoute
$permissionOwn = self::definePermission('download_order_attachments_own', subusers_permission_node_key::ORDERS_LIST); $permissionOwn = self::definePermission('download_order_attachments_own', subusers_permission_node_key::ORDERS_LIST);
$permissionOther = self::definePermission('download_order_attachments'); $permissionOther = self::definePermission('download_order_attachments');
$hasPermissionOther = self::hasPermission($permissionOther); $hasPermissionOther = $this->hasPermission($permissionOther);
if (!$hasPermissionOther) { if (!$hasPermissionOther) {
self::requirePermission($permissionOwn); $this->requirePermission($permissionOwn);
} }
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
+1 -1
View File
@@ -28,7 +28,7 @@ class passkeysRoute
]; ];
} }
self::requirePermission($classicUserPermission); $this->requirePermission($classicUserPermission);
$user = $auth->get_user(); $user = $auth->get_user();
if (!$user) { if (!$user) {
(new logs_o())->add('user_security', 'global', 0, 0, 'USER_SECURITY_PASSKEYS_AUTH', 'User not logged in'); (new logs_o())->add('user_security', 'global', 0, 0, 'USER_SECURITY_PASSKEYS_AUTH', 'User not logged in');
@@ -40,7 +40,7 @@ class permissionsRoute
/** Permissions > User > List */ /** Permissions > User > List */
self::get('/user/permissions', function () { self::get('/user/permissions', function () {
global $response; global $response;
self::requirePermission('permissions_list_own'); $this->requirePermission('permissions_list_own');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('permissions', 'global', 1, 0, 'PERMISSIONS', 'User accessed the user permissions list'); (new logs_o())->add('permissions', 'global', 1, 0, 'PERMISSIONS', 'User accessed the user permissions list');
@@ -183,7 +183,7 @@ class plateScannersRoute
self::get('/department/numberplatescanners', function () { self::get('/department/numberplatescanners', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('list_department_number_plate_scanners'); $this->requirePermission('list_department_number_plate_scanners');
// Get the user object // Get the user object
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
// Check if the request was successful // Check if the request was successful
@@ -16,9 +16,9 @@ class potentialOrderMatchesRoute
$this->get('/orders/sync/potential-matches', function () { $this->get('/orders/sync/potential-matches', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('list_potential_order_matches'); $this->requirePermission('list_potential_order_matches');
// Check if the user has permission to list all potential order matches // Check if the user has permission to list all potential order matches
if (self::hasPermission('list_all_potential_order_matches')) { if ($this->hasPermission('list_all_potential_order_matches')) {
$this->requirePermission('list_all_potential_order_matches'); $this->requirePermission('list_all_potential_order_matches');
} else { } else {
$this->requirePermission('list_own_potential_order_matches'); $this->requirePermission('list_own_potential_order_matches');
@@ -85,7 +85,7 @@ class potentialOrderMatchesRoute
$this->post('/orders/sync/potential-matches/ignore-duplicate', function () { $this->post('/orders/sync/potential-matches/ignore-duplicate', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('ignore_duplicate_potential_order_matches'); $this->requirePermission('ignore_duplicate_potential_order_matches');
// Get the user object // Get the user object
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
// Check if the request was successful // Check if the request was successful
+2 -2
View File
@@ -215,9 +215,9 @@ class productsRoute
$subuser = $auth->get_subuser(); $subuser = $auth->get_subuser();
$hasAuthenticatedUser = $user !== false && $user !== null; $hasAuthenticatedUser = $user !== false && $user !== null;
$isSubuserSession = $subuser !== false; $isSubuserSession = $subuser !== false;
$hasCustomerPermission = $hasAuthenticatedUser ? self::hasPermission('user') : false; $hasCustomerPermission = $hasAuthenticatedUser ? $this->hasPermission('user') : false;
$isCustomerBookingSession = $this->isCustomerBookingSession($hasAuthenticatedUser, $hasCustomerPermission, $isSubuserSession); $isCustomerBookingSession = $this->isCustomerBookingSession($hasAuthenticatedUser, $hasCustomerPermission, $isSubuserSession);
$hasListProductsPermission = $hasAuthenticatedUser ? self::hasPermission($permission_node) : false; $hasListProductsPermission = $hasAuthenticatedUser ? $this->hasPermission($permission_node) : false;
if ($hasAuthenticatedUser || $isSubuserSession) { if ($hasAuthenticatedUser || $isSubuserSession) {
$isProductDetailsRestricted = false; $isProductDetailsRestricted = false;
if (!$this->canReadProductList($isCustomerBookingSession, $hasListProductsPermission)) { if (!$this->canReadProductList($isCustomerBookingSession, $hasListProductsPermission)) {
+8 -8
View File
@@ -17,7 +17,7 @@ class rolesRoute
self::get('/roles', function () { self::get('/roles', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('list_roles'); $this->requirePermission('list_roles');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('roles', 'global', 1, 0, 'ROLES', 'User accessed the roles list'); (new logs_o())->add('roles', 'global', 1, 0, 'ROLES', 'User accessed the roles list');
@@ -54,7 +54,7 @@ class rolesRoute
self::post('/roles', function () { self::post('/roles', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('add_role'); $this->requirePermission('add_role');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('roles', 'global', 1, 0, 'ROLES', 'User added a role'); (new logs_o())->add('roles', 'global', 1, 0, 'ROLES', 'User added a role');
@@ -80,7 +80,7 @@ class rolesRoute
self::put('/roles', function () { self::put('/roles', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('edit_role'); $this->requirePermission('edit_role');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
self::requireParameters(['id']); self::requireParameters(['id']);
@@ -109,8 +109,8 @@ class rolesRoute
self::get('/roles/limited-backoffice-permission-templates', function () { self::get('/roles/limited-backoffice-permission-templates', function () {
global $response; global $response;
self::requirePermission('superuser'); $this->requirePermission('superuser');
self::requirePermission('add_role_permission'); $this->requirePermission('add_role_permission');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
(new logs_o())->add('roles', 'global', 1, $user->id, 'ROLES', 'User accessed limited backoffice role permission templates'); (new logs_o())->add('roles', 'global', 1, $user->id, 'ROLES', 'User accessed limited backoffice role permission templates');
@@ -129,7 +129,7 @@ class rolesRoute
self::post('/roles/permissions', function () { self::post('/roles/permissions', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('add_role_permission'); $this->requirePermission('add_role_permission');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
self::requireParameters(['group_id', 'permission_id']); self::requireParameters(['group_id', 'permission_id']);
@@ -154,7 +154,7 @@ class rolesRoute
self::delete('/roles/permissions', function () { self::delete('/roles/permissions', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('delete_role_permission'); $this->requirePermission('delete_role_permission');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
self::requireParameters(['group_id', 'permission_id']); self::requireParameters(['group_id', 'permission_id']);
@@ -181,7 +181,7 @@ class rolesRoute
self::post('/roles/clone', function () { self::post('/roles/clone', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('clone_role'); $this->requirePermission('clone_role');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if ($user) { if ($user) {
self::requireParameters(['id']); self::requireParameters(['id']);
+14 -14
View File
@@ -77,7 +77,7 @@ class subusersRoute
if ($targetCustomerNumber !== null && $customerNumber !== (int)$targetCustomerNumber) { if ($targetCustomerNumber !== null && $customerNumber !== (int)$targetCustomerNumber) {
$this->emitForbidden([$permission]); $this->emitForbidden([$permission]);
} }
self::requirePermission($permission); $this->requirePermission($permission);
return $customerNumber; return $customerNumber;
} }
@@ -90,7 +90,7 @@ class subusersRoute
if ($targetCustomerNumber !== null && $customerNumber !== (int)$targetCustomerNumber) { if ($targetCustomerNumber !== null && $customerNumber !== (int)$targetCustomerNumber) {
$this->emitForbidden([$permission]); $this->emitForbidden([$permission]);
} }
self::requirePermission($permission); $this->requirePermission($permission);
return $customerNumber; return $customerNumber;
} }
@@ -1910,7 +1910,7 @@ class subusersRoute
/** Permissions (subuser-aware) */ /** Permissions (subuser-aware) */
$permission_own = self::definePermission('list_own_subuser_grants', subusers_permission_node_key::SUBUSERS_LIST); $permission_own = self::definePermission('list_own_subuser_grants', subusers_permission_node_key::SUBUSERS_LIST);
$permission_other = self::definePermission('list_subuser_grants'); $permission_other = self::definePermission('list_subuser_grants');
$has_permission_other = self::hasPermission($permission_other); $has_permission_other = $this->hasPermission($permission_other);
// Optional filters: customer_number, subuser_id // Optional filters: customer_number, subuser_id
$filters = ['deleted_at' => null]; $filters = ['deleted_at' => null];
@@ -2000,7 +2000,7 @@ class subusersRoute
self::requireType($subuser_id, self::type_int()); self::requireType($subuser_id, self::type_int());
$this->rejectBlockedSubuser($subuser_id); $this->rejectBlockedSubuser($subuser_id);
if (!self::hasPermission($permission_other, (int)$customer_number)) { if (!$this->hasPermission($permission_other, (int)$customer_number)) {
$this->requireManagedCustomerScope(subusers_permission_node_key::SUBUSERS_ADD, (int)$customer_number); $this->requireManagedCustomerScope(subusers_permission_node_key::SUBUSERS_ADD, (int)$customer_number);
} }
@@ -2061,13 +2061,13 @@ class subusersRoute
$this->rejectBlockedSubuser((int)$grant->subuser->value()); $this->rejectBlockedSubuser((int)$grant->subuser->value());
$targetCustomer = (int)$grant->billing_customer_number->value(); $targetCustomer = (int)$grant->billing_customer_number->value();
if (!self::hasPermission($permission_other, $targetCustomer)) { if (!$this->hasPermission($permission_other, $targetCustomer)) {
$this->requireManagedCustomerScope(subusers_permission_node_key::SUBUSERS_EDIT, $targetCustomer); $this->requireManagedCustomerScope(subusers_permission_node_key::SUBUSERS_EDIT, $targetCustomer);
} }
if (self::isParametersSet(['enabled'])) { if (self::isParametersSet(['enabled'])) {
$enabledPreview = filter_var(self::getParameter('enabled'), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); $enabledPreview = filter_var(self::getParameter('enabled'), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
if ($enabledPreview === false && !self::hasPermission($permission_other)) { if ($enabledPreview === false && !$this->hasPermission($permission_other)) {
$this->requireManagedCustomerScope(subusers_permission_node_key::SUBUSERS_DELETE, $targetCustomer); $this->requireManagedCustomerScope(subusers_permission_node_key::SUBUSERS_DELETE, $targetCustomer);
} }
} }
@@ -2121,10 +2121,10 @@ class subusersRoute
$this->get('/subusers/permission-nodes', function () { $this->get('/subusers/permission-nodes', function () {
global $response; global $response;
$canUseGlobalManagement = self::hasPermission('manage_subuser_grants') $canUseGlobalManagement = $this->hasPermission('manage_subuser_grants')
|| self::hasPermission('list_subusers') || $this->hasPermission('list_subusers')
|| self::hasPermission('add_subusers') || $this->hasPermission('add_subusers')
|| self::hasPermission('edit_subusers'); || $this->hasPermission('edit_subusers');
if (!$canUseGlobalManagement) { if (!$canUseGlobalManagement) {
$this->requireManagedCustomerScope(subusers_permission_node_key::SUBUSERS_LIST); $this->requireManagedCustomerScope(subusers_permission_node_key::SUBUSERS_LIST);
} }
@@ -2166,10 +2166,10 @@ class subusersRoute
$this->get('/subusers/permission-templates', function () { $this->get('/subusers/permission-templates', function () {
global $response; global $response;
$canUseGlobalManagement = self::hasPermission('manage_subuser_grants') $canUseGlobalManagement = $this->hasPermission('manage_subuser_grants')
|| self::hasPermission('list_subusers') || $this->hasPermission('list_subusers')
|| self::hasPermission('add_subusers') || $this->hasPermission('add_subusers')
|| self::hasPermission('edit_subusers'); || $this->hasPermission('edit_subusers');
if (!$canUseGlobalManagement) { if (!$canUseGlobalManagement) {
$this->requireManagedCustomerScope(subusers_permission_node_key::SUBUSERS_LIST); $this->requireManagedCustomerScope(subusers_permission_node_key::SUBUSERS_LIST);
} }
@@ -16,7 +16,7 @@ class userInvoicesRoute
$this->get('/user/invoices', function () { $this->get('/user/invoices', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('user_invoices'); $this->requirePermission('user_invoices');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
(new logs_o())->add('user_invoices', 'global', 0, 0, 'USER_INVOICES', 'User not logged in'); (new logs_o())->add('user_invoices', 'global', 0, 0, 'USER_INVOICES', 'User not logged in');
@@ -48,7 +48,7 @@ class userInvoicesRoute
$this->put('/collected-invoices', function () { $this->put('/collected-invoices', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('user_invoices'); $this->requirePermission('user_invoices');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
(new logs_o())->add('user_invoices', 'global', 0, 0, 'USER_INVOICES', 'User not logged in'); (new logs_o())->add('user_invoices', 'global', 0, 0, 'USER_INVOICES', 'User not logged in');
@@ -60,7 +60,7 @@ class userInvoicesRoute
// Make sure the id is valid // Make sure the id is valid
self::requireMinValue($id, 1); self::requireMinValue($id, 1);
self::requireSameLength($id, self::getParameter('id')); self::requireSameLength($id, self::getParameter('id'));
$is_superuser = self::hasPermission('superuser'); $is_superuser = $this->hasPermission('superuser');
if (!self::isParametersSet(['po_number']) && !self::isParametersSet(['closed_at'])) { if (!self::isParametersSet(['po_number']) && !self::isParametersSet(['closed_at'])) {
$response->error('Missing required parameters: po_number, closed_at', 400); $response->error('Missing required parameters: po_number, closed_at', 400);
} }
@@ -17,7 +17,7 @@ class userNotificationsRoute
$this->put('/account/notifications', function () { $this->put('/account/notifications', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('user_notifications_update'); $this->requirePermission('user_notifications_update');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
(new logs_o())->add('user_notifications', 'global', 0, 0, 'USER_NOTIFICATIONS_UPDATE', 'User not logged in'); (new logs_o())->add('user_notifications', 'global', 0, 0, 'USER_NOTIFICATIONS_UPDATE', 'User not logged in');
@@ -63,7 +63,7 @@ class userNotificationsRoute
* Superuser New Customer Email Notifications Enabled * Superuser New Customer Email Notifications Enabled
*/ */
if ($superuser_new_customer_email_notifications_enabled !== null) { if ($superuser_new_customer_email_notifications_enabled !== null) {
self::requirePermission('superuser'); $this->requirePermission('superuser');
self::requireType($superuser_new_customer_email_notifications_enabled, self::type_bool()); self::requireType($superuser_new_customer_email_notifications_enabled, self::type_bool());
$user->setSuperuserNewCustomerEmailNotificationsEnabled($superuser_new_customer_email_notifications_enabled); $user->setSuperuserNewCustomerEmailNotificationsEnabled($superuser_new_customer_email_notifications_enabled);
} }
@@ -16,7 +16,7 @@ class userSecurityRoute
$this->post('/account/security/change-email', function () { $this->post('/account/security/change-email', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('user_security_change_email'); $this->requirePermission('user_security_change_email');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
(new logs_o())->add('user_security', 'global', 0, 0, 'USER_SECURITY_CHANGE_EMAIL', 'User not logged in'); (new logs_o())->add('user_security', 'global', 0, 0, 'USER_SECURITY_CHANGE_EMAIL', 'User not logged in');
@@ -73,7 +73,7 @@ class userSecurityRoute
$this->post('/account/security/validate-password', function () { $this->post('/account/security/validate-password', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('user_security_validate_password'); $this->requirePermission('user_security_validate_password');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
(new logs_o())->add('user_security', 'global', 0, 0, 'USER_SECURITY_VALIDATE_PASSWORD', 'User not logged in'); (new logs_o())->add('user_security', 'global', 0, 0, 'USER_SECURITY_VALIDATE_PASSWORD', 'User not logged in');
@@ -102,7 +102,7 @@ class userSecurityRoute
$this->post('/account/security/change-password', function () { $this->post('/account/security/change-password', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('user_security_change_password'); $this->requirePermission('user_security_change_password');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
(new logs_o())->add('user_security', 'global', 0, 0, 'USER_SECURITY_CHANGE_PASSWORD', 'User not logged in'); (new logs_o())->add('user_security', 'global', 0, 0, 'USER_SECURITY_CHANGE_PASSWORD', 'User not logged in');
@@ -142,7 +142,7 @@ class userSecurityRoute
$this->post('/account/security/change-phone-number', function () { $this->post('/account/security/change-phone-number', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('user_security_change_phone_number'); $this->requirePermission('user_security_change_phone_number');
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
if (!$user) { if (!$user) {
(new logs_o())->add('user_security', 'global', 0, 0, 'USER_SECURITY_CHANGE_PHONE_NUMBER', 'User not logged in'); (new logs_o())->add('user_security', 'global', 0, 0, 'USER_SECURITY_CHANGE_PHONE_NUMBER', 'User not logged in');
@@ -50,7 +50,7 @@ class vehiclePlateLookupRoute
$this->get('/department/license-plate/customer-lookup', function () { $this->get('/department/license-plate/customer-lookup', function () {
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
self::requirePermission('department_license_plate_lookup'); $this->requirePermission('department_license_plate_lookup');
// Get the user object // Get the user object
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
// Check if the request was successful // Check if the request was successful
+1 -1
View File
@@ -352,7 +352,7 @@ class vehiclesRoute
// Define permissions with subuser node linkage // Define permissions with subuser node linkage
$permission_own = self::definePermission('list_own_vehicles', subusers_permission_node_key::VEHICLES_LIST); $permission_own = self::definePermission('list_own_vehicles', subusers_permission_node_key::VEHICLES_LIST);
$permission_other = self::definePermission('list_vehicles_other'); $permission_other = self::definePermission('list_vehicles_other');
$has_permission_other = self::hasPermission($permission_other); $has_permission_other = $this->hasPermission($permission_other);
// If a specific ID is requested, validate access against that vehicle's customer context // If a specific ID is requested, validate access against that vehicle's customer context
if ($this->isParametersSet(['id'])) { if ($this->isParametersSet(['id'])) {
+3 -3
View File
@@ -33,7 +33,7 @@ class workerRoute
$this->get('/worker/update-version', function () { $this->get('/worker/update-version', function () {
global /** @var router $router */ global /** @var router $router */
$response, $router; $response, $router;
self::requirePermission('worker_update_version'); $this->requirePermission('worker_update_version');
self::requireParameters(['version']); self::requireParameters(['version']);
$version = (string)self::getParameter('version'); $version = (string)self::getParameter('version');
redis->set('worker_target_version', $version); redis->set('worker_target_version', $version);
@@ -89,7 +89,7 @@ class workerRoute
}); });
$this->get('/economic/doesCustomerExist', function () { $this->get('/economic/doesCustomerExist', function () {
global $response; global $response;
self::requirePermission( 'economic_does_customer_exist'); // TODO: Remove this $this->requirePermission( 'economic_does_customer_exist'); // TODO: Remove this
self::requireParameters(['cvr']); self::requireParameters(['cvr']);
$cvr = self::getParameter('cvr'); $cvr = self::getParameter('cvr');
// Check if the customer exists in E-conomic. // Check if the customer exists in E-conomic.
@@ -110,7 +110,7 @@ class workerRoute
}); });
$this->get('/cvr/lookup', function () { $this->get('/cvr/lookup', function () {
global $response; global $response;
self::requirePermission('cvr_lookup'); // TODO: Remove this $this->requirePermission('cvr_lookup'); // TODO: Remove this
self::requireParameters(['cvr']); self::requireParameters(['cvr']);
$cvr = self::getParameter('cvr'); $cvr = self::getParameter('cvr');
if (!is_numeric($cvr)) { if (!is_numeric($cvr)) {
@@ -36,14 +36,14 @@ class xlvaskUsageLogsRoute
$response_includes_items = false; // Whether to include items in the response (This would increase the memory usage significantly) $response_includes_items = false; // Whether to include items in the response (This would increase the memory usage significantly)
// Require the user to be logged in // Require the user to be logged in
global $response; global $response;
if (!self::hasPermission($permission_list_all)) { if (!$this->hasPermission($permission_list_all)) {
$this->requirePermission($permission_list_own); $this->requirePermission($permission_list_own);
} }
// Get the user object // Get the user object
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
// Check if the request was successful // Check if the request was successful
if ($user) { if ($user) {
$allowedHallIds = self::allowedHallIdsForUser($user); $allowedHallIds = $this->allowedHallIdsForUser($user);
if ($allowedHallIds === []) { if ($allowedHallIds === []) {
$response->error('No XL Vask hall scope is available', 403); $response->error('No XL Vask hall scope is available', 403);
return; return;
@@ -163,7 +163,7 @@ class xlvaskUsageLogsRoute
$this->get('/modules/xlvask/services/usage/orders/summary', function () { $this->get('/modules/xlvask/services/usage/orders/summary', function () {
global $response; global $response;
if (!self::hasPermission('list_xlvask_usage_orders_all')) { if (!$this->hasPermission('list_xlvask_usage_orders_all')) {
$this->requirePermission('list_xlvask_usage_orders_own'); $this->requirePermission('list_xlvask_usage_orders_own');
} }
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
@@ -177,7 +177,7 @@ class xlvaskUsageLogsRoute
'summary' => (new xlvask_autopilot_service())->getSummary( 'summary' => (new xlvask_autopilot_service())->getSummary(
$dateFrom, $dateFrom,
$dateTo, $dateTo,
self::allowedHallIdsForUser($user) $this->allowedHallIdsForUser($user)
), ),
]); ]);
}, },
@@ -207,7 +207,7 @@ class xlvaskUsageLogsRoute
'run' => (new xlvask_autopilot_service())->createRun( 'run' => (new xlvask_autopilot_service())->createRun(
$input, $input,
(int)$user->id, (int)$user->id,
self::allowedHallIdsForUser($user) $this->allowedHallIdsForUser($user)
), ),
], 202); ], 202);
}, },
@@ -228,7 +228,7 @@ class xlvaskUsageLogsRoute
$response->success((new xlvask_automation_policy_service())->readinessReadOnly( $response->success((new xlvask_automation_policy_service())->readinessReadOnly(
$dateFrom, $dateFrom,
$dateTo, $dateTo,
self::allowedHallIdsForUser($user) $this->allowedHallIdsForUser($user)
)); ));
}, [ }, [
'superuser_xlvask_automation_activate' => 'Inspect XL Vask automation activation readiness', 'superuser_xlvask_automation_activate' => 'Inspect XL Vask automation activation readiness',
@@ -236,8 +236,8 @@ class xlvaskUsageLogsRoute
$this->get('/modules/xlvask/services/usage/automation/capabilities', function () { $this->get('/modules/xlvask/services/usage/automation/capabilities', function () {
global $response; global $response;
if (!self::hasPermission('list_xlvask_usage_orders_all') if (!$this->hasPermission('list_xlvask_usage_orders_all')
&& !self::hasPermission('list_xlvask_usage_orders_own')) { && !$this->hasPermission('list_xlvask_usage_orders_own')) {
$this->requirePermission('list_xlvask_usage_orders_own'); $this->requirePermission('list_xlvask_usage_orders_own');
} }
$user = (new authentication())->get_user(); $user = (new authentication())->get_user();
@@ -247,9 +247,9 @@ class xlvaskUsageLogsRoute
$dateFrom = $this->isParametersSet(['dateFrom']) ? trim((string)$this->getParameter('dateFrom')) : null; $dateFrom = $this->isParametersSet(['dateFrom']) ? trim((string)$this->getParameter('dateFrom')) : null;
$dateTo = $this->isParametersSet(['dateTo']) ? trim((string)$this->getParameter('dateTo')) : null; $dateTo = $this->isParametersSet(['dateTo']) ? trim((string)$this->getParameter('dateTo')) : null;
$service = new xlvask_automation_policy_service(); $service = new xlvask_automation_policy_service();
$capabilities = $service->capabilitiesReadOnly($dateFrom, $dateTo, self::allowedHallIdsForUser($user)); $capabilities = $service->capabilitiesReadOnly($dateFrom, $dateTo, $this->allowedHallIdsForUser($user));
$canManage = self::hasPermission('manage_xlvask_usage_automation'); $canManage = $this->hasPermission('manage_xlvask_usage_automation');
$canManagePolicy = self::hasPermission('superuser_xlvask_automation_activate'); $canManagePolicy = $this->hasPermission('superuser_xlvask_automation_activate');
$response->success([ $response->success([
'can_view' => true, 'can_view' => true,
'can_review' => $canManage, 'can_review' => $canManage,
@@ -271,7 +271,7 @@ class xlvaskUsageLogsRoute
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
} }
$response->success(['run' => (new xlvask_automation_policy_service())->activeRunReadOnly( $response->success(['run' => (new xlvask_automation_policy_service())->activeRunReadOnly(
self::allowedHallIdsForUser($user) $this->allowedHallIdsForUser($user)
)]); )]);
}, ['manage_xlvask_usage_automation' => 'Inspect the active XL Vask automation run']); }, ['manage_xlvask_usage_automation' => 'Inspect the active XL Vask automation run']);
@@ -342,7 +342,7 @@ class xlvaskUsageLogsRoute
if (!$user) { if (!$user) {
$response->error('Invalid session', 400); $response->error('Invalid session', 400);
} }
$allowedHallIds = self::allowedHallIdsForUser($user); $allowedHallIds = $this->allowedHallIdsForUser($user);
$result = (new xlvask_autopilot_service())->adjudicateCalibrationLabel( $result = (new xlvask_autopilot_service())->adjudicateCalibrationLabel(
(int)$this->getParameter('suggestion_id'), (int)$this->getParameter('suggestion_id'),
trim((string)$this->getParameter('outcome')), trim((string)$this->getParameter('outcome')),
@@ -402,7 +402,7 @@ class xlvaskUsageLogsRoute
$run = (new xlvask_autopilot_service())->getRun( $run = (new xlvask_autopilot_service())->getRun(
$id, $id,
(int)$user->id, (int)$user->id,
self::allowedHallIdsForUser($user) $this->allowedHallIdsForUser($user)
); );
$response->success(['run' => $run]); $response->success(['run' => $run]);
}, },
@@ -428,7 +428,7 @@ class xlvaskUsageLogsRoute
'preview' => (new xlvask_autopilot_service())->createDecisionPreview( 'preview' => (new xlvask_autopilot_service())->createDecisionPreview(
$input, $input,
(int)$user->id, (int)$user->id,
self::allowedHallIdsForUser($user) $this->allowedHallIdsForUser($user)
), ),
]); ]);
}, ['manage_xlvask_usage_automation' => 'Preview an XL Vask automation decision']); }, ['manage_xlvask_usage_automation' => 'Preview an XL Vask automation decision']);
@@ -450,7 +450,7 @@ class xlvaskUsageLogsRoute
(new xlvask_autopilot_service())->applyDecision( (new xlvask_autopilot_service())->applyDecision(
$input, $input,
(int)$user->id, (int)$user->id,
self::allowedHallIdsForUser($user) $this->allowedHallIdsForUser($user)
) )
); );
}, ['manage_xlvask_usage_automation' => 'Apply a previewed XL Vask automation decision']); }, ['manage_xlvask_usage_automation' => 'Apply a previewed XL Vask automation decision']);
@@ -498,7 +498,7 @@ class xlvaskUsageLogsRoute
if ($id < 1) { if ($id < 1) {
$response->error('Invalid XL Vask usage log id', 400); $response->error('Invalid XL Vask usage log id', 400);
} }
self::requireUsageLogInHallScope($id, self::allowedHallIdsForUser($user)); self::requireUsageLogInHallScope($id, $this->allowedHallIdsForUser($user));
$response->error('Use the server-generated automation decision preview and apply endpoints.', 409); $response->error('Use the server-generated automation decision preview and apply endpoints.', 409);
}, },
@@ -520,7 +520,7 @@ class xlvaskUsageLogsRoute
if ($id < 1) { if ($id < 1) {
$response->error('Invalid XL Vask usage log id', 400); $response->error('Invalid XL Vask usage log id', 400);
} }
self::requireUsageLogInHallScope($id, self::allowedHallIdsForUser($user)); self::requireUsageLogInHallScope($id, $this->allowedHallIdsForUser($user));
$response->error('Use the server-generated automation decision preview and apply endpoints.', 409); $response->error('Use the server-generated automation decision preview and apply endpoints.', 409);
}, },
@@ -555,7 +555,7 @@ class xlvaskUsageLogsRoute
$data = json_decode($cached_data, true); $data = json_decode($cached_data, true);
// Check if the data is valid // Check if the data is valid
if (is_array($data)) { if (is_array($data)) {
$allowedHallIds = self::allowedHallIdsForUser($user); $allowedHallIds = $this->allowedHallIdsForUser($user);
if (!in_array(trim((string)($data['HallId'] ?? '')), $allowedHallIds, true)) { if (!in_array(trim((string)($data['HallId'] ?? '')), $allowedHallIds, true)) {
$response->error('Fast link is outside the current XL Vask hall scope', 403); $response->error('Fast link is outside the current XL Vask hall scope', 403);
} }
@@ -623,10 +623,10 @@ class xlvaskUsageLogsRoute
); );
} }
private static function allowedHallIdsForUser(object $user): array private function allowedHallIdsForUser(object $user): array
{ {
global $db; global $db;
if (self::hasPermission('list_xlvask_usage_orders_all')) { if ($this->hasPermission('list_xlvask_usage_orders_all')) {
$result = $db->query( $result = $db->query(
"SELECT DISTINCT HallId FROM plate_scanners "SELECT DISTINCT HallId FROM plate_scanners
WHERE HallId IS NOT NULL AND TRIM(HallId) <> '' AND deleted_at IS NULL" WHERE HallId IS NOT NULL AND TRIM(HallId) <> '' AND deleted_at IS NULL"
@@ -9,7 +9,7 @@ it('wires the order booking completion confirmation resend endpoint', function (
expect($routeCode) expect($routeCode)
->toContain("$" . "this->post('/order-bookings/completion-confirmation/resend', function () {") ->toContain("$" . "this->post('/order-bookings/completion-confirmation/resend', function () {")
->toContain("self::requirePermission('complete_bookings');") ->toContain("\$this->requirePermission('complete_bookings');")
->toContain('self::requireDepartmentAccess((int)$object->department->value());') ->toContain('self::requireDepartmentAccess((int)$object->department->value());')
->toContain('(new email())->sendWashCertificateEmailToCustomer($object);') ->toContain('(new email())->sendWashCertificateEmailToCustomer($object);')
->toContain("'Completion confirmation resent successfully.'"); ->toContain("'Completion confirmation resent successfully.'");
@@ -6,7 +6,7 @@ it('wires collected invoice customer moves through the dedicated route and permi
expect($routeContent)->not->toBeFalse() expect($routeContent)->not->toBeFalse()
->and($routeContent)->toContain("\$this->post('/collected-invoices/move-to-customer'") ->and($routeContent)->toContain("\$this->post('/collected-invoices/move-to-customer'")
->and($routeContent)->toContain("self::requirePermission('move_collected_invoice_customer')") ->and($routeContent)->toContain("\$this->requirePermission('move_collected_invoice_customer')")
->and($routeContent)->toContain('$collected_order_invoices->moveToCustomer') ->and($routeContent)->toContain('$collected_order_invoices->moveToCustomer')
->and($routeContent)->toContain("\$response->add_meta('move', \$move_result)") ->and($routeContent)->toContain("\$response->add_meta('move', \$move_result)")
->and($objectContent)->not->toBeFalse() ->and($objectContent)->not->toBeFalse()
@@ -7,7 +7,7 @@ it('requires id and at least one mutable field for PUT /collected-invoices in us
expect($content)->not->toBeFalse(); expect($content)->not->toBeFalse();
expect($content)->toContain("\$this->put('/collected-invoices'"); expect($content)->toContain("\$this->put('/collected-invoices'");
expect($content)->toContain("self::requireParameters(['id']);"); expect($content)->toContain("self::requireParameters(['id']);");
expect($content)->toContain("\$is_superuser = self::hasPermission('superuser');"); expect($content)->toContain("\$is_superuser = \$this->hasPermission('superuser');");
expect($content)->toContain("if (!self::isParametersSet(['po_number']) && !self::isParametersSet(['closed_at'])) {"); expect($content)->toContain("if (!self::isParametersSet(['po_number']) && !self::isParametersSet(['closed_at'])) {");
expect($content)->toContain("\$response->error('Missing required parameters: po_number, closed_at', 400);"); expect($content)->toContain("\$response->error('Missing required parameters: po_number, closed_at', 400);");
expect($content)->toContain("if (self::isParametersSet(['closed_at']) && !\$is_superuser) {"); expect($content)->toContain("if (self::isParametersSet(['closed_at']) && !\$is_superuser) {");
@@ -0,0 +1,53 @@
<?php
it('invokes route permission methods through an object instance', function (): void {
$violations = [];
$routesDirectory = dirname(__DIR__, 3) . '/routes';
foreach (glob($routesDirectory . '/*.php') ?: [] as $routeFile) {
$source = file_get_contents($routeFile);
expect($source)->not->toBeFalse();
$tokens = token_get_all((string)$source);
$tokenCount = count($tokens);
for ($index = 0; $index < $tokenCount; $index++) {
$tokenText = is_array($tokens[$index]) ? $tokens[$index][1] : $tokens[$index];
if (strtolower($tokenText) !== 'self') {
continue;
}
$operatorIndex = $index + 1;
while ($operatorIndex < $tokenCount
&& is_array($tokens[$operatorIndex])
&& in_array($tokens[$operatorIndex][0], [T_WHITESPACE, T_COMMENT, T_DOC_COMMENT], true)) {
$operatorIndex++;
}
$operator = $operatorIndex < $tokenCount
? (is_array($tokens[$operatorIndex]) ? $tokens[$operatorIndex][1] : $tokens[$operatorIndex])
: null;
if ($operator !== '::') {
continue;
}
$methodIndex = $operatorIndex + 1;
while ($methodIndex < $tokenCount
&& is_array($tokens[$methodIndex])
&& in_array($tokens[$methodIndex][0], [T_WHITESPACE, T_COMMENT, T_DOC_COMMENT], true)) {
$methodIndex++;
}
$method = $methodIndex < $tokenCount
? (is_array($tokens[$methodIndex]) ? $tokens[$methodIndex][1] : $tokens[$methodIndex])
: null;
if (!is_string($method)
|| !in_array(strtolower($method), ['haspermission', 'requirepermission'], true)) {
continue;
}
$line = is_array($tokens[$index]) ? $tokens[$index][2] : 0;
$violations[] = basename($routeFile) . ':' . $line . ' self::' . $method;
}
}
expect($violations)->toBe([]);
});
@@ -595,13 +595,13 @@ it('classifies self-serve lane command route authorization by customer product b
expect($commandCases['OPEN_PROPERTY_ACCESS_GATE']) expect($commandCases['OPEN_PROPERTY_ACCESS_GATE'])
->toContain('requirePropertyGateCommandPermission') ->toContain('requirePropertyGateCommandPermission')
->toContain("'modules_selfserve_lane_command_execute_open_property_access_gate'") ->toContain("'modules_selfserve_lane_command_execute_open_property_access_gate'")
->not->toContain('self::requirePermission') ->not->toContain('$this->requirePermission')
->not->toContain('requireDepartmentAccess'); ->not->toContain('requireDepartmentAccess');
expect($commandCases['OPEN_PROPERTY_EXIT_GATE']) expect($commandCases['OPEN_PROPERTY_EXIT_GATE'])
->toContain('requirePropertyGateCommandPermission') ->toContain('requirePropertyGateCommandPermission')
->toContain("'modules_selfserve_lane_command_execute_open_property_exit_gate'") ->toContain("'modules_selfserve_lane_command_execute_open_property_exit_gate'")
->not->toContain('self::requirePermission') ->not->toContain('$this->requirePermission')
->not->toContain('requireDepartmentAccess'); ->not->toContain('requireDepartmentAccess');
foreach (['RESERVE', 'RELEASE', 'RESET'] as $operatorOnlyCommand) { foreach (['RESERVE', 'RELEASE', 'RESET'] as $operatorOnlyCommand) {
@@ -153,5 +153,5 @@ it('requires own subuser permissions for classic customer users in managed custo
$code = (string)file_get_contents($routeFile); $code = (string)file_get_contents($routeFile);
$normalized = preg_replace('/\s+/', ' ', $code); $normalized = preg_replace('/\s+/', ' ', $code);
expect($normalized)->toContain("\$user = \$auth->get_user(); if (\$user !== false) { \$customerNumber = (int)\$user->customer_number->value(); if (\$customerNumber <= 0) { \$response->error('Unauthorized', 401); } if (\$targetCustomerNumber !== null && \$customerNumber !== (int)\$targetCustomerNumber) { \$this->emitForbidden([\$permission]); } self::requirePermission(\$permission); return \$customerNumber;"); expect($normalized)->toContain("\$user = \$auth->get_user(); if (\$user !== false) { \$customerNumber = (int)\$user->customer_number->value(); if (\$customerNumber <= 0) { \$response->error('Unauthorized', 401); } if (\$targetCustomerNumber !== null && \$customerNumber !== (int)\$targetCustomerNumber) { \$this->emitForbidden([\$permission]); } \$this->requirePermission(\$permission); return \$customerNumber;");
}); });
@@ -0,0 +1,134 @@
<?php
require_once dirname(__DIR__, 3) . '/routes/xlvaskUsageLogsRoute.php';
class XLVaskUsageHallScopeRouteHarness extends \routes\xlvaskUsageLogsRoute
{
public bool $hasAllPermission = false;
public function __construct()
{
// Avoid request initialization in this focused unit test.
}
public function hasPermission(
string|\classes\permission_node $permission,
?int $customer_number = null
): bool {
$permissionKey = $permission instanceof \classes\permission_node
? (string)$permission->permission
: $permission;
return $this->hasAllPermission && $permissionKey === 'list_xlvask_usage_orders_all';
}
}
class XLVaskUsageHallScopeDbFake
{
public int $queryCount = 0;
/** @param array<int,array{HallId:mixed}> $rows */
public function __construct(private readonly array $rows)
{
}
public function query(string $sql): object
{
$this->queryCount++;
expect($sql)->toContain('SELECT DISTINCT HallId FROM plate_scanners');
return new stdClass();
}
/** @return array<int,array{HallId:mixed}> */
public function fetch_all(object $result): array
{
return $this->rows;
}
}
/**
* @param array<int,mixed> $groupHallIds
*/
function xlvask_usage_hall_scope_user(array $groupHallIds): object
{
return new class($groupHallIds) {
/** @param array<int,mixed> $groupHallIds */
public function __construct(private readonly array $groupHallIds)
{
}
public function getGroup(): object
{
return new class($this->groupHallIds) {
/** @param array<int,mixed> $groupHallIds */
public function __construct(private readonly array $groupHallIds)
{
}
/** @return array<int,mixed> */
public function getDepartmentsScannersHallIds(): array
{
return $this->groupHallIds;
}
};
}
};
}
/** @param array<int,mixed> $groupHallIds */
function resolve_xlvask_usage_hall_scope(
XLVaskUsageHallScopeRouteHarness $route,
XLVaskUsageHallScopeDbFake $dbFake,
array $groupHallIds
): array {
$hadDb = array_key_exists('db', $GLOBALS);
$originalDb = $GLOBALS['db'] ?? null;
$GLOBALS['db'] = $dbFake;
try {
$method = new ReflectionMethod(\routes\xlvaskUsageLogsRoute::class, 'allowedHallIdsForUser');
return $method->invoke($route, xlvask_usage_hall_scope_user($groupHallIds));
} finally {
if ($hadDb) {
$GLOBALS['db'] = $originalDb;
} else {
unset($GLOBALS['db']);
}
}
}
it('uses every normalized scanner hall for users with all-scope permission', function (): void {
$route = new XLVaskUsageHallScopeRouteHarness();
$route->hasAllPermission = true;
$dbFake = new XLVaskUsageHallScopeDbFake([
['HallId' => ' Hall-A '],
['HallId' => ''],
['HallId' => 'Hall-A'],
['HallId' => str_repeat('x', 192)],
['HallId' => 'Hall-B'],
]);
$hallIds = resolve_xlvask_usage_hall_scope($route, $dbFake, ['Own-Hall']);
expect($hallIds)->toBe(['Hall-A', 'Hall-B'])
->and($dbFake->queryCount)->toBe(1);
});
it('keeps own-scope users limited to normalized group halls', function (): void {
$route = new XLVaskUsageHallScopeRouteHarness();
$dbFake = new XLVaskUsageHallScopeDbFake([
['HallId' => 'Global-Hall'],
]);
$hallIds = resolve_xlvask_usage_hall_scope($route, $dbFake, [
' Own-Hall-A ',
'',
'Own-Hall-A',
'Own-Hall-B',
]);
expect($hallIds)->toBe(['Own-Hall-A', 'Own-Hall-B'])
->and($dbFake->queryCount)->toBe(0);
});
@@ -105,7 +105,7 @@ it('exposes additive XL Vask autopilot run and summary routes', function (): voi
->toContain('(new xlvask_autopilot_service())->getSummary(') ->toContain('(new xlvask_autopilot_service())->getSummary(')
->toContain('(new xlvask_autopilot_service())->createRun(') ->toContain('(new xlvask_autopilot_service())->createRun(')
->toContain('(new xlvask_autopilot_service())->getRun(') ->toContain('(new xlvask_autopilot_service())->getRun(')
->toContain('self::allowedHallIdsForUser($user)') ->toContain('$this->allowedHallIdsForUser($user)')
->toContain('], 202);'); ->toContain('], 202);');
}); });
@@ -138,9 +138,11 @@ it('exposes permission-aware capabilities active run and preview-bound server po
it('allows all-only permission and uses every configured scanner hall for all scope', function (): void { it('allows all-only permission and uses every configured scanner hall for all scope', function (): void {
$route = (string)file_get_contents(WD . '/routes/xlvaskUsageLogsRoute.php'); $route = (string)file_get_contents(WD . '/routes/xlvaskUsageLogsRoute.php');
expect($route) expect($route)
->toContain("if (!self::hasPermission(\$permission_list_all))") ->toContain("if (!\$this->hasPermission(\$permission_list_all))")
->toContain("if (self::hasPermission('list_xlvask_usage_orders_all'))") ->toContain("if (\$this->hasPermission('list_xlvask_usage_orders_all'))")
->toContain("if (!self::hasPermission('list_xlvask_usage_orders_all'))") ->toContain("if (!\$this->hasPermission('list_xlvask_usage_orders_all'))")
->toContain('private function allowedHallIdsForUser(object $user): array')
->not->toContain('private static function allowedHallIdsForUser')
->toContain("'list_xlvask_usage_orders_all' => 'Read all XL Vask usage-log automation summaries'") ->toContain("'list_xlvask_usage_orders_all' => 'Read all XL Vask usage-log automation summaries'")
->toContain('SELECT DISTINCT HallId FROM plate_scanners'); ->toContain('SELECT DISTINCT HallId FROM plate_scanners');
}); });