From 78608392208cb73351354cda5678daee232159d8 Mon Sep 17 00:00:00 2001 From: "Acid Chicken (硫酸鶏)" Date: Tue, 28 Apr 2020 14:29:33 +0900 Subject: Add support for hCaptcha --- src/server/api/endpoints/admin/update-meta.ts | 33 +++++++++++++++++++++++++++ src/server/api/endpoints/meta.ts | 4 ++++ src/server/api/private/signup.ts | 13 ++++++++++- src/server/nodeinfo.ts | 1 + src/server/web/views/info.pug | 3 +++ 5 files changed, 53 insertions(+), 1 deletion(-) (limited to 'src/server') diff --git a/src/server/api/endpoints/admin/update-meta.ts b/src/server/api/endpoints/admin/update-meta.ts index 1bc20029ef..dffe7ffe7f 100644 --- a/src/server/api/endpoints/admin/update-meta.ts +++ b/src/server/api/endpoints/admin/update-meta.ts @@ -145,6 +145,27 @@ export const meta = { } }, + enableHcaptcha: { + validator: $.optional.bool, + desc: { + 'ja-JP': 'hCaptchaを使用するか否か' + } + }, + + hcaptchaSiteKey: { + validator: $.optional.nullable.str, + desc: { + 'ja-JP': 'hCaptcha site key' + } + }, + + hcaptchaSecretKey: { + validator: $.optional.nullable.str, + desc: { + 'ja-JP': 'hCaptcha secret key' + } + }, + enableRecaptcha: { validator: $.optional.bool, desc: { @@ -472,6 +493,18 @@ export default define(meta, async (ps, me) => { set.proxyRemoteFiles = ps.proxyRemoteFiles; } + if (ps.enableHcaptcha !== undefined) { + set.enableHcaptcha = ps.enableHcaptcha; + } + + if (ps.hcaptchaSiteKey !== undefined) { + set.hcaptchaSiteKey = ps.hcaptchaSiteKey; + } + + if (ps.hcaptchaSecretKey !== undefined) { + set.hcaptchaSecretKey = ps.hcaptchaSecretKey; + } + if (ps.enableRecaptcha !== undefined) { set.enableRecaptcha = ps.enableRecaptcha; } diff --git a/src/server/api/endpoints/meta.ts b/src/server/api/endpoints/meta.ts index 179355489b..eefc370124 100644 --- a/src/server/api/endpoints/meta.ts +++ b/src/server/api/endpoints/meta.ts @@ -122,6 +122,8 @@ export default define(meta, async (ps, me) => { driveCapacityPerRemoteUserMb: instance.remoteDriveCapacityMb, cacheRemoteFiles: instance.cacheRemoteFiles, proxyRemoteFiles: instance.proxyRemoteFiles, + enableHcaptcha: instance.enableHcaptcha, + hcaptchaSiteKey: instance.hcaptchaSiteKey, enableRecaptcha: instance.enableRecaptcha, recaptchaSiteKey: instance.recaptchaSiteKey, swPublickey: instance.swPublicKey, @@ -149,6 +151,7 @@ export default define(meta, async (ps, me) => { localTimeLine: !instance.disableLocalTimeline, globalTimeLine: !instance.disableGlobalTimeline, elasticsearch: config.elasticsearch ? true : false, + hcaptcha: instance.enableHcaptcha, recaptcha: instance.enableRecaptcha, objectStorage: instance.useObjectStorage, twitter: instance.enableTwitterIntegration, @@ -164,6 +167,7 @@ export default define(meta, async (ps, me) => { response.pinnedUsers = instance.pinnedUsers; response.hiddenTags = instance.hiddenTags; response.blockedHosts = instance.blockedHosts; + response.hcaptchaSecretKey = instance.hcaptchaSecretKey; response.recaptchaSecretKey = instance.recaptchaSecretKey; response.proxyAccountId = instance.proxyAccountId; response.twitterConsumerKey = instance.twitterConsumerKey; diff --git a/src/server/api/private/signup.ts b/src/server/api/private/signup.ts index 79ee74389c..e23fe43583 100644 --- a/src/server/api/private/signup.ts +++ b/src/server/api/private/signup.ts @@ -1,5 +1,6 @@ import * as Koa from 'koa'; import { fetchMeta } from '../../../misc/fetch-meta'; +import { verify } from 'hcaptcha'; import * as recaptcha from 'recaptcha-promise'; import { Users, RegistrationTickets } from '../../../models'; import { signup } from '../common/signup'; @@ -9,8 +10,18 @@ export default async (ctx: Koa.Context) => { const instance = await fetchMeta(true); - // Verify recaptcha + // Verify *Captcha // ただしテスト時はこの機構は障害となるため無効にする + if (process.env.NODE_ENV !== 'test' && instance.enableHcaptcha && instance.hcaptchaSecretKey) { + const success = await verify(instance.hcaptchaSecretKey, body['hcaptcha-response']).then( + ({ 'error-codes': x }) => !x || !x.length, + () => false, + ); + + if (!success) { + ctx.throw(400, 'hcaptcha-failed'); + } + } if (process.env.NODE_ENV !== 'test' && instance.enableRecaptcha && instance.recaptchaSecretKey) { recaptcha.init({ secret_key: instance.recaptchaSecretKey diff --git a/src/server/nodeinfo.ts b/src/server/nodeinfo.ts index 2ff924e68d..442e946df3 100644 --- a/src/server/nodeinfo.ts +++ b/src/server/nodeinfo.ts @@ -65,6 +65,7 @@ const nodeinfo2 = async () => { disableRegistration: meta.disableRegistration, disableLocalTimeline: meta.disableLocalTimeline, disableGlobalTimeline: meta.disableGlobalTimeline, + enableHcaptcha: meta.enableHcaptcha, enableRecaptcha: meta.enableRecaptcha, maxNoteTextLength: meta.maxNoteTextLength, enableTwitterIntegration: meta.enableTwitterIntegration, diff --git a/src/server/web/views/info.pug b/src/server/web/views/info.pug index 992e652a60..4553d2e2b9 100644 --- a/src/server/web/views/info.pug +++ b/src/server/web/views/info.pug @@ -106,6 +106,9 @@ html tr th Registration td= !meta.disableRegistration ? 'yes' : 'no' + tr + th hCaptcha enabled + td= meta.enableHcaptcha ? 'enabled' : 'disabled' tr th reCAPTCHA enabled td= meta.enableRecaptcha ? 'enabled' : 'disabled' -- cgit v1.2.3-freya From 9daa9007935578ed1d12d46916d913d802816087 Mon Sep 17 00:00:00 2001 From: "Acid Chicken (硫酸鶏)" Date: Wed, 29 Apr 2020 05:30:58 +0900 Subject: Refactor codes --- src/client/components/hcaptcha.vue | 20 ++++++-------------- src/client/pages/instance/settings.vue | 3 +-- src/server/api/private/signup.ts | 2 +- 3 files changed, 8 insertions(+), 17 deletions(-) (limited to 'src/server') diff --git a/src/client/components/hcaptcha.vue b/src/client/components/hcaptcha.vue index 4711b303d7..f493366486 100644 --- a/src/client/components/hcaptcha.vue +++ b/src/client/components/hcaptcha.vue @@ -40,20 +40,12 @@ export default Vue.extend({ if (window.hcaptcha) { // loaded this.available = true; } else { - const alreadyLoading = document.getElementById('hcaptcha'); - - if (alreadyLoading) { // loading - alreadyLoading.addEventListener('load', () => this.available = true); - - return; - } // init - - const script = document.createElement('script'); - script.addEventListener('load', () => this.available = true); - script.async = true; - script.id = 'hcaptcha'; - script.src = 'https://hcaptcha.com/1/api.js?render=explicit'; - document.head.appendChild(script); + (document.getElementById('hcaptcha') || (x => document.head.appendChild(Object.assign(x, { + async: true, + id: 'hcaptcha', + src: 'https://hcaptcha.com/1/api.js?render=explicit', + })))(document.createElement('script'))) + .addEventListener('load', () => this.available = true); } }, diff --git a/src/client/pages/instance/settings.vue b/src/client/pages/instance/settings.vue index 088db8763e..1292316b22 100644 --- a/src/client/pages/instance/settings.vue +++ b/src/client/pages/instance/settings.vue @@ -371,11 +371,10 @@ export default Vue.extend({ } if (recaptchaLoaded) { // loaded - delete window.onRecaptchaLoad; renderRecaptchaPreview(); } else { // init window.onRecaptchaLoad = () => { - recaptchaLoaded = true; + recaptchaLoaded = delete window.onRecaptchaLoad; renderRecaptchaPreview(); }; const script = document.createElement('script'); diff --git a/src/server/api/private/signup.ts b/src/server/api/private/signup.ts index e23fe43583..04d0501b6c 100644 --- a/src/server/api/private/signup.ts +++ b/src/server/api/private/signup.ts @@ -14,7 +14,7 @@ export default async (ctx: Koa.Context) => { // ただしテスト時はこの機構は障害となるため無効にする if (process.env.NODE_ENV !== 'test' && instance.enableHcaptcha && instance.hcaptchaSecretKey) { const success = await verify(instance.hcaptchaSecretKey, body['hcaptcha-response']).then( - ({ 'error-codes': x }) => !x || !x.length, + ({ success }) => success, () => false, ); -- cgit v1.2.3-freya From 9053b9635e1b2f1daf233f644d6f8f3bb8411cc0 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 2 May 2020 10:28:45 +0900 Subject: refactor --- src/server/api/private/signup.ts | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) (limited to 'src/server') diff --git a/src/server/api/private/signup.ts b/src/server/api/private/signup.ts index 04d0501b6c..4e475e1982 100644 --- a/src/server/api/private/signup.ts +++ b/src/server/api/private/signup.ts @@ -12,25 +12,28 @@ export default async (ctx: Koa.Context) => { // Verify *Captcha // ただしテスト時はこの機構は障害となるため無効にする - if (process.env.NODE_ENV !== 'test' && instance.enableHcaptcha && instance.hcaptchaSecretKey) { - const success = await verify(instance.hcaptchaSecretKey, body['hcaptcha-response']).then( - ({ success }) => success, - () => false, - ); - - if (!success) { - ctx.throw(400, 'hcaptcha-failed'); + if (process.env.NODE_ENV !== 'test') { + if (instance.enableHcaptcha && instance.hcaptchaSecretKey) { + const success = await verify(instance.hcaptchaSecretKey, body['hcaptcha-response']).then( + ({ success }) => success, + () => false, + ); + + if (!success) { + ctx.throw(400, 'hcaptcha-failed'); + } } - } - if (process.env.NODE_ENV !== 'test' && instance.enableRecaptcha && instance.recaptchaSecretKey) { - recaptcha.init({ - secret_key: instance.recaptchaSecretKey - }); - const success = await recaptcha(body['g-recaptcha-response']); + if (instance.enableRecaptcha && instance.recaptchaSecretKey) { + recaptcha.init({ + secret_key: instance.recaptchaSecretKey + }); + + const success = await recaptcha(body['g-recaptcha-response']); - if (!success) { - ctx.throw(400, 'recaptcha-failed'); + if (!success) { + ctx.throw(400, 'recaptcha-failed'); + } } } -- cgit v1.2.3-freya From b2c703c173ccd19439bf7ec38a9570fd2eb432e8 Mon Sep 17 00:00:00 2001 From: "Acid Chicken (硫酸鶏)" Date: Sat, 2 May 2020 10:31:37 +0900 Subject: Update src/server/api/private/signup.ts --- src/server/api/private/signup.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/server') diff --git a/src/server/api/private/signup.ts b/src/server/api/private/signup.ts index 4e475e1982..6dc252ac45 100644 --- a/src/server/api/private/signup.ts +++ b/src/server/api/private/signup.ts @@ -13,7 +13,7 @@ export default async (ctx: Koa.Context) => { // Verify *Captcha // ただしテスト時はこの機構は障害となるため無効にする if (process.env.NODE_ENV !== 'test') { - if (instance.enableHcaptcha && instance.hcaptchaSecretKey) { + if (instance.enableHcaptcha && instance.hcaptchaSecretKey) { const success = await verify(instance.hcaptchaSecretKey, body['hcaptcha-response']).then( ({ success }) => success, () => false, -- cgit v1.2.3-freya