assure/Contestation/integration_example.php
2026-02-22 10:01:06 +00:00

342 lines
11 KiB
PHP

<?php
/**
* Exemple d'intégration de la vérification faciale dans le flux existant
* À utiliser après la lecture du tag NFC ou QR code
*/
require_once 'config.php';
require_once 'database.php';
require_once 'send_verification_link.php';
// ====================================================================
// SCÉNARIO 1: Lecture du tag NFC/QR Code
// ====================================================================
/**
* Fonction appelée après la lecture réussie du tag NFC ou QR code
*/
function handleNFCOrQRCodeScan($tagData) {
// 1. Décoder les données du tag
$assureData = json_decode($tagData, true);
$assureId = $assureData['assure_id'];
// 2. Vérifier que l'assuré existe
$db = new Database();
$conn = $db->getConnection();
$sql = "SELECT id, nom, prenoms, numero_carte, email, telephone, photo_reference_path
FROM assures
WHERE id = ? AND statut = 'actif'";
$stmt = $conn->prepare($sql);
$stmt->execute([$assureId]);
$assure = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$assure) {
return [
'success' => false,
'message' => 'Assuré non trouvé ou inactif'
];
}
// 3. Vérifier si une photo de référence existe
if (empty($assure['photo_reference_path'])) {
// Pas de photo de référence = accès sans vérification faciale
// Loguer cette tentative pour sécurité
logAction("Accès sans vérification faciale - Assuré #{$assureId} - Aucune photo de référence", 'WARNING');
return [
'success' => true,
'require_facial_verification' => false,
'message' => 'Accès autorisé (pas de photo de référence)',
'assure' => $assure
];
}
// 4. Envoyer le lien de vérification faciale
$verifier = new FacialVerificationLink($conn);
// Choisir le canal d'envoi selon les préférences
$method = 'both'; // 'email', 'whatsapp', ou 'both'
$result = $verifier->sendVerificationLink($assureId, $method);
if ($result['success']) {
return [
'success' => true,
'require_facial_verification' => true,
'message' => 'Lien de vérification envoyé',
'email_sent' => $result['email_sent'],
'whatsapp_sent' => $result['whatsapp_sent'],
'assure' => $assure
];
} else {
return [
'success' => false,
'message' => $result['message']
];
}
}
// ====================================================================
// SCÉNARIO 2: Vérification de session avant saisie des prestations
// ====================================================================
/**
* Vérifie si l'utilisateur a une session d'autorisation valide
* À appeler au début de saisie_prestations.php
*/
function checkAuthorizationSession() {
$sessionToken = $_GET['token'] ?? $_SESSION['authorization_token'] ?? null;
if (!$sessionToken) {
return [
'authorized' => false,
'message' => 'Aucune session d\'autorisation'
];
}
$db = new Database();
$conn = $db->getConnection();
$sql = "SELECT pas.*, a.id as assure_id, a.nom, a.prenoms, a.numero_carte
FROM prestation_authorization_sessions pas
JOIN assures a ON pas.assure_id = a.id
WHERE pas.session_token = ?
AND pas.status = 'active'
AND pas.expires_at > NOW()";
$stmt = $conn->prepare($sql);
$stmt->execute([$sessionToken]);
$session = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$session) {
return [
'authorized' => false,
'message' => 'Session invalide ou expirée'
];
}
// Stocker en session PHP pour les requêtes suivantes
$_SESSION['authorization_token'] = $sessionToken;
$_SESSION['authorized_assure_id'] = $session['assure_id'];
return [
'authorized' => true,
'assure' => [
'id' => $session['assure_id'],
'nom' => $session['nom'],
'prenoms' => $session['prenoms'],
'numero_carte' => $session['numero_carte']
],
'session' => $session
];
}
/**
* Marque une session comme utilisée après saisie d'une prestation
*/
function markSessionAsUsed($sessionToken) {
$db = new Database();
$conn = $db->getConnection();
$sql = "UPDATE prestation_authorization_sessions
SET prestations_saisies = prestations_saisies + 1,
used_at = NOW()
WHERE session_token = ?";
$stmt = $conn->prepare($sql);
return $stmt->execute([$sessionToken]);
}
// ====================================================================
// SCÉNARIO 3: Interface utilisateur pour le prestataire
// ====================================================================
/**
* Génère l'interface HTML pour le prestataire après scan NFC/QR
*/
function renderVerificationWaitingScreen($assure, $verificationSent) {
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vérification en attente - INTER-SANTÉ</title>
<style>
body {
font-family: Arial, sans-serif;
background: #f5f5f5;
margin: 0;
padding: 20px;
}
.container {
max-width: 600px;
margin: 50px auto;
background: white;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
padding: 40px;
text-align: center;
}
.spinner {
width: 60px;
height: 60px;
border: 5px solid #f3f3f3;
border-top: 5px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 30px auto;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.assure-info {
background: #ecf0f1;
padding: 20px;
border-radius: 8px;
margin: 20px 0;
}
.status {
color: #7f8c8d;
font-size: 14px;
margin: 10px 0;
}
.channels {
display: flex;
justify-content: center;
gap: 20px;
margin: 20px 0;
}
.channel {
padding: 10px 20px;
border-radius: 5px;
font-size: 14px;
}
.channel.sent {
background: #d4edda;
color: #155724;
}
.channel.not-sent {
background: #f8d7da;
color: #721c24;
}
</style>
</head>
<body>
<div class="container">
<h1>🏥 INTER-SANTÉ</h1>
<h2>Vérification d'identité en cours</h2>
<div class="assure-info">
<h3><?php echo htmlspecialchars($assure['prenoms'] . ' ' . $assure['nom']); ?></h3>
<p>Carte N° <?php echo htmlspecialchars($assure['numero_carte']); ?></p>
</div>
<div class="spinner"></div>
<p class="status">
Un lien de vérification a été envoyé à l'assuré.<br>
En attente de la vérification faciale...
</p>
<div class="channels">
<?php if ($verificationSent['email_sent']): ?>
<div class="channel sent">✓ Email envoyé</div>
<?php else: ?>
<div class="channel not-sent">✗ Email non envoyé</div>
<?php endif; ?>
<?php if ($verificationSent['whatsapp_sent']): ?>
<div class="channel sent">✓ WhatsApp envoyé</div>
<?php else: ?>
<div class="channel not-sent">✗ WhatsApp non envoyé</div>
<?php endif; ?>
</div>
<p style="font-size: 12px; color: #95a5a6;">
Le lien de vérification est valable pendant 15 minutes
</p>
</div>
<script>
// Vérifier le statut toutes les 3 secondes
const requestId = <?php echo $verificationSent['request_id']; ?>;
function checkVerificationStatus() {
fetch('check_verification_status.php?request_id=' + requestId)
.then(response => response.json())
.then(data => {
if (data.status === 'verified') {
// Rediriger vers la saisie des prestations
window.location.href = 'saisie_prestations.php?token=' + data.session_token;
} else if (data.status === 'failed' || data.status === 'expired') {
// Afficher un message d'erreur
alert('La vérification a échoué ou a expiré');
window.location.href = 'index.php';
}
});
}
// Vérifier toutes les 3 secondes
setInterval(checkVerificationStatus, 3000);
</script>
</body>
</html>
<?php
}
// ====================================================================
// EXEMPLE D'UTILISATION COMPLÈTE
// ====================================================================
// Dans votre fichier de scan NFC/QR (ex: scan_handler.php)
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$tagData = $_POST['tag_data'] ?? null;
if (!$tagData) {
echo json_encode(['success' => false, 'message' => 'Données manquantes']);
exit;
}
// Traiter le scan
$result = handleNFCOrQRCodeScan($tagData);
if ($result['success'] && $result['require_facial_verification']) {
// Afficher l'écran d'attente
renderVerificationWaitingScreen($result['assure'], $result);
} elseif ($result['success'] && !$result['require_facial_verification']) {
// Accès direct (pas de photo de référence)
header('Location: saisie_prestations.php?assure_id=' . $result['assure']['id']);
} else {
// Erreur
echo json_encode($result);
}
}
// Dans votre fichier saisie_prestations.php
session_start();
// Vérifier l'autorisation
$auth = checkAuthorizationSession();
if (!$auth['authorized']) {
die('Accès non autorisé. Veuillez scanner la carte de l\'assuré.');
}
// L'utilisateur est autorisé, afficher le formulaire de saisie
$assure = $auth['assure'];
// ... Votre code de saisie de prestations ...
// Après enregistrement d'une prestation
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_prestation'])) {
// Enregistrer la prestation
// ...
// Marquer la session comme utilisée
markSessionAsUsed($_SESSION['authorization_token']);
}