fix: secure cloud sessions and replace stale dashboard examples
This commit is contained in:
@@ -30,7 +30,7 @@ STORAGE_DIR = Path(os.environ.get("APP_STORAGE_DIR", ROOT / "data" / "files"))
|
||||
SESSION_COOKIE = "cw_fusion_session" if portal_sso.enabled() else "cw_session"
|
||||
# Local plain-HTTP deployment: the cookie intentionally carries no Secure
|
||||
# flag (see docs/decisions/003-auth.md).
|
||||
COOKIE_FLAGS = "HttpOnly; SameSite=Lax; Path=/"
|
||||
COOKIE_FLAGS = "HttpOnly; SameSite=Lax; Path=/" + ("; Secure" if os.environ.get("PORTAL_COOKIE_SECURE") == "1" else "")
|
||||
|
||||
|
||||
class AppHandler(portal_sso.PortalMixin, SimpleHTTPRequestHandler):
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
import hashlib
|
||||
import sqlite3
|
||||
import tempfile
|
||||
import unittest
|
||||
@@ -13,6 +14,7 @@ from bank_importer.db import connect, migrate, utc_now
|
||||
|
||||
class LedgerBase(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
self._source_file_sequence = 0
|
||||
self.temp_dir = tempfile.TemporaryDirectory()
|
||||
self.addCleanup(self.temp_dir.cleanup)
|
||||
root = Path(self.temp_dir.name)
|
||||
@@ -66,13 +68,15 @@ class LedgerBase(unittest.TestCase):
|
||||
summary: str | None = None,
|
||||
purpose: str | None = None,
|
||||
) -> int:
|
||||
self._source_file_sequence = getattr(self, "_source_file_sequence", 0) + 1
|
||||
fixture_hash = hashlib.sha256(f"ledger-fixture-{self._source_file_sequence}".encode()).hexdigest()
|
||||
with self.connection:
|
||||
cursor = self.connection.execute(
|
||||
"""
|
||||
INSERT INTO source_files (sha256, original_filename, size_bytes, storage_path, created_at)
|
||||
VALUES (?, '测试.xlsx', 1, 'data/files/测试.xlsx', ?)
|
||||
""",
|
||||
(utc_now(), utc_now()),
|
||||
(fixture_hash, utc_now()),
|
||||
)
|
||||
source_file_id = int(cursor.lastrowid)
|
||||
cursor = self.connection.execute(
|
||||
|
||||
@@ -5,6 +5,7 @@ idempotency, concurrency, Decimal precision and B-44 eligibility."""
|
||||
from __future__ import annotations
|
||||
|
||||
from decimal import Decimal
|
||||
import hashlib
|
||||
from pathlib import Path
|
||||
import sqlite3
|
||||
import tempfile
|
||||
@@ -17,6 +18,7 @@ from bank_importer.db import connect, migrate, utc_now
|
||||
|
||||
class MatchingBase(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
self._source_file_sequence = 0
|
||||
self.temp_dir = tempfile.TemporaryDirectory()
|
||||
self.addCleanup(self.temp_dir.cleanup)
|
||||
root = Path(self.temp_dir.name)
|
||||
@@ -74,13 +76,15 @@ class MatchingBase(unittest.TestCase):
|
||||
summary: str | None = None,
|
||||
sheet: str = "流水",
|
||||
) -> int:
|
||||
self._source_file_sequence = getattr(self, "_source_file_sequence", 0) + 1
|
||||
fixture_hash = hashlib.sha256(f"matching-fixture-{self._source_file_sequence}".encode()).hexdigest()
|
||||
with self.connection:
|
||||
cursor = self.connection.execute(
|
||||
"""
|
||||
INSERT INTO source_files (sha256, original_filename, size_bytes, storage_path, created_at)
|
||||
VALUES (?, '测试.xlsx', 1, 'data/files/测试.xlsx', ?)
|
||||
""",
|
||||
(utc_now(), utc_now()),
|
||||
(fixture_hash, utc_now()),
|
||||
)
|
||||
source_file_id = int(cursor.lastrowid)
|
||||
cursor = self.connection.execute(
|
||||
|
||||
+6
-6
@@ -205,8 +205,8 @@
|
||||
</div>
|
||||
<div class="detail-box row-between" style="margin-top: 12px;">
|
||||
<div>
|
||||
<div style="font-weight: 650;">金牛农业 → 应收 386.24 万元</div>
|
||||
<div class="meta" style="margin-top: 2px;">14 笔(借 9 / 贷 5)· 最早未结 2026-03-12</div>
|
||||
<div style="font-weight: 650;">查看所选公司的实际往来</div>
|
||||
<div class="meta" style="margin-top: 2px;">金额、统计截止日及未解决事项以往来查询结果为准</div>
|
||||
</div>
|
||||
<button class="btn btn-sm" data-view-link="pair">查看逐笔往来</button>
|
||||
</div>
|
||||
@@ -217,9 +217,9 @@
|
||||
<span class="card-title">账期与结账<span class="sub" id="dashboardPeriodSub">每月 5 日结账 · 全局起算日 2026-01-01</span></span>
|
||||
</div>
|
||||
<dl class="kv">
|
||||
<dt>当前账期</dt><dd>2026-07 · 进行中</dd>
|
||||
<dt>结账日</dt><dd style="color: var(--warn); font-weight: 650;">2026-08-29(顺延)· 距今 9 天</dd>
|
||||
<dt>上一账期</dt><dd>2026-06 · 已于 07-03 结账</dd>
|
||||
<dt>待结账期</dt><dd id="dashboardClosePeriod">正在读取</dd>
|
||||
<dt>结账状态</dt><dd id="dashboardCloseStatus">正在读取</dd>
|
||||
<dt>最近结账</dt><dd id="dashboardCloseHistory">正在读取</dd>
|
||||
</dl>
|
||||
<button class="btn" data-view-link="settings" style="width: 100%; margin-top: 14px;">进入结账检查</button>
|
||||
</div>
|
||||
@@ -1257,6 +1257,6 @@
|
||||
<script src="theme.js?v=1"></script>
|
||||
<script src="select.js?v=1"></script>
|
||||
<script src="datepicker.js?v=2"></script>
|
||||
<script src="app.js?v=18"></script>
|
||||
<script src="app.js?v=18-cloud1"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -2278,6 +2278,11 @@ function applyClosePanel(overview) {
|
||||
state.periodClose = overview;
|
||||
const close = overview.close || {};
|
||||
const ym = close.year_month || overview.target_month || "—";
|
||||
if ($("#dashboardClosePeriod")) $("#dashboardClosePeriod").textContent = ym;
|
||||
if ($("#dashboardCloseStatus")) $("#dashboardCloseStatus").textContent =
|
||||
({ closed: "已结账", closing: "处理中", failed: "结账失败", reopened: "已重开", open: "未结账" })[close.status] || "待结账检查";
|
||||
if ($("#dashboardCloseHistory")) $("#dashboardCloseHistory").textContent = overview.history
|
||||
? `${overview.history.year_month} · ${String(overview.history.closed_at || "").slice(0, 10)}` : "尚无结账记录";
|
||||
renderTimeline(overview.timeline);
|
||||
const start = state.calculationStart || "—";
|
||||
if ($("#timelineSub")) $("#timelineSub").textContent = `全局起算日 ${start} 起,每月 ${overview.closing_day || "—"} 日结账`;
|
||||
@@ -2388,6 +2393,9 @@ async function loadPeriodClose() {
|
||||
if (response?.status === 401) { window.location.href = window.PORTAL_HOME || "index.html"; return; }
|
||||
const result = await response?.json().catch(() => null);
|
||||
if (!response?.ok || result?.status !== "ok") {
|
||||
for (const id of ['dashboardClosePeriod', 'dashboardCloseStatus', 'dashboardCloseHistory']) {
|
||||
if ($(`#${id}`)) $(`#${id}`).textContent = '读取失败,请重试';
|
||||
}
|
||||
showToast("结账状态加载失败", result?.message || "请稍后重试", "danger");
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user