Files
html/ca.dat
2026-04-12 22:57:03 +02:00

157 lines
5.7 KiB
Plaintext

<?php
/**
* ETHICA CONSENT API — Token-based consent management
* Deployed at: consent.wevup.app/api/ethica-consent.php
* Also accessible at: ethica.wevup.app/api/ethica-consent.php (Arsenal)
*/
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');
if($_SERVER['REQUEST_METHOD']==='OPTIONS'){http_response_code(204);exit;}
$db = new PDO("pgsql:host=127.0.0.1;dbname=adx_system", "admin", "admin123");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$action = $_GET['action'] ?? 'status';
switch($action) {
case 'validate_token':
$token = $_GET['token'] ?? '';
if(!$token || $token==='TEST'){
echo json_encode(["ok"=>false,"error"=>"Invalid token"]);
break;
}
$st = $db->prepare("SELECT ct.id, ct.medecin_id, ct.status as token_status, ct.channel,
m.nom, m.prenom, m.specialite, m.ville, m.pays, m.email, m.telephone, m.consent_status
FROM ethica.consent_tokens ct
JOIN ethica.medecins_real m ON m.id = ct.medecin_id
WHERE ct.token = ?");
$st->execute([$token]);
$row = $st->fetch(PDO::FETCH_ASSOC);
if(!$row){
echo json_encode(["ok"=>false,"error"=>"Token not found"]);
break;
}
echo json_encode([
"ok" => true,
"hcp" => [
"nom" => $row['nom'],
"prenom" => $row['prenom'],
"specialite" => $row['specialite'],
"ville" => $row['ville'],
"pays" => $row['pays'],
"email" => $row['email'] ? substr($row['email'],0,3).'***@'.explode('@',$row['email'])[1] : null,
"telephone" => $row['telephone'] ? substr($row['telephone'],0,4).'****'.substr($row['telephone'],-2) : null
],
"token_status" => $row['token_status'],
"consent_status" => $row['consent_status']
], JSON_PRETTY_PRINT);
break;
case 'submit_consent':
$input = json_decode(file_get_contents('php://input'), true);
$token = $input['token'] ?? $_GET['token'] ?? '';
$consent = $input['consent'] ?? $_GET['consent'] ?? 'optin';
$channels = $input['channels'] ?? ['email'];
$ip = $_SERVER['REMOTE_ADDR'] ?? '';
if(!$token){
echo json_encode(["ok"=>false,"error"=>"Token required"]);
break;
}
// Get HCP from token
$st = $db->prepare("SELECT medecin_id FROM ethica.consent_tokens WHERE token = ?");
$st->execute([$token]);
$tid = $st->fetchColumn();
if(!$tid){
echo json_encode(["ok"=>false,"error"=>"Invalid token"]);
break;
}
$status = ($consent === 'optin') ? 'opted_in' : 'opted_out';
$method = 'web_form';
$channel_str = implode(',', $channels);
// Update HCP consent
$db->prepare("UPDATE ethica.medecins_real SET
consent_status = ?,
consent_date = NOW(),
consent_method = ?,
consent_source = ?
WHERE id = ?")->execute([$status, $method, $channel_str, $tid]);
// Update token
$db->prepare("UPDATE ethica.consent_tokens SET
status = ?,
confirmed_at = NOW(),
ip_address = ?
WHERE token = ?")->execute([$status, $ip, $token]);
// Log consent action
$db->prepare("INSERT INTO ethica.consent_log (medecin_id, action, method, ip_address, channels, user_agent, created_at)
VALUES (?, ?, 'web_form', ?, ?, ?, NOW())")->execute([
$tid, $consent, $ip, $channel_str, $_SERVER['HTTP_USER_AGENT'] ?? ''
]);
echo json_encode([
"ok" => true,
"consent" => $status,
"channels" => $channels,
"medecin_id" => (int)$tid,
"ip" => $ip,
"timestamp" => date('c')
], JSON_PRETTY_PRINT);
break;
case 'search':
$q = trim($_GET['q'] ?? '');
if(strlen($q) < 3){
echo json_encode(["ok"=>false,"error"=>"Min 3 characters"]);
break;
}
// Search by email or phone
$st = $db->prepare("SELECT m.id, ct.token FROM ethica.medecins_real m
LEFT JOIN ethica.consent_tokens ct ON ct.medecin_id = m.id AND ct.channel = 'email'
WHERE (m.email = ? OR m.telephone = ?)
LIMIT 1");
$st->execute([$q, $q]);
$row = $st->fetch(PDO::FETCH_ASSOC);
if($row && $row['token']){
echo json_encode(["ok"=>true,"token"=>$row['token']]);
} elseif($row) {
// HCP exists but no token — generate one
$new_token = md5($row['id'] . time() . random_bytes(8));
$db->prepare("INSERT INTO ethica.consent_tokens (medecin_id, token, channel, status, created_at)
VALUES (?, ?, 'email', 'pending', NOW())")->execute([$row['id'], $new_token]);
echo json_encode(["ok"=>true,"token"=>$new_token]);
} else {
echo json_encode(["ok"=>false,"error"=>"Not found"]);
}
break;
case 'stats':
$total = (int)$db->query("SELECT count(*) FROM ethica.consent_tokens")->fetchColumn();
$opted_in = (int)$db->query("SELECT count(*) FROM ethica.medecins_real WHERE consent_status='opted_in'")->fetchColumn();
$opted_out = (int)$db->query("SELECT count(*) FROM ethica.medecins_real WHERE consent_status='opted_out'")->fetchColumn();
$pending = (int)$db->query("SELECT count(*) FROM ethica.consent_tokens WHERE status='pending'")->fetchColumn();
echo json_encode([
"ok" => true,
"total_tokens" => $total,
"opted_in" => $opted_in,
"opted_out" => $opted_out,
"pending" => $pending,
"optin_rate" => $total > 0 ? round($opted_in / $total * 100, 1) : 0
], JSON_PRETTY_PRINT);
break;
default:
echo json_encode(["ok"=>false,"actions"=>["validate_token","submit_consent","search","stats"]]);
}