diff --git a/docs/code-design.md b/docs/code-design.md index 50560b8..4b09ab5 100644 --- a/docs/code-design.md +++ b/docs/code-design.md @@ -57,6 +57,12 @@ GitHub Actions 的 `.github/workflows/deploy.yml` 只监听 `master` 分支。 会话签名密钥从 `WEREAD_SESSION_SECRET` 读取且必须稳定配置;缺失时服务对动态页面和 API 以 503 失败关闭。永久会话时长是固定 5 天,不因每次请求续期。Cookie 为 HttpOnly、SameSite=Lax,并默认 Secure;仅本机 HTTP 预览可以关闭 Secure。生产站点须使用 HTTPS。前端 JSON 写请求从页面 meta 标签读取 CSRF token 并放入 `X-CSRF-Token` 请求头,表单请求使用隐藏字段。 +## 网站备案页脚 + +正式看板页脚保留数据状态,并展示可点击的 ICP 备案号,链接至工信部备案查询平台。窄屏时隐藏次要的数据快照,备案号仍可见。 + +例:正式域名为 `laohang.space`、备案号为 `浙ICP备202607916号-1`,首页页脚显示该备案号;点击后打开 `https://beian.miit.gov.cn/`。截图里的公安联网备案数据码不是公安备案号,不作为备案号码展示。 + 应用未内置登录尝试限流;公网部署应在可信反向代理上为 `POST /auth/login` 设置频率限制,且不要直接信任未校验的 `X-Forwarded-For`。 ## 示例与真实接口的边界 diff --git a/docs/technical-guide.md b/docs/technical-guide.md index e4d3744..9807551 100644 --- a/docs/technical-guide.md +++ b/docs/technical-guide.md @@ -148,6 +148,8 @@ DEPLOY_BRANCH=master ./deploy.sh 浏览器旧目标不会自动覆盖数据库。在原访问地址打开“阅读目标”,点击“导入已有目标”;数据库已有同一 ID 时跳过,整批成功才标记导入完成。`weread-goals` 原数据保留,`weread-goals-imported` 只记录已导入。不同浏览器、域名和端口的旧存储需要分别在原地址导入。 +正式网站域名 `laohang.space` 的页脚展示工信部 ICP 备案号 `浙ICP备202607916号-1`,点击后跳转至工信部备案查询平台。公安联网备案数据码不是公安备案号,因此不在页脚作为公安备案信息展示。 + 保存失败会保留表单并提示重试;读取失败显示错误和重试按钮,不冒充空列表。若新建提示 ID 已存在,刷新目标列表确认上次请求是否已经保存。数据库不可用或尚未执行迁移时,目标接口返回 503,不退回浏览器保存。 验证命令: diff --git a/templates/index.html b/templates/index.html index 03d8d3a..adb62b6 100644 --- a/templates/index.html +++ b/templates/index.html @@ -4,13 +4,17 @@ 阅间 · 微信读书看板 + -
L
正在连接微信读书…阅读目标跨浏览器保存
+
L
正在连接微信读书…阅读目标跨浏览器保存

书籍详情

MAKE ROOM FOR READING

新建阅读目标

想读些什么?

选择书籍或加入书单当前书目,重复书籍只算一本,已读完直接计入完成。

diff --git a/tests/test_auth.py b/tests/test_auth.py index df252cd..9cf74b1 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -80,6 +80,19 @@ class AuthTests(unittest.TestCase): self.assertEqual(client.get("/api/reading/status").status_code, 401) self.assertEqual(client.get("/api/v2/status").status_code, 401) + def test_home_footer_displays_icp_record_link(self): + with patch.dict(os.environ, {"WEREAD_SESSION_SECRET": "test-secret"}): + web_app = importlib.import_module("app").app + web_app.config.update(SECRET_KEY="test-secret", SESSION_COOKIE_SECURE=False) + client = web_app.test_client() + with client.session_transaction() as session: + session["auth_user"] = "reader" + + response = client.get("/") + self.assertEqual(response.status_code, 200) + self.assertIn(b"https://beian.miit.gov.cn/", response.data) + self.assertIn("浙ICP备202607916号-1".encode(), response.data) + def test_first_account_requires_setup_token_and_is_stored_as_hash(self): page = self.client.get("/login") csrf = self.csrf(page)