feat: awesome index 全功能实现
- M1-M2: 数据层与核心API(DuckDB, entries/tags/comments/search服务) - M3: SSR页面(EJS模板,接真实数据) - M4: 管理后台(登录/用户/内容源/AI ingest) - M5: 采集层(scheduler+rss/html/eryajf适配器) - M6: MCP只读接口(Streamable HTTP, 4工具) - M7: Docker部署(Dockerfile+docker-compose) - 测试: 10个用例全部通过 - 修复: DuckDB连接参数绑定、状态机迁移、标签树操作
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
import * as sourceService from "../services/source.service.js";
|
||||
import { HttpError } from "./errors.js";
|
||||
|
||||
export function requireLogin(req, res, next) {
|
||||
if (!req.session.userId) {
|
||||
throw new HttpError(401, "unauthorized", "请先登录");
|
||||
}
|
||||
next();
|
||||
}
|
||||
|
||||
export function requireAdmin(req, res, next) {
|
||||
if (!req.session.userId) {
|
||||
throw new HttpError(401, "unauthorized", "请先登录");
|
||||
}
|
||||
if (req.session.role !== "admin") {
|
||||
throw new HttpError(403, "forbidden", "需要管理员权限");
|
||||
}
|
||||
next();
|
||||
}
|
||||
|
||||
export function loadUser(req, res, next) {
|
||||
res.locals.user = req.session.userId
|
||||
? { id: req.session.userId, username: req.session.username, role: req.session.role }
|
||||
: null;
|
||||
next();
|
||||
}
|
||||
|
||||
export async function aiSourceFromRequest(req) {
|
||||
const key = req.get("x-ingest-key") || "";
|
||||
const source = await sourceService.findByApiKey(key);
|
||||
if (!source) {
|
||||
throw new HttpError(403, "invalid_key", "AI 录入密钥无效或未启用");
|
||||
}
|
||||
return source;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
export class HttpError extends Error {
|
||||
constructor(status, code, message) {
|
||||
super(message);
|
||||
this.status = status;
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
|
||||
export function notFoundHandler(req, res) {
|
||||
if (req.path.startsWith("/api/")) {
|
||||
return res.status(404).json({ ok: false, error: { code: "not_found", message: "接口不存在" } });
|
||||
}
|
||||
res.status(404).send("404 Not Found");
|
||||
}
|
||||
|
||||
export function errorHandler(err, req, res, _next) {
|
||||
const status = err.status || 500;
|
||||
if (status >= 500) console.error(err);
|
||||
const message = err.message || "服务器内部错误";
|
||||
if (req.path.startsWith("/api/") || req.path === "/mcp") {
|
||||
return res.status(status).json({ ok: false, error: { code: err.code || "error", message } });
|
||||
}
|
||||
res.status(status).send(message);
|
||||
}
|
||||
Reference in New Issue
Block a user