summaryrefslogtreecommitdiff
path: root/packages/backend/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/backend/src')
-rw-r--r--packages/backend/src/core/CaptchaService.ts11
-rw-r--r--packages/backend/src/models/entities/Meta.ts17
-rw-r--r--packages/backend/src/server/api/SignupApiService.ts6
-rw-r--r--packages/backend/src/server/api/endpoints/admin/meta.ts15
-rw-r--r--packages/backend/src/server/api/endpoints/admin/update-meta.ts15
-rw-r--r--packages/backend/src/server/api/endpoints/meta.ts11
6 files changed, 75 insertions, 0 deletions
diff --git a/packages/backend/src/core/CaptchaService.ts b/packages/backend/src/core/CaptchaService.ts
index 67b4b90061..acfa7d5910 100644
--- a/packages/backend/src/core/CaptchaService.ts
+++ b/packages/backend/src/core/CaptchaService.ts
@@ -66,5 +66,16 @@ export class CaptchaService {
throw `hcaptcha-failed: ${errorCodes}`;
}
}
+
+ public async verifyTurnstile(secret: string, response: string): Promise<void> {
+ const result = await this.getCaptchaResponse('https://challenges.cloudflare.com/turnstile/v0/siteverify', secret, response).catch(e => {
+ throw `turnstile-request-failed: ${e}`;
+ });
+
+ if (result.success !== true) {
+ const errorCodes = result['error-codes'] ? result['error-codes'].join(', ') : '';
+ throw `turnstile-failed: ${errorCodes}`;
+ }
+ }
}
diff --git a/packages/backend/src/models/entities/Meta.ts b/packages/backend/src/models/entities/Meta.ts
index f528b7ac08..fb25e370d2 100644
--- a/packages/backend/src/models/entities/Meta.ts
+++ b/packages/backend/src/models/entities/Meta.ts
@@ -188,6 +188,23 @@ export class Meta {
})
public recaptchaSecretKey: string | null;
+ @Column('boolean', {
+ default: false,
+ })
+ public enableTurnstile: boolean;
+
+ @Column('varchar', {
+ length: 64,
+ nullable: true,
+ })
+ public turnstileSiteKey: string | null;
+
+ @Column('varchar', {
+ length: 64,
+ nullable: true,
+ })
+ public turnstileSecretKey: string | null;
+
@Column('enum', {
enum: ['none', 'all', 'local', 'remote'],
default: 'none',
diff --git a/packages/backend/src/server/api/SignupApiService.ts b/packages/backend/src/server/api/SignupApiService.ts
index 6552dac4bf..edb8e4e8e6 100644
--- a/packages/backend/src/server/api/SignupApiService.ts
+++ b/packages/backend/src/server/api/SignupApiService.ts
@@ -61,6 +61,12 @@ export class SignupApiService {
ctx.throw(400, e);
});
}
+
+ if (instance.enableTurnstile && instance.turnstileSecretKey) {
+ await this.captchaService.verifyTurnstile(instance.turnstileSecretKey, body['turnstile-response']).catch(e => {
+ ctx.throw(400, e);
+ });
+ }
}
const username = body['username'];
diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts
index 5b43c180d8..e5b8b6f8fe 100644
--- a/packages/backend/src/server/api/endpoints/admin/meta.ts
+++ b/packages/backend/src/server/api/endpoints/admin/meta.ts
@@ -47,6 +47,14 @@ export const meta = {
type: 'string',
optional: false, nullable: true,
},
+ enableTurnstile: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ turnstileSiteKey: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
swPublickey: {
type: 'string',
optional: false, nullable: true,
@@ -197,6 +205,10 @@ export const meta = {
type: 'string',
optional: true, nullable: true,
},
+ turnstileSecretKey: {
+ type: 'string',
+ optional: true, nullable: true,
+ }
sensitiveMediaDetection: {
type: 'string',
optional: true, nullable: false,
@@ -374,6 +386,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
hcaptchaSiteKey: instance.hcaptchaSiteKey,
enableRecaptcha: instance.enableRecaptcha,
recaptchaSiteKey: instance.recaptchaSiteKey,
+ enableTurnstile: instance.enableTurnstile,
+ turnstileSiteKey: instance.turnstileSiteKey,
swPublickey: instance.swPublicKey,
themeColor: instance.themeColor,
mascotImageUrl: instance.mascotImageUrl,
@@ -400,6 +414,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
blockedHosts: instance.blockedHosts,
hcaptchaSecretKey: instance.hcaptchaSecretKey,
recaptchaSecretKey: instance.recaptchaSecretKey,
+ turnstileSecretKey: instance.turnstileSecretKey,
sensitiveMediaDetection: instance.sensitiveMediaDetection,
sensitiveMediaDetectionSensitivity: instance.sensitiveMediaDetectionSensitivity,
setSensitiveFlagAutomatically: instance.setSensitiveFlagAutomatically,
diff --git a/packages/backend/src/server/api/endpoints/admin/update-meta.ts b/packages/backend/src/server/api/endpoints/admin/update-meta.ts
index 48fae9b947..2a19b1df5f 100644
--- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts
+++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts
@@ -52,6 +52,9 @@ export const paramDef = {
enableRecaptcha: { type: 'boolean' },
recaptchaSiteKey: { type: 'string', nullable: true },
recaptchaSecretKey: { type: 'string', nullable: true },
+ enableTurnstile: { type: 'boolean' },
+ turnstileSiteKey: { type: 'string', nullable: true },
+ turnstileSecretKey: { type: 'string', nullable: true },
sensitiveMediaDetection: { type: 'string', enum: ['none', 'all', 'local', 'remote'] },
sensitiveMediaDetectionSensitivity: { type: 'string', enum: ['medium', 'low', 'high', 'veryLow', 'veryHigh'] },
setSensitiveFlagAutomatically: { type: 'boolean' },
@@ -231,6 +234,18 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
set.recaptchaSecretKey = ps.recaptchaSecretKey;
}
+ if (ps.enableTurnstile !== undefined) {
+ set.enableTurnstile = ps.enableTurnstile;
+ }
+
+ if (ps.turnstileSiteKey !== undefined) {
+ set.turnstileSiteKey = ps.turnstileSiteKey;
+ }
+
+ if (ps.turnstileSecretKey !== undefined) {
+ set.turnstileSecretKey = ps.turnstileSecretKey;
+ }
+
if (ps.sensitiveMediaDetection !== undefined) {
set.sensitiveMediaDetection = ps.sensitiveMediaDetection;
}
diff --git a/packages/backend/src/server/api/endpoints/meta.ts b/packages/backend/src/server/api/endpoints/meta.ts
index 5c09c33941..f2e6e6aea8 100644
--- a/packages/backend/src/server/api/endpoints/meta.ts
+++ b/packages/backend/src/server/api/endpoints/meta.ts
@@ -119,6 +119,14 @@ export const meta = {
type: 'string',
optional: false, nullable: true,
},
+ enableTurnstile: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ turnstileSiteKey: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
swPublickey: {
type: 'string',
optional: false, nullable: true,
@@ -372,6 +380,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
hcaptchaSiteKey: instance.hcaptchaSiteKey,
enableRecaptcha: instance.enableRecaptcha,
recaptchaSiteKey: instance.recaptchaSiteKey,
+ enableTurnstile: instance.enableTurnstile,
+ turnstileSiteKey: instance.turnstileSiteKey,
swPublickey: instance.swPublicKey,
themeColor: instance.themeColor,
mascotImageUrl: instance.mascotImageUrl,
@@ -423,6 +433,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
elasticsearch: this.config.elasticsearch ? true : false,
hcaptcha: instance.enableHcaptcha,
recaptcha: instance.enableRecaptcha,
+ turnstile: instance.enableTurnstile,
objectStorage: instance.useObjectStorage,
twitter: instance.enableTwitterIntegration,
github: instance.enableGithubIntegration,