<?php
/**
 * webauthn-login-options.php — Passkey login (2nd factor): step 1
 *
 * Called by index.php's second-factor prompt AFTER the password has
 * already been verified (see index.php — sets $_SESSION['pending_2fa_user_id']
 * instead of completing login when the account has registered passkeys).
 * Does NOT require a fully authenticated session (there isn't one yet) —
 * it requires the narrower pending_2fa_user_id flag set by a successful
 * password check, which only index.php's login POST handler can set.
 */
require_once __DIR__ . '/../includes/functions.php';

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

if (!isset($_SESSION['pending_2fa_user_id'])) {
    http_response_code(403);
    echo json_encode(['success' => false, 'error' => 'No pending login.']);
    exit;
}
if (!isset($_GET['csrf_token']) || !verify_token($_GET['csrf_token'])) {
    http_response_code(403);
    echo json_encode(['success' => false, 'error' => 'Invalid request.']);
    exit;
}

$userId = (int) $_SESSION['pending_2fa_user_id'];
$credentials = $db->select('webauthn_credentials', 'credential_id', 'user_id = :uid', '', [':uid' => $userId]);

if (empty($credentials)) {
    // Should not normally happen (index.php only enters this flow when
    // credentials exist), but fail safely rather than issue a
    // no-allowed-credentials challenge that could never succeed.
    http_response_code(400);
    echo json_encode(['success' => false, 'error' => 'No passkeys registered.']);
    exit;
}

$allowedIds = array_map(
    fn($row) => \lbuchs\WebAuthn\Binary\ByteBuffer::fromHex($row['credential_id']),
    $credentials
);

$getArgs = $webAuthn->getGetArgs(credentialIds: $allowedIds, requireUserVerification: 'preferred');

$_SESSION['webauthn_login_challenge'] = base64_encode($webAuthn->getChallenge()->getBinaryString());

echo json_encode(['success' => true, 'options' => $getArgs], JSON_UNESCAPED_SLASHES);
