Backoffice - personnalisations
Le template personnalise le backoffice Umbraco sur quatre axes : login dev rapide, styles (login + indication d'environnement), 2FA, et un dashboard "Système".
Login dev rapide (Controllers/DevLoginController.cs)
GET /l, DEBUG uniquement (voir extensibility.md). Auto-connecte le premier utilisateur dont l'email finit par @spektrummedia.com. Double garde (#if DEBUG + IsDevelopment()) a ne jamais retirer. Evite de saisir des identifiants en developpement local.
App_Plugins
Tous declares via umbraco-package.json (manifests Umbraco 17 : backofficeEntryPoint, mfaLoginProvider, propertyEditorUi).
CustomBackofficeLoginStyles
Personnalise l'ecran de login backoffice. backoffice.js (entry point) injecte backoffice-login.css (couleur primaire --umb-login-primary-color). L'image de fond est servie depuis wwwroot/images/custom-backoffice-login/ et referencee par Umbraco:CMS:Content:LoginBackgroundImage (appsettings.json).
Fond + logo de login par skin. Un visuel par police, cadre carre 1200x1200 : apol.jpg (motard Police Lavaux devant le Leman) et pel.jpg (vehicule Skoda de police), plus un logo blanc par-dessus (LoginLogoImage) : apol-logo.svg (= logos/apol/logo-desktop.svg) et pel-logo.svg (= logos/pel/main-logo.svg), choisis blancs pour ressortir sur la photo. appsettings.json pointe par defaut sur les visuels apol (skin par defaut du template, Site:Theme=apol). Une instance aval en skin PEL doit pointer LoginBackgroundImage/LoginLogoImage vers pel.jpg/pel-logo.svg en meme temps qu'elle passe Site:Theme=pel (le login precede le chargement du contenu, il ne peut pas resoudre le theme dynamiquement). Les sources photo originales ne sont pas versionnees dans le repo.
CustomEnvironmentBackofficeStyles
Affiche une indication visuelle de l'environnement courant dans le backoffice (pour ne pas confondre local / staging / prod). backoffice.js (onInit) injecte backoffice-env.css ; des variantes backoffice-env.master.css et backoffice-env.staging.css existent par environnement.
TwoFactorProviders
Manifeste (type mfaLoginProvider, alias UmbracoUserAppAuthenticator, label "Google Authenticator") qui declare cote UI le provider 2FA implemente cote serveur.
ButtonPicker (property editor)
Property editor custom (type propertyEditorUi, alias Spektrum.PropertyEditorUi.ButtonPicker) : un groupe de boutons a selection unique ; la valeur stockee est celle du bouton choisi (une classe CSS). Module Lit sans build (button-picker.element.js, imports bare @umbraco-cms/backoffice/* resolus par l'import map du backoffice). Schema de valeur reutilise = Umbraco.TextBox (chaine ; Umbraco.Plainstring n'existe pas cote serveur dans cet Umbraco 17). La config (buttons/defaultValue/small) est declaree dans meta.settings.properties et lue via config.getValueByAlias(...). La liste buttons (tableau [{label,value}]) s'edite dans le backoffice via un 2e property editor Spektrum.PropertyEditorUi.ButtonPickerConfig (repeater button-picker-config.element.js : une ligne = libelle + classe-css + supprimer, bouton ajouter) - stockage en tableau JSON, donc les .config restent simples. defaultValue = TextBox, small = Toggle. Sert les reglages du bloc oneColumnLayoutBlock (voir content-model.md).
VacationsEditor (property editor, PEL)
Property editor custom (propertyEditorUi, alias Spektrum.PropertyEditorUi.VacationsEditor) pour le champ vacations de la fiche membre (PEL). Module Lit sans build (vacations-editor.element.js, même pattern que ButtonPicker). Schéma de valeur = Umbraco.TextArea ; la valeur est un JSON maison [{ "year", "entries": [{ "title", "start", "end", "note" }] }] (start/end en yyyy-MM-dd). UI : dossiers par année créés à la main (bouton « Ajouter une année », année éditable), périodes ajoutées dedans (motif / du / au / note). Lu côté serveur par simple parse JSON dans MemberDirectoryService (voir content-model.md / extensibility.md).
SentinelleDashboard (dashboard « Système »)
Dashboard de la section Content (type dashboard, alias Sentinelle.Dashboard.System, onglet « Système »). Module Lit sans build (dashboard.js) qui fetch l'API back-office avec le Bearer token du UMB_AUTH_CONTEXT. Backend : Controllers/DashboardInfoController.cs (ManagementApiControllerBase, route /umbraco/management/api/v1/sentinelle-dashboard/, [Authorize(BackOfficeAccess)]) :
GET info-> version source (git), date de derniere modif, etat de l'index de recherche (pages / PDF / total) viaIDashboardInfoService(Services/DashboardInfoService.cs).POST reindex-> reconstruit l'ExternalIndex (IIndexRebuilder.RebuildIndex(ExternalIndexName, useBackgroundThread: true)), ce qui relanceFullTextIndexHandlerdonc l'extraction texte/OCR des PDF (voirextensibility.md). Renvoie 202 aussitot (rebuild en tache de fond), ou 409 si un rebuild tourne deja. Cote UI, le bouton « Relancer l'indexation des PDF » (encart « Index de recherche ») demande confirmation (umbConfirmModal), lance le POST, puis rafraichit les compteurs apres ~15 s.
Le dashboard porte aussi une carte Support (contact + coordonnees d'agence + reseaux sociaux Spektrum en SVG inline, aucune requete externe : CSP backoffice) et une carte Nouveautés : accordeon alimente par le fichier statique App_Plugins/SentinelleDashboard/changelog.json (fetch direct, sans backend ; echec non bloquant -> carte masquee). Chaque entree = un deploiement repere par sa date (la plus recente ouverte par defaut) ; les types Ajout/Amelioration/Correction sont mappes a une couleur via TAG_CLASSES dans dashboard.js. Redaction et regles : skill updating-changelog (+ section Changelog du CLAUDE.md). Le changelog est commun aux deux skins (pas de mention APOL/PEL). Pas de numero de version dans le changelog : la carte « Version & build » (git) en est la seule source.
2FA - Google Authenticator (Services/UmbracoUserAppAuthenticator.cs)
ITwoFactorProvider (nom constant UmbracoUserAppAuthenticator), enregistre dans SiteComposer via BackOfficeIdentityBuilder.AddTwoFactorProvider<...>. Utilise le package GoogleAuthenticator :
GetSetupDataAsync: genere le QR-code de setup (TwoFactorAuthInfoModel) ; le nom d'application est en dur ("My application name") - a personnaliser par projet.ValidateTwoFactorPIN/ValidateTwoFactorSetup: valident le code TOTP.
Securite backoffice (appsettings.json)
- Politique mot de passe : >= 15 caracteres, majuscule + minuscule + chiffre + caractere non-alphanumerique.
AllowConcurrentLogins=false.DefaultUILanguage=fr-FR,TimeOut=01:00:00.

