update
This commit is contained in:
@@ -1,49 +0,0 @@
|
|||||||
import { Request, Response } from 'express';
|
|
||||||
import { captchaService } from '../services/captcha.service';
|
|
||||||
|
|
||||||
interface VerifyCaptchaCredentialsBody {
|
|
||||||
provider: 'hcaptcha' | 'recaptcha';
|
|
||||||
siteKey?: string;
|
|
||||||
secretKey?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CaptchaController {
|
|
||||||
async verifyCredentials(
|
|
||||||
request: Request<{}, {}, VerifyCaptchaCredentialsBody>, // Express Request type
|
|
||||||
reply: Response // Express Response type
|
|
||||||
): Promise<void> {
|
|
||||||
const { provider, siteKey, secretKey } = request.body;
|
|
||||||
|
|
||||||
if (!provider || (provider !== 'hcaptcha' && provider !== 'recaptcha')) {
|
|
||||||
reply.status(400).json({ message: '无效的 CAPTCHA 提供商。' }); // Use .json for Express
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!siteKey || !secretKey) {
|
|
||||||
let missingKeyMessage = `缺少 ${provider} 的 Site Key 或 Secret Key。`;
|
|
||||||
if (!siteKey && !secretKey) {
|
|
||||||
missingKeyMessage = `缺少 ${provider} 的 Site Key 和 Secret Key。`;
|
|
||||||
} else if (!siteKey) {
|
|
||||||
missingKeyMessage = `缺少 ${provider} 的 Site Key。`;
|
|
||||||
} else if (!secretKey) {
|
|
||||||
missingKeyMessage = `缺少 ${provider} 的 Secret Key。`;
|
|
||||||
}
|
|
||||||
reply.status(400).json({ message: missingKeyMessage }); // Use .json
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const isValid = await captchaService.verifyCredentials(provider, siteKey, secretKey);
|
|
||||||
if (isValid) {
|
|
||||||
reply.status(200).json({ message: 'CAPTCHA 凭据验证成功。' }); // Use .json
|
|
||||||
} else {
|
|
||||||
reply.status(400).json({ message: 'CAPTCHA 凭据验证失败。请检查您的 Site Key 和 Secret Key 是否正确,并确保服务器可以访问 CAPTCHA 服务提供商。' }); // Use .json
|
|
||||||
}
|
|
||||||
} catch (error: any) {
|
|
||||||
console.error(`[CaptchaController] 凭据验证时发生意外错误: ${error.message}`);
|
|
||||||
reply.status(500).json({ message: error.message || 'CAPTCHA 凭据验证时发生服务器内部错误。' }); // Use .json
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const captchaController = new CaptchaController();
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import express, { Router } from 'express';
|
|
||||||
import { captchaController } from './captcha.controller';
|
|
||||||
// import { requireAuth } from '../auth/auth.middleware'; // 假设的认证中间件
|
|
||||||
|
|
||||||
const router: Router = express.Router();
|
|
||||||
|
|
||||||
// POST /api/v1/settings/captcha/verify (路径将由 index.ts 中的 app.use 指定)
|
|
||||||
// 如果需要认证,可以在这里添加中间件: router.post('/verify', requireAuth, captchaController.verifyCredentials);
|
|
||||||
router.post('/verify', captchaController.verifyCredentials);
|
|
||||||
|
|
||||||
export default router;
|
|
||||||
@@ -44,7 +44,6 @@ import sftpRouter from './sftp/sftp.routes';
|
|||||||
import proxyRoutes from './proxies/proxies.routes';
|
import proxyRoutes from './proxies/proxies.routes';
|
||||||
import tagsRouter from './tags/tags.routes';
|
import tagsRouter from './tags/tags.routes';
|
||||||
import settingsRoutes from './settings/settings.routes';
|
import settingsRoutes from './settings/settings.routes';
|
||||||
import captchaRoutes from './captcha/captcha.routes'; // +++ Import CAPTCHA routes +++
|
|
||||||
import notificationRoutes from './notifications/notification.routes';
|
import notificationRoutes from './notifications/notification.routes';
|
||||||
import auditRoutes from './audit/audit.routes';
|
import auditRoutes from './audit/audit.routes';
|
||||||
import commandHistoryRoutes from './command-history/command-history.routes';
|
import commandHistoryRoutes from './command-history/command-history.routes';
|
||||||
@@ -265,7 +264,6 @@ const startServer = () => {
|
|||||||
app.use('/api/v1/proxies', proxyRoutes);
|
app.use('/api/v1/proxies', proxyRoutes);
|
||||||
app.use('/api/v1/tags', tagsRouter);
|
app.use('/api/v1/tags', tagsRouter);
|
||||||
app.use('/api/v1/settings', settingsRoutes);
|
app.use('/api/v1/settings', settingsRoutes);
|
||||||
app.use('/api/v1/settings/captcha', captchaRoutes); // +++ Register CAPTCHA routes under settings +++
|
|
||||||
app.use('/api/v1/notifications', notificationRoutes);
|
app.use('/api/v1/notifications', notificationRoutes);
|
||||||
app.use('/api/v1/audit-logs', auditRoutes);
|
app.use('/api/v1/audit-logs', auditRoutes);
|
||||||
app.use('/api/v1/command-history', commandHistoryRoutes);
|
app.use('/api/v1/command-history', commandHistoryRoutes);
|
||||||
|
|||||||
@@ -59,77 +59,9 @@ export function useCaptchaSettings() {
|
|||||||
captchaMessage.value = '';
|
captchaMessage.value = '';
|
||||||
captchaSuccess.value = false;
|
captchaSuccess.value = false;
|
||||||
try {
|
try {
|
||||||
let needsVerification = false;
|
// Verification steps removed
|
||||||
let providerForVerification: CaptchaProvider | null = null;
|
|
||||||
let siteKeyForVerification: string | undefined = undefined;
|
|
||||||
let secretKeyForVerification: string | undefined = undefined;
|
|
||||||
|
|
||||||
// Step 1: Determine if verification is needed
|
// Prepare DTO for saving
|
||||||
if (captchaForm.enabled && captchaForm.provider && captchaForm.provider !== 'none') {
|
|
||||||
const originalSettings = captchaSettings.value; // Persisted settings from store
|
|
||||||
|
|
||||||
if (captchaForm.provider === 'hcaptcha') {
|
|
||||||
const originalSiteKeyValue = originalSettings?.hcaptchaSiteKey || '';
|
|
||||||
const currentSiteKeyValue = captchaForm.hcaptchaSiteKey || '';
|
|
||||||
const currentSecretKeyValue = captchaForm.hcaptchaSecretKey || '';
|
|
||||||
|
|
||||||
if (currentSiteKeyValue !== originalSiteKeyValue) {
|
|
||||||
if (!currentSiteKeyValue || !currentSecretKeyValue) {
|
|
||||||
throw new Error(t('settings.captcha.error.hcaptchaKeysRequired'));
|
|
||||||
}
|
|
||||||
needsVerification = true;
|
|
||||||
providerForVerification = 'hcaptcha';
|
|
||||||
siteKeyForVerification = currentSiteKeyValue;
|
|
||||||
secretKeyForVerification = currentSecretKeyValue;
|
|
||||||
} else if (currentSecretKeyValue) {
|
|
||||||
if (!currentSiteKeyValue) {
|
|
||||||
throw new Error(t('settings.captcha.error.hcaptchaKeysRequired'));
|
|
||||||
}
|
|
||||||
needsVerification = true;
|
|
||||||
providerForVerification = 'hcaptcha';
|
|
||||||
siteKeyForVerification = currentSiteKeyValue;
|
|
||||||
secretKeyForVerification = currentSecretKeyValue;
|
|
||||||
}
|
|
||||||
} else if (captchaForm.provider === 'recaptcha') {
|
|
||||||
const originalSiteKeyValue = originalSettings?.recaptchaSiteKey || '';
|
|
||||||
const currentSiteKeyValue = captchaForm.recaptchaSiteKey || '';
|
|
||||||
const currentSecretKeyValue = captchaForm.recaptchaSecretKey || '';
|
|
||||||
|
|
||||||
if (currentSiteKeyValue !== originalSiteKeyValue) {
|
|
||||||
if (!currentSiteKeyValue || !currentSecretKeyValue) {
|
|
||||||
throw new Error(t('settings.captcha.error.recaptchaKeysRequired'));
|
|
||||||
}
|
|
||||||
needsVerification = true;
|
|
||||||
providerForVerification = 'recaptcha';
|
|
||||||
siteKeyForVerification = currentSiteKeyValue;
|
|
||||||
secretKeyForVerification = currentSecretKeyValue;
|
|
||||||
} else if (currentSecretKeyValue) {
|
|
||||||
if (!currentSiteKeyValue) {
|
|
||||||
throw new Error(t('settings.captcha.error.recaptchaKeysRequired'));
|
|
||||||
}
|
|
||||||
needsVerification = true;
|
|
||||||
providerForVerification = 'recaptcha';
|
|
||||||
siteKeyForVerification = currentSiteKeyValue;
|
|
||||||
secretKeyForVerification = currentSecretKeyValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 2: Perform verification if needed
|
|
||||||
if (needsVerification && providerForVerification && siteKeyForVerification && secretKeyForVerification) {
|
|
||||||
try {
|
|
||||||
await apiClient.post('/settings/captcha/verify', {
|
|
||||||
provider: providerForVerification,
|
|
||||||
siteKey: siteKeyForVerification,
|
|
||||||
secretKey: secretKeyForVerification,
|
|
||||||
});
|
|
||||||
} catch (verifyError: any) {
|
|
||||||
console.error('CAPTCHA verification failed:', verifyError);
|
|
||||||
throw new Error(verifyError.response?.data?.message || verifyError.message || t('settings.captcha.error.verificationFailed'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3: Prepare DTO for saving
|
|
||||||
const dtoToSave: UpdateCaptchaSettingsDto = {
|
const dtoToSave: UpdateCaptchaSettingsDto = {
|
||||||
enabled: captchaForm.enabled,
|
enabled: captchaForm.enabled,
|
||||||
provider: captchaForm.provider,
|
provider: captchaForm.provider,
|
||||||
|
|||||||
Reference in New Issue
Block a user