feat: WmailHub v1.0.0 —— Cloudflare Email Workers 邮件接收与转发平台(本地可用版本)
- Console:React 19 + antd 6.6.5 前端(登录 admin/admin)+ Hono 管理 API (Nodes/Domains/Mailboxes/Emails/Webhooks/Keys/OAuth/Admin) - Node:Bun 转发节点(HMAC 签名、有限重试、心跳、结构化日志、优雅退出) - Email Worker:Cloudflare email handler + 本地联调入口 - shared:HMAC 协议(docs/04)、wmh_ Key(32 位)、AES-GCM 加密、SSRF 防护 - 邮件管线:postal-mime 解析、附件、catch-all、限额、malformed 降级、TTL 1 天 - Webhook:签名投递、指数退避重试、SSRF 校验、投递日志 - API v1 + MCP(JSON-RPC,六工具,凭据 kind 隔离) - Cloudflare OAuth:真实 + 本地 sim 模式,自动安装管线(幂等,无需手工命令) - 测试:bun test 41 例(协议安全/管线/TTL/Webhook/SSRF/MCP/OAuth/鉴权)+ Playwright UI 冒烟 - LOGO/favicon 由 codex CLI 生成
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
/** 认证与会话测试:登录、错误密码、会话校验、登出、CSRF Origin */
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { authedFetch, loginCookie, makeTestEnv } from "./helpers.ts";
|
||||
|
||||
describe("用户认证(默认 admin/admin)", () => {
|
||||
test("正确账密登录并拿到会话", async () => {
|
||||
const t = await makeTestEnv();
|
||||
const cookie = await loginCookie(t);
|
||||
const me = await authedFetch(t, cookie, "http://localhost/api/auth/me");
|
||||
expect(me.status).toBe(200);
|
||||
const data = (await me.json()) as { user: { username: string } };
|
||||
expect(data.user.username).toBe("admin");
|
||||
});
|
||||
|
||||
test("错误密码返回 401", async () => {
|
||||
const t = await makeTestEnv();
|
||||
const resp = await t.app.fetch(
|
||||
new Request("http://localhost/api/auth/login", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ username: "admin", password: "wrong" }),
|
||||
}),
|
||||
t.env,
|
||||
);
|
||||
expect(resp.status).toBe(401);
|
||||
});
|
||||
|
||||
test("无会话访问受保护接口返回 401", async () => {
|
||||
const t = await makeTestEnv();
|
||||
const resp = await t.app.fetch(new Request("http://localhost/api/nodes"), t.env);
|
||||
expect(resp.status).toBe(401);
|
||||
});
|
||||
|
||||
test("登出后会话失效(clients 清 cookie 后 401)", async () => {
|
||||
const t = await makeTestEnv();
|
||||
const cookie = await loginCookie(t);
|
||||
await authedFetch(t, cookie, "http://localhost/api/auth/logout", { method: "POST" });
|
||||
const me = await t.app.fetch(new Request("http://localhost/api/auth/me"), t.env);
|
||||
expect(me.status).toBe(401);
|
||||
});
|
||||
|
||||
test("伪造会话 cookie 被拒(签名不匹配)", async () => {
|
||||
const t = await makeTestEnv();
|
||||
const resp = await authedFetch(t, "wmh_session=eyJhIjoxfQ.deadbeef", "http://localhost/api/auth/me");
|
||||
expect(resp.status).toBe(401);
|
||||
});
|
||||
|
||||
test("跨域 Origin 写请求被拒(CSRF)", async () => {
|
||||
const t = await makeTestEnv();
|
||||
const cookie = await loginCookie(t);
|
||||
const resp = await authedFetch(t, cookie, "http://localhost/api/keys", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", Origin: "https://evil.example.com" },
|
||||
body: JSON.stringify({ kind: "api" }),
|
||||
});
|
||||
expect(resp.status).toBe(403);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user