157 lines
5.7 KiB
Plaintext
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"]]);
|
|
}
|