<?php

include('../functions.php');
include('../login/auth.php');
include('../helpers/passkeys.php');

sendy_passkeys_resume_session();
sendy_passkeys_ensure_table();

$action = isset($_GET['action']) ? $_GET['action'] : '';
$post = sendy_passkeys_read_json();
$userID = (int)get_app_info('userID');

try
{
if($action=='list')
{
	$items = array();
	$q = 'SELECT id, name, created, last_used FROM passkeys WHERE userID = '.$userID.' ORDER BY created DESC';
	$r = mysqli_query($mysqli, $q);
	if($r)
	{
		while($row = mysqli_fetch_array($r))
		{
			$items[] = array(
				'id'=>(int)$row['id'],
				'name'=>stripslashes($row['name']),
				'created'=>(int)$row['created'],
				'last_used'=>$row['last_used']==='' || $row['last_used']===null ? null : (int)$row['last_used']
			);
		}
	}
	sendy_passkeys_json(array('success'=>true, 'passkeys'=>$items, 'supported'=>sendy_passkeys_supported()));
}
else if($action=='start-register')
{
	$credential_ids = array();
	$q = 'SELECT credential_id FROM passkeys WHERE userID = '.$userID;
	$r = mysqli_query($mysqli, $q);
	if($r)
	{
		while($row = mysqli_fetch_array($r))
			$credential_ids[] = base64_decode($row['credential_id']);
	}

	$WebAuthn = sendy_passkeys_webauthn();
	$args = $WebAuthn->getCreateArgs((string)$userID, get_app_info('email'), get_app_info('name'), 60, 'preferred', true, null, $credential_ids);
	$_SESSION['passkey_register_challenge'] = $WebAuthn->getChallenge()->getBinaryString();
	sendy_passkeys_json($args);
}
else if($action=='finish-register')
{
	$challenge = sendy_passkeys_session_challenge('passkey_register_challenge');
	if($challenge===null) sendy_passkeys_error('Passkey registration expired. Please try again.');

	$WebAuthn = sendy_passkeys_webauthn();
	$data = $WebAuthn->processCreate(
		sendy_passkeys_b64decode(isset($post['clientDataJSON']) ? $post['clientDataJSON'] : ''),
		sendy_passkeys_b64decode(isset($post['attestationObject']) ? $post['attestationObject'] : ''),
		$challenge,
		true,
		true,
		false
	);
	unset($_SESSION['passkey_register_challenge']);

	$credential_id = mysqli_real_escape_string($mysqli, base64_encode($data->credentialId));
	$credential_id_hash = mysqli_real_escape_string($mysqli, hash('sha256', $data->credentialId));
	$public_key = mysqli_real_escape_string($mysqli, $data->credentialPublicKey);
	$name = isset($post['name']) && trim($post['name'])!='' ? trim($post['name']) : 'Passkey';
	$name = mysqli_real_escape_string($mysqli, substr($name, 0, 100));
	$transports = isset($post['transports']) && is_array($post['transports']) ? implode(',', $post['transports']) : '';
	$transports = mysqli_real_escape_string($mysqli, substr($transports, 0, 255));
	$attestation_format = mysqli_real_escape_string($mysqli, $data->attestationFormat);
	$counter = $data->signatureCounter===null ? 'NULL' : (int)$data->signatureCounter;

	$q = 'INSERT INTO passkeys (userID, credential_id, credential_id_hash, credential_public_key, signature_counter, name, transports, attestation_format, created)
		  VALUES ('.$userID.', "'.$credential_id.'", "'.$credential_id_hash.'", "'.$public_key.'", '.$counter.', "'.$name.'", "'.$transports.'", "'.$attestation_format.'", '.time().')
		  ON DUPLICATE KEY UPDATE name = VALUES(name), credential_public_key = VALUES(credential_public_key), signature_counter = VALUES(signature_counter), transports = VALUES(transports)';
	$r = mysqli_query($mysqli, $q);
	if(!$r) sendy_passkeys_error('Unable to save passkey.');

	sendy_passkeys_json(array('success'=>true));
}
else if($action=='delete')
{
	$id = isset($post['id']) && is_numeric($post['id']) ? (int)$post['id'] : 0;
	if($id==0) sendy_passkeys_error('Invalid passkey.');
	$r = mysqli_query($mysqli, 'DELETE FROM passkeys WHERE id = '.$id.' AND userID = '.$userID.' LIMIT 1');
	if(!$r) sendy_passkeys_error('Unable to delete passkey.');
	sendy_passkeys_json(array('success'=>true));
}

sendy_passkeys_error('Invalid passkey action.');
}
catch(Exception $e)
{
	sendy_passkeys_error($e->getMessage());
}
