An app that is allowed to send push notifications gets them in the browser it asked from, without a trip to Settings. For PUT-2258. Stacks on #4354.
What
Until now, the only way to turn push on in a browser was the Turn on button in Settings. An app granted notifications:push on the desktop or on its own subdomain still got nothing in that browser.
Allow turns the browser on. When a permission request includes notifications:push and this browser's push is off, the Allow click in the permission dialog also calls the push client's enable(), synchronously inside the click (the browser's notification prompt needs that). The grant result never depends on it: a failed or refused registration still grants the permission. One registration per dialog. A note under the permission list says notifications will be turned on in this browser. If the grant itself ends in a denial, the registration is undone.
Popup for apps on their own origin. /action/request-permission starts the service worker before showing the dialog (it never did in the popup, so enable() would have timed out there), answers the opener as soon as the user decides, then waits for the registration before closing. The wait only counts time while the browser's own prompt isn't open, so a slow answer never gets the popup closed under it.
Registering again without a click. helpers/pushSync.js runs on desktop and dashboard boot and on app launch. When the browser already allows notifications for this origin, a user is signed in, an app holds notifications:push and the push client says off, it registers this browser again. Single-flight, cheap local checks before any request. Turn off and Remove in Settings leave a per-user record (puter.push.browser-off:<uuid>) that the sync honours, so an explicit choice in this browser stays. A new sign-in in a browser that already allows notifications registers again.
puter.notifications.enablePush(). For apps that were granted before this change and whose browser hasn't been asked yet, a click is unavoidable. The call shows a one-button "Turn on notifications" dialog: on the desktop through a new enablePush IPC message (advertised in puter.gui_features as enable-push, so older GUIs don't hang), on a website through /action/enable-push, a popup that hands over no token. Both paths first check that the app holds notifications:push and show nothing otherwise. One dialog at a time. The SDK handler accepts only the canonical GUI origin, the pinned popup window and the matching message id. PuterDialog gained a message option for the no-gesture fallback.
Docs: doc/push-client.md lists every path that now calls enable(); src/docs has an enablePush page and updated requestPermission / hasPermission pages.
A hidden puter.com iframe for a silent re-register from another origin was looked at and not built: the push client and the worker only run top-level, and browsers partition third-party storage and service workers, so the iframe would never see the registration.
Tests
New: UIPermissionDialog.allow.test.js (enable called before the grant request, grant succeeds when enable rejects, not called when on/blocked/unavailable or without the permission, denial after a failed grant undoes it), UIEnablePushDialog.test.js (one registration per dialog, waits while the prompt is open, settles on when it resolves), pushSync.test.js (every early-out, opt-out honoured, single-flight), IPC.enablePush.test.js (permission check, re-entry), UI.enablePush.test.js (origin, source and id checks, popup closed, cross-origin-isolated page, consent dialog path). Extended: pushClient.test.js, TabNotifications.test.js, initgui.gates.test.js, popupAuth.test.js, notifications.test.js.
GUI suite: 113 files, 1421 tests pass (1362 before). SDK unit files touched: 88 pass (71 before). check:puterjs:types clean. With the implementation removed, 24 of the new GUI tests and 15 SDK tests fail; the review fixes add 12 more that fail without them.
Not verified
Not exercised in a real browser yet; the paths are covered by jsdom tests and source checks. A run on a test server with Chrome, Firefox and Safari is the next step.
Coverage Report for puter.js SDK
⬇️ -0.42 pp
⬇️ -0.41 pp
⬇️ -0.45 pp
⬇️ -0.28 pp
File Coverage
🟰 ±0 pp
⬇️ -0.35 pp
🟰 ±0 pp
🟰 ±0 pp
⬇️ -0.46 pp
⬇️ -0.19 pp
⬇️ -0.28 pp
⬇️ -0.46 pp
⬆️ +1.60 pp
🟰 ±0 pp
🟰 ±0 pp
⬆️ +1.59 pp