Files
NightSpire/web-next/lib/change-password.ts
T
Inna 1da7349373 Token de seguridad y cambio de contraseña (páginas protegidas)
- lib/security-token.ts: requestSecurityToken (token de 6 chars, cooldown 7 días,
  guarda en home_securitytoken, email) + checkSecurityToken.
- lib/change-password.ts: changePassword (valida token + contraseña actual con
  authenticate, re-deriva verifier SRP6 v2, actualiza battlenet_accounts).
- Routes /api/account/security-token y /change-password (guard; el cambio hace
  logout de la sesión). Páginas /security-token y /change-password (protegidas) con
  sus forms cliente e i18n (SecurityToken, ChangePassword).

Verificado: páginas redirigen a login sin sesión, APIs 401. Reutiliza
home_securitytoken de Django y la crypto validada.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 23:36:05 +00:00

42 lines
1.6 KiB
TypeScript

import { db, DB } from './db'
import { authenticate } from './auth'
import { bnetMakeRegistration, normalizeEmail } from './bnet'
import { checkSecurityToken } from './security-token'
import type { SessionData } from './session'
export interface Result {
success: boolean
error?: string
}
/** Cambia la contraseña de la cuenta Battle.net (re-deriva el verifier SRP6 v2). */
export async function changePassword(
session: SessionData,
currentPassword: string,
newPassword: string,
confPassword: string,
token: string,
): Promise<Result> {
const email = session.bnetEmail ?? ''
const userId = session.accountId ?? 0
if (!currentPassword || !newPassword || !confPassword || !token) return { success: false, error: 'missingFields' }
if (newPassword !== confPassword) return { success: false, error: 'passwordMismatch' }
if (newPassword.length > 16) return { success: false, error: 'passwordTooLong' }
if (!(await checkSecurityToken(userId, token))) return { success: false, error: 'invalidToken' }
if (!(await authenticate(email, currentPassword))) return { success: false, error: 'wrongCurrentPassword' }
try {
const reg = bnetMakeRegistration(email, newPassword)
const [res] = await db(DB.auth).query(
'UPDATE battlenet_accounts SET srp_version = ?, salt = ?, verifier = ? WHERE email = ?',
[reg.srpVersion, reg.salt, reg.verifier, normalizeEmail(email)],
)
// @ts-expect-error affectedRows
if (!res.affectedRows) return { success: false, error: 'accountNotFound' }
} catch {
return { success: false, error: 'genericError' }
}
return { success: true }
}