#4317
feat(push): notifications:push app permission
A per-app permission, notifications:push, that decides whether an app's notifications may go out as pushes. Part of PUT-2168. Stacks on #4316.
What
notifications:push, granted per app through the usual permission prompt and stored like other user-to-app grants. Without it, an app's notifications still show inside Puter; they just aren't pushed.hasPushConsent(deps, userId, appUid)(services/push/pushConsent.ts): the check the push sender runs on every send, with no request actor. It builds the app-under-user actor from the stored user and app rows (the app's canonical uid) and asks the permission service, so caches and revocation apply. Missing rows or errors read as no consent.- Default holding:
notifications:pushis added todefault_user_permissions, likeevents:background, so only the explicit user-to-app grant decides for apps. - Prompt: the permission dialog describes it as "send notifications to your devices, even while it is closed". Only the exact string is described.
- Docs: the permission is listed in
Perms/request.mdwith a short section on what it does.
Tests
$ npx vitest run --config src/backend/vitest.config.ts src/backend/services/push src/backend/services/permission/PermissionService.defaultGrants.test.ts
Tests 11 passed (11)Plus GUI dialog tests and a puter.js request test. Covers: no grant means no consent, a grant covers only that app and user, revoking one permission or all of an app's access takes effect on the next check, events:background and notifications:push don't imply each other, and the actor uses the stored app uid.
Activity
11Coverage Report for puter.js SDK
| Status | Category | Percentage | Covered / Total |
|---|---|---|---|
| 🔵 | Lines | 59.48% 🟰 ±0 pp | 5283 / 8881 |
| 🔵 | Statements | 57.59% 🟰 ±0 pp | 5628 / 9772 |
| 🔵 | Functions | 59.33% 🟰 ±0 pp | 976 / 1645 |
| 🔵 | Branches | 52.69% 🟰 ±0 pp | 3584 / 6802 |
Coverage Report
⬆️ +0.02 pp
⬆️ +0.02 pp
⬆️ +0.01 pp
⬆️ +0.04 pp
File Coverage
🟰 ±0 pp
🟰 ±0 pp
🟰 ±0 pp
🟰 ±0 pp
🟰 ±0 pp
🟰 ±0 pp
🟰 ±0 pp
🟰 ±0 pp
🟰 ±0 pp
🟰 ±0 pp
🟰 ±0 pp
🟰 ±0 pp