Jelajahi Sumber

claude.md更新;back-to-top位置修改

admincjy 3 minggu lalu
induk
melakukan
9358ed59e0
2 mengubah file dengan 177 tambahan dan 33 penghapusan
  1. 173 29
      CLAUDE.md
  2. 4 4
      public/css/style.css

+ 173 - 29
CLAUDE.md

@@ -5,9 +5,12 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
 ## 项目概述
 
 CJYDocs 是一个基于 Node.js + Express 的轻量级 Markdown 文档管理和渲染系统,采用前后端分离架构。核心特点包括:
+- 🔐 **登录认证系统** - 基于 express-session 的会话管理,7天免登录
 - 通过解析 `index.md` 配置文件实现文档的层级化管理
 - 支持在线编辑功能,智能光标定位
 - 全文搜索、TOC 目录、响应式设计
+- 📁 **子目录支持** - 文档可以组织在子目录中
+- 🖼️ **图片资源服务** - 支持从文档目录加载图片
 - 高性能优化: DOM 缓存、事件委托、IntersectionObserver
 
 ## 开发命令
@@ -72,10 +75,16 @@ docker run -d \
 - 返回结构: `{ name, docs: [{ number, name, level, fullName }] }`
 
 **重要**: 添加新文档时:
-1. 在 `docs/分类名/` 下创建 `.md` 文件
-2. 在项目根目录的 `index.md` 中添加对应条目
+1. 在 `docs/分类名/` 下创建 `.md` 文件(可以放在子目录中,如 `docs/分类名/子目录/文档.md`)
+2. 在项目根目录的 `index.md` 中添加对应条目(子目录文档使用斜杠,如 `1: 子目录/文档.md`)
 3. 两者必须同时存在,文件名必须匹配
 
+**子目录支持**:
+- 文档可以组织在分类下的子目录中
+- index.md 格式: `1: 子目录/文档名.md`
+- API 路径: `/api/doc/分类名/子目录/文档名`
+- 图片引用: Markdown 中使用相对路径,后端会通过 `/api/image/:category/*` 提供服务
+
 ### 前端架构
 
 **DOM 缓存策略** (`reader.js:8-22`):
