🔐 Nueva Politica de Passwords — Zxcvbn

Actualizado: 2026-04
⚠️
Desde PrestaShop 8.0

La politica de passwords cambio radicalmente. Si tu modulo gestiona cuentas de empleados o clientes, DEBES adaptarlo.

#Que es Zxcvbn

PrestaShop adopto Zxcvbn, la libreria open-source de Dropbox para estimacion de fuerza de passwords. En lugar de reglas arbitrarias (8 caracteres, 1 mayuscula, 1 numero), analiza patrones reales de vulnerabilidad.

La libreria devuelve un score de 0 a 4 (mayor = mas seguro) evaluando longitud, patrones comunes, secuencias, repeticiones y palabras de diccionario.

#Como funciona

Durante la creacion o actualizacion de cuenta, la API proporciona feedback en tiempo real via JavaScript. El frontend muestra un indicador visual de fuerza.

ScoreNivelDescripcion
0Muy debilPassword trivial — rechazado siempre
1DebilFacil de adivinar — rechazado por defecto
2RegularProteccion basica — minimo aceptable habitual
3FuerteResistente a ataques offline
4Muy fuerteExcelente — maxima seguridad
ℹ️
Carga asincrona

La libreria Zxcvbn se carga de forma asincrona via core.js debido a su tamano (~400KB). No bloquea el renderizado de la pagina.

#Breaking Changes

Estos son los cambios que rompen compatibilidad hacia atras:

#Cambios en Commands

#AddEmployeeCommand

Ahora requiere parametros adicionales:

AddEmployeeCommand — nuevos parametros obligatorios
php
// ANTES (PS 1.7.x)
$command = new AddEmployeeCommand(
    'John', 'Doe', 'john@shop.com',
    'MyP@ss123', $defaultPage, $langId,
    $profileId, $shopAssociation
);

// AHORA (PS 8.0+)
$command = new AddEmployeeCommand(
    'John', 'Doe', 'john@shop.com',
    'MyP@ss123', $defaultPage, $langId,
    $profileId, $shopAssociation,
    $hasEnabledGravatar, // bool — nuevo
    $minLength,          // int  — nuevo
    $maxLength,          // int  — nuevo
    $minScore            // int  — nuevo (0-4)
);

#EditEmployeeCommand

EditEmployeeCommand::setPlainPassword()
php
// ANTES
$command->setPlainPassword('NewP@ss456');

// AHORA — requiere limites y score minimo
$command->setPlainPassword(
    'NewP@ss456',
    $minLength, // int
    $maxLength, // int
    $minScore   // int (0-4)
);

#Password ValueObject

Employee\ValueObject\Password — nuevo constructor
php
// ANTES
use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\Password;
$password = new Password('MyP@ss123');
// Usaba Password::MIN_LENGTH / Password::MAX_LENGTH internamente

// AHORA — constantes eliminadas, parametros explicitos
$password = new Password(
    'MyP@ss123',
    8,   // minLength — configurable
    72,  // maxLength — configurable
    2    // minScore  — score Zxcvbn minimo
);

#Funciones deprecadas

FuncionEstadoAlternativa
Validate::isPlaintextPassword()DeprecatedUsar Password ValueObject con score Zxcvbn
Validate::isPasswdAdmin()DeprecatedUsar Password ValueObject con minScore mas alto
jquery-passy.jsEliminadoLibreria Zxcvbn integrada en core.js

#Requisitos en el tema

Si tu tema extiende Classic o Hummingbird, debe preservar estos elementos para que la validacion de password funcione:

Estructura requerida en form-fields.tpl
smarty
{* Campo password con wrapper de politica *}
{if $field.type === 'password'}
  <div class="field-password-policy">
    <input
      type="password"
      name="{$field.name}"
      id="field-{$field.name}"
      class="form-control"
      data-minlength="{$field.minLength}"
      data-maxlength="{$field.maxLength}"
      data-minscore="{$field.minScore}"
    />
    {* Indicador de fuerza — renderizado por JS *}
    <div class="password-strength-feedback"></div>
  </div>
{/if}

#Implementacion en modulo

Si tu modulo crea o modifica empleados/clientes con password, adapta asi:

Leer configuracion de politica de password
php
// Obtener los limites configurados en el BO
$minLength = (int) Configuration::get('PS_PASSWD_MIN_LENGTH', null, null, null, 8);
$maxLength = (int) Configuration::get('PS_PASSWD_MAX_LENGTH', null, null, null, 72);
$minScore  = (int) Configuration::get('PS_PASSWD_MIN_SCORE', null, null, null, 2);

// Validar un password antes de guardarlo
use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\Password;

try {
    $password = new Password($plainPassword, $minLength, $maxLength, $minScore);
    // Password valido — continuar
} catch (\PrestaShop\PrestaShop\Core\Domain\Employee\Exception\InvalidEmployeePasswordException $e) {
    // Password no cumple la politica
    // $e->getCode() indica el tipo de error:
    // - PASSWORD_TOO_SHORT
    // - PASSWORD_TOO_LONG  
    // - PASSWORD_TOO_WEAK (score insuficiente)
}
Integrar indicador Zxcvbn en formulario custom
javascript
// La libreria se carga asincronamente desde core.js
// Esperar a que este disponible:
function checkPasswordStrength(password) {
    if (typeof zxcvbn === 'undefined') {
        console.warn('Zxcvbn not loaded yet');
        return null;
    }
    
    const result = zxcvbn(password);
    // result.score: 0-4
    // result.feedback.warning: string con advertencia
    // result.feedback.suggestions: array de sugerencias
    
    return {
        score: result.score,
        warning: result.feedback.warning,
        suggestions: result.feedback.suggestions,
        crackTime: result.crack_times_display.offline_slow_hashing_1e4_per_second
    };
}

// Ejemplo: escuchar cambios en campo password
document.querySelector('input[type="password"]')
    .addEventListener('input', function(e) {
        const strength = checkPasswordStrength(e.target.value);
        if (strength) {
            updateStrengthIndicator(strength.score);
        }
    });
💡
Checklist de migracion

1. Eliminar referencias a jquery-passy.js 2. Actualizar llamadas a AddEmployeeCommand con nuevos parametros 3. Actualizar EditEmployeeCommand::setPlainPassword() con 3 parametros extra 4. Reemplazar new Password($pass) por new Password($pass, $min, $max, $score) 5. Reemplazar Validate::isPlaintextPassword() por validacion con ValueObject 6. Verificar que el tema incluye field-password-policy wrapper 7. Testear con passwords de score 0 a 4 que la validacion funciona

Descargar en Markdown Pensado para pegar en ChatGPT, Claude u otra IA. Incluye solo el contenido de esta pagina.