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>
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
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 }
|
||||
}
|
||||
Reference in New Issue
Block a user