diff options
| author | CyberRex <hspwinx86@gmail.com> | 2022-10-13 09:19:57 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-13 09:19:57 +0900 |
| commit | 1309367884197f4f4d94686fddfbd99fa20262bc (patch) | |
| tree | 3f21e60ee1bc155a903c403106fbdc6c0e0440b9 /packages/client/src | |
| parent | add webhookId to api request (#9113) (diff) | |
| download | sharkey-1309367884197f4f4d94686fddfbd99fa20262bc.tar.gz sharkey-1309367884197f4f4d94686fddfbd99fa20262bc.tar.bz2 sharkey-1309367884197f4f4d94686fddfbd99fa20262bc.zip | |
Add Cloudflare Turnstile CAPTCHA support (#9111)
* Add Cloudflare Turnstile CAPTCHA support
* Update packages/client/src/components/MkCaptcha.vue
Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>
Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>
Diffstat (limited to 'packages/client/src')
| -rw-r--r-- | packages/client/src/components/MkCaptcha.vue | 4 | ||||
| -rw-r--r-- | packages/client/src/components/MkSignup.vue | 6 | ||||
| -rw-r--r-- | packages/client/src/pages/admin/bot-protection.vue | 24 | ||||
| -rw-r--r-- | packages/client/src/pages/admin/index.vue | 2 | ||||
| -rw-r--r-- | packages/client/src/pages/admin/security.vue | 3 |
5 files changed, 36 insertions, 3 deletions
diff --git a/packages/client/src/components/MkCaptcha.vue b/packages/client/src/components/MkCaptcha.vue index 7360734914..b399bb8921 100644 --- a/packages/client/src/components/MkCaptcha.vue +++ b/packages/client/src/components/MkCaptcha.vue @@ -20,7 +20,7 @@ type Captcha = { getResponse(id: string): string; }; -type CaptchaProvider = 'hcaptcha' | 'recaptcha'; +type CaptchaProvider = 'hcaptcha' | 'recaptcha' | 'turnstile'; type CaptchaContainer = { readonly [_ in CaptchaProvider]?: Captcha; @@ -48,6 +48,7 @@ const variable = computed(() => { switch (props.provider) { case 'hcaptcha': return 'hcaptcha'; case 'recaptcha': return 'grecaptcha'; + case 'turnstile': return 'turnstile'; } }); @@ -57,6 +58,7 @@ const src = computed(() => { switch (props.provider) { case 'hcaptcha': return 'https://js.hcaptcha.com/1/api.js?render=explicit&recaptchacompat=off'; case 'recaptcha': return 'https://www.recaptcha.net/recaptcha/api.js?render=explicit'; + case 'turnstile': return 'https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit'; } }); diff --git a/packages/client/src/components/MkSignup.vue b/packages/client/src/components/MkSignup.vue index a324bb6f5a..c1f91b18c2 100644 --- a/packages/client/src/components/MkSignup.vue +++ b/packages/client/src/components/MkSignup.vue @@ -59,6 +59,7 @@ </MkSwitch> <MkCaptcha v-if="instance.enableHcaptcha" ref="hcaptcha" v-model="hCaptchaResponse" class="_formBlock captcha" provider="hcaptcha" :sitekey="instance.hcaptchaSiteKey"/> <MkCaptcha v-if="instance.enableRecaptcha" ref="recaptcha" v-model="reCaptchaResponse" class="_formBlock captcha" provider="recaptcha" :sitekey="instance.recaptchaSiteKey"/> + <MkCaptcha v-if="instance.enableTurnstile" ref="turnstile" v-model="turnstileResponse" class="_formBlock captcha" provider="turnstile" :sitekey="instance.turnstileSiteKey"/> <MkButton class="_formBlock" type="submit" :disabled="shouldDisableSubmitting" gradate data-cy-signup-submit>{{ i18n.ts.start }}</MkButton> </form> </template> @@ -92,6 +93,7 @@ const host = toUnicode(config.host); let hcaptcha = $ref(); let recaptcha = $ref(); +let turnstile = $ref(); let username: string = $ref(''); let password: string = $ref(''); @@ -106,12 +108,14 @@ let submitting: boolean = $ref(false); let ToSAgreement: boolean = $ref(false); let hCaptchaResponse = $ref(null); let reCaptchaResponse = $ref(null); +let turnstileResponse = $ref(null); const shouldDisableSubmitting = $computed((): boolean => { return submitting || instance.tosUrl && !ToSAgreement || instance.enableHcaptcha && !hCaptchaResponse || instance.enableRecaptcha && !reCaptchaResponse || + instance.enableTurnstile && !turnstileResponse || passwordRetypeState === 'not-match'; }); @@ -198,6 +202,7 @@ function onSubmit(): void { invitationCode, 'hcaptcha-response': hCaptchaResponse, 'g-recaptcha-response': reCaptchaResponse, + 'turnstile-response': turnstileResponse, }).then(() => { if (instance.emailRequiredForSignup) { os.alert({ @@ -222,6 +227,7 @@ function onSubmit(): void { submitting = false; hcaptcha.reset?.(); recaptcha.reset?.(); + turnstile.reset?.(); os.alert({ type: 'error', diff --git a/packages/client/src/pages/admin/bot-protection.vue b/packages/client/src/pages/admin/bot-protection.vue index 72d5e379de..484a9d1a1a 100644 --- a/packages/client/src/pages/admin/bot-protection.vue +++ b/packages/client/src/pages/admin/bot-protection.vue @@ -6,6 +6,7 @@ <option :value="null">{{ i18n.ts.none }} ({{ i18n.ts.notRecommended }})</option> <option value="hcaptcha">hCaptcha</option> <option value="recaptcha">reCAPTCHA</option> + <option value="turnstile">Turnstile</option> </FormRadios> <template v-if="provider === 'hcaptcha'"> @@ -36,6 +37,20 @@ <MkCaptcha provider="recaptcha" :sitekey="recaptchaSiteKey"/> </FormSlot> </template> + <template v-else-if="provider === 'turnstile'"> + <FormInput v-model="turnstileSiteKey" class="_formBlock"> + <template #prefix><i class="fas fa-key"></i></template> + <template #label>{{ i18n.ts.turnstileSiteKey }}</template> + </FormInput> + <FormInput v-model="turnstileSecretKey" class="_formBlock"> + <template #prefix><i class="fas fa-key"></i></template> + <template #label>{{ i18n.ts.turnstileSecretKey }}</template> + </FormInput> + <FormSlot class="_formBlock"> + <template #label>{{ i18n.ts.preview }}</template> + <MkCaptcha provider="turnstile" :sitekey="turnstileSiteKey || '1x00000000000000000000AA'"/> + </FormSlot> + </template> <FormButton primary @click="save"><i class="fas fa-save"></i> {{ i18n.ts.save }}</FormButton> </div> @@ -61,6 +76,8 @@ let hcaptchaSiteKey: string | null = $ref(null); let hcaptchaSecretKey: string | null = $ref(null); let recaptchaSiteKey: string | null = $ref(null); let recaptchaSecretKey: string | null = $ref(null); +let turnstileSiteKey: string | null = $ref(null); +let turnstileSecretKey: string | null = $ref(null); async function init() { const meta = await os.api('admin/meta'); @@ -68,8 +85,10 @@ async function init() { hcaptchaSecretKey = meta.hcaptchaSecretKey; recaptchaSiteKey = meta.recaptchaSiteKey; recaptchaSecretKey = meta.recaptchaSecretKey; + turnstileSiteKey = meta.turnstileSiteKey; + turnstileSecretKey = meta.turnstileSecretKey; - provider = meta.enableHcaptcha ? 'hcaptcha' : meta.enableRecaptcha ? 'recaptcha' : null; + provider = meta.enableHcaptcha ? 'hcaptcha' : meta.enableRecaptcha ? 'recaptcha' : meta.enableTurnstile ? 'turnstile' : null; } function save() { @@ -80,6 +99,9 @@ function save() { enableRecaptcha: provider === 'recaptcha', recaptchaSiteKey, recaptchaSecretKey, + enableTurnstile: provider === 'turnstile', + turnstileSiteKey, + turnstileSecretKey, }).then(() => { fetchInstance(); }); diff --git a/packages/client/src/pages/admin/index.vue b/packages/client/src/pages/admin/index.vue index 9200b5d547..20f82bba28 100644 --- a/packages/client/src/pages/admin/index.vue +++ b/packages/client/src/pages/admin/index.vue @@ -53,7 +53,7 @@ let view = $ref(null); let el = $ref(null); let pageProps = $ref({}); let noMaintainerInformation = isEmpty(instance.maintainerName) || isEmpty(instance.maintainerEmail); -let noBotProtection = !instance.disableRegistration && !instance.enableHcaptcha && !instance.enableRecaptcha; +let noBotProtection = !instance.disableRegistration && !instance.enableHcaptcha && !instance.enableRecaptcha && !instance.enableTurnstile; let noEmailServer = !instance.enableEmail; let thereIsUnresolvedAbuseReport = $ref(false); let currentPage = $computed(() => router.currentRef.value.child); diff --git a/packages/client/src/pages/admin/security.vue b/packages/client/src/pages/admin/security.vue index c36cedb312..65d079c2cf 100644 --- a/packages/client/src/pages/admin/security.vue +++ b/packages/client/src/pages/admin/security.vue @@ -9,6 +9,7 @@ <template #label>{{ i18n.ts.botProtection }}</template> <template v-if="enableHcaptcha" #suffix>hCaptcha</template> <template v-else-if="enableRecaptcha" #suffix>reCAPTCHA</template> + <template v-else-if="enableTurnstile" #suffix>Turnstile</template> <template v-else #suffix>{{ i18n.ts.none }} ({{ i18n.ts.notRecommended }})</template> <XBotProtection/> @@ -120,6 +121,7 @@ import { definePageMetadata } from '@/scripts/page-metadata'; let summalyProxy: string = $ref(''); let enableHcaptcha: boolean = $ref(false); let enableRecaptcha: boolean = $ref(false); +let enableTurnstile: boolean = $ref(false); let sensitiveMediaDetection: string = $ref('none'); let sensitiveMediaDetectionSensitivity: number = $ref(0); let setSensitiveFlagAutomatically: boolean = $ref(false); @@ -132,6 +134,7 @@ async function init() { summalyProxy = meta.summalyProxy; enableHcaptcha = meta.enableHcaptcha; enableRecaptcha = meta.enableRecaptcha; + enableTurnstile = meta.enableTurnstile; sensitiveMediaDetection = meta.sensitiveMediaDetection; sensitiveMediaDetectionSensitivity = meta.sensitiveMediaDetectionSensitivity === 'veryLow' ? 0 : |