1import Constants from 'expo-constants';
2import { CodedError, Platform, SyntheticPlatformEmitter } from 'expo-modules-core';
3export default async function getDevicePushTokenAsync() {
4    const data = await _subscribeDeviceToPushNotificationsAsync();
5    SyntheticPlatformEmitter.emit('onDevicePushToken', { devicePushToken: data });
6    return { type: Platform.OS, data };
7}
8function guardPermission() {
9    if (!('Notification' in window)) {
10        throw new CodedError('ERR_UNAVAILABLE', 'The Web Notifications API is not available on this device.');
11    }
12    if (!navigator.serviceWorker) {
13        throw new CodedError('ERR_UNAVAILABLE', 'Notifications cannot be used because the service worker API is not supported on this device. This might also happen because your web page does not support HTTPS.');
14    }
15    if (Notification.permission !== 'granted') {
16        throw new CodedError('ERR_NOTIFICATIONS_PERMISSION_DENIED', `Cannot use web notifications without permissions granted. Request permissions with "expo-permissions".`);
17    }
18}
19async function _subscribeDeviceToPushNotificationsAsync() {
20    const vapidPublicKey =
21    // @ts-expect-error: TODO: not on the schema
22    Constants.manifest?.notification?.vapidPublicKey ??
23        // @ts-expect-error: TODO: not on the schema
24        Constants.manifest2?.extra?.expoClient?.notification?.vapidPublicKey;
25    if (!vapidPublicKey) {
26        throw new CodedError('ERR_NOTIFICATIONS_PUSH_WEB_MISSING_CONFIG', 'You must provide `notification.vapidPublicKey` in `app.json` to use push notifications on web. Learn more: https://docs.expo.dev/versions/latest/guides/using-vapid/.');
27    }
28    const serviceWorkerPath =
29    // @ts-expect-error: TODO: not on the schema
30    Constants.manifest?.notification.serviceWorkerPath ??
31        // @ts-expect-error: TODO: not on the schema
32        Constants.manifest2?.extra?.expoClient?.notification?.serviceWorkerPath;
33    if (!serviceWorkerPath) {
34        throw new CodedError('ERR_NOTIFICATIONS_PUSH_MISSING_CONFIGURATION', 'You must specify `notification.serviceWorkerPath` in `app.json` to use push notifications on the web. Please provide the path to the service worker that will handle notifications.');
35    }
36    guardPermission();
37    let registration = null;
38    try {
39        registration = await navigator.serviceWorker.register(serviceWorkerPath);
40    }
41    catch (error) {
42        throw new CodedError('ERR_NOTIFICATIONS_PUSH_REGISTRATION_FAILED', `Could not register this device for push notifications because the service worker (${serviceWorkerPath}) could not be registered: ${error}`);
43    }
44    await navigator.serviceWorker.ready;
45    if (!registration.active) {
46        throw new CodedError('ERR_NOTIFICATIONS_PUSH_REGISTRATION_FAILED', 'Could not register this device for push notifications because the service worker is not active.');
47    }
48    const subscribeOptions = {
49        userVisibleOnly: true,
50        applicationServerKey: _urlBase64ToUint8Array(vapidPublicKey),
51    };
52    let pushSubscription = null;
53    try {
54        pushSubscription = await registration.pushManager.subscribe(subscribeOptions);
55    }
56    catch (error) {
57        throw new CodedError('ERR_NOTIFICATIONS_PUSH_REGISTRATION_FAILED', 'The device was unable to register for remote notifications with the browser endpoint. (' +
58            error +
59            ')');
60    }
61    const pushSubscriptionJson = pushSubscription.toJSON();
62    const subscriptionObject = {
63        endpoint: pushSubscriptionJson.endpoint,
64        keys: {
65            p256dh: pushSubscriptionJson.keys.p256dh,
66            auth: pushSubscriptionJson.keys.auth,
67        },
68    };
69    // Store notification icon string in service worker.
70    // This message is received by `/expo-service-worker.js`.
71    // We wrap it with `fromExpoWebClient` to make sure other message
72    // will not override content such as `notificationIcon`.
73    // https://stackoverflow.com/a/35729334/2603230
74    const notificationIcon = (Constants.manifest?.notification ??
75        Constants.manifest2?.extra?.expoClient?.notification ??
76        {}).icon;
77    await registration.active.postMessage(JSON.stringify({ fromExpoWebClient: { notificationIcon } }));
78    return subscriptionObject;
79}
80// https://github.com/web-push-libs/web-push#using-vapid-key-for-applicationserverkey
81function _urlBase64ToUint8Array(base64String) {
82    const padding = '='.repeat((4 - (base64String.length % 4)) % 4);
83    const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/');
84    const rawData = window.atob(base64);
85    const outputArray = new Uint8Array(rawData.length);
86    for (let i = 0; i < rawData.length; ++i) {
87        outputArray[i] = rawData.charCodeAt(i);
88    }
89    return outputArray;
90}
91//# sourceMappingURL=getDevicePushTokenAsync.web.js.map