EN · DE · RU · FR · ES

#2762: webauthn.js

projectforge-webapp/src/utilities/webauthn.js Utilitaires de conversion d’identifiants WebAuthn · projectforge-webapp/src/utilities/webauthn-json.js 86 lignes · 80 code · 1 commentaire · 5 vides
Couche de conversion d’identifiants WebAuthn (FIDO2/U2F) développée sur mesure par ProjectForge. Ce module fournit le pont de codage/décodage entre l’API native PublicKeyCredential du navigateur (qui utilise des valeurs binaires ArrayBuffer) et l’API JSON côté serveur (qui attend des chaînes encodées en base64url). Trois fonctions principales gèrent des étapes distinctes du cycle de vie : convertPublicKeyCredentialRequestOptions décode le défi et les identifiants utilisateur fournis par le serveur en ArrayBuffer pour l’API du navigateur ; convertRegisterCredential transforme un identifiant fraîchement créé dans la structure JSON attendue par le serveur pour l’enregistrement ; convertAuthenticateCredential fait de même pour les assertions d’authentification.

Architecture

Fonctions internes

decodeBase64url — Convertit une chaîne base64 URL-safe en ArrayBuffer. Utilise le pont atob : reconstruit d’abord le base64 standard (en remplaçant -+, _/, en ajoutant du padding), puis décode via atob, et copie le charCode de chaque caractère dans un Uint8Array soutenu par un nouveau ArrayBuffer.

bufferToBase64url — L’inverse : parcourt une vue Uint8Array, construit une chaîne binaire via String.fromCharCode, encode avec btoa, puis convertit en forme URL-safe.

convertCredentials — Fonction utilitaire extraite lors du refactoring, qui convertit un tableau d’objets descripteurs d’identifiants (avec les champs rawId et id) de chaînes base64url en ArrayBuffer, pour les listes allowCredentials et excludeCredentials.

Enregistrement vs. Authentification

L’enregistrement (convertRegisterCredential) regroupe : rawId, clientDataJSON, attestationObject et transports de la réponse d’identifiant, ainsi que les métadonnées de la requête (requestId, challenge, sessionToken). L’authentification (convertAuthenticateCredential) regroupe : authenticatorData, signature, userHandle à la place des champs d’attestation. Les deux enveloppent le résultat dans la même structure que les endpoints REST côté serveur attendent.

Évolution de l’approche

Ce fichier représente l’implémentation WebAuthn de production, distincte de la bibliothèque webauthn-json.js intégrée. L’équipe a commencé avec un décodage base64 manuel par manipulation de bits (utilisant une table de correspondance inversée), puis a refactorisé vers l’approche plus simple basée sur atob/btoa. Les fonctions séparées d’enregistrement et d’authentification, ainsi que l’utilitaire convertCredentials, ont été extraites d’une conversion d’identifiants initialement monolithique.

Historique Git

CommitCe qui a changé
9c86a74e5Extraction des boucles de conversion inline allowCredentials/excludeCredentials dans une fonction utilitaire partagée convertCredentials(dest, src). Réduction de la duplication : les deux listes d’identifiants appellent désormais la même fonction. La conversion excludeCredentials de la fonction originale convertPublicKeyCredentialRequestOptions a également été ajoutée ici, complétant la gestion des listes d’identifiants.
c6ba8d11cDeux ajouts significatifs : (1) Ajout de la conversion de liste d’identifiants dans convertPublicKeyCredentialRequestOptions pour gérer les tableaux allowCredentialsrawId et id de chaque identifiant sont décodés depuis le base64url ; (2) Ajout de convertAuthenticateCredential comme fonction dédiée aux assertions d’authentification (auparavant, l’enregistrement et l’authentification étaient gérés par une seule fonction convertCredential). L’ancienne fonction a été renommée en convertRegisterCredential pour clarifier son rôle.
4c5cc21e9Refactoring de convertCredential pour retourner l’objet résultat directement au lieu de l’assigner à une variable intermédiaire result, et ajout du champ challenge à l’enveloppe de sortie — un correctif critique car le serveur a besoin du défi original pour vérifier l’identifiant.
4a70ca329Correction de l’extraction des champs de la réponse d’identifiant en utilisant la déstructuration : const { response } = credential; — le code précédent lisait incorrectement clientDataJSON, attestationObject et transports depuis l’objet credential de premier niveau au lieu de credential.response, ce qui aurait produit des valeurs undefined. C’était un correctif de bug critique.
ddccb2e68Refactoring majeur de l’approche d’encodage/décodage base64url. Le décodeur original par manipulation de bits (utilisant une table de correspondance inversée et des décalages de bits manuels) a été remplacé par l’approche plus simple basée sur atob/btoa. Également conversion de convertPublicKeyCredentialRequestOptions d’une approche par mutation (modification de l’entrée sur place) à une approche par copie (utilisation de JSON.parse(JSON.stringify(...)) pour une copie profonde d’abord). Ajout de la première version de convertCredential pour l’encodage d’enregistrement.
05c32c27fCommit initial WebAuthn : création du décodeur base64url et de la première version de convertPublicKeyCredentialRequestOptions. Utilisation du nom de paramètre registerData et accès à challenge/user.id via registerData.publicKey.challenge, reflétant une structure d’API antérieure qui a été simplifiée par la suite.