Browse Source

feat(comments): guest display name and body validation

Made-with: Cursor
main
npmrun 4 hours ago
parent
commit
607f70477f
  1. 38
      server/utils/post-comment-guest.test.ts
  2. 38
      server/utils/post-comment-guest.ts

38
server/utils/post-comment-guest.test.ts

@ -0,0 +1,38 @@
import { describe, expect, test } from "bun:test";
import {
GuestCommentValidationError,
normalizeGuestDisplayName,
validateGuestCommentBody,
} from "./post-comment-guest";
describe("normalizeGuestDisplayName", () => {
test("trims and accepts valid name", () => {
expect(normalizeGuestDisplayName(" ada ")).toBe("ada");
});
test("rejects empty", () => {
expect(() => normalizeGuestDisplayName(" ")).toThrow(GuestCommentValidationError);
});
test("rejects too long", () => {
expect(() => normalizeGuestDisplayName("a".repeat(33))).toThrow(GuestCommentValidationError);
});
});
describe("validateGuestCommentBody", () => {
test("accepts plain text", () => {
expect(validateGuestCommentBody("你好,世界")).toBe("你好,世界");
});
test("rejects http URL", () => {
expect(() => validateGuestCommentBody("see http://x.com")).toThrow(GuestCommentValidationError);
});
test("rejects markdown link", () => {
expect(() => validateGuestCommentBody("[a](http://b)")).toThrow(GuestCommentValidationError);
});
test("rejects too long", () => {
expect(() => validateGuestCommentBody("z".repeat(501))).toThrow(GuestCommentValidationError);
});
});

38
server/utils/post-comment-guest.ts

@ -0,0 +1,38 @@
const MAX_NAME = 32;
const MAX_BODY = 500;
export class GuestCommentValidationError extends Error {
constructor(message: string) {
super(message);
this.name = "GuestCommentValidationError";
}
}
export function normalizeGuestDisplayName(raw: string): string {
const t = raw.trim();
if (!t) {
throw new GuestCommentValidationError("请填写昵称");
}
if (t.length > MAX_NAME) {
throw new GuestCommentValidationError("昵称过长");
}
return t;
}
/** 返回 trim 后正文;违规抛 GuestCommentValidationError(由 API 映射为 400) */
export function validateGuestCommentBody(raw: string): string {
const t = raw.trim();
if (!t) {
throw new GuestCommentValidationError("请填写内容");
}
if (t.length > MAX_BODY) {
throw new GuestCommentValidationError("内容过长");
}
if (/https?:\/\//i.test(t) || /\bwww\./i.test(t)) {
throw new GuestCommentValidationError("不能包含链接");
}
if (/\[[^\]]*\]\([^)]*\)/.test(t)) {
throw new GuestCommentValidationError("不能使用 Markdown 链接");
}
return t;
}
Loading…
Cancel
Save