Moderators block a file network-wide by its sha256, from a product's files or the console's new Blocks tab, which first shows the products using it. Blocking removes those products (their creators are told and may appeal), puts a `block` change in the changes feed of every catalog hosting it, and refuses uploads with it; moderators see who tried. Unblocking lets it in again; the products it removed stay removed until restored. Co-Authored-By: Claude Opus 5.5 <[email protected]>
32 lines
1.2 KiB
TypeScript
32 lines
1.2 KiB
TypeScript
"use server";
|
|
// File blocks, from the console.
|
|
import { revalidatePath } from "next/cache";
|
|
import { api, unwrap } from "@/lib/api";
|
|
import { attempt, field, type ActionState } from "@/lib/actions";
|
|
|
|
const done = (sha256: string) => {
|
|
revalidatePath("/console/blocks");
|
|
revalidatePath(`/console/blocks/${sha256}`);
|
|
revalidatePath("/console/products");
|
|
};
|
|
|
|
/** Blocks a file network-wide, removing the products using it. */
|
|
export async function blockFile(_: ActionState, form: FormData): Promise<ActionState> {
|
|
const sha256 = field(form, "sha256");
|
|
return attempt(async () => {
|
|
const { removed } = unwrap(await api.blocks({ sha256 }).put({ reason: field(form, "reason") }));
|
|
done(sha256);
|
|
return removed.length ? `Blocked. Removed ${removed.length === 1 ? "1 product" : `${removed.length} products`}.` : "Blocked.";
|
|
});
|
|
}
|
|
|
|
/** Unblocks a file. The products it removed stay removed. */
|
|
export async function unblockFile(_: ActionState, form: FormData): Promise<ActionState> {
|
|
const sha256 = field(form, "sha256");
|
|
return attempt(async () => {
|
|
unwrap(await api.blocks({ sha256 }).delete({ reason: field(form, "reason") }));
|
|
done(sha256);
|
|
return "Unblocked.";
|
|
});
|
|
}
|