web-push-notifications 3.40.3 → 3.44.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +11 -0
- package/.gitlab-ci.yml +190 -0
- package/babel.config.js +7 -0
- package/ci/cdn/Dockerfile +12 -0
- package/ci/dev/Dockerfile +30 -0
- package/ci/dev/rootfs/entrypoint.sh +18 -0
- package/ci/dev/rootfs/entrypoint.sh.d/nginx.sh +6 -0
- package/ci/dev/rootfs/entrypoint.sh.d/supervisor.sh +5 -0
- package/ci/dev/rootfs/etc/nginx/_real_ip.conf +2 -0
- package/ci/dev/rootfs/etc/nginx/conf.d/default.conf +20 -0
- package/ci/dev/rootfs/etc/supervisor.d/nginx.ini +11 -0
- package/ci/github/Dockerfile +59 -0
- package/ci/github/release-zip.js +61 -0
- package/ci/npm/Dockerfile +19 -0
- package/config/config.js +24 -0
- package/config/configBuilder.js +126 -0
- package/config/helpers.js +9 -0
- package/config/index.js +1 -0
- package/develop/README.md +42 -0
- package/develop/favicon.png +0 -0
- package/develop/index.html +511 -0
- package/eslint.config.mjs +114 -0
- package/package.json +4 -34
- package/{lib → public}/index.d.ts +10 -10
- package/scripts/zip.js +26 -0
- package/src/core/Pushwoosh.ts +768 -0
- package/src/core/Pushwoosh.types.ts +254 -0
- package/src/core/Safari.types.ts +26 -0
- package/src/core/constants.ts +58 -0
- package/src/core/events.types.ts +46 -0
- package/src/core/functions.ts +33 -0
- package/src/core/legacyEventsMap.ts +64 -0
- package/src/core/logger.ts +64 -0
- package/src/core/modules/EventBus/EventBus.ts +66 -0
- package/src/core/modules/EventBus/index.ts +1 -0
- package/src/core/storage.ts +254 -0
- package/src/helpers/logger.ts +81 -0
- package/src/helpers/pwlogger/Logger.constants.ts +31 -0
- package/src/helpers/pwlogger/Logger.ts +218 -0
- package/src/helpers/pwlogger/Logger.types.ts +66 -0
- package/src/helpers/pwlogger/handlers/handler-console/handler-console.ts +40 -0
- package/src/helpers/pwlogger/index.ts +2 -0
- package/src/helpers/unescape.ts +36 -0
- package/src/models/InboxMessages.ts +202 -0
- package/src/models/InboxMessages.types.ts +111 -0
- package/src/models/NotificationPayload.ts +216 -0
- package/src/models/NotificationPayload.types.ts +65 -0
- package/src/modules/Api/Api.ts +386 -0
- package/src/modules/Api/Api.types.ts +7 -0
- package/src/modules/ApiClient/ApiClient.ts +153 -0
- package/src/modules/ApiClient/ApiClient.types.ts +222 -0
- package/src/modules/Data/Data.ts +345 -0
- package/src/modules/DateModule.ts +53 -0
- package/src/modules/InboxMessagesPublic.ts +222 -0
- package/src/modules/PlatformChecker/PlatformChecker.ts +170 -0
- package/src/modules/PlatformChecker/PlatformChecker.types.ts +5 -0
- package/src/modules/PlatformChecker/index.ts +1 -0
- package/src/modules/storage/Storage.ts +164 -0
- package/src/modules/storage/Storage.types.ts +54 -0
- package/src/modules/storage/Store.ts +104 -0
- package/src/modules/storage/migrations/26-11-2018.ts +25 -0
- package/src/modules/storage/migrations/MigrationExecutor.ts +31 -0
- package/src/modules/storage/migrations/Migrations.ts +41 -0
- package/src/modules/storage/migrations/constants.ts +8 -0
- package/src/modules/storage/migrations/helpers.ts +16 -0
- package/src/modules/storage/migrations/initial.ts +47 -0
- package/src/modules/storage/version.ts +2 -0
- package/src/npm.ts +1 -0
- package/src/pushwoosh-web-notifications.ts +47 -0
- package/src/pushwoosh-widget-inbox.ts +8 -0
- package/src/pushwoosh-widget-subscribe-popup.ts +9 -0
- package/src/pushwoosh-widget-subscription-button.ts +8 -0
- package/src/pushwoosh-widget-subscription-prompt.ts +6 -0
- package/src/service-worker.ts +455 -0
- package/src/services/PushService/PushService.ts +2 -0
- package/src/services/PushService/PushService.types.ts +74 -0
- package/src/services/PushService/drivers/PushServiceDefault/PushServiceDefault.ts +235 -0
- package/src/services/PushService/drivers/PushServiceDefault/PushServiceDefault.types.ts +3 -0
- package/src/services/PushService/drivers/PushServiceSafari/PushServiceSafari.ts +125 -0
- package/src/services/PushService/drivers/PushServiceSafari/PushServiceSafari.types.ts +4 -0
- package/src/widget-inbox.ts +1 -0
- package/src/widget-subscribe-popup.ts +1 -0
- package/src/widget-subscription-button.ts +1 -0
- package/src/widget-subscription-prompt.ts +33 -0
- package/src/widgets/Inbox/InboxWidget.ts +564 -0
- package/src/widgets/Inbox/constants.ts +49 -0
- package/src/widgets/Inbox/css/inboxWidgetStyle.css +274 -0
- package/src/widgets/Inbox/helpers.ts +63 -0
- package/src/widgets/Inbox/inbox.d.ts +9 -0
- package/src/widgets/Inbox/inbox_widget.types.ts +41 -0
- package/src/widgets/Inbox/index.ts +1 -0
- package/src/widgets/Inbox/widgetTemplates.ts +55 -0
- package/src/widgets/SubscribePopup/SubscribePopup.ts +241 -0
- package/src/widgets/SubscribePopup/constants.ts +66 -0
- package/src/widgets/SubscribePopup/helpers.ts +11 -0
- package/src/widgets/SubscribePopup/index.ts +1 -0
- package/src/widgets/SubscribePopup/popupTemplates.ts +24 -0
- package/src/widgets/SubscribePopup/styles/popup.css +226 -0
- package/src/widgets/SubscribePopup/types/subscribe-popup.ts +68 -0
- package/src/widgets/SubscriptionButton/assets/css/main.css +205 -0
- package/src/widgets/SubscriptionButton/bell.ts +67 -0
- package/src/widgets/SubscriptionButton/constants.ts +28 -0
- package/src/widgets/SubscriptionButton/index.ts +377 -0
- package/src/widgets/SubscriptionButton/positioning.ts +165 -0
- package/src/widgets/SubscriptionButton/subscribe_widget.types.ts +53 -0
- package/src/widgets/SubscriptionPrompt/SubscriptionPromptWidget.constants.ts +1 -0
- package/src/widgets/SubscriptionPrompt/SubscriptionPromptWidget.helpers.ts +110 -0
- package/src/widgets/SubscriptionPrompt/SubscriptionPromptWidget.ts +102 -0
- package/src/widgets/SubscriptionPrompt/SubscriptionPromptWidget.types.ts +23 -0
- package/src/widgets/SubscriptionPrompt/constants.ts +22 -0
- package/src/widgets/SubscriptionPrompt/helpers.ts +42 -0
- package/src/widgets/widgets.d.ts +4 -0
- package/src/worker/global.ts +36 -0
- package/src/worker/notification.ts +34 -0
- package/src/worker/worker.types.ts +4 -0
- package/test/__helpers__/apiHelpers.ts +22 -0
- package/test/__helpers__/keyValueHelpers.ts +15 -0
- package/test/__helpers__/platformHelpers.ts +54 -0
- package/test/__helpers__/sinonHelpers.ts +7 -0
- package/test/__helpers__/storageHelpers.ts +56 -0
- package/test/__mocks__/apiRequests.ts +26 -0
- package/test/__mocks__/idbMock.ts +12 -0
- package/test/__mocks__/idbObjectStoreMock.ts +38 -0
- package/test/__mocks__/inboxMessages.ts +292 -0
- package/test/__mocks__/models/inboxModel.ts +71 -0
- package/test/__mocks__/modules/apiClientModule.ts +18 -0
- package/test/__mocks__/modules/dateModule.ts +34 -0
- package/test/__mocks__/modules/inboxParamsModule.ts +21 -0
- package/test/__mocks__/modules/paramsBuilder.ts +12 -0
- package/test/__mocks__/modules/paramsModule.ts +35 -0
- package/test/__mocks__/modules/payloadBuilderModule.ts +15 -0
- package/test/__mocks__/modules/storageModule.ts +58 -0
- package/test/__mocks__/navigator.ts +38 -0
- package/test/__mocks__/notification.ts +84 -0
- package/test/__mocks__/pushwoosh.ts +12 -0
- package/test/__mocks__/userAgents +8 -0
- package/test/functions.test.ts +22 -0
- package/test/ignore-html.js +6 -0
- package/test/mocha.opts +6 -0
- package/test/modules/DateModule/unit.test.ts +80 -0
- package/test/modules/storage/Storage/unit.test.ts +180 -0
- package/test/modules/storage/Store/unit.test.ts +192 -0
- package/testRegister.js +24 -0
- package/tsconfig.json +31 -0
- package/webpack.config.js +163 -0
- package/lib/index.js +0 -2
- package/lib/index.js.map +0 -1
- package/lib/service-worker.js +0 -2
- package/lib/service-worker.js.map +0 -1
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PERIOD_GOAL_EVENT,
|
|
3
|
+
LEGACY_EVENT_ON_PUSH_DELIVERY,
|
|
4
|
+
LEGACY_EVENT_ON_NOTIFICATION_CLICK,
|
|
5
|
+
LEGACY_EVENT_ON_NOTIFICATION_CLOSE,
|
|
6
|
+
LEGACY_EVENT_ON_PUT_NEW_MESSAGE_TO_INBOX_STORE,
|
|
7
|
+
} from './core/constants';
|
|
8
|
+
import { getVersion, parseSerializedNotificationParams } from './core/functions';
|
|
9
|
+
import { Logger } from './core/logger';
|
|
10
|
+
import { EventBus } from './core/modules/EventBus';
|
|
11
|
+
import { type INotificationOptions, type IPWBroadcastClientsParams, type IWorkerPushwooshGlobal } from './core/Pushwoosh.types';
|
|
12
|
+
import { message as messagesLog } from './core/storage';
|
|
13
|
+
import { sendFatalLogToRemoteServer } from './helpers/logger';
|
|
14
|
+
import InboxMessages from './models/InboxMessages';
|
|
15
|
+
import { type TInboxMessageStatusOpen } from './models/InboxMessages.types';
|
|
16
|
+
import NotificationPayload from './models/NotificationPayload';
|
|
17
|
+
import { type INotificationButton } from './models/NotificationPayload.types';
|
|
18
|
+
import { Api } from './modules/Api/Api';
|
|
19
|
+
import { Data } from './modules/Data/Data';
|
|
20
|
+
import InboxMessagesPublic from './modules/InboxMessagesPublic';
|
|
21
|
+
import { PushServiceDefault } from './services/PushService/drivers/PushServiceDefault/PushServiceDefault';
|
|
22
|
+
import WorkerPushwooshGlobal from './worker/global';
|
|
23
|
+
import PushwooshNotification from './worker/notification';
|
|
24
|
+
import { type PushSubscriptionChangeEvent } from './worker/worker.types';
|
|
25
|
+
|
|
26
|
+
declare const self: ServiceWorkerGlobalScope & {
|
|
27
|
+
Pushwoosh: IWorkerPushwooshGlobal;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const eventBus = new EventBus();
|
|
31
|
+
const data = new Data();
|
|
32
|
+
const api = new Api(eventBus, data);
|
|
33
|
+
|
|
34
|
+
const Pushwoosh = self.Pushwoosh = new WorkerPushwooshGlobal(eventBus, data, api);
|
|
35
|
+
const clickedNotifications: string[] = [];
|
|
36
|
+
|
|
37
|
+
self.addEventListener('install', onInstallEventHandler);
|
|
38
|
+
|
|
39
|
+
self.addEventListener('activate', onActivateEventHandler);
|
|
40
|
+
|
|
41
|
+
self.addEventListener('push', onPushEventHandler);
|
|
42
|
+
|
|
43
|
+
self.addEventListener('notificationclick', onClickNotificationEventHandler);
|
|
44
|
+
|
|
45
|
+
self.addEventListener('notificationclose', onCloseNotificationEventHandler);
|
|
46
|
+
|
|
47
|
+
self.addEventListener('pushsubscriptionchange', onPushSubscriptionChange);
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* On install SW event handler
|
|
51
|
+
* Update indexedDB SW version and skip waiting stage
|
|
52
|
+
* @param event
|
|
53
|
+
*/
|
|
54
|
+
function onInstallEventHandler(event: ExtendableEvent): void {
|
|
55
|
+
async function onInstall(): Promise<void> {
|
|
56
|
+
await Promise.all([
|
|
57
|
+
Pushwoosh.data.setServiceWorkerVersion(getVersion()),
|
|
58
|
+
Logger.write('info', 'install'),
|
|
59
|
+
]);
|
|
60
|
+
|
|
61
|
+
// PUSH-21674 - not auto closing push if push receive when chrome is closed
|
|
62
|
+
await self.skipWaiting();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return event.waitUntil(
|
|
66
|
+
onInstall()
|
|
67
|
+
.catch(onInstallFailure),
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* On activate SW event handler
|
|
73
|
+
* Do nothing, only write log
|
|
74
|
+
* @param event
|
|
75
|
+
*/
|
|
76
|
+
function onActivateEventHandler(event: ExtendableEvent) {
|
|
77
|
+
async function onActivate(): Promise<void> {
|
|
78
|
+
await Promise.all([
|
|
79
|
+
Logger.write('info', 'activate'),
|
|
80
|
+
]);
|
|
81
|
+
|
|
82
|
+
await self.clients.claim();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
event.waitUntil(
|
|
86
|
+
onActivate()
|
|
87
|
+
.catch(onActivateFailure),
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* On push SW event handler
|
|
93
|
+
* @param event
|
|
94
|
+
*/
|
|
95
|
+
function onPushEventHandler(event: PushEvent): void {
|
|
96
|
+
async function onPush(event: PushEvent): Promise<void> {
|
|
97
|
+
// wake up SW on all pages
|
|
98
|
+
await self.clients.claim();
|
|
99
|
+
|
|
100
|
+
// get payload
|
|
101
|
+
const payload = await event.data!.json();
|
|
102
|
+
|
|
103
|
+
// create notification payload
|
|
104
|
+
const notificationPayload = new NotificationPayload(payload);
|
|
105
|
+
|
|
106
|
+
// get notification options
|
|
107
|
+
const notificationOptions = await notificationPayload.getNotificationOptionsPayload();
|
|
108
|
+
|
|
109
|
+
// get notification show options
|
|
110
|
+
const notificationShowOptions = await notificationPayload.getShowNotificationOptions();
|
|
111
|
+
|
|
112
|
+
// get message hash
|
|
113
|
+
const messageHash = notificationPayload.messageHash;
|
|
114
|
+
|
|
115
|
+
// logging in indexedDB;
|
|
116
|
+
await Logger.write('info', JSON.stringify(notificationOptions), 'onPush');
|
|
117
|
+
|
|
118
|
+
// show notification instance
|
|
119
|
+
const notification = new PushwooshNotification(
|
|
120
|
+
notificationShowOptions,
|
|
121
|
+
notificationPayload.body,
|
|
122
|
+
await notificationPayload.getTitle(),
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
// Call receive push listeners
|
|
126
|
+
const callbacks = Pushwoosh.getListeners('onPush');
|
|
127
|
+
|
|
128
|
+
await callbacks.reduce((pr, fun) => pr.then(() => fun(notification)), Promise.resolve());
|
|
129
|
+
|
|
130
|
+
// Execute receive push actions
|
|
131
|
+
const onPushActions = [
|
|
132
|
+
notification.show(), // Show notification
|
|
133
|
+
messagesLog.add({ // Put message to messages store
|
|
134
|
+
payload: payload,
|
|
135
|
+
parsedPayload: notificationOptions,
|
|
136
|
+
showOptions: notificationShowOptions,
|
|
137
|
+
}),
|
|
138
|
+
broadcastClients({ type: LEGACY_EVENT_ON_PUSH_DELIVERY, payload: notificationOptions }), // post message to window clients
|
|
139
|
+
];
|
|
140
|
+
|
|
141
|
+
// Send delivery statistic
|
|
142
|
+
if (messageHash) {
|
|
143
|
+
onPushActions.push(
|
|
144
|
+
Pushwoosh.initApi().then(() => Pushwoosh.api.messageDeliveryEvent(messageHash, true, notificationOptions.metaData)),
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Inbox message actions
|
|
149
|
+
if (notificationPayload.inboxId !== '') {
|
|
150
|
+
const inboxMessages = new InboxMessages(Pushwoosh.eventBus, Pushwoosh.data, Pushwoosh.api);
|
|
151
|
+
const inboxMessagesPublic = new InboxMessagesPublic(Pushwoosh.data, Pushwoosh.api, inboxMessages);
|
|
152
|
+
const inboxMessagePayload = await notificationPayload.getInboxMessage();
|
|
153
|
+
|
|
154
|
+
const payload = await inboxMessagesPublic.publicMessageBuilder(inboxMessagePayload);
|
|
155
|
+
onPushActions.push(
|
|
156
|
+
inboxMessages.putMessage(inboxMessagePayload), // put message to inboxMessages store
|
|
157
|
+
broadcastClients({ // post message to window clients
|
|
158
|
+
type: LEGACY_EVENT_ON_PUT_NEW_MESSAGE_TO_INBOX_STORE,
|
|
159
|
+
payload,
|
|
160
|
+
}),
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
await Promise.all(onPushActions);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
event.waitUntil(
|
|
168
|
+
onPush(event)
|
|
169
|
+
.catch((error) => onPushFailure(error, event)),
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* On click notification event handler
|
|
175
|
+
* @param event
|
|
176
|
+
*/
|
|
177
|
+
function onClickNotificationEventHandler(event: NotificationEvent): void {
|
|
178
|
+
async function onClickNotification(event: NotificationEvent) {
|
|
179
|
+
await self.clients.claim();
|
|
180
|
+
|
|
181
|
+
// get notification options
|
|
182
|
+
const notificationOptions = await parseNotificationEvent(event);
|
|
183
|
+
|
|
184
|
+
const {
|
|
185
|
+
messageHash,
|
|
186
|
+
metaData,
|
|
187
|
+
url,
|
|
188
|
+
code,
|
|
189
|
+
inboxId,
|
|
190
|
+
} = notificationOptions;
|
|
191
|
+
|
|
192
|
+
if (code) {
|
|
193
|
+
clickedNotifications.push(code);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (inboxId !== '') {
|
|
197
|
+
const inboxMessages = new InboxMessages(Pushwoosh.eventBus, Pushwoosh.data, Pushwoosh.api);
|
|
198
|
+
|
|
199
|
+
const message = await inboxMessages.getMessage(inboxId);
|
|
200
|
+
(<TInboxMessageStatusOpen>message.status) = 3;
|
|
201
|
+
await inboxMessages.putMessage(message);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
event.notification.close();
|
|
205
|
+
|
|
206
|
+
const message = { type: LEGACY_EVENT_ON_NOTIFICATION_CLICK, payload: notificationOptions };
|
|
207
|
+
|
|
208
|
+
if (url) {
|
|
209
|
+
event.waitUntil(
|
|
210
|
+
self.clients.matchAll({ type: 'window' })
|
|
211
|
+
.then((windowClients) => {
|
|
212
|
+
return focusWindow(windowClients as any, url);
|
|
213
|
+
})
|
|
214
|
+
.then((isFocusOnNewWindowClient) => {
|
|
215
|
+
if (isFocusOnNewWindowClient) {
|
|
216
|
+
Pushwoosh.data.setDelayedEvent(message);
|
|
217
|
+
}
|
|
218
|
+
}),
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return Promise.all([
|
|
223
|
+
Pushwoosh.initApi().then(() => Pushwoosh.api.pushStat(messageHash, true, metaData)),
|
|
224
|
+
Pushwoosh.data.setLastOpenMessage({
|
|
225
|
+
url,
|
|
226
|
+
messageHash,
|
|
227
|
+
expiry: Date.now() + PERIOD_GOAL_EVENT,
|
|
228
|
+
}),
|
|
229
|
+
broadcastClients(message),
|
|
230
|
+
]);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
event.waitUntil(
|
|
234
|
+
onClickNotification(event)
|
|
235
|
+
.catch(onClickNotificationFailure),
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* On close notification event handler
|
|
241
|
+
* @param event
|
|
242
|
+
*/
|
|
243
|
+
function onCloseNotificationEventHandler(event: NotificationEvent) {
|
|
244
|
+
async function closeNotification(event: NotificationEvent): Promise<void> {
|
|
245
|
+
await self.clients.claim();
|
|
246
|
+
|
|
247
|
+
const notificationOptions = await parseNotificationEvent(event);
|
|
248
|
+
const { code } = notificationOptions;
|
|
249
|
+
|
|
250
|
+
event.notification.close();
|
|
251
|
+
|
|
252
|
+
if (!code) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const index = clickedNotifications.indexOf(code);
|
|
257
|
+
if (index >= 0) {
|
|
258
|
+
clickedNotifications.splice(index, 1);
|
|
259
|
+
} else {
|
|
260
|
+
return broadcastClients({ type: LEGACY_EVENT_ON_NOTIFICATION_CLOSE, payload: notificationOptions });
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
event.waitUntil(
|
|
265
|
+
closeNotification(event)
|
|
266
|
+
.catch(closeNotificationFailure),
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
async function onPushSubscriptionChange(event: PushSubscriptionChangeEvent): Promise<void> {
|
|
271
|
+
async function changePushSubscription(event: PushSubscriptionChangeEvent): Promise<void> {
|
|
272
|
+
let subscription = event.newSubscription;
|
|
273
|
+
if (!subscription) {
|
|
274
|
+
subscription = await self.registration.pushManager.getSubscription();
|
|
275
|
+
if (!subscription) {
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const pushService = new PushServiceDefault(api, data, {});
|
|
281
|
+
await pushService.subscribe(subscription);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
event.waitUntil(
|
|
285
|
+
changePushSubscription(event)
|
|
286
|
+
.catch(pushSubscriptionChangeFailure),
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Post message to all Window Clients
|
|
292
|
+
* @param msg
|
|
293
|
+
*/
|
|
294
|
+
async function broadcastClients(msg: IPWBroadcastClientsParams) {
|
|
295
|
+
const clients = await self.clients.matchAll();
|
|
296
|
+
clients.forEach((client) => client.postMessage(msg));
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
async function focusWindow(windowClients: Array<WindowClient>, url: string): Promise<boolean> {
|
|
300
|
+
// if opened url without location, use service worker origin
|
|
301
|
+
const {
|
|
302
|
+
hostname: openedHostname,
|
|
303
|
+
pathname: openedPathname,
|
|
304
|
+
} = new URL(url, self.location.origin);
|
|
305
|
+
|
|
306
|
+
const clientWithSameAddress = windowClients.find((windowClient) => {
|
|
307
|
+
const {
|
|
308
|
+
hostname: windowClientHostname,
|
|
309
|
+
pathname: windowClientPathname,
|
|
310
|
+
} = new URL(windowClient.url);
|
|
311
|
+
|
|
312
|
+
// opened url is equal with current window client url if hostname and pathname are equals
|
|
313
|
+
return windowClientHostname === openedHostname && windowClientPathname === openedPathname;
|
|
314
|
+
});
|
|
315
|
+
if (clientWithSameAddress) {
|
|
316
|
+
await clientWithSameAddress.focus();
|
|
317
|
+
return false; // focus on exist window client
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// if not window client with opened url we must open new window and focus it
|
|
321
|
+
await self.clients.openWindow(url)
|
|
322
|
+
.then((newClientWindow) => {
|
|
323
|
+
// if new client window url does not match
|
|
324
|
+
// of service worker domain then new client window is null
|
|
325
|
+
if (!newClientWindow) {
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
newClientWindow.focus();
|
|
330
|
+
});
|
|
331
|
+
return true; // focus on new window client
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
async function parseNotificationEvent(event: NotificationEvent): Promise<INotificationOptions> {
|
|
335
|
+
const { notification = {} as Notification } = event;
|
|
336
|
+
const { data: notificationData } = notification;
|
|
337
|
+
const notificationTag = parseSerializedNotificationParams(notification.tag, {});
|
|
338
|
+
|
|
339
|
+
let url = '';
|
|
340
|
+
|
|
341
|
+
if (event.action && Array.isArray(notificationData.buttons)) {
|
|
342
|
+
const button = notificationData.buttons.find((button: INotificationButton) => button.action === event.action) || {};
|
|
343
|
+
url = button.url;
|
|
344
|
+
} else {
|
|
345
|
+
url = notificationTag.url;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
return {
|
|
349
|
+
title: notification.title,
|
|
350
|
+
body: notification.body,
|
|
351
|
+
icon: notification.icon,
|
|
352
|
+
|
|
353
|
+
buttons: notificationData.buttons,
|
|
354
|
+
image: notificationData.image,
|
|
355
|
+
code: notificationData.code,
|
|
356
|
+
campaignCode: notificationData.campaignCode,
|
|
357
|
+
inboxId: notificationData.inboxId,
|
|
358
|
+
|
|
359
|
+
messageHash: notificationTag.messageHash,
|
|
360
|
+
customData: notificationTag.customData,
|
|
361
|
+
metaData: notificationTag.metaData,
|
|
362
|
+
openUrl: notificationTag.url,
|
|
363
|
+
|
|
364
|
+
tag: notification.tag,
|
|
365
|
+
url,
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
async function onInstallFailure(error: Error | string): Promise<void> {
|
|
370
|
+
const applicationCode = await Pushwoosh.data.getApplicationCode();
|
|
371
|
+
const workerVersion = await Pushwoosh.data.getServiceWorkerVersion();
|
|
372
|
+
|
|
373
|
+
await sendFatalLogToRemoteServer({
|
|
374
|
+
message: 'Error in onInstallEventHandler',
|
|
375
|
+
code: 'FATAL-SW-001',
|
|
376
|
+
error,
|
|
377
|
+
applicationCode,
|
|
378
|
+
workerVersion,
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
async function onActivateFailure(error: Error | string): Promise<void> {
|
|
383
|
+
const applicationCode = await Pushwoosh.data.getApplicationCode();
|
|
384
|
+
const workerVersion = await Pushwoosh.data.getServiceWorkerVersion();
|
|
385
|
+
|
|
386
|
+
await sendFatalLogToRemoteServer({
|
|
387
|
+
message: 'Error in onActivateEventHandler',
|
|
388
|
+
code: 'FATAL-SW-002',
|
|
389
|
+
error,
|
|
390
|
+
applicationCode,
|
|
391
|
+
workerVersion,
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
async function onPushFailure(error: Error | string, event: PushEvent): Promise<void> {
|
|
396
|
+
const applicationCode = await Pushwoosh.data.getApplicationCode();
|
|
397
|
+
const workerVersion = await Pushwoosh.data.getServiceWorkerVersion();
|
|
398
|
+
|
|
399
|
+
await sendFatalLogToRemoteServer({
|
|
400
|
+
message: 'Error in onPushEventHandler',
|
|
401
|
+
code: 'FATAL-SW-003',
|
|
402
|
+
error,
|
|
403
|
+
applicationCode,
|
|
404
|
+
workerVersion,
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
if (!(error instanceof Error)) {
|
|
408
|
+
error = new Error(error);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
return messagesLog.add({
|
|
412
|
+
error: `${error}`,
|
|
413
|
+
stack: error.stack,
|
|
414
|
+
payload: event.data && event.data.text(),
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
async function onClickNotificationFailure(error: Error | string): Promise<void> {
|
|
419
|
+
const applicationCode = await Pushwoosh.data.getApplicationCode();
|
|
420
|
+
const workerVersion = await Pushwoosh.data.getServiceWorkerVersion();
|
|
421
|
+
|
|
422
|
+
await sendFatalLogToRemoteServer({
|
|
423
|
+
message: 'Error in onNotificationClickEventHandler',
|
|
424
|
+
code: 'FATAL-SW-004',
|
|
425
|
+
error,
|
|
426
|
+
applicationCode,
|
|
427
|
+
workerVersion,
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
async function closeNotificationFailure(error: Error | string): Promise<void> {
|
|
432
|
+
const applicationCode = await Pushwoosh.data.getApplicationCode();
|
|
433
|
+
const workerVersion = await Pushwoosh.data.getServiceWorkerVersion();
|
|
434
|
+
|
|
435
|
+
await sendFatalLogToRemoteServer({
|
|
436
|
+
message: 'Error in onNotificationCloseEventHandler',
|
|
437
|
+
code: 'FATAL-SW-005',
|
|
438
|
+
error,
|
|
439
|
+
applicationCode,
|
|
440
|
+
workerVersion,
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
async function pushSubscriptionChangeFailure(error: Error | string): Promise<void> {
|
|
445
|
+
const applicationCode = await Pushwoosh.data.getApplicationCode();
|
|
446
|
+
const workerVersion = await Pushwoosh.data.getServiceWorkerVersion();
|
|
447
|
+
|
|
448
|
+
await sendFatalLogToRemoteServer({
|
|
449
|
+
message: 'Error in onPushSubscriptionChange',
|
|
450
|
+
code: 'FATAL-SW-006',
|
|
451
|
+
error,
|
|
452
|
+
applicationCode,
|
|
453
|
+
workerVersion,
|
|
454
|
+
});
|
|
455
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export interface IPushServiceSubscriptionKeys {
|
|
2
|
+
pushToken?: string;
|
|
3
|
+
publicKey?: string;
|
|
4
|
+
authToken?: string;
|
|
5
|
+
endpoint?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export abstract class IPushService {
|
|
9
|
+
/**
|
|
10
|
+
* Get current status of permission for send notifications.
|
|
11
|
+
*
|
|
12
|
+
* @return { NotificationPermission }
|
|
13
|
+
*/
|
|
14
|
+
public abstract getPermission(): NotificationPermission;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Check is permission granted.
|
|
18
|
+
*
|
|
19
|
+
* @return { boolean }
|
|
20
|
+
*/
|
|
21
|
+
public abstract checkIsPermissionGranted(): boolean;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Check is permission default.
|
|
25
|
+
*
|
|
26
|
+
* @return { boolean }
|
|
27
|
+
*/
|
|
28
|
+
public abstract checkIsPermissionDefault(): boolean;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Check is manual unsubscribed for push notifications.
|
|
32
|
+
*/
|
|
33
|
+
public abstract checkIsManualUnsubscribed(): Promise<boolean>;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Request permission for send notifications.
|
|
37
|
+
*
|
|
38
|
+
* @return { Promise<void> }
|
|
39
|
+
*/
|
|
40
|
+
public abstract askPermission(): Promise<void>;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Get subscription keys for send push notifications.
|
|
44
|
+
*
|
|
45
|
+
* @return { Promise<IPushServiceSubscriptionKeys> }
|
|
46
|
+
*/
|
|
47
|
+
public abstract getTokens(): Promise<IPushServiceSubscriptionKeys>;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Subscribe for push notifications.
|
|
51
|
+
*
|
|
52
|
+
* @return { Promise<void> }
|
|
53
|
+
*/
|
|
54
|
+
public abstract subscribe(): Promise<void>;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Unsubscribe for push notifications.
|
|
58
|
+
*
|
|
59
|
+
* @return { Promise<void> }
|
|
60
|
+
*/
|
|
61
|
+
public abstract unsubscribe(): Promise<void>;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Check can receive notifications from Pushwoosh.
|
|
65
|
+
*
|
|
66
|
+
* @return { Promise<boolean> }
|
|
67
|
+
*/
|
|
68
|
+
public abstract checkIsRegister(): Promise<boolean>;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Check is change sender configuration
|
|
72
|
+
*/
|
|
73
|
+
public abstract checkIsNeedResubscribe(): Promise<boolean>;
|
|
74
|
+
}
|