turnero: restricción por token de navegador en lugar de IP pública

- Token UUID generado en localStorage del navegador, persistido como cookie
- turnero_dispositivos.token: nueva columna para identificar equipos
- recepcion.php y lugar.php: chequean token (cookie) primero, IP como fallback
- configuracion.php: banner con token del equipo actual + botón "Registrar este equipo"
- save_dispositivo.php: acepta campo token al crear/editar dispositivo
- Migración: 20260709_dispositivos_token.sql

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-07-09 10:56:53 -05:00
co-authored by Claude Sonnet 4.6
parent 9651f14302
commit d5b6de1f46
6 changed files with 142 additions and 112 deletions
+28 -13
View File
@@ -9,22 +9,37 @@ if (!isUserLoggedIn()) {
exit;
}
// Tablet asignada → forzar su escritorio, bloquear cualquier otro
// Chequeo en vivo por IP (no solo sesión, para sesiones preexistentes)
// Tablet asignada → forzar su escritorio por token de navegador (o IP como fallback)
$_recepForzado = 0;
try {
$_clientIp = trim(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR'] ?? '')[0]);
$_dispPdo = Database::getInstance()->getConnection();
$_dispStmt = $_dispPdo->prepare(
"SELECT td.lugar_id, td.nombre, tl.tipo
FROM turnero_dispositivos td
JOIN turnero_lugares tl ON tl.id = td.lugar_id
WHERE td.ip = ? AND td.activo = 1 LIMIT 1"
);
$_dispStmt->execute([$_clientIp]);
$_dispRow = $_dispStmt->fetch(PDO::FETCH_ASSOC);
$_dispPdo = Database::getInstance()->getConnection();
$_dispRow = null;
// 1. Chequeo por token de navegador (cookie)
$_devToken = trim($_COOKIE['turnero_token'] ?? '');
if ($_devToken) {
$_s = $_dispPdo->prepare(
"SELECT td.lugar_id, td.nombre, tl.tipo
FROM turnero_dispositivos td
JOIN turnero_lugares tl ON tl.id = td.lugar_id
WHERE td.token = ? AND td.activo = 1 LIMIT 1"
);
$_s->execute([$_devToken]);
$_dispRow = $_s->fetch(PDO::FETCH_ASSOC) ?: null;
}
// 2. Fallback por IP
if (!$_dispRow) {
$_clientIp = trim(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR'] ?? '')[0]);
$_s = $_dispPdo->prepare(
"SELECT td.lugar_id, td.nombre, tl.tipo
FROM turnero_dispositivos td
JOIN turnero_lugares tl ON tl.id = td.lugar_id
WHERE td.ip = ? AND td.token IS NULL AND td.activo = 1 LIMIT 1"
);
$_s->execute([$_clientIp]);
$_dispRow = $_s->fetch(PDO::FETCH_ASSOC) ?: null;
}
if ($_dispRow) {
$_SESSION['turnero_dispositivo'] = $_dispRow; // mantener sesión actualizada
$_SESSION['turnero_dispositivo'] = $_dispRow;
$_forzado = (int)$_dispRow['lugar_id'];
if ($_dispRow['tipo'] !== 'recepcion') {
header('Location: ' . BASE_URL . 'erp.php?m=turnero&v=lugar&lugar_id=' . $_forzado); exit;