PHP WebShell
Текущая директория: /var/www/bitcardoApp/lib
Просмотр файла: device.php
<?php
// lib/device.php
// Device trust cookie + helpers (keeps your schema/semantics).
/**
* Create a UUIDv4 (string).
*/
function device_uuid4(): string {
$d = random_bytes(16);
$d[6] = chr((ord($d[6]) & 0x0f) | 0x40);
$d[8] = chr((ord($d[8]) & 0x3f) | 0x80);
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($d), 4));
}
/**
* Get or create a stable device_id cookie (UUID v4 style).
* NOTE: Keep cookie name 'device_id' to match your existing use.
*/
function device_get_id(): string {
$cookie = $_COOKIE['device_id'] ?? '';
// Accept only uuid-like values
if (!preg_match('/^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/i', $cookie)) {
$cookie = device_uuid4();
// 2 years cookie
$cookieParams = [
'expires' => time() + 60*60*24*730, // ~2 years
'path' => '/',
// Keep your explicit domain (subdomain cookie). If you later want wallet+apps
// to share, use '.bitcardo.com' and ensure both apps are on HTTPS.
'domain' => 'wallet.bitcardo.com',
'secure' => !empty($_SERVER['HTTPS']), // only mark secure if HTTPS
'httponly' => true, // JS doesn't need to read this
'samesite' => 'Lax',
];
setcookie('device_id', $cookie, $cookieParams);
$_COOKIE['device_id'] = $cookie; // make it visible this request
}
return $cookie;
}
/**
* Build a coarse fingerprint (UA only for now).
*/
function device_fingerprint(): string {
$ua = $_SERVER['HTTP_USER_AGENT'] ?? 'unknown';
return hash('sha256', $ua);
}
/**
* Human label (UA-based).
*/
function device_label(): string {
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
if (stripos($ua, 'iPhone') !== false) return 'iPhone';
if (stripos($ua, 'iPad') !== false) return 'iPad';
if (stripos($ua, 'Android') !== false) return 'Android';
if (stripos($ua, 'Windows') !== false) return 'Windows';
if (stripos($ua, 'Mac OS') !== false || stripos($ua, 'Macintosh') !== false) return 'macOS';
return 'Browser';
}
/**
* Small helper to “touch” last seen and IP.
*/
function device_touch_seen(mysqli $conn, int $userId, string $deviceId): void {
$ip = $_SERVER['REMOTE_ADDR'] ?? '';
$sql = "UPDATE user_devices SET last_ip=?, last_seen_at=NOW() WHERE user_id=? AND device_id=?";
if ($stmt = $conn->prepare($sql)) {
$stmt->bind_param('sis', $ip, $userId, $deviceId);
$stmt->execute();
$stmt->close();
}
}
/**
* Check if this device is trusted for the user (by cookie + expiry + trusted flag).
* If trusted, we also update last_seen_at.
*/
function device_is_trusted(mysqli $conn, int $userId): bool {
$deviceId = device_get_id();
$sql = "SELECT trusted_until FROM user_devices
WHERE user_id=? AND device_id=? AND trusted=1
LIMIT 1";
$stmt = $conn->prepare($sql);
$stmt->bind_param('is', $userId, $deviceId);
$stmt->execute();
$stmt->bind_result($trustedUntil);
$ok = false;
if ($stmt->fetch()) {
$ok = $trustedUntil && (new DateTimeImmutable($trustedUntil) > new DateTimeImmutable());
}
$stmt->close();
if ($ok) {
device_touch_seen($conn, $userId, $deviceId);
}
return $ok;
}
/**
* Mark device trusted for +$trustDays days (upsert).
*/
function device_mark_trusted(mysqli $conn, int $userId, int $trustDays): void {
$deviceId = device_get_id();
$finger = device_fingerprint();
$label = device_label();
$ip = $_SERVER['REMOTE_ADDR'] ?? '';
$trustedTil = (new DateTimeImmutable("+{$trustDays} days"))->format('Y-m-d H:i:s');
$sql = "INSERT INTO user_devices
(user_id, device_id, device_fingerprint, device_label, first_ip, last_ip, last_seen_at, trusted_until, trusted)
VALUES
(?, ?, ?, ?, ?, ?, NOW(), ?, 1)
ON DUPLICATE KEY UPDATE
device_fingerprint=VALUES(device_fingerprint),
device_label=VALUES(device_label),
last_ip=VALUES(last_ip),
last_seen_at=NOW(),
trusted_until=VALUES(trusted_until),
trusted=1";
$stmt = $conn->prepare($sql);
$stmt->bind_param('issssss', $userId, $deviceId, $finger, $label, $ip, $ip, $trustedTil);
$stmt->execute();
$stmt->close();
}
/**
* (Optional) Revoke ALL trusted devices for the user (e.g., after password reset).
*/
function device_revoke_all(mysqli $conn, int $userId): void {
$conn->query("UPDATE user_devices SET trusted=0, trusted_until=NOW() WHERE user_id=".(int)$userId);
}
Выполнить команду
Для локальной разработки. Не используйте в интернете!