차량 모니터 mnt 인증 의존 제거
This commit is contained in:
1 parent
a1a9f29fcc
commit
36f5a30450
1 file changed
+84
-22
+84
-22
@@ -17,6 +17,8 @@ define('DB_CHARSET', (string)($carDbConfig['charset'] ?? 'utf8mb4'));
|
||||
|
||||
const LOG_LIMIT = 300;
|
||||
const CHART_LIMIT = 500;
|
||||
const CAR_MONITOR_COOKIE = 'car_monitor_access';
|
||||
const CAR_MONITOR_AUTH_TTL = 2592000;
|
||||
const DATA_MONTHLY_INCLUDED_BYTES = 104857600; // 100MB
|
||||
const DATA_BILLING_UNIT_BYTES = 512; // 0.5KB
|
||||
const DATA_BILLING_UNIT_KRW = 0.011;
|
||||
@@ -874,6 +876,72 @@ function json_response(array $payload, int $status = 200): void
|
||||
exit;
|
||||
}
|
||||
|
||||
function car_monitor_cookie_secret(): string
|
||||
{
|
||||
global $carSecretConfig;
|
||||
|
||||
$secret = (string)($carSecretConfig['monitor_auth']['secret'] ?? $carSecretConfig['auth_token'] ?? '');
|
||||
if ($secret === '') {
|
||||
throw new RuntimeException('Car monitor auth secret is missing.');
|
||||
}
|
||||
|
||||
return $secret;
|
||||
}
|
||||
|
||||
function car_monitor_cookie_options(int $expires): array
|
||||
{
|
||||
return [
|
||||
'expires' => $expires,
|
||||
'path' => '/car/',
|
||||
'secure' => (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'),
|
||||
'httponly' => true,
|
||||
'samesite' => 'Strict',
|
||||
];
|
||||
}
|
||||
|
||||
function car_monitor_cookie_value(int $expires): string
|
||||
{
|
||||
$body = base64_encode(json_encode([
|
||||
'exp' => $expires,
|
||||
'iat' => time(),
|
||||
], JSON_UNESCAPED_SLASHES));
|
||||
$sig = hash_hmac('sha256', $body, car_monitor_cookie_secret());
|
||||
|
||||
return $body . '.' . $sig;
|
||||
}
|
||||
|
||||
function car_monitor_issue_cookie(): void
|
||||
{
|
||||
$expires = time() + CAR_MONITOR_AUTH_TTL;
|
||||
setcookie(CAR_MONITOR_COOKIE, car_monitor_cookie_value($expires), car_monitor_cookie_options($expires));
|
||||
}
|
||||
|
||||
function car_monitor_has_cookie(): bool
|
||||
{
|
||||
$cookie = $_COOKIE[CAR_MONITOR_COOKIE] ?? '';
|
||||
if (!is_string($cookie) || strpos($cookie, '.') === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
[$body, $sig] = explode('.', $cookie, 2);
|
||||
$expected = hash_hmac('sha256', $body, car_monitor_cookie_secret());
|
||||
if (!hash_equals($expected, $sig)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$decoded = base64_decode($body, true);
|
||||
if ($decoded === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$payload = json_decode($decoded, true);
|
||||
if (!is_array($payload)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (int)($payload['exp'] ?? 0) >= time();
|
||||
}
|
||||
|
||||
function car_monitor_launcher_session(): array
|
||||
{
|
||||
static $session = null;
|
||||
@@ -886,11 +954,19 @@ function car_monitor_launcher_session(): array
|
||||
if ($cookieHeader !== '') {
|
||||
$remoteSession = car_monitor_launcher_api_request('GET', 'https://chaegeon.com/custom/launcher/api.php?session=1', null, $cookieHeader);
|
||||
if (is_array($remoteSession)) {
|
||||
if (!empty($remoteSession['authenticated'])) {
|
||||
car_monitor_issue_cookie();
|
||||
}
|
||||
$session = $remoteSession;
|
||||
return $session;
|
||||
}
|
||||
}
|
||||
|
||||
if (car_monitor_has_cookie()) {
|
||||
$session = ['authenticated' => true, 'admin' => false];
|
||||
return $session;
|
||||
}
|
||||
|
||||
$session = ['authenticated' => false, 'admin' => false];
|
||||
return $session;
|
||||
}
|
||||
@@ -978,7 +1054,7 @@ function car_monitor_require_access(bool $json = false): void
|
||||
<main class="car-auth-page">
|
||||
<div id="findMyShortcut"></div>
|
||||
</main>
|
||||
<script src="https://chaegeon.com/custom/common/js/auth-pin.js?v=<?php echo (int)(@filemtime('/mnt/synology-web/custom/common/js/auth-pin.js') ?: time()); ?>"></script>
|
||||
<script src="https://chaegeon.com/custom/common/js/auth-pin.js"></script>
|
||||
<script>
|
||||
window.addEventListener('DOMContentLoaded', function () {
|
||||
window.CustomAuthPin && window.CustomAuthPin.render({
|
||||
@@ -1009,20 +1085,12 @@ function car_monitor_issue_pwa_cookie_if_requested(): void
|
||||
return;
|
||||
}
|
||||
|
||||
$commonAuth = '/mnt/synology-web/custom/common/auth.php';
|
||||
if (!is_readable($commonAuth)) {
|
||||
return;
|
||||
}
|
||||
|
||||
require_once $commonAuth;
|
||||
if (function_exists('custom_issue_auth_cookie')) {
|
||||
$cookieHeader = trim((string)($_SERVER['HTTP_COOKIE'] ?? ''));
|
||||
$remoteSession = $cookieHeader !== ''
|
||||
? car_monitor_launcher_api_request('GET', 'https://chaegeon.com/custom/launcher/api.php?session=1', null, $cookieHeader)
|
||||
: null;
|
||||
if (is_array($remoteSession) && !empty($remoteSession['authenticated'])) {
|
||||
custom_issue_auth_cookie(!empty($remoteSession['admin']));
|
||||
}
|
||||
$cookieHeader = trim((string)($_SERVER['HTTP_COOKIE'] ?? ''));
|
||||
$remoteSession = $cookieHeader !== ''
|
||||
? car_monitor_launcher_api_request('GET', 'https://chaegeon.com/custom/launcher/api.php?session=1', null, $cookieHeader)
|
||||
: null;
|
||||
if (is_array($remoteSession) && !empty($remoteSession['authenticated'])) {
|
||||
car_monitor_issue_cookie();
|
||||
}
|
||||
|
||||
header('Location: /car/monitor.php', true, 302);
|
||||
@@ -1031,12 +1099,6 @@ function car_monitor_issue_pwa_cookie_if_requested(): void
|
||||
|
||||
function car_monitor_auth_api(): void
|
||||
{
|
||||
$commonAuth = '/mnt/synology-web/custom/common/auth.php';
|
||||
if (!is_readable($commonAuth)) {
|
||||
json_response(['result' => 'fail', 'message' => 'auth_module_missing'], 500);
|
||||
}
|
||||
require_once $commonAuth;
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['failMessages'])) {
|
||||
json_response(['failMessages' => ['비밀번호가 틀립니다.']]);
|
||||
}
|
||||
@@ -1056,7 +1118,7 @@ function car_monitor_auth_api(): void
|
||||
'password' => $password,
|
||||
]);
|
||||
if (is_array($remote) && ($remote['result'] ?? '') === 'ok') {
|
||||
custom_issue_auth_cookie(false);
|
||||
car_monitor_issue_cookie();
|
||||
json_response(['result' => 'ok']);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user