Skip to content

fix: [SDK-4737] persist user consent in localStorage to survive iOS PWA wedge#1474

Merged
sherwinski merged 1 commit into
mainfrom
sherwin/sdk-4737
Jun 10, 2026
Merged

fix: [SDK-4737] persist user consent in localStorage to survive iOS PWA wedge#1474
sherwinski merged 1 commit into
mainfrom
sherwin/sdk-4737

Conversation

@sherwinski

Copy link
Copy Markdown
Contributor

Description

1 Line Summary

Persist user consent in localStorage instead of IndexedDB so a revoked opt-out isn't silently lost on a wedged iOS Safari PWA.

Details

Follow-up hardening to SDK-4336 / SDK-4754. OneSignal.setConsentGiven() wrote consent to the IndexedDB Options store. On a wedged iOS Safari PWA, the circuit breaker added for SDK-4336/4754 silently drops that write — so on the next load the SDK reads the stale userConsent row back and re-hydrates consent as still granted. A user's privacy/legal opt-out is lost across reloads with no error, rejection, or log.

userConsent is the only guarded Options key that is not re-derivable from another source of truth, which is what makes this privacy-/legal-critical (the trigger itself is narrow: iOS Safari PWA + active wedge + a same-session setConsentGiven call).

This change:

  • Adds setConsentGiven / getConsentGiven accessors in shared/helpers/localStorage.ts, mirroring how requiresPrivacyConsent is already persisted via setConsentRequired / getConsentRequired. localStorage is synchronous and immune to the IndexedDB wedge.
  • OneSignal.setConsentGiven() now writes to localStorage instead of db.put('Options', { key: 'userConsent', ... }).
  • config.getConsentGiven() reads localStorage first and falls back once to the legacy Options.userConsent row, migrating it forward so existing consenting users don't lose their stored consent on upgrade.

Not a regression — before SDK-4336 the page hung ~30 min, so a user could never reach the revoke step. SDK-4754 (now merged) made init reliably complete during a wedge, which is what makes this path reachable.

Systems Affected

  • WebSDK
  • Backend
  • Dashboard

Validation

Tests

Info

  • vp check: 0 errors (5 pre-existing no-floating-promises warnings in unrelated test files).
  • vp test --run: 523 passed. New src/shared/database/config.test.ts covers getConsentGiven: default false, reads the localStorage value, migrates a legacy IndexedDB value forward (and survives the IDB row being dropped), and prefers localStorage over a stale legacy IndexedDB value.
  • vp run build:prod: passes. Bumped the OneSignalSDK.page.es6.js size-limit 42.57 kB → 42.65 kB to cover the added migration path. Note this limit was 42.7 kB until 4 days ago (b7bb0cf6), so 42.65 kB is still tighter than the recent ceiling.

Checklist

  • All the automated tests pass or I explained why that is not possible
  • I have personally tested this on my machine or explained why that is not possible
  • I have included test coverage for these changes or explained why they are not needed

Screenshots

Info

N/A — behavior is covered by unit tests.

Checklist

  • I have included screenshots/recordings of the intended results or explained why they are not needed

Related Tickets


…WA wedge

setConsentGiven wrote consent to IndexedDB. On a wedged iOS Safari PWA the
circuit breaker silently drops that write, so a revoked consent reverts to
the stale value on the next load -- a privacy/legal opt-out lost across
reloads with no error. Unlike every other guarded Options key, userConsent
isn't re-derivable from another source of truth.

Persist consent in localStorage instead (synchronous, immune to the wedge),
mirroring how requiresPrivacyConsent is stored. getConsentGiven reads
localStorage first and falls back once to the legacy Options.userConsent row,
migrating it forward so existing consent isn't lost on upgrade.

Bumps the page.es6 size-limit 42.57 -> 42.65 kB for the added migration path.
@sherwinski sherwinski merged commit f291489 into main Jun 10, 2026
3 checks passed
@sherwinski sherwinski deleted the sherwin/sdk-4737 branch June 10, 2026 22:08
@github-actions github-actions Bot mentioned this pull request Jun 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants