From 33940d63ca642b4ccf9d4d3c73ebd4f2138c83d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89mile=20R=C3=A9?= Date: Sat, 2 May 2026 19:01:13 +0400 Subject: [PATCH] Run cookie detection regardless of banner state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Decouple detection from the banner's active state so admins can discover cookies before making the banner visible. The client now starts the detector even when the config endpoint returns 404, and the detector stops itself if the report endpoint returns 404 (wrong or deleted banner ID). Signed-off-by: Émile Ré --- packages/cookie-banner/src/client.ts | 11 +++++++---- packages/cookie-banner/src/detector.ts | 7 ++++++- pkg/cookiebanner/service.go | 8 ++++---- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/packages/cookie-banner/src/client.ts b/packages/cookie-banner/src/client.ts index 37d7a0434..f44d79a0a 100644 --- a/packages/cookie-banner/src/client.ts +++ b/packages/cookie-banner/src/client.ts @@ -120,6 +120,7 @@ export class CookieBannerClient { try { config = await fetchJSON(configUrl); } catch { + this.startDetector(); return; } this.bannerConfig = config; @@ -324,12 +325,14 @@ export class CookieBannerClient { this.observer = observeAndActivate(consentData, categoryLabels, texts); } - private startDetector(config: BannerConfig): void { + private startDetector(config?: BannerConfig): void { const knownNames = new Set(); knownNames.add(COOKIE_NAME); - for (const cat of config.categories) { - for (const cookie of cat.cookies) { - knownNames.add(cookie.name); + if (config) { + for (const cat of config.categories) { + for (const cookie of cat.cookies) { + knownNames.add(cookie.name); + } } } diff --git a/packages/cookie-banner/src/detector.ts b/packages/cookie-banner/src/detector.ts index b706ea20f..cf267028d 100644 --- a/packages/cookie-banner/src/detector.ts +++ b/packages/cookie-banner/src/detector.ts @@ -13,6 +13,7 @@ // PERFORMANCE OF THIS SOFTWARE. import { isDeletion, parseCookieName, parseMaxAgeSeconds } from "./cookie-utils"; +import { NotFoundError } from "./errors"; import { fetchJSON } from "./http"; interface DetectedCookieEntry { @@ -140,7 +141,11 @@ export class CookieDetector { void fetchJSON(this.reportUrl, { method: "POST", body: { cookies: entries }, - }).catch(() => {}); + }).catch((err) => { + if (err instanceof NotFoundError) { + this.stop(); + } + }); if (this.pending.size > 0) { this.scheduleFlush(); diff --git a/pkg/cookiebanner/service.go b/pkg/cookiebanner/service.go index 1c4ea33ca..927695ad5 100644 --- a/pkg/cookiebanner/service.go +++ b/pkg/cookiebanner/service.go @@ -2202,16 +2202,16 @@ func (s *Service) ReportDetectedCookies( return s.pg.WithTx( ctx, func(ctx context.Context, tx pg.Tx) error { + scope := coredata.NewScopeFromObjectID(bannerID) + var banner coredata.CookieBanner - if err := banner.LoadActiveByID(ctx, tx, bannerID); err != nil { + if err := banner.LoadByID(ctx, tx, scope, bannerID); err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return ErrBannerNotFound } - return fmt.Errorf("cannot load active cookie banner: %w", err) + return fmt.Errorf("cannot load cookie banner: %w", err) } - scope := coredata.NewScopeFromObjectID(banner.ID) - var uncategorised coredata.CookieCategory if err := uncategorised.LoadUncategorisedByCookieBannerID(ctx, tx, scope, banner.ID); err != nil { return fmt.Errorf("cannot load uncategorised category: %w", err)