@@ -105,20 +114,72 @@ const DOM = {
 
 所有 API 都在 `server.js` 中定义:
 
+**认证相关**:
+- `POST /api/login` - 用户登录(密码: `cjy@0526`)
+- `POST /api/logout` - 用户登出
+- `GET /api/check-auth` - 检查登录状态
+
+**文档操作** (需要登录):
 - `GET /api/structure` - 获取完整文档结构(解析 index.md,带5秒缓存)
 - `GET /api/category/:category` - 获取指定分类信息
-- `GET /api/doc/:category/:docName` - 获取文档内容
-- `PUT /api/doc/:category/:docName` - 保存文档内容(在线编辑)
+- `GET /api/doc/:category/*` - 获取文档内容(支持子目录路径)
+- `PUT /api/doc/:category/*` - 保存文档内容(在线编辑,支持子目录)
 - `GET /api/search/:category?q=xxx&currentDoc=yyy` - 搜索文档
 
+**资源服务** (需要登录):
+- `GET /api/image/:category/*` - 获取文档目录中的图片资源
+
 **安全机制**:
-所有用户输入都经过 `sanitizePath()` 清理和 `validatePath()` 验证,防止路径遍历攻击。
+- 所有文档和图片 API 都需要登录认证(`requireAuth` 中间件)
+- 用户输入经过 `sanitizePath()` 清理和 `validatePath()` 验证,防止路径遍历攻击
+- Session 配置为 HttpOnly Cookie,防止 XSS 攻击
 
 **缓存策略**:
-`index.md` 解析结果缓存5秒(`server.js:9-12`),减少文件系统读取频率。
+`index.md` 解析结果缓存5秒(`server.js:14-16`),减少文件系统读取频率。
 
 ### 关键功能实现
 
+#### 0. 登录认证系统
+`server.js:10-167` - 完整的会话管理和认证系统:
+
+**认证流程**:
+```
+用户访问 / 或 /reader.html → 检查 session.isAuthenticated
+    ↓ (未登录)
+重定向到 /login.html
+    ↓
+用户输入密码 → POST /api/login
+    ↓
+验证密码 (cjy@0526) → 创建 session
+    ↓
+重定向到首页 → 可以访问所有文档
+```
+
+**Session 配置** (`server.js:48-61`):
+- 有效期: 7天 (`maxAge: 7 * 24 * 60 * 60 * 1000`)
+- Cookie 名称: `cjydocs.sid`
+- HttpOnly: true (防止 XSS)
+- SameSite: lax (允许合理的跨站请求)
+- Rolling: true (每次请求重置过期时间)
+
+**认证中间件** (`server.js:64-76`):
+```javascript
+function requireAuth(req, res, next) {
+  if (req.session && req.session.isAuthenticated) {
+    return next();
+  }
+  // API 请求返回 401,页面请求重定向
+  if (req.path.startsWith('/api')) {
+    return res.status(401).json({ error: '未登录,请先登录' });
+  }
+  res.redirect('/login.html');
+}
+```
+
+**密码配置**:
+- 硬编码在 `server.js:11` (`PASSWORD = 'cjy@0526'`)
+- 生产环境建议改用环境变量: `process.env.PASSWORD`
+
 #### 1. Markdown 渲染
 使用 `marked.js` + `highlight.js`,配置在 `reader.js:25-38`
 
@@ -144,8 +205,30 @@ const DOM = {
 - 搜索防抖:500ms,减少 40% 的 API 请求
 - `IntersectionObserver`:替代 scroll 事件,性能提升 20-30%
 
-#### 6. 在线编辑功能
-`reader.js:820-1095` + `server.js:113-156` - 完整的在线文档编辑系统:
+#### 6. 图片资源服务
+`server.js:170-202` - 从文档目录提供图片资源:
+
+**功能说明**:
+- Markdown 文档可以引用同目录或子目录下的图片
+- 图片通过 API 端点 `/api/image/:category/*` 提供
+- 支持路径验证,防止越权访问
+
+**使用示例**:
+```markdown
+<!-- Markdown 文档中 -->
+![图片描述](assets/test.png)
+
+<!-- 前端会自动转换为 -->
+/api/image/分类名/assets/test.png
+```
+
+**安全验证**:
+- 路径必须在对应分类的 docs 目录内
+- 需要登录认证才能访问
+- 使用 `validatePath()` 确保不会访问到系统其他文件
+
+#### 7. 在线编辑功能
+`reader.js:820-1095` + `server.js:278-324` - 完整的在线文档编辑系统:
 
 **编辑器特性**:
 - **智能光标定位** (`reader.js:869-988`):根据当前阅读位置(标题、段落)在编辑器中自动定位到对应的 markdown 源码行
@@ -184,22 +267,29 @@ saveDocument() → PUT /api/doc/:category/:docName
 
 ```
 cjydocs/
-├── server.js              # Express 后端(288行)
-│                          # - 所有 API 端点(GET/PUT)
+├── server.js              # Express 后端(499行)
+│                          # - 登录认证和会话管理
+│                          # - 所有 API 端点(GET/PUT/POST)
 │                          # - index.md 解析逻辑(带5秒缓存)
 │                          # - 安全验证函数(sanitizePath, validatePath)
 │                          # - 搜索引擎实现
+│                          # - 图片资源服务
 ├── index.md               # 文档结构配置文件(项目根目录)
 ├── docs/
 │   └── 分类名/
-│       └── 文档.md        # 实际文档内容(可通过在线编辑修改)
+│       ├── 文档.md        # 实际文档内容(可通过在线编辑修改)
+│       ├── 子目录/
+│       │   └── 文档.md    # 支持子目录组织
+│       └── assets/
+│           └── 图片.png   # 图片资源
 ├── public/
-│   ├── index.html         # 首页(显示分类列表)35行
-│   ├── reader.html        # 阅读器页面(三栏布局+编辑器)129行
+│   ├── login.html         # 登录页面
+│   ├── index.html         # 首页(显示分类列表)
+│   ├── reader.html        # 阅读器页面(三栏布局+编辑器)
 │   ├── css/style.css      # 统一样式
 │   └── js/
-│       ├── index.js       # 首页逻辑(70行)
-│       └── reader.js      # 阅读器核心逻辑(1113行)
+│       ├── index.js       # 首页逻辑
+│       └── reader.js      # 阅读器核心逻辑
 │                          # - DOM缓存、事件委托
 │                          # - 搜索、TOC、侧边栏交互
 │                          # - 在线编辑器(智能光标定位)
@@ -213,9 +303,15 @@ cjydocs/
 
 ### 添加新 API
 1. 在 `server.js` 中定义新路由
-2. 使用 `sanitizePath()` 清理所有用户输入
-3. 使用 `validatePath()` 验证文件路径在 `docs/` 目录内
-4. 返回详细的错误信息(但不泄露内部路径)
+2. 如果需要登录,添加 `requireAuth` 中间件
+3. 使用 `sanitizePath()` 清理所有用户输入
+4. 使用 `validatePath()` 验证文件路径在 `docs/` 目录内
+5. 返回详细的错误信息(但不泄露内部路径)
+
+### 修改登录密码
+1. 修改 `server.js:11` 中的 `PASSWORD` 常量
+2. 或使用环境变量: `const PASSWORD = process.env.PASSWORD || 'cjy@0526';`
+3. 考虑实施更安全的认证方案(如使用数据库存储哈希密码)
 
 ### 修改前端逻辑
 1. 优先使用 `DOM` 缓存对象获取元素
@@ -239,10 +335,26 @@ cjydocs/
 
 ## 安全注意事项
 
-**路径遍历防护**:
-- `sanitizePath()` - 移除 `../`、`/`、`\` 等危险字符
-- `validatePath()` - 确保解析后的路径在 `docs/` 目录内
-- 所有 API 都必须使用这两个函数验证用户输入
+### 1. 认证和会话安全
+**Session 配置**:
+- HttpOnly Cookie - 防止 JavaScript 访问(XSS 防护)
+- SameSite: lax - 防止 CSRF 攻击
+- 会话密钥应使用环境变量,不要硬编码
+- 生产环境建议启用 HTTPS 并设置 `secure: true`
+
+**密码安全**:
+- 当前使用硬编码密码 `cjy@0526`,仅适用于开发/个人使用
+- 生产环境建议:
+  - 使用环境变量存储密码
+  - 实施密码哈希(如 bcrypt)
+  - 考虑多用户支持和数据库存储
+  - 添加登录失败限制和验证码
+
+### 2. 路径遍历防护
+**核心函数**:
+- `sanitizePath()` (`server.js:19-29`) - 移除 `../`、开头的 `/`、`\` 等危险字符
+- `validatePath()` (`server.js:32-36`) - 确保解析后的路径在 `docs/` 目录内
+- 所有文件操作 API 都必须使用这两个函数验证用户输入
 
 **示例**:
 ```javascript
@@ -253,6 +365,11 @@ if (!validatePath(docPath, docsDir)) {
 }
 ```
 
+**注意事项**:
+- 对于子目录路径,`sanitizePath()` 会移除所有斜杠,因此某些参数(如 `currentDoc`)不能使用此函数
+- API 路由使用通配符 `*` 来支持子目录,如 `/api/doc/:category/*`
+- 即使支持子目录,`validatePath()` 依然确保路径不会越出 docs 目录
+
 ## 响应式设计要点
 
 ### 移动端适配 (≤768px)
@@ -271,11 +388,30 @@ if (!validatePath(docPath, docsDir)) {
 
 ## 常见问题
 
+### 登录相关
+
+#### 忘记密码
+- 查看 `server.js:11` 中的 `PASSWORD` 常量
+- 或启动服务器时查看控制台输出,会显示当前密码
+
+#### 登录后仍然重定向到登录页
+检查:
+1. 浏览器是否启用了 Cookie
+2. 浏览器控制台是否有 CORS 错误
+3. Session 配置是否正确(特别是跨域场景)
+
+#### Session 频繁过期
+- 检查 `server.js:48-61` 中的 session 配置
+- `rolling: true` 应该会在每次请求时重置过期时间
+- 确保浏览器没有频繁清除 Cookie
+
 ### 文档显示为空或 404
 检查:
-1. 项目根目录的 `index.md` 中是否有对应条目
-2. 文件名是否与 `index.md` 中的名称完全一致(区分大小写)
-3. 文件是否在正确的分类目录下
+1. 是否已登录(未登录会重定向到登录页)
+2. 项目根目录的 `index.md` 中是否有对应条目
+3. 文件名是否与 `index.md` 中的名称完全一致(区分大小写)
+4. 文件是否在正确的分类目录下
+5. 如果是子目录文档,路径格式是否正确(使用正斜杠 `/`)
 
 ### 搜索功能不工作
 检查:
@@ -297,10 +433,18 @@ if (!validatePath(docPath, docsDir)) {
 
 ### 编辑功能无法保存
 检查:
-1. 文件是否存在(编辑功能不能创建新文件)
-2. 浏览器控制台是否有 PUT API 错误
-3. 服务器是否返回 403(路径验证失败)或 400(数据格式错误)
-4. 文件权限是否允许服务器写入
+1. 是否已登录(编辑功能需要认证)
+2. 文件是否存在(编辑功能不能创建新文件)
+3. 浏览器控制台是否有 PUT API 错误
+4. 服务器是否返回 403(路径验证失败)或 400(数据格式错误)
+5. 文件权限是否允许服务器写入
+
+### 图片无法显示
+检查:
+1. 图片文件是否在对应分类的 docs 目录下
+2. Markdown 中的图片路径是否正确(相对路径)
+3. 浏览器控制台中图片请求的 URL 是否正确
+4. 是否已登录(图片资源需要认证)
 
 ## 技术栈版本
 

+ 4 - 4
public/css/style.css

@@ -1087,13 +1087,13 @@ body {
     }
 
     .back-to-top {
-        bottom: 100px;
-        right: 20px;
+        bottom: 78px !important;
+        right: 20px !important;
     }
 
     .edit-btn {
-        bottom: 100px;
-        right: 75px;
+        bottom: 78px !important;
+        right: 75px !important;
     }
 
     .editor-header {