mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-28 04:02:18 +01:00
Harden Clip publish moderation defaults
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
e10d403e5e
commit
24b1191ca2
2 files changed
+63
-1
No files matched your search
@@ -168,6 +168,59 @@ describe("clip routes", () => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("normalizes public publish moderation and trust states before persistence", async () => {
|
||||
const companyId = "11111111-1111-4111-8111-111111111111";
|
||||
const clipId = "22222222-2222-4222-8222-222222222222";
|
||||
const revisionId = "33333333-3333-4333-8333-333333333333";
|
||||
mockClipService.publish.mockResolvedValue({
|
||||
clip: {
|
||||
id: clipId,
|
||||
slug: "support-triage",
|
||||
visibility: "public",
|
||||
status: "pending_review",
|
||||
},
|
||||
revision: {
|
||||
id: revisionId,
|
||||
revisionNumber: 1,
|
||||
},
|
||||
creatorProfile: {
|
||||
id: "44444444-4444-4444-8444-444444444444",
|
||||
},
|
||||
});
|
||||
|
||||
const res = await request(createApp())
|
||||
.post(`/api/companies/${companyId}/clips/publish`)
|
||||
.send({
|
||||
creatorProfile: {
|
||||
handle: "support-team",
|
||||
displayName: "Support Team",
|
||||
},
|
||||
slug: "support-triage",
|
||||
type: "bundle",
|
||||
title: "Support Triage",
|
||||
summary: "Routes support tickets.",
|
||||
visibility: "public",
|
||||
status: "published",
|
||||
revision: {
|
||||
manifestChecksum: HASH,
|
||||
artifactChecksum: HASH,
|
||||
manifestPayload: { ok: true },
|
||||
securityReviewState: "security_reviewed",
|
||||
verificationState: "passed",
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.status).toBe(201);
|
||||
expect(mockClipService.publish).toHaveBeenCalledWith(companyId, expect.objectContaining({
|
||||
visibility: "public",
|
||||
status: "pending_review",
|
||||
revision: expect.objectContaining({
|
||||
securityReviewState: "unreviewed",
|
||||
verificationState: "not_run",
|
||||
}),
|
||||
}));
|
||||
});
|
||||
|
||||
it("rejects malformed companyId path params before share-preview database lookups", async () => {
|
||||
const res = await request(createApp())
|
||||
.post("/api/companies/random-company-id/clips/share-preview")
|
||||
|
||||
@@ -510,7 +510,16 @@ export function clipRoutes(db: Db, storage?: StorageService) {
|
||||
const companyId = getClipCompanyIdParam(req);
|
||||
assertCompanyAccess(req, companyId);
|
||||
if (!consumeClipRateLimit(req, res, "publish")) return;
|
||||
const result = await svc.publish(companyId, req.body);
|
||||
const publishInput = {
|
||||
...req.body,
|
||||
status: req.body.visibility === "public" ? "pending_review" as const : req.body.status,
|
||||
revision: {
|
||||
...req.body.revision,
|
||||
securityReviewState: "unreviewed" as const,
|
||||
verificationState: "not_run" as const,
|
||||
},
|
||||
};
|
||||
const result = await svc.publish(companyId, publishInput);
|
||||
const actor = getActorInfo(req);
|
||||
await logActivity(db, {
|
||||
companyId,
|
||||
|
||||
Reference in new issue
Block a user