fix: P2 medium priority issues - validation and logging

P2-1: Tool selection fallback optimization
- Return only utility tools when no patterns match
- Reduces token usage by ~80% in fallback cases

P2-2: Minimum deposit amount validation
- Add MIN_DEPOSIT_AMOUNT = 1,000원
- Prevents spam with tiny deposits

P2-3: Standardize logging
- Replace console.log/error with structured logger
- bank-sms-parser.ts and security.ts

P2-4: Nameserver format validation
- Add validateNameservers() function
- Check minimum 2 NS, valid hostname format
- Clear error messages in Korean

P2-5: Optimistic lock error context
- Return specific error for version conflicts
- User-friendly message: "동시 요청으로 처리가 지연됨"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
kappa
2026-01-28 20:40:41 +09:00
parent 97b8f3c7f7
commit 69e4dcc338
5 changed files with 63 additions and 17 deletions

View File

@@ -1,6 +1,8 @@
import { Env, TelegramUpdate } from './types';
import { createLogger } from './utils/logger';
const logger = createLogger('security');
// Telegram 서버 IP 대역 (2024년 기준)
// https://core.telegram.org/bots/webhooks#the-short-version
const TELEGRAM_IP_RANGES = [
@@ -99,12 +101,12 @@ export async function validateWebhookRequest(
// 3. Secret Token 검증 (필수)
if (!env.WEBHOOK_SECRET) {
console.error('WEBHOOK_SECRET not configured - rejecting request');
logger.error('WEBHOOK_SECRET not configured - rejecting request', new Error('Missing WEBHOOK_SECRET'));
return { valid: false, error: 'Security configuration error' };
}
if (!isValidSecretToken(request, env.WEBHOOK_SECRET)) {
console.error('Invalid webhook secret token');
logger.warn('Invalid webhook secret token');
return { valid: false, error: 'Invalid secret token' };
}
@@ -112,7 +114,7 @@ export async function validateWebhookRequest(
const clientIP = request.headers.get('CF-Connecting-IP');
if (clientIP && !isValidTelegramIP(clientIP)) {
// 경고만 로그 (Cloudflare 프록시 환경에서는 정확하지 않을 수 있음)
console.warn(`Request from non-Telegram IP: ${clientIP}`);
logger.warn('Request from non-Telegram IP', { clientIP });
}
// 5. 요청 본문 파싱 및 검증