import { _get, _post } from "./common.js"; export class Captcha { isPWR = false; enabled = true; verified = false; captchaID = ""; input = document.getElementById("captcha-input") as HTMLInputElement; checkbox = document.getElementById("captcha-success") as HTMLSpanElement; previous = ""; reCAPTCHA = false; code = ""; get value(): string { return this.input.value; } hasChanged = (): boolean => { return this.value != this.previous; } baseValidatorWrapper = (_baseValidator: (oncomplete: (valid: boolean) => void, captchaValid: boolean) => void) => { return (oncomplete: (valid: boolean) => void): void => { if (this.enabled && !this.reCAPTCHA && this.hasChanged()) { this.previous = this.value; this.verify(() => { _baseValidator(oncomplete, this.verified); }); } else { _baseValidator(oncomplete, this.verified); } }; }; verify = (callback: () => void) => _post("/captcha/verify/" + this.code + "/" + this.captchaID + "/" + this.input.value + (this.isPWR ? "?pwr=true" : ""), null, (req: XMLHttpRequest) => { if (req.readyState == 4) { if (req.status == 204) { this.checkbox.innerHTML = ``; this.checkbox.classList.add("~positive"); this.checkbox.classList.remove("~critical"); this.verified = true; } else { this.checkbox.innerHTML = ``; this.checkbox.classList.add("~critical"); this.checkbox.classList.remove("~positive"); this.verified = false; } callback(); } }); generate = () => _get("/captcha/gen/"+this.code+(this.isPWR ? "?pwr=true" : ""), null, (req: XMLHttpRequest) => { if (req.readyState == 4) { if (req.status == 200) { this.captchaID = this.isPWR ? this.code : req.response["id"]; // the Math.random() appearance below is used for PWRs, since they don't have a unique captchaID. The parameter is ignored by the server, but tells the browser to reload the image. document.getElementById("captcha-img").innerHTML = ` `; this.input.value = ""; } } }); constructor(code: string, enabled: boolean, reCAPTCHA: boolean, isPWR: boolean) { this.code = code; this.enabled = enabled; this.reCAPTCHA = reCAPTCHA; this.isPWR = isPWR; } } export interface GreCAPTCHA { render: (container: HTMLDivElement, parameters: { sitekey?: string, theme?: string, size?: string, tabindex?: number, "callback"?: () => void, "expired-callback"?: () => void, "error-callback"?: () => void }) => void; getResponse: (opt_widget_id?: HTMLDivElement) => string; }