mirror of
https://github.com/andrey271192/PCAtelegram_web.git
synced 2026-09-20 11:55:32 +00:00
fix: persist admin sessions across restart
This commit is contained in:
@@ -119,16 +119,37 @@ def public_host_for_notes() -> str:
|
||||
return HOST if HOST != "0.0.0.0" else "127.0.0.1"
|
||||
|
||||
|
||||
def session_secret() -> bytes:
|
||||
user, password = load_admin_credentials()
|
||||
return f"{user}:{password}:{ADMIN_AUTH_FILE}".encode("utf-8")
|
||||
|
||||
|
||||
def make_session() -> str:
|
||||
token = secrets.token_urlsafe(32)
|
||||
SESSIONS[token] = time.time() + SESSION_TTL_SECONDS
|
||||
nonce = secrets.token_urlsafe(24)
|
||||
exp = int(time.time() + SESSION_TTL_SECONDS)
|
||||
payload = f"{exp}.{nonce}"
|
||||
sig = hmac.new(session_secret(), payload.encode("utf-8"), hashlib.sha256).hexdigest()
|
||||
token = f"{payload}.{sig}"
|
||||
SESSIONS[token] = exp
|
||||
return token
|
||||
|
||||
|
||||
def session_is_valid(token: str) -> bool:
|
||||
if not token:
|
||||
return False
|
||||
exp = SESSIONS.get(token)
|
||||
if not exp:
|
||||
return False
|
||||
parts = token.split(".")
|
||||
if len(parts) != 3:
|
||||
return False
|
||||
exp_raw, nonce, sig = parts
|
||||
if not exp_raw.isdigit() or not nonce:
|
||||
return False
|
||||
payload = f"{exp_raw}.{nonce}"
|
||||
expected = hmac.new(session_secret(), payload.encode("utf-8"), hashlib.sha256).hexdigest()
|
||||
if not hmac.compare_digest(sig, expected):
|
||||
return False
|
||||
exp = int(exp_raw)
|
||||
if exp < time.time():
|
||||
SESSIONS.pop(token, None)
|
||||
return False
|
||||
|
||||
@@ -636,6 +636,10 @@ async function api(path, options = {}) {
|
||||
if (options.body && !headers["Content-Type"]) headers["Content-Type"] = "application/json";
|
||||
const res = await fetch(path, { ...options, headers, credentials: "same-origin" });
|
||||
const data = await res.json().catch(() => ({}));
|
||||
if (res.status === 401) {
|
||||
window.location.assign("/");
|
||||
throw new Error("unauthorized");
|
||||
}
|
||||
if (!res.ok || data.ok === false) throw new Error(data.error || `HTTP ${res.status}`);
|
||||
return data.data ?? data;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
document.documentElement.dataset.theme = theme;
|
||||
}());
|
||||
</script>
|
||||
<link rel="stylesheet" href="/styles.css?v=2.5.0-admin25">
|
||||
<link rel="stylesheet" href="/styles.css?v=2.5.0-admin26">
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
@@ -482,6 +482,6 @@
|
||||
<button id="qrCopyBtn" type="button" class="soft" data-i18n="copyLink">Copy link</button>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/app.js?v=2.5.0-admin25" type="module"></script>
|
||||
<script src="/app.js?v=2.5.0-admin26" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user