Skip to content

Commit 7dd9742

Browse files
committed
fix: use legacy Safari push path only for existing legacy subscribers
Safari 16.4+ supports standard Web Push (VAPID), but `window.safari.pushNotification` was never removed. The SDK checked for API existence to decide the push path, which routed ALL macOS Safari users through the legacy flow — even on versions that fully support VAPID. When the legacy push package validation fails (e.g. invalid allowedDomains), this causes the error: "Safari url/icon/certificate invalid or in private mode" Now `useSafariLegacyPush()` checks the actual permission state: only users who have already granted legacy push (with a valid deviceToken) stay on the legacy path. New users on Safari 16.4+ are routed through the standard VAPID flow via `useSafariVapidPush()`.
1 parent 354f504 commit 7dd9742

1 file changed

Lines changed: 21 additions & 2 deletions

File tree

src/shared/environment/detect.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,27 @@ export const supportsServiceWorkers = () => {
1919

2020
export const windowEnvString = IS_SERVICE_WORKER ? 'Service Worker' : 'Browser';
2121

22-
export const useSafariLegacyPush = () =>
23-
isBrowser() && window.safari?.pushNotification != undefined;
22+
/**
23+
* Returns true only when the user has an active legacy Safari push subscription.
24+
*
25+
* Safari 16.4+ supports standard Web Push (VAPID), but `window.safari.pushNotification`
26+
* was never removed. Previously this function returned true whenever that API existed,
27+
* which forced ALL macOS Safari users onto the legacy path — even on browsers that
28+
* fully support VAPID. Now we check the actual permission state: only users who have
29+
* already granted legacy push (and have a deviceToken) stay on the legacy path, because
30+
* Safari doesn't support migrating from legacy push to standard web push.
31+
*/
32+
export const useSafariLegacyPush = (): boolean => {
33+
if (!isBrowser() || window.safari?.pushNotification == undefined) {
34+
return false;
35+
}
36+
const safariWebId = OneSignal?.config?.safariWebId;
37+
if (!safariWebId) return false;
38+
39+
const { permission, deviceToken } =
40+
window.safari.pushNotification.permission(safariWebId);
41+
return permission === 'granted' && deviceToken != null;
42+
};
2443

2544
export const supportsVapidPush =
2645
typeof PushSubscriptionOptions !== 'undefined' &&

0 commit comments

Comments
 (0)