npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@libriciel/ls-password

v2.0.0

Published

A dependency-free vanilla JS component for password fields at Libriciel SCOP. It adds a toggler and a strength meter (with respect to ANSSI recommendations) to password fields.

Downloads

64

Readme

ls-password

Description

Un composant sans dépendance (JS vanilla) pour les champs de mot de passe de Libriciel SCOP. Il ajoute un bouton d'affichage/masquage et un indicateur de robustesse (conforme aux recommandations de l'ANSSI) aux champs de mot de passe. Ni jQuery, ni Bootstrap, ni police d'icônes requis.

La version 2.x est sans dépendance — jQuery n'est plus requis (le paquet a été renommé de @libriciel/ls-jquery-password). Voir le guide de migration si vous effectuez une mise à niveau depuis la 1.x.

L'indicateur de robustesse a été inspiré par la bande dessinée xkcd « Password Strength », afin d'encourager des mots de passe faciles à retenir pour un humain tout en offrant une grande entropie (nombre de valeurs possibles).

Le bouton d'affichage permet à l'utilisateur de basculer le champ de mot de passe en champ texte afin de vérifier ce qu'il a saisi.

L'indicateur de robustesse doit devenir vert et atteindre 100 % une fois l'entropie souhaitée atteinte. Il prend uniquement en compte l'entropie du mot de passe (force brute). Contrairement à d'autres indicateurs de robustesse, il ne vérifie pas les répétitions, les mots de passe courants, les mots de passe divulgués, les mots du dictionnaire, etc.

Installation

npm install @libriciel/ls-password

Utilisation

Modules ES (bundler)

import { toggler, strengthMeter } from '@libriciel/ls-password'
import '@libriciel/ls-password/dist/css/ls-password.css'

const field = document.querySelector('input[type=password]')
strengthMeter(field)               // par défaut : cible d'entropie 130 (administrateurs RSSI)
toggler(field)

Balise <script> simple (global LsPassword)

<link rel="stylesheet" href="dist/css/ls-password.css">
<script src="dist/js/ls-password.min.js"></script>
<script>
  LsPassword.strengthMeter('input[type=password]', LsPassword.strengthMeter.configure(80)); // cible d'entropie 80 (utilisateurs)
  LsPassword.toggler('input[type=password]');
</script>

Symfony AssetMapper (sans bundler)

Ajoutez le paquet à l'importmap :

php bin/console importmap:require @libriciel/ls-password

Le paquet déclarant sa feuille de style (champ style du package.json), la CSS est ajoutée automatiquement à l'importmap. Puis, dans votre point d'entrée JS (ex. assets/app.js) :

import { toggler, strengthMeter } from '@libriciel/ls-password'
import '@libriciel/ls-password/dist/css/ls-password.css' // AssetMapper génère automatiquement le <link>

const field = document.querySelector('input[type=password]')
strengthMeter(field)               // par défaut : cible d'entropie 130 (administrateurs RSSI)
toggler(field)

Les deux fonctions acceptent un élément, une NodeList, un tableau d'éléments ou un sélecteur CSS (chaîne de caractères). Le fichier CSS est requis (il met en forme la barre et le bouton, et expose les variables de thème).

Exemple autonome

API

toggler(target, options?)

Ajoute un <button type="button"> accessible d'affichage/masquage à côté du champ, en enveloppant les deux dans un conteneur .ls-pw. L'icône est un SVG intégré (aria-hidden) ; le libellé accessible est porté par les attributs title / aria-label du bouton.

