Il banner di consenso di FAZ Cookie Manager 1.32.0

Contenuto

FAZ Cookie Manager 1.32.0 è online. Questa volta le segnalazioni dal forum di wordpress.org sono tre, e hanno qualcosa in comune che mi ha fatto riflettere: in tutti e tre i casi il plugin faceva la cosa giusta sul contenuto che vedeva, ma il contenuto vero, quello che il browser del visitatore caricava davvero, era un altro. Un widget che salva un indirizzo e ne apre un secondo, una mappa che non è un iframe, una libreria che arriva un istante dopo chi la stava aspettando.

Il video di Elementor che non ascoltava

La prima segnalazione era precisa fino al file: un video YouTube dentro il widget Video di Elementor, YouTube impostato come necessario nelle impostazioni, e il video che continuava a mostrare il riquadro «contenuto bloccato». L’autore aveva già letto il codice e aveva ragione. Il widget non stampa un iframe: stampa un contenitore vuoto con le sue impostazioni e costruisce il player nel browser. Il blocco degli iframe quindi non lo vede, e il plugin lo giudicava su un percorso a parte, che prendeva la categoria direttamente dal catalogo interno, dove YouTube è Marketing. Una regola personalizzata, un’eccezione, il filtro faz_blocking_rules e la classe faz-skip funzionavano su un iframe normale e non facevano nulla sul widget.

Far passare il widget per le stesse regole era la correzione ovvia. Quella meno ovvia l’ha trovata la revisione: il widget salva l’indirizzo come lo scrive chi compila la pagina, youtube.com/watch?v=…, youtu.be/…, vimeo.com/123, ma il browser apre l’indirizzo di embed che Elementor ne ricava, youtube.com/embed/… o player.vimeo.com/video/…. Le regole scritte per un iframe usano il secondo. Una regola su player.vimeo.com, per esempio, non avrebbe mai toccato un widget Vimeo. Adesso il widget viene giudicato prima sull’indirizzo che carica davvero, esattamente come un iframe verso quell’indirizzo, e poi su quello salvato.

Una mappa che non era un iframe

La seconda segnalazione veniva da un sito costruito con Bricks, con un link alla pagina dei contatti. Sopra la mappa mancava l’avviso che invita ad accettare i cookie: al suo posto c’era uno spazio vuoto. Aprendo la pagina il quadro era chiaro. Lo script di Google Maps era bloccato correttamente fino al consenso, ma l’elemento Map di Bricks è un contenitore vuoto che Bricks disegna da JavaScript quando Google richiama la sua funzione. Il plugin aveva bloccato lo script e non aveva niente da mettere nel contenitore. Il visitatore vedeva un buco e non aveva modo di dire sì.

Ora il contenitore riceve lo stesso riquadro di consenso di qualunque contenuto bloccato, e le impostazioni della mappa restano parcheggiate finché il visitatore non accetta, così Bricks non trova niente da disegnare e a Google non parte nessuna richiesta. Dopo il clic lo script si carica e la mappa compare nella stessa pagina. Il sito usava anche il Delay JavaScript di WP Rocket, che fa arrivare lo script della mappa di Bricks dopo la chiamata di Google: in quel caso il plugin avvia la mappa appena ci sono entrambi, una volta sola e mai per una mappa già disegnata.

Su questo punto la revisione mi ha fatto notare una cosa scomoda: tre dei controlli che proteggono quel riavvio non avevano un test capace di fallire. Togliendoli uno alla volta, la suite restava verde. Adesso ognuno ha il suo, e c’è una prova nel browser che costruisce lo stesso markup di Bricks, conta le richieste a Google prima del consenso e fallisce sulla versione precedente del plugin, che è il minimo che chiedo a un test scritto per un bug.

WooCommerce e l’attribuzione degli ordini

La terza segnalazione: con il plugin e la WP Consent API attivi, WooCommerce registrava l’origine degli ordini come «Unknown». La diagnosi dell’utente era già giusta, e il suo test con setOrderTracking(true) lanciato a mano la confermava. Il plugin tiene bloccata sourcebuster.js, la libreria che WooCommerce usa per leggere da dove arriva un visitatore, e la ripristina al consenso inserendo un nuovo script, che parte solo dopo che il clic è finito. WooCommerce reagisce al consenso dentro lo stesso clic, chiede il tracciamento, non trova la libreria, prende nota e si ferma. Nessuno richiedeva più niente quando la libreria arrivava, e i parametri della pagina di atterraggio andavano persi.

Il plugin ora ripete la chiamata di WooCommerce una volta, quando sourcebuster è arrivata, e solo se WooCommerce aveva già deciso di tracciare: la decisione resta sua e del consenso del visitatore. Ho anche spostato Sourcebuster da Statistiche a Marketing, che è la categoria che WooCommerce controlla, e l’aggiornamento sposta i cookie sbjs_* già in elenco solo se li aveva scritti una scansione e nessuno li ha toccati da allora. Una categoria scelta da una persona non la cambio da solo: la lascio com’è e un avviso chiede di controllarla.

Anche qui la revisione ha smontato una mia certezza. Per evitare di inizializzare sourcebuster due volte confrontavo l’oggetto di WooCommerce prima e dopo il ripristino, convinto che un WooCommerce caricato in ritardo ne creasse uno nuovo. Il WooCommerce vero non lo fa: crea l’oggetto con i suoi parametri e poi ci aggiunge la funzione, sullo stesso oggetto. Il mio test passava perché lo simulava a modo mio. Ho letto il sorgente di WooCommerce, ho rifatto il test sulla sua forma reale, e la decisione ora si prende una volta sola, alla prima occasione utile.

Le eccezioni GPC, e cosa un registro può dimostrare

Dalla 1.31.0 un visitatore con Global Privacy Control può aprire una mappa o un video cliccando «Accetta» sul suo riquadro. Restava una domanda da audit: come si distingue un’eccezione vera da una scritta da uno script? La risposta onesta è che non si può dimostrare un clic umano. Uno script che gira nelle pagine del sito ha gli stessi poteri del visitatore, e qualunque gettone emesso nella pagina è leggibile da quello script. Il registro dei consensi quindi non dice «autentico»: dice se le circostanze tornano. Il segnale c’era, il cookie portava davvero il consenso e il suo marcatore, la pagina aveva mostrato un riquadro per quel servizio. Se una di queste manca, l’eccezione resta segnata come non verificata, anche sulle pagine successive, e una revoca interrompe la catena.

Il resto

La procedura guidata può creare la pagina della Cookie Policy nella lingua scelta, spenta di default e disponibile solo dove esiste un modello. La Dashboard non lascia più intendere che arriveranno dati quando la misurazione delle visite è spenta, e dice che i registri dei consensi si conservano comunque. System Status elenca i servizi che, bloccati, non lasciano alcuna traccia visibile, come i Google Fonts: il sintomo di solito punta al tema o alla cache, e adesso punta anche qui. Il Delay JavaScript di WP Rocket non ritarda più né la configurazione iniziale del plugin né il registro dei consensi, che altrimenti perdeva la prima scelta del visitatore.

La lezione che mi porto via da questa release è sempre la stessa, e ogni volta la imparo da capo: un test che simula il mondo a modo mio controlla solo la mia idea del mondo. Quando posso, adesso, il test lo scrivo sulla forma del codice vero, e prima di fidarmi controllo che sulla versione vecchia fallisca.