<?php
// Stores a newly-created passkey for the logged-in user.
session_start();
header('Content-Type: application/json');
require_once __DIR__ . '/config/db.php';
require_once __DIR__ . '/includes/webauthn.php';

if (empty($_SESSION['user_id'])) { http_response_code(401); echo json_encode(['ok' => false, 'error' => 'auth']); exit; }
wa_ensure_table($conn);
$uid = (int)$_SESSION['user_id'];

$body = json_decode(file_get_contents('php://input'), true);
if (!is_array($body) || empty($body['response'])) { echo json_encode(['ok' => false, 'error' => 'bad_request']); exit; }

$clientDataJSON = wa_b64url_decode($body['response']['clientDataJSON'] ?? '');
$attObj         = wa_b64url_decode($body['response']['attestationObject'] ?? '');
$chal           = $_SESSION['wa_reg_challenge'] ?? '';
unset($_SESSION['wa_reg_challenge']);

if (!$chal || !wa_check_client_data($clientDataJSON, 'webauthn.create', $chal)) {
    echo json_encode(['ok' => false, 'error' => 'client_data']); exit;
}

$o   = 0;
$att = wa_cbor_decode($attObj, $o);
$authData = is_array($att) ? ($att['authData'] ?? '') : '';
if (!is_string($authData) || strlen($authData) < 37) { echo json_encode(['ok' => false, 'error' => 'auth_data']); exit; }

$p = wa_parse_auth_data($authData);
if (!hash_equals($p['rpIdHash'], hash('sha256', wa_rp_id(), true))) { echo json_encode(['ok' => false, 'error' => 'rp_mismatch']); exit; }
if (!($p['flags'] & 0x01)) { echo json_encode(['ok' => false, 'error' => 'user_not_present']); exit; }
if (!$p['credId'] || !$p['cose']) { echo json_encode(['ok' => false, 'error' => 'no_credential']); exit; }

$pem = wa_cose_to_pem($p['cose']);
if (!$pem) { echo json_encode(['ok' => false, 'error' => 'This device uses an unsupported key type. Try a device that supports Face ID, Touch ID or fingerprint (ES256).']); exit; }

$credId = wa_b64url_encode($p['credId']);
$sc     = (int)$p['signCount'];
$ins = $conn->prepare(
    "INSERT INTO webauthn_credentials (user_id, credential_id, public_key, sign_count)
     VALUES (?, ?, ?, ?)
     ON DUPLICATE KEY UPDATE user_id=VALUES(user_id), public_key=VALUES(public_key), sign_count=VALUES(sign_count)"
);
$ins->bind_param("issi", $uid, $credId, $pem, $sc);
echo json_encode(['ok' => (bool)$ins->execute()]);