| Option | Défaut | Description | | --- | --- | --- | | position | after | Position du bouton par rapport au champ (before/after) ; after = œil à droite | | showTitle | Afficher le mot de passe | Libellé lorsque le mot de passe est masqué | | hideTitle | Masquer le mot de passe | Libellé lorsque le mot de passe est affiché | | className | ls-pt | Classe du bouton | | wrapperTag | div | Balise du conteneur créé autour du champ | | wrapperClass | ls-pw | Classe du conteneur (partagée avec l'indicateur de robustesse) | | iconShow | (SVG œil barré) | Balisage SVG affiché lorsque le mot de passe est masqué | | iconHide | (SVG œil) | Balisage SVG affiché lorsque le mot de passe est affiché |

Balisage généré (par défaut) :

<div class="ls-pw">
    <button type="button" class="ls-pt" title="Afficher le mot de passe" aria-label="Afficher le mot de passe">
        <svg class="ls-pt__icon" aria-hidden="true" focusable="false">…</svg>
    </button>
    <input type="password" …>
</div>

strengthMeter(target, options?)

Ajoute une barre de robustesse après le champ (ou après le conteneur .ls-pw si le bouton d'affichage est également utilisé). Elle se met à jour automatiquement lors des événements input / change / blur.

Utilisez strengthMeter.configure(target) pour construire les options, où target est la cible d'entropie (en bits) à laquelle la barre atteint 100 % :

strengthMeter(field, strengthMeter.configure(130))
// équivalent au comportement par défaut :
{
    "className": "ls-pm",
    "barClassName": "ls-pm__bar",
    "levelClassName": "ls-pm__level",
    "complementClassName": "ls-pm__complement",
    "hintClassName": "ls-pm__hint",
    "levelPrefix": "Niveau de sécurité : ",
    "complement": { "empty": "", "very-weak": "", "weak": "Un peu plus", "average": "Encore un effort", "strong": "Presque, continuez", "very-strong": "Niveau de sécurité du mot de passe excellent." },
    "hint": { "empty": "Augmentez la longueur…", "very-weak": "Augmentez la longueur…", "weak": "Augmentez la longueur…", "average": "Augmentez la longueur…", "strong": "Augmentez la longueur…", "very-strong": "" },
    "inputGroupClass": "ls-pw",
    "inputGroupTag": "div",
    "target": 130
}

Les 2ᵉ à 4ᵉ arguments personnalisent les textes : le préfixe du texte de niveau, ainsi que les messages complement et hint par niveau (fusionnés avec les valeurs par défaut, ce qui permet de surcharger un seul niveau) :

strengthMeter(field, strengthMeter.configure(80, 'Robustesse : ')) // "Robustesse : Moyen"
strengthMeter(field, strengthMeter.configure(80, ''))              // "Moyen" (sans préfixe)
strengthMeter(field, strengthMeter.configure(80, undefined, { average: 'Presque !' }, { average: 'Ma consigne.' }))

La cible suit les préconisations du RSSI. Deux constantes nommées sont exposées par commodité :

| Constante | Entropie | Cas d'usage | | --- | --- | --- | | strengthMeter.configure.USER | 80 | utilisateurs finaux | | strengthMeter.configure.ADMIN | 130 | administrateurs / matériel cryptographique sensible — par défaut |

strengthMeter(field, strengthMeter.configure(strengthMeter.configure.USER)) // cible 80
strengthMeter(field) // pas d'options → cible par défaut 130 (ADMIN)

Une cible invalide (non numérique ou ≤ 0) génère une erreur dans la console et retombe sur la valeur par défaut (130). La barre se remplit jusqu'à 100 % une fois l'entropie atteignant la cible ; sa couleur reflète la progression vers celle-ci.

La barre comporte 5 niveaux de robustesse (plus un état empty pour un champ vide). Les quatre niveaux en dessous de la cible découpent la plage [0, target) en quarts ; atteindre la cible (100 %) donne very-strong :

| Niveau | Classe | Plage (% de la cible) | aria-valuetext | | --- | --- | --- | --- | | empty | ls-pm__bar--empty | champ vide | Vide | | very-weak | ls-pm__bar--very-weak | [0 %, 25 %) | Très faible | | weak | ls-pm__bar--weak | [25 %, 50 %) | Faible | | average | ls-pm__bar--average | [50 %, 75 %) | Moyen | | strong | ls-pm__bar--strong | [75 %, 100 %) | Fort | | very-strong | ls-pm__bar--very-strong | ≥ 100 % | Très fort |

Sous la barre, trois éléments de texte reformulent la progression (afin que l'information ne soit pas transmise par la couleur seule — WCAG) et sont mis à jour à chaque changement :

  • div.ls-pm__level — le niveau courant sous la forme <préfixe><libellé> (ex. Niveau de sécurité : Moyen), coloré comme le niveau. Vide tant que le champ est vide.
  • div.ls-pm__complement — un court complément par niveau, coloré comme le niveau (Un peu plus / Encore un effort / Presque, continuez / Niveau de sécurité du mot de passe excellent. ; aucun pour very-weak).
  • div.ls-pm__hint — une consigne de format affichée dès le départ (champ vide inclus) et partagée par tous les niveaux en dessous de la cible (Augmentez la longueur ou ajoutez des types de caractères différents…) ; absente uniquement une fois la cible atteinte.

Le complément et la consigne sont masqués (CSS :empty) dès que leur contenu est vide. Tous les textes sont configurables (voir les arguments de configure ci-dessus).

Balisage généré (barre de progression accessible avec aria-valuetext, puis les trois éléments de texte) :

<div class="ls-pm">
    <div class="ls-pm__bar ls-pm__bar--empty" role="progressbar"
         aria-label="Indicateur de robustesse du mot de passe"
         aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"
         aria-valuetext="Vide" style="width:0%;">0%</div>
</div>
<div class="ls-pm__level ls-pm__level--empty"></div>
<div class="ls-pm__complement ls-pm__complement--empty"></div>
<div class="ls-pm__hint">Augmentez la longueur ou ajoutez des types de caractères différents (chiffres, majuscules, caractères spéciaux).</div>

Personnalisation du thème

Les couleurs sont personnalisables via des variables CSS. Le composant utilise la variable de votre système de design lorsqu'elle est définie, avec une valeur de repli codée en dur sinon :

:root {
    /* Fond de la barre */
    --ls-pm-color-empty:       var(--ds-color-grey-200, #d3d3d3);
    --ls-pm-color-very-weak:   var(--ds-color-danger-600, #c02b2b);
    --ls-pm-color-weak:        var(--ds-color-danger-600, #c02b2b);
    --ls-pm-color-average:     var(--ds-color-warning-600, #c07000);
    /* « Fort » reste orange : le vert est réservé à la validation (cible atteinte, very-strong) */
    --ls-pm-color-strong:      var(--ds-color-warning-600, #c07000);
    --ls-pm-color-very-strong: var(--ds-color-success-600, #23a237);
    /* Texte de niveau visible — seuls average/strong/very-strong nécessitent une teinte plus foncée que la
       barre pour le contraste WCAG AA sur fond clair ; les autres réutilisent les variables de barre ci-dessus */
    --ls-pm-level-color-average:     var(--ds-color-warning-800, #843500);
    --ls-pm-level-color-strong:      var(--ds-color-warning-800, #843500);
    --ls-pm-level-color-very-strong: var(--ds-color-success-800, #02590f);
    --ls-pm-hint-color:        var(--ds-color-grey-600, #5c6370);   /* texte de la consigne de format */
    --ls-pt-icon-color:        var(--ds-color-grey-600, #5c6370);   /* icône œil */
    --ls-pt-hover-bg:          var(--ds-color-grey-200, #d3d3d3);    /* survol du bouton */
}

Développement

Toutes les commandes s'exécutent dans Docker (voir CLAUDE.md) ; l'installation Node de l'hôte n'est pas utilisée.

make test       # lance la suite de tests (Vitest)
make coverage   # lance les tests avec rapport de couverture (coverage/)
make build      # construit dist/ (ESM + UMD + CSS) avec Vite
make dev        # démo de développement avec rechargement à chaud → http://localhost:5173/