fix(commission) : replace repeated notification buttons with entry prompt
CI / Verify (push) Successful in 1m36s
CI / Build immutable images and deploy (push) Successful in 2m17s

This commit is contained in:
2026-10-02 12:07:41 +07:00 Unverified
parent 3473b55768
commit 96c27f8fc3
11 changed files with 122 additions and 107 deletions
@@ -14,7 +14,7 @@ vi.mock("@/lib/commission/push", () => ({
validPushEndpoint: (value: string) => value.startsWith("https://fcm.googleapis.com/"),
}));
const { POST } = await import("./route");
const { GET, POST } = await import("./route");
const subscription = { endpoint: "https://fcm.googleapis.com/fcm/send/token",
keys: { p256dh: "a".repeat(87), auth: "b".repeat(22) } };
@@ -40,6 +40,14 @@ describe("commission push subscriptions", () => {
expect(insert).not.toHaveBeenCalled();
});
it("only offers admin push scope to verified admins", async () => {
expect(await (await GET()).json()).toEqual({ publicKey: "public-key", canAdmin: false });
requireCommissionUser.mockResolvedValue({ id: "admin-1", role: "admin", emailVerified: false });
expect(await (await GET()).json()).toEqual({ publicKey: "public-key", canAdmin: false });
requireCommissionUser.mockResolvedValue({ id: "admin-1", role: "admin", emailVerified: true });
expect(await (await GET()).json()).toEqual({ publicKey: "public-key", canAdmin: true });
});
it("rejects a push endpoint outside browser push services", async () => {
expect((await POST(request("customer", "https://internal.example/push"))).status).toBe(400);
expect(insert).not.toHaveBeenCalled();
@@ -16,10 +16,11 @@ const subscriptionSchema = z.object({
export async function GET() {
try {
await requireCommissionUser();
const user = await requireCommissionUser();
const publicKey = pushPublicKey();
if (!publicKey) throw new HttpError(503, "push-not-configured");
return Response.json({ publicKey }, { headers: { "Cache-Control": "no-store" } });
return Response.json({ publicKey, canAdmin: user.role === "admin" && user.emailVerified },
{ headers: { "Cache-Control": "no-store" } });
} catch (cause) { return errorResponse(cause); }
}