Aller au contenu
Candidater

Journal des modifications

Les évolutions de Cohez.io, de la plus récente à la plus ancienne.

93 versions correspondent à « inscription ».

Versions 1 à 10 sur 93

0.25.19.0 — 2026-10-07

Ajouts

  • Conditions d’utilisation /conditions-utilisation (#360, 2026-10-06). Ces conditions courtes (version 2026-10, dix articles) s’adressent à toute personne qui utilise Cohez.io : membre du bureau, salarié, bénévole, ou personne qui remplit un formulaire public d’une association. Elles couvrent l’accès, la sécurité du compte, le bon usage, les rôles (l’association est responsable de traitement, l’éditeur sous-traitant), les formulaires publics, la phase de test, la responsabilité, la suspension, les données personnelles et le droit applicable. La page est en noindex, hors sitemap, avec un lien dans le pied de page de la vitrine. Les comptes existants n’ont pas à les accepter de nouveau.
  • Journal d’acceptation des conditions d’utilisation (#360, 2026-10-06). Chaque acceptation ajoute une ligne à la table terms_acceptances (utilisateur, association, version du texte, date, parcours), jamais modifiée : quand les conditions évoluent, la preuve de chaque version acceptée est conservée. Ni adresse IP ni navigateur ne sont enregistrés ; l’inscription passe par un lien signé envoyé à l’adresse de la personne. Les lignes sont supprimées avec le compte ou avec l’association. La page affiche la version en vigueur, la même que celle enregistrée.
  • Pied de page du funnel d’inscription public (#360, 2026-10-06). Les pages publiques des associations affichent « Propulsé par Cohez.io · Conditions d’utilisation · Confidentialité », avec des liens absolus vers le domaine racine qui s’ouvrent dans un nouvel onglet.

Modifications

  • Case d’acceptation de l’inscription sur invitation (#360, 2026-10-06). La case renvoie désormais aux conditions d’utilisation et n’est plus présentée comme un consentement RGPD : la description indique que les données sont traitées par l’association avec Cohez.io et renvoie à la politique de confidentialité. Elle est exigée de tous, salariés compris (terms_accepted_at renseigné pour tout nouveau compte).
  • Preuve de l’acceptation déclarée comme traitement de l’éditeur (#360, 2026-10-06). La politique de confidentialité la décrit (section « Acceptation des conditions d’utilisation » : données, intérêt légitime, aucune adresse IP, durée), l’article 1 bis de la fiche /dpa la cite parmi les traitements dont l’éditeur est responsable (ligne d’historique du 6 octobre, version 2026-10 inchangée), et l’article 9 des conditions d’utilisation y renvoie.

0.25.15.0 — 2026-10-02

Corrections

  • Rapports CSP « eval » sur le back-office (2026-10-02). La librairie de glisser-déposer vuedraggable 4.1.0 (cours, rubriques et propositions de campagne) embarquait un shim webpack 4 qui tente new Function("return this"). La CSP le bloquait et chaque chargement de ces écrans envoyait un rapport script-src 'eval'. Le rapport pouvait porter l'URL de la page précédente (/dashboard, racine), parce qu'Inertia charge la page suivante avant de changer d'URL. Le comportement n'était pas affecté. vuedraggable est remplacé par vue-draggable-plus (ESM, sans eval). À noter : cette librairie embarque sa propre copie de Sortable (1.15.2), dont les correctifs n'arrivent que par une nouvelle version de vue-draggable-plus.
  • Ordre enregistré seulement s'il change (2026-10-02). Relâcher un cours, une rubrique ou une proposition à sa place d'origine n'envoie plus de requête de réordonnancement ni de rechargement de page.

Modifications

  • Code de glisser-déposer chargé seulement là où il sert (2026-10-02). Ce code était inclus dans le bundle commun chargé par toutes les pages, y compris le funnel public d'inscription. Il n'est plus téléchargé que par les écrans qui l'utilisent. Le bundle commun passe de 178 Ko à 125 Ko.

0.25.11.0 — 2026-09-29

Ajouts

  • Aide en ligne : rubrique Paniers & paiements (#333, 2026-09-29). Six guides pour les trésoriers et dirigeants : comprendre un panier, versements, paiement manuel, paiement en ligne HelloAsso, relances, annuler une inscription. Les guides décrivent le comportement actuel, limites comprises (pas de remboursement par Cohez.io, versement corrigé par rejet, pas de paiement en plusieurs fois HelloAsso). L'accueil de l'aide ajoute l'étape « Choisir les moyens de paiement » avant l'ouverture, et les pages Inscriptions renvoient vers la nouvelle rubrique. Chemins figés par des tests ; captures dans une PR suivante.

0.25.9.0 — 2026-09-29

Ajouts

  • Aide en ligne : rubrique Inscriptions et parcours « Par où commencer » (#331, 2026-09-29). Six guides pour les dirigeants : saisons et cours, campagne et formulaire public, rubriques, propositions et tarifs, suivi des inscriptions, export CSV, ajout, retrait et échange de cours. L'accueil de l'aide guide la mise en route d'une saison dans l'ordre (saison, cours, campagne, formulaire, ouverture). Les libellés cités sont ceux des écrans ; un test vérifie que le guide du formulaire public reprend les titres exacts des pages « Les inscriptions sont clôturées », « Ce lien d'inscription a expiré » et « Page introuvable ». Les chemins des guides sont figés par des tests.

Corrections

  • Code en ligne sans accents graves dans l'aide (2026-09-29). Le plugin typographique de Tailwind entourait chaque <code> d'accents graves visibles (noms de fichier, colonnes du CSV). Neutralisé dans vitrine.css pour les pages d'aide.

0.25.6.1 — 2026-09-28

Corrections

  • Dédoublonnage des personnes sans e-mail par identité civile (#324, 2026-09-28). Une inscription publique ou une ligne d'import sans e-mail, mais avec nom et date de naissance, rattache désormais l'adhérent à la fiche existante de même prénom, nom et date (casse et espaces ignorés) au lieu de créer un doublon ; la fiche portant déjà un Member est préférée, son e-mail n'est jamais modifié. Sans nom ou sans date, une nouvelle fiche est créée comme avant ; la date doit être identique (une fiche sans date n'est pas rattachée). Le garde-fou d'adhésion active et le préflight d'import suivent la même règle : une ligne sans e-mail rattachable n'est plus bloquante (« réutilisée ») ; sans nom ou sans date, elle reste bloquante. Les doublons déjà en base ne sont ni fusionnés ni corrigés.
  • Repli civil borné : consentements jamais appliqués, contact principal jamais rétrogradé (#324, 2026-09-28). Sur ce repli civil sans e-mail, la mise à jour d'une fiche retrouvée n'applique plus l'opt-in des consentements RGPD (import et funnel public) ; dans le funnel public, le contact principal (LegalGuardian) déjà déclaré pour un mineur n'est plus rétrogradé par une soumission qui le retrouve sans e-mail — un nouveau responsable ne devient principal que si le mineur n'en a encore aucun. Le chemin e-mail garde son comportement actuel (opt-in des consentements, rétrogradation de l'ancien contact principal).

0.25.6.0 — 2026-09-28

Ajouts

  • Page d'erreur applicative en français sur les espaces association (#318, 2026-09-26). Les 403, 404, 410 (et les 500 hors mode debug) des sous-domaines tenant affichent une page Inertia du Design System (errors/HttpError) au lieu de la page Laravel en anglais : titre et message par statut, bouton « Retour au tableau de bord » réservé aux utilisateurs connectés. Le 410 reste générique (« Ce lien ou ce document n'est plus disponible ») car il couvre aussi les liens publics expirés du funnel. Seul le code de statut est transmis à la page : ni message d'exception, ni chemin, ni trace. La vitrine, l'admin Filament et les réponses JSON gardent leur comportement d'origine ; si le rendu échoue, l'erreur est journalisée et la réponse d'origine est renvoyée.

Modifications

  • Contraste AA des couleurs de statut success et warning, dans toute l'application (#318, 2026-09-26). Blanc sur #27AE60 ou #C68C00 plafonnait à 2,9:1 ; les tokens passent à #1F7A3E et #8A6100 en clair (≥ 5:1 sous texte blanc et sur le fond de page), avec un texte foncé sur les badges en sombre. Tous les badges, pastilles et textes de statut changent de teinte (Dashboard, paniers, inscriptions, réunions, toasts).
  • Accessibilité de l'onglet Santé et de la page Archives santé (#318, 2026-09-26). Formats, taille maximale et plage de dates acceptés affichés sous le champ de dépôt, dérivés des règles serveur ; champ fichier vidé après un dépôt réussi ; boutons « Déposer » / « Enregistrer » actifs, validation à la soumission, erreurs annoncées (role="alert") et focus sur le premier champ en erreur ; erreur de saison reliée au sélecteur. Archives : titres de tableaux (<caption>), aide du motif reliée au champ, état de téléchargement. Icônes décoratives masquées aux lecteurs d'écran, noms accessibles distincts d'une saison à l'autre, mention « nouvel onglet », cibles tactiles de 44 px sur mobile.
  • Composants de formulaire (#318, 2026-09-26). Input, Textarea et Select ne posent aria-describedby que si l'aide ou l'erreur visée existe ; Select accepte une aide et une erreur reliées, et aligne sa valeur à gauche partout.

Corrections / Sécurité

  • Les pièces santé sont téléchargées avec leur vrai type de fichier (#318, 2026-09-26). StreamMemberDocument ne posait pas de Content-Type : la pièce partait en text/html. Elle est maintenant servie en PDF, JPEG ou PNG selon son extension (liste blanche, repli application/octet-stream), avec X-Content-Type-Options: nosniff. Formats acceptés, attribut accept, aide affichée et type servi viennent d'une source unique, HealthDocumentRules.
  • Page d'erreur applicative : correctifs de revue (#318, 2026-09-26). L'admin sur admin.{domaine} garde sa page d'origine même si ADMIN_DOMAIN diffère ; une réponse d'erreur déjà en JSON n'est jamais remplacée par la page HTML ; tous les appels fetch JSON du front (funnel public, groupes, utilisateurs, représentants légaux, réunion live) envoient Accept: application/json, pour recevoir le message d'erreur du serveur plutôt qu'une page ; un visiteur sans session (URL inexistante) se voit proposer « Retour à l'accueil ». Une fiche introuvable (404 levé à la résolution du modèle de la route, par exemple /members/{id} inconnu) garde l'utilisateur connecté et le nom de l'association : les middlewares Inertia passent désormais avant SubstituteBindings.
  • Onglet Santé et Archives : erreurs mieux rattachées (#318, 2026-09-26). L'erreur sur le représentant légal d'une attestation est affichée et reliée à son champ, et une erreur sans champ dédié est annoncée au niveau du formulaire. Dans les Archives, une pièce déjà supprimée (410), une erreur réseau ou un refus serveur s'affichent dans le dialogue sans marquer le motif invalide ; l'erreur « motif trop court » s'efface à la saisie.
  • Stack Docker de dev : healthcheck nginx limité à /health exact (#322, 2026-09-28). location /health était un préfixe et interceptait /health-archives, qui répondait healthy au lieu d'afficher la page Archives santé en local. Aucun effet sur Clever Cloud.

0.25.5.3 — 2026-09-27

Corrections

  • Dédoublonnage des personnes : une date de naissance absente d'un côté ne crée plus de doublon (#321, 2026-09-27). À e-mail et prénom égaux (casse et espaces ignorés), PersonIdentityMatcher::whereDedupKey() traite une date de naissance absente — sur la fiche ou dans la saisie — comme compatible : le funnel d'inscription publique et l'import HelloAsso retrouvent une fiche créée sans date (back-office, import) au lieu d'en créer une seconde, et complètent sa date sans jamais écraser une date existante. Deux dates renseignées et distinctes restent deux personnes (fratries, jumeaux). Une fiche sans date qui n'est que payeur ou responsable légal (sans adhésion) n'est pas rapprochée d'une saisie datée, pour ne pas rattacher un enfant homonyme à la fiche de son parent. Quand plusieurs fiches correspondent, celle qui porte déjà un Member est retenue, puis celle dont la date est exactement celle saisie (preferringMemberThenExactBirthdate()). Un nouveau Member créé sur une fiche datée retrouvée sans date saisie tire son statut mineur de la date de la fiche. Le contrôle de doublon d'inscription, le garde-fou d'adhésion active et le préflight d'import (« Réutilisée » au lieu de « Ambiguë », message dédié pour la fiche payeur / responsable légal) suivent la même règle. L'import résout les adhérents d'un panier avant son payeur et ses représentants : un adhérent qui paie pour lui-même retrouve sa fiche sans date au lieu d'en créer une seconde ; le préflight bloque une fiche sans date ni adhésion dont l'identité est payeur ou représentant d'une autre commande du fichier (issue dépendante de l'ordre des commandes), et son message d'ambiguïté cite de préférence la fiche datée. Le garde-fou d'adhésion active et le contrôle « déjà inscrit » ignorent une fiche sans date quand une fiche à la date saisie porte déjà une adhésion : une fille datée n'est plus bloquée par l'inscription de sa mère homonyme sans date sur l'e-mail familial. Les doublons déjà en base ne sont ni fusionnés ni corrigés.

0.25.5.1 — 2026-09-26

Corrections

  • Dédoublonnage des personnes insensible à la casse et aux espaces de l'e-mail et du prénom (#319, 2026-09-26). Le funnel d'inscription publique et l'import HelloAsso reconnaissent désormais une personne déjà en base même si son e-mail ou son prénom diffère par la casse ou par des espaces, via PersonIdentityMatcher (LOWER(TRIM())) : dédoublonnage PersonDeduplicationService, contrôle de doublon d'inscription, garde-fou d'adhésion active, payeur et responsable légal (funnel et ImportPayerResolver), préflight d'import. Quand plusieurs fiches correspondent, la fiche qui porte déjà un Member (ou un Payeur) est retenue, puis la plus ancienne ; le contrôle de doublon et le garde-fou d'adhésion examinent toutes les fiches. Les doublons déjà en base ne sont ni fusionnés ni corrigés.

0.25.5.0 — 2026-09-25

Ajouts

  • Les pièces santé sont rangées par saison, et la fiche adhérent affiche un bloc de conformité par saison active (#317, 2026-09-25). Une pièce appartient désormais à une saison : clé (member_id, season_id, document_type), une attestation par (adhérent, saison), avec la campagne d'inscription quand elle est connue (member_documents.campaign_id). SeasonHealthProof est l'oracle unique d'une saison (certificat courant + historique) et GoverningCampaignResolver raisonne par saison. Dans une saison, le certificat au valid_until le plus tardif reste courant ; un dépôt qui expire plus tôt entre en historique, et le remplacement ne supprime jamais de fichier. Le back-office choisit explicitement la saison (et la campagne) au dépôt ; dépôt et retrait sont refusés (404) sur une saison close. Un certificat déjà expiré à la date du dépôt est signalé (CertificateState, statut StaleCertificate). Le tunnel public n'échoue plus sur une seconde attestation pour la même saison.
  • Page « Archives santé » : consultation motivée et journalisée des pièces des saisons closes (#317, 2026-09-25). Nouvelle permission nominative view_archived_health_documents, accordée par utilisateur (case « Archives santé » dans les réglages utilisateur) et jamais attribuée par défaut, même au rôle admin. Ouvrir une pièce archivée exige un motif d'au moins 10 caractères, journalisé dans member_document_accesses (reason, context = archive) avant l'envoi du premier octet ; 403 sans permission, 422 sans motif, 404 hors phase archivée, AdminUser refusé.
  • health:unanchored-documents liste les pièces santé sans saison et permet de les rattacher (--attach) (#317, 2026-09-25). Lecture seule par défaut ; ces pièces ne sont jamais purgées automatiquement.

Modifications

  • La conservation des pièces santé est une durée par saison : fin de saison + N ans (#317, 2026-09-25). tenants.health_retention_years (5 par défaut) et HealthRetention définissent trois phases — active, archivée, supprimée — utilisées partout (fiche, téléchargements, archives, purge). health:purge-documents ne purge plus à l'expiration du certificat (+ 30 jours) : elle supprime fichiers, lignes et attestations des saisons arrivées en fin de conservation, par lots, tenant par tenant. Le fichier est supprimé avant sa ligne : un échec de stockage laisse la ligne en place et la suppression est retentée la nuit suivante. La commande renvoie FAILURE dès qu'un tenant échoue, et la tâche planifiée est protégée contre le chevauchement. ⚠️ Une date de fin de saison erronée dans le passé déclenche une purge prématurée et irréversible.
  • Migration de données (#317, 2026-09-25). Les pièces existantes sont rattachées à leur saison, les doublons par saison résolus par supersession, les index uniques posés par saison. La réponse d'attestation « au moins une positive » (has_positive) est retirée : une réponse positive appelle un certificat.

Notes de déploiement

  • En production, post_build.sh relance PermissionSeeder et RoleSeeder : rien à faire. Sur une base de développement non re-seedée, la nouvelle permission manque et la page des réglages utilisateur renvoie une 500 (PermissionDoesNotExist) : relancer ces deux seeders.

0.25.4.0 — 2026-09-25

Ajouts

  • Identification d'un adhérent déjà connu dans le funnel d'inscription publique (#296, 2026-09-25). Un adhérent qui a déjà un dossier dans l'association peut désormais s'identifier avant de s'inscrire à une nouvelle proposition : il saisit son e-mail, reçoit un code à usage unique, et le funnel pré-remplit son identité, ses représentants légaux et ses acceptations à partir du dossier retrouvé, sans dédoublonner un nouveau Person.

Corrections / Sécurité

  • Durcissement de bout en bout de l'identification adhérent, à l'issue d'une revue de sécurité de la PR #296 (2026-09-25). L'identité rapprochée est désormais liée côté serveur (aucun identifiant de personne fourni par le client n'est fait confiance) et filtrée par tenant (applyIdentifiedMember) ; le rapprochement civil passe par un PersonIdentityMatcher partagé et normalisé (casse, espaces) au lieu de comparaisons dupliquées ; une adhésion active déjà en cours bloque désormais la soumission, avec repli sur l'identité rapprochée quand nécessaire ; l'e-mail d'une personne identifiée n'est ni écrasé ni modifiable côté front tant qu'elle reste identifiée ; un seul contact principal subsiste parmi les responsables légaux, l'ajout d'un nouveau responsable principal rétrogradant l'ancien. Sur le canal d'identification lui-même : le code envoyé est désormais lié au jeton public de la campagne qui l'a émis, réservé atomiquement à chaque tentative (5 maximum), à usage unique une fois vérifié avec succès, vérifié à coût constant (anti-énumération), et un délai minimal de 60 secondes s'impose entre deux envois de code. Un jeton XSRF est relu via un helper partagé (readXsrfToken) plutôt que dupliqué. La déduplication insensible à la casse de PersonDeduplicationService (trouvaille F3, doublons silencieux en base) reste hors périmètre de cette PR et fait l'objet d'un plan séparé.