Files
phptits 0d6cd37579 DevOS v1 + Phase 2: unified resource model, infra ops, website deployment, AI chat ops
- Monorepo: NestJS API (Fastify) + React web (antd/ProComponents) + shared packages
- PostgreSQL/Prisma (unified resources, relations graph, audit, events, jobs)
- Auth/RBAC/workspace isolation, credential vault (AES-256-GCM)
- Servers/SSH, Docker discovery & lifecycle, Job Center
- Websites & deployments (git provider credential clone, env, health verification)
- Domains/DNS (Cloudflare adapter), certificates (TLS probe), monitoring
- Automation (cron/event/webhook HMAC + notifications), AI Gateway, MCP (29 tools)
- AI chat window (LLM function-calling + rules fallback, SSE streaming, approvals)
- Notes: Vditor WYSIWYG markdown editor, non-blocking autosave
- Tests: 35 unit/security tests; UI audit clean (desktop+mobile, deep links)
2026-09-10 06:35:55 +00:00

59 lines
2.2 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/** JWT 签发/校验单元测试(@devos/auth) */
import { describe, test, expect } from "bun:test";
import { signJwt, verifyJwt, hashPassword, verifyPassword } from "../packages/auth/src/index";
const SECRET = "test-secret";
describe("JWT", () => {
test("签发并校验合法令牌", () => {
const token = signJwt({ sub: "u1", email: "a@b.c", wid: "w1" }, SECRET, { nowSec: 1000, expiresInSec: 3600 });
const result = verifyJwt(token, SECRET, 2000);
expect(result.ok).toBe(true);
if (result.ok) {
expect(result.payload.sub).toBe("u1");
expect(result.payload.wid).toBe("w1");
expect(result.payload.exp).toBe(4600);
}
});
test("过期令牌被拒绝", () => {
const token = signJwt({ sub: "u1", email: "a@b.c", wid: null }, SECRET, { nowSec: 1000, expiresInSec: 100 });
const result = verifyJwt(token, SECRET, 2000);
expect(result.ok).toBe(false);
if (!result.ok) expect(result.reason).toBe("EXPIRED");
});
test("篡改签名被拒绝", () => {
const token = signJwt({ sub: "u1", email: "a@b.c", wid: null }, SECRET);
const parts = token.split(".");
const tampered = `${parts[0]}.${parts[1]}.AAAA${parts[2].slice(4)}`;
expect(verifyJwt(tampered, SECRET).ok).toBe(false);
});
test("错误密钥被拒绝", () => {
const token = signJwt({ sub: "u1", email: "a@b.c", wid: null }, SECRET);
expect(verifyJwt(token, "other-secret").ok).toBe(false);
});
test("alg 混淆攻击被拒绝(仅接受 HS256)", () => {
const forgedHeader = Buffer.from(JSON.stringify({ alg: "none" })).toString("base64url");
const payload = Buffer.from(JSON.stringify({ sub: "u1", exp: 9999999999 })).toString("base64url");
const forged = `${forgedHeader}.${payload}.`;
expect(verifyJwt(forged, SECRET).ok).toBe(false);
});
test("畸形令牌被拒绝", () => {
expect(verifyJwt("abc", SECRET).ok).toBe(false);
expect(verifyJwt("a.b.c", SECRET).ok).toBe(false);
});
});
describe("Password", () => {
test("哈希并校验密码", async () => {
const hash = await hashPassword("MyPassword123!");
expect(hash).not.toContain("MyPassword123!");
expect(await verifyPassword("MyPassword123!", hash)).toBe(true);
expect(await verifyPassword("wrong", hash)).toBe(false);
});
});