diff --git a/public/index.php b/public/index.php index f945313..81dc4f7 100644 --- a/public/index.php +++ b/public/index.php @@ -138,6 +138,25 @@ if ($route === 'attachment') { readfile($path); exit; } +if ($route === 'credential_reveal') { + require_permission('credentials.view'); + if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') { http_response_code(405); exit('Reveal requires POST'); } + verify_csrf(); + $credentialId = filter_var(scalar_input($_POST['credential_id'] ?? null), FILTER_VALIDATE_INT); + $credentialStmt = db()->prepare('SELECT id, client_id, secret_ciphertext FROM credentials WHERE id = :id AND is_active = 1'); + $credentialStmt->execute(['id' => $credentialId]); + $credential = $credentialStmt->fetch(); + if (!$credential || !can_access_client((int)$credential['client_id'])) { http_response_code(404); header('Content-Type: application/json'); echo json_encode(['ok' => false, 'error' => 'Credential not found.']); exit; } + try { + $secret = (new \App\Domain\Credential\CredentialVault())->decrypt($credential['secret_ciphertext']); + audit('credential_revealed', 'credential', (int)$credential['id'], ['client_id' => (int)$credential['client_id']]); + header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0'); + header('Content-Type: application/json; charset=UTF-8'); + echo json_encode(['ok' => true, 'secret' => $secret], JSON_THROW_ON_ERROR); + } catch (Throwable) { http_response_code(500); header('Content-Type: application/json'); echo json_encode(['ok' => false, 'error' => 'Credential could not be decrypted.']); } + exit; +} + if ($route === 'client_history') { require_permission('clients.view'); $clientId = filter_var(scalar_input($_GET['id'] ?? null), FILTER_VALIDATE_INT); @@ -529,7 +548,7 @@ if ($route === 'client') { $credentialRows = $credentialStmt->fetchAll(); } render_header('Client details'); - echo '
Jobcard history
'; + echo '
Jobcard history
'; echo '
← Back to clients View history

' . e($client['name']) . '

Client profile and support contacts.

' . e(ucfirst($client['status'])) . '
' . (isset($_GET['contact_created']) ? '
Contact added successfully.
' : '') . (isset($_GET['sla_updated']) ? '
SLA agreement updated.
' : '') . ($contactErrors ? '
' . e(implode(' ', $contactErrors)) . '
' : '') . ($slaErrors ? '
' . e(implode(' ', $slaErrors)) . '
' : '') . '

Support information

Email
' . e((string)($client['support_email'] ?? '—')) . '
Phone
' . e((string)($client['support_phone'] ?? '—')) . '
Preferred method
' . e((string)($client['preferred_contact_method'] ?? '—')) . '
Address
' . nl2br(e((string)($client['physical_address'] ?? '—'))) . '

Contacts

'; if (!$contacts) echo '

No contacts recorded.

'; foreach ($contacts as $contact) { echo '
' . e($contact['name']) . ($contact['is_primary'] ? ' Primary' : '') . '
' . e((string)($contact['email'] ?? '')) . ' ' . e((string)($contact['phone'] ?? '')) . '
'; if (can('clients.manage')) { echo '
'; } echo '
'; } @@ -547,8 +566,8 @@ if ($route === 'client') { if ($credentialErrors) echo '
' . e(implode(' ', $credentialErrors)) . '
'; if (isset($_GET['credential_created'])) echo '
Credential saved securely.
'; foreach ($credentialRows as $credentialRow) { - echo '
' . e($credentialRow['label']) . ' ' . e($credentialRow['category']) . '
Username: ' . e((string)($credentialRow['username'] ?? '—')) . ' · Secret: ' . ($revealedCredential && $revealedCredential['id'] === (int)$credentialRow['id'] ? '' . e($revealedCredential['secret']) . '' : '••••••••••••••••••••') . '
'; - if (can('credentials.view') && !($revealedCredential && $revealedCredential['id'] === (int)$credentialRow['id'])) echo '
'; + echo '
' . e($credentialRow['label']) . '
Username: ' . e((string)($credentialRow['username'] ?? '—')) . ' · Password: ••••••••••••••••••••
'; + if (can('credentials.view')) echo ' '; echo '
'; } echo '
'; @@ -557,7 +576,7 @@ if ($route === 'client') { $technicalRows = (new \App\Domain\Credential\TechnicalInformationRepository(db()))->forClient($clientId); echo '

Technical information

'; foreach ($technicalRows as $technical) { $display = $technical['display']; echo '
' . e(ucfirst($technical['category'])) . '
' . e((string)$display['label']) . ($display['username'] ? ' · ' . e((string)$display['username']) : '') . '
' . nl2br(e((string)($display['notes'] ?? ''))) . '
'; } - if (can('credentials.manage')) { echo '

Add client information

'; } + if (can('credentials.manage')) { echo '

Add client information

'; } echo '
'; } if (can('clients.manage')) echo '

Edit client

';