mirror of
https://github.com/certd/certd.git
synced 2026-06-27 14:07:33 +08:00
69 lines
1.7 KiB
TypeScript
69 lines
1.7 KiB
TypeScript
import { AddonInput, BaseAddon, IsAddon } from "@certd/lib-server";
|
|
import { CaptchaRequest, ICaptchaAddon } from "../api.js";
|
|
|
|
@IsAddon({
|
|
addonType: "captcha",
|
|
name: "cfTurnstile",
|
|
title: "Cloudflare Turnstile",
|
|
desc: "谨慎使用,国内被墙了",
|
|
showTest: false,
|
|
})
|
|
export class CfTurnstileCaptcha extends BaseAddon implements ICaptchaAddon {
|
|
@AddonInput({
|
|
title: "站点密钥",
|
|
component: {
|
|
placeholder: "SiteKey",
|
|
},
|
|
helper: "[Cloudflare Turnstile](https://www.cloudflare.com/zh-cn/application-services/products/turnstile/) -> 添加小组件",
|
|
required: true,
|
|
})
|
|
siteKey = "";
|
|
|
|
@AddonInput({
|
|
title: "密钥",
|
|
component: {
|
|
placeholder: "SecretKey",
|
|
},
|
|
required: true,
|
|
})
|
|
secretKey = "";
|
|
|
|
async onValidate(data?: any, req?: CaptchaRequest) {
|
|
if (!data) {
|
|
return false;
|
|
}
|
|
const { token } = data;
|
|
const { remoteIp } = req;
|
|
|
|
const formData = new FormData();
|
|
formData.append("secret", this.secretKey);
|
|
formData.append("response", token);
|
|
formData.append("remoteip", remoteIp);
|
|
|
|
const res = await this.http.request({
|
|
url: "https://challenges.cloudflare.com/turnstile/v0/siteverify",
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "multipart/form-data",
|
|
},
|
|
data: formData,
|
|
});
|
|
|
|
if (res.success) {
|
|
// Token is valid - process the form
|
|
return true;
|
|
} else {
|
|
// Token is invalid - reject the submission
|
|
const errorMessage = "Cloudflare Turnstile 校验失败:" + res["error-codes"].join(", ");
|
|
this.logger.error(errorMessage);
|
|
throw new Error(errorMessage);
|
|
}
|
|
}
|
|
|
|
async getCaptcha(): Promise<any> {
|
|
return {
|
|
siteKey: this.siteKey,
|
|
};
|
|
}
|
|
}
|