차량 모니터 mnt 인증 의존 제거
This commit is contained in:
1 parent
a1a9f29fcc
commit
36f5a30450
1 file changed
+79
-17
+79
-17
@@ -17,6 +17,8 @@ define('DB_CHARSET', (string)($carDbConfig['charset'] ?? 'utf8mb4'));
|
|||||||
|
|
||||||
const LOG_LIMIT = 300;
|
const LOG_LIMIT = 300;
|
||||||
const CHART_LIMIT = 500;
|
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_MONTHLY_INCLUDED_BYTES = 104857600; // 100MB
|
||||||
const DATA_BILLING_UNIT_BYTES = 512; // 0.5KB
|
const DATA_BILLING_UNIT_BYTES = 512; // 0.5KB
|
||||||
const DATA_BILLING_UNIT_KRW = 0.011;
|
const DATA_BILLING_UNIT_KRW = 0.011;
|
||||||
@@ -874,6 +876,72 @@ function json_response(array $payload, int $status = 200): void
|
|||||||
exit;
|
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
|
function car_monitor_launcher_session(): array
|
||||||
{
|
{
|
||||||
static $session = null;
|
static $session = null;
|
||||||
@@ -886,11 +954,19 @@ function car_monitor_launcher_session(): array
|
|||||||
if ($cookieHeader !== '') {
|
if ($cookieHeader !== '') {
|
||||||
$remoteSession = car_monitor_launcher_api_request('GET', 'https://chaegeon.com/custom/launcher/api.php?session=1', null, $cookieHeader);
|
$remoteSession = car_monitor_launcher_api_request('GET', 'https://chaegeon.com/custom/launcher/api.php?session=1', null, $cookieHeader);
|
||||||
if (is_array($remoteSession)) {
|
if (is_array($remoteSession)) {
|
||||||
|
if (!empty($remoteSession['authenticated'])) {
|
||||||
|
car_monitor_issue_cookie();
|
||||||
|
}
|
||||||
$session = $remoteSession;
|
$session = $remoteSession;
|
||||||
return $session;
|
return $session;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (car_monitor_has_cookie()) {
|
||||||
|
$session = ['authenticated' => true, 'admin' => false];
|
||||||
|
return $session;
|
||||||
|
}
|
||||||
|
|
||||||
$session = ['authenticated' => false, 'admin' => false];
|
$session = ['authenticated' => false, 'admin' => false];
|
||||||
return $session;
|
return $session;
|
||||||
}
|
}
|
||||||
@@ -978,7 +1054,7 @@ function car_monitor_require_access(bool $json = false): void
|
|||||||
<main class="car-auth-page">
|
<main class="car-auth-page">
|
||||||
<div id="findMyShortcut"></div>
|
<div id="findMyShortcut"></div>
|
||||||
</main>
|
</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>
|
<script>
|
||||||
window.addEventListener('DOMContentLoaded', function () {
|
window.addEventListener('DOMContentLoaded', function () {
|
||||||
window.CustomAuthPin && window.CustomAuthPin.render({
|
window.CustomAuthPin && window.CustomAuthPin.render({
|
||||||
@@ -1009,20 +1085,12 @@ function car_monitor_issue_pwa_cookie_if_requested(): void
|
|||||||
return;
|
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'] ?? ''));
|
$cookieHeader = trim((string)($_SERVER['HTTP_COOKIE'] ?? ''));
|
||||||
$remoteSession = $cookieHeader !== ''
|
$remoteSession = $cookieHeader !== ''
|
||||||
? car_monitor_launcher_api_request('GET', 'https://chaegeon.com/custom/launcher/api.php?session=1', null, $cookieHeader)
|
? car_monitor_launcher_api_request('GET', 'https://chaegeon.com/custom/launcher/api.php?session=1', null, $cookieHeader)
|
||||||
: null;
|
: null;
|
||||||
if (is_array($remoteSession) && !empty($remoteSession['authenticated'])) {
|
if (is_array($remoteSession) && !empty($remoteSession['authenticated'])) {
|
||||||
custom_issue_auth_cookie(!empty($remoteSession['admin']));
|
car_monitor_issue_cookie();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
header('Location: /car/monitor.php', true, 302);
|
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
|
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'])) {
|
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['failMessages'])) {
|
||||||
json_response(['failMessages' => ['비밀번호가 틀립니다.']]);
|
json_response(['failMessages' => ['비밀번호가 틀립니다.']]);
|
||||||
}
|
}
|
||||||
@@ -1056,7 +1118,7 @@ function car_monitor_auth_api(): void
|
|||||||
'password' => $password,
|
'password' => $password,
|
||||||
]);
|
]);
|
||||||
if (is_array($remote) && ($remote['result'] ?? '') === 'ok') {
|
if (is_array($remote) && ($remote['result'] ?? '') === 'ok') {
|
||||||
custom_issue_auth_cookie(false);
|
car_monitor_issue_cookie();
|
||||||
json_response(['result' => 'ok']);
|
json_response(['result' => 'ok']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user