release: WRNexusJS 0.4.0
This commit is contained in:
@@ -5,25 +5,66 @@ import type { CaptchaEngine } from "../src/types.ts";
|
||||
const engine: CaptchaEngine = {
|
||||
provider: "self-hosted",
|
||||
basePath: "/api/captcha",
|
||||
async create(options) { return { id: "c1", provider: "self-hosted", type: "number", presentation: "visual", action: options.action, prompt: "Enter 1", createdAt: 1, expiresAt: 2, responseField: "wrn-captcha-response" }; },
|
||||
async verify(input) { return { success: input.answer === "1", provider: "self-hosted", action: input.action, code: input.answer === "1" ? undefined : "incorrect-answer" }; },
|
||||
async verifyResponseToken(input) { return { success: true, provider: "self-hosted", action: input.action }; },
|
||||
async renderAudio() { return { bytes: new Uint8Array([1, 2, 3]), contentType: "audio/wav" }; },
|
||||
async create(options) {
|
||||
return {
|
||||
id: "c1",
|
||||
provider: "self-hosted",
|
||||
type: "number",
|
||||
presentation: "visual",
|
||||
action: options.action,
|
||||
prompt: "Enter 1",
|
||||
createdAt: 1,
|
||||
expiresAt: 2,
|
||||
responseField: "wrn-captcha-response",
|
||||
};
|
||||
},
|
||||
async verify(input) {
|
||||
return {
|
||||
success: input.answer === "1",
|
||||
provider: "self-hosted",
|
||||
action: input.action,
|
||||
code: input.answer === "1" ? undefined : "incorrect-answer",
|
||||
};
|
||||
},
|
||||
async verifyResponseToken(input) {
|
||||
return { success: true, provider: "self-hosted", action: input.action };
|
||||
},
|
||||
async renderAudio() {
|
||||
return { bytes: new Uint8Array([1, 2, 3]), contentType: "audio/wav" };
|
||||
},
|
||||
async gc() {},
|
||||
};
|
||||
|
||||
describe("CAPTCHA HTTP handlers", () => {
|
||||
test("creates and verifies same-origin challenges", async () => {
|
||||
const handlers = createCaptchaHttpHandlers(engine);
|
||||
const created = await handlers.handle(new Request("https://example.test/api/captcha/challenge", { method: "POST", headers: { origin: "https://example.test", "content-type": "application/json" }, body: JSON.stringify({ action: "signup" }) }));
|
||||
const created = await handlers.handle(
|
||||
new Request("https://example.test/api/captcha/challenge", {
|
||||
method: "POST",
|
||||
headers: { origin: "https://example.test", "content-type": "application/json" },
|
||||
body: JSON.stringify({ action: "signup" }),
|
||||
}),
|
||||
);
|
||||
expect(created?.status).toBe(201);
|
||||
const verified = await handlers.handle(new Request("https://example.test/api/captcha/verify", { method: "POST", headers: { origin: "https://example.test", "content-type": "application/json" }, body: JSON.stringify({ action: "signup", answer: "1" }) }));
|
||||
const verified = await handlers.handle(
|
||||
new Request("https://example.test/api/captcha/verify", {
|
||||
method: "POST",
|
||||
headers: { origin: "https://example.test", "content-type": "application/json" },
|
||||
body: JSON.stringify({ action: "signup", answer: "1" }),
|
||||
}),
|
||||
);
|
||||
expect(verified?.status).toBe(200);
|
||||
});
|
||||
|
||||
test("rejects cross-origin requests", async () => {
|
||||
const handlers = createCaptchaHttpHandlers(engine);
|
||||
const response = await handlers.create(new Request("https://example.test/api/captcha/challenge", { method: "POST", headers: { origin: "https://evil.test", "content-type": "application/json" }, body: "{}" }));
|
||||
const response = await handlers.create(
|
||||
new Request("https://example.test/api/captcha/challenge", {
|
||||
method: "POST",
|
||||
headers: { origin: "https://evil.test", "content-type": "application/json" },
|
||||
body: "{}",
|
||||
}),
|
||||
);
|
||||
expect(response.status).toBe(403);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user