3573b7eb40
- lib/recover.ts: requestRecovery(type,email) -> password (crea token en home_passwordreset + email), accountname (email con las cuentas), activation (reenvía enlace); respuesta genérica anti-enumeración. resetPassword(token,pass) re-deriva el verifier SRP6 v2 (bnetMakeRegistration) y actualiza battlenet_accounts, marca el token usado. - Routes /api/auth/recover (Turnstile) y /api/auth/reset-password. - Páginas app/[locale]/recover (RecoverForm: selector de tipo + email + Turnstile) y reset-password (ResetForm con token de la URL). Catálogos Recover, Reset. Verificado: recover sin captcha -> captchaFailed; reset token inválido -> invalidLink; páginas 200. Reutiliza home_passwordreset de Django. Crypto de reset ya validada. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
23 lines
774 B
TypeScript
23 lines
774 B
TypeScript
import { requestRecovery } from '@/lib/recover'
|
|
import { verifyTurnstile } from '@/lib/turnstile'
|
|
|
|
export async function POST(request: Request) {
|
|
let type = ''
|
|
let email = ''
|
|
let turnstileToken = ''
|
|
try {
|
|
const body = await request.json()
|
|
type = String(body.type ?? '')
|
|
email = String(body.email ?? '')
|
|
turnstileToken = String(body.turnstileToken ?? '')
|
|
} catch {
|
|
return Response.json({ success: false, error: 'invalidRequest' }, { status: 400 })
|
|
}
|
|
const ip = (request.headers.get('x-forwarded-for') || '').split(',')[0].trim()
|
|
if (!(await verifyTurnstile(turnstileToken, ip))) {
|
|
return Response.json({ success: false, error: 'captchaFailed' })
|
|
}
|
|
const result = await requestRecovery(type, email)
|
|
return Response.json(result)
|
|
}
|