<?php
/**
 * webauthn-register-verify.php — Passkey registration: step 2
 *
 * Receives the browser's navigator.credentials.create() response,
 * verifies it against the challenge stored in the session by
 * webauthn-register-options.php, and persists the new credential.
 *
 * Requires an authenticated session, same as the options endpoint.
 */
require_once __DIR__ . '/../includes/auth.php';

header('Content-Type: application/json; charset=UTF-8');

$input = json_decode((string) file_get_contents('php://input'), true);
if (!is_array($input) || !verify_token((string) ($input['csrf_token'] ?? ''))) {
    http_response_code(403);
    echo json_encode(['success' => false, 'error' => 'Invalid request.']);
    exit;
}

$challengeB64 = $_SESSION['webauthn_register_challenge'] ?? null;
if ($challengeB64 === null) {
    http_response_code(400);
    echo json_encode(['success' => false, 'error' => 'No pending registration. Please try again.']);
    exit;
}

$label = trim((string) ($input['label'] ?? ''));
if ($label === '') {
    $label = 'Passkey added ' . date('Y-m-d');
}

$clientDataJSON = base64_decode((string) ($input['clientDataJSON'] ?? ''), true);
$attestationObject = base64_decode((string) ($input['attestationObject'] ?? ''), true);

if ($clientDataJSON === false || $attestationObject === false) {
    http_response_code(400);
    echo json_encode(['success' => false, 'error' => 'Malformed registration response.']);
    exit;
}

try {
    $data = $webAuthn->processCreate(
        $clientDataJSON,
        $attestationObject,
        base64_decode($challengeB64, true),
        requireUserVerification: false,
        requireUserPresent: true
    );

    $db->insert('webauthn_credentials', [
        'user_id' => 1,
        'credential_id' => bin2hex($data->credentialId),
        'public_key' => $data->credentialPublicKey,
        'sign_count' => $data->signatureCounter ?? 0,
        'label' => $label,
        'created_at' => date('Y-m-d H:i:s'),
        'last_used_at' => null,
    ]);

    unset($_SESSION['webauthn_register_challenge']);

    echo json_encode(['success' => true]);
} catch (\lbuchs\WebAuthn\WebAuthnException $e) {
    http_response_code(400);
    echo json_encode(['success' => false, 'error' => 'Registration failed: ' . $e->getMessage()]);
} catch (\Throwable $e) {
    // Catch-all so a bug here (or anywhere in the WebAuthn library) always
    // returns valid JSON instead of PHP's uncaught-error HTML output,
    // which the browser's fetch()/JSON.parse() can't handle — this exact
    // failure mode (a fatal Error, not a caught WebAuthnException) is what
    // originally surfaced as "JSON.parse: unexpected character at line 1
    // column 1" in the browser.
    error_log('webauthn-register-verify: unexpected error: ' . $e->getMessage());
    http_response_code(500);
    echo json_encode(['success' => false, 'error' => 'An unexpected error occurred during registration.']);
}
