mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 21:15:32 +09:00
feat(captcha): make ALTCHA the only captcha (#3035)
This commit is contained in:
1 parent
d433a039b5
commit
4f968bbc47
209 files changed
+4097
-8692
No files matched your search
@@ -194,10 +194,6 @@ function defaultConfig(): MasterConfig {
|
||||
from_name: 'Fluxer',
|
||||
app_base_url: '',
|
||||
},
|
||||
captcha: {
|
||||
enabled: false,
|
||||
provider: 'none',
|
||||
},
|
||||
voice: {
|
||||
enabled: false,
|
||||
api_key: '',
|
||||
@@ -425,24 +421,6 @@ function validatePostgresConfig(config: MasterConfig): void {
|
||||
}
|
||||
}
|
||||
|
||||
function validateCaptchaConfig(config: MasterConfig): void {
|
||||
const captcha = config.integrations.captcha;
|
||||
if (!captcha.enabled) {
|
||||
return;
|
||||
}
|
||||
if (captcha.provider === 'hcaptcha') {
|
||||
requireString(captcha.hcaptcha?.site_key, 'FLUXER_CAPTCHA_HCAPTCHA_SITE_KEY');
|
||||
requireString(captcha.hcaptcha?.secret_key, 'FLUXER_CAPTCHA_HCAPTCHA_SECRET_KEY');
|
||||
return;
|
||||
}
|
||||
if (captcha.provider === 'turnstile') {
|
||||
requireString(captcha.turnstile?.site_key, 'FLUXER_CAPTCHA_TURNSTILE_SITE_KEY');
|
||||
requireString(captcha.turnstile?.secret_key, 'FLUXER_CAPTCHA_TURNSTILE_SECRET_KEY');
|
||||
return;
|
||||
}
|
||||
throw new Error('FLUXER_CAPTCHA_PROVIDER must be hcaptcha or turnstile when FLUXER_CAPTCHA_ENABLED is true');
|
||||
}
|
||||
|
||||
function validateApiWorkerConfig(config: MasterConfig): void {
|
||||
const worker = config.services.api?.worker;
|
||||
if (!worker) {
|
||||
@@ -564,11 +542,9 @@ function normalizeConfig(config: MasterConfig): MasterConfig {
|
||||
assertOneOf(config.internal.kv_provider, ['redis'], 'FLUXER_KV_PROVIDER');
|
||||
assertOneOf(config.internal.kv_mode, ['standalone', 'cluster'], 'FLUXER_KV_MODE');
|
||||
assertOneOf(config.integrations.email.provider, ['smtp', 'none'], 'FLUXER_EMAIL_PROVIDER');
|
||||
assertOneOf(config.integrations.captcha.provider, ['hcaptcha', 'turnstile', 'none'], 'FLUXER_CAPTCHA_PROVIDER');
|
||||
assertOneOf(config.integrations.search.engine, ['elasticsearch', 'meilisearch'], 'FLUXER_SEARCH_ENGINE');
|
||||
assertOneOf(config.integrations.cache_purge.adapter, CACHE_PURGE_ADAPTER_NAMES, 'FLUXER_CACHE_PURGE_ADAPTER');
|
||||
validatePostgresConfig(config);
|
||||
validateCaptchaConfig(config);
|
||||
validateApiWorkerConfig(config);
|
||||
validateStorageChangeFeedConfig(config);
|
||||
validateCachePurgeConfig(config);
|
||||
|
||||
@@ -207,18 +207,6 @@ export interface MasterConfig {
|
||||
secure: boolean;
|
||||
};
|
||||
};
|
||||
captcha: {
|
||||
enabled: boolean;
|
||||
provider: 'hcaptcha' | 'turnstile' | 'none';
|
||||
hcaptcha?: {
|
||||
site_key: string;
|
||||
secret_key: string;
|
||||
};
|
||||
turnstile?: {
|
||||
site_key: string;
|
||||
secret_key: string;
|
||||
};
|
||||
};
|
||||
voice: {
|
||||
enabled: boolean;
|
||||
api_key: string;
|
||||
|
||||
@@ -507,46 +507,6 @@ describe('ConfigLoader', () => {
|
||||
expect(config.instance.setup.configured).toBe(true);
|
||||
});
|
||||
|
||||
test('rejects an enabled captcha with no keys for the selected provider', async () => {
|
||||
stubMinimalEnv({FLUXER_CAPTCHA_ENABLED: 'true', FLUXER_CAPTCHA_PROVIDER: 'hcaptcha'});
|
||||
await expect(loadConfig()).rejects.toThrow('FLUXER_CAPTCHA_HCAPTCHA_SITE_KEY is required');
|
||||
});
|
||||
|
||||
test('rejects an enabled captcha with a site key but no secret key', async () => {
|
||||
stubMinimalEnv({
|
||||
FLUXER_CAPTCHA_ENABLED: 'true',
|
||||
FLUXER_CAPTCHA_PROVIDER: 'turnstile',
|
||||
FLUXER_CAPTCHA_TURNSTILE_SITE_KEY: 'turnstile-site-key',
|
||||
});
|
||||
await expect(loadConfig()).rejects.toThrow('FLUXER_CAPTCHA_TURNSTILE_SECRET_KEY is required');
|
||||
});
|
||||
|
||||
test('rejects an enabled captcha with no provider', async () => {
|
||||
stubMinimalEnv({FLUXER_CAPTCHA_ENABLED: 'true'});
|
||||
await expect(loadConfig()).rejects.toThrow(
|
||||
'FLUXER_CAPTCHA_PROVIDER must be hcaptcha or turnstile when FLUXER_CAPTCHA_ENABLED is true',
|
||||
);
|
||||
});
|
||||
|
||||
test('accepts an enabled captcha with both keys for the selected provider', async () => {
|
||||
stubMinimalEnv({
|
||||
FLUXER_CAPTCHA_ENABLED: 'true',
|
||||
FLUXER_CAPTCHA_PROVIDER: 'hcaptcha',
|
||||
FLUXER_CAPTCHA_HCAPTCHA_SITE_KEY: 'hcaptcha-site-key',
|
||||
FLUXER_CAPTCHA_HCAPTCHA_SECRET_KEY: 'hcaptcha-secret-key',
|
||||
});
|
||||
|
||||
const config = await loadConfig();
|
||||
|
||||
expect(config.integrations.captcha.enabled).toBe(true);
|
||||
expect(config.integrations.captcha.hcaptcha?.secret_key).toBe('hcaptcha-secret-key');
|
||||
});
|
||||
|
||||
test('leaves a disabled captcha unvalidated', async () => {
|
||||
stubMinimalEnv({FLUXER_CAPTCHA_PROVIDER: 'hcaptcha'});
|
||||
expect((await loadConfig()).integrations.captcha.enabled).toBe(false);
|
||||
});
|
||||
|
||||
test('defaults the cache purge adapter to none', async () => {
|
||||
stubMinimalEnv();
|
||||
expect((await loadConfig()).integrations.cache_purge).toEqual({
|
||||
|
||||
@@ -233,12 +233,6 @@ const NAMED_FLUXER_ENV_OVERRIDES: Record<string, NamedEnvOverride> = {
|
||||
FLUXER_EMAIL_SMTP_USERNAME: {path: ['integrations', 'email', 'smtp', 'username']},
|
||||
FLUXER_EMAIL_SMTP_PASSWORD: {path: ['integrations', 'email', 'smtp', 'password']},
|
||||
FLUXER_EMAIL_SMTP_SECURE: {path: ['integrations', 'email', 'smtp', 'secure'], parse: parseBoolean},
|
||||
FLUXER_CAPTCHA_ENABLED: {path: ['integrations', 'captcha', 'enabled'], parse: parseBoolean},
|
||||
FLUXER_CAPTCHA_PROVIDER: {path: ['integrations', 'captcha', 'provider']},
|
||||
FLUXER_CAPTCHA_HCAPTCHA_SITE_KEY: {path: ['integrations', 'captcha', 'hcaptcha', 'site_key']},
|
||||
FLUXER_CAPTCHA_HCAPTCHA_SECRET_KEY: {path: ['integrations', 'captcha', 'hcaptcha', 'secret_key']},
|
||||
FLUXER_CAPTCHA_TURNSTILE_SITE_KEY: {path: ['integrations', 'captcha', 'turnstile', 'site_key']},
|
||||
FLUXER_CAPTCHA_TURNSTILE_SECRET_KEY: {path: ['integrations', 'captcha', 'turnstile', 'secret_key']},
|
||||
FLUXER_LIVEKIT_ENABLED: {path: ['integrations', 'voice', 'enabled'], parse: parseBoolean},
|
||||
FLUXER_LIVEKIT_API_KEY: {path: ['integrations', 'voice', 'api_key']},
|
||||
FLUXER_LIVEKIT_API_SECRET: {path: ['integrations', 'voice', 'api_secret']},
|
||||
|
||||
Reference in new issue
Block a user