feat: Improve logging and error handling in PushNotificationService and Service Worker; remove Logger from Cookie and LocalStorage classes

This commit is contained in:
Simon Larsen
2025-07-17 14:06:17 +01:00
parent af66709363
commit 618dcbdcce
6 changed files with 78 additions and 24 deletions

View File

@@ -25,12 +25,16 @@ export default class PushNotificationService {
if (!VapidPublicKey || !VapidPrivateKey) {
logger.warn("VAPID keys not configured. Web push notifications will not work.");
logger.warn(`VapidPublicKey present: ${!!VapidPublicKey}`);
logger.warn(`VapidPrivateKey present: ${!!VapidPrivateKey}`);
logger.warn(`VapidSubject: ${VapidSubject}`);
return;
}
logger.info(`Initializing web push with VAPID subject: ${VapidSubject}`);
webpush.setVapidDetails(VapidSubject, VapidPublicKey, VapidPrivateKey);
this.isWebPushInitialized = true;
logger.info("Web push notifications initialized");
logger.info("Web push notifications initialized successfully");
}
public static async sendPushNotification(
@@ -100,17 +104,33 @@ export default class PushNotificationService {
url: message.url || message.clickAction,
});
await webpush.sendNotification(
JSON.parse(deviceToken), // deviceToken is the subscription object for web push
logger.debug(`Sending push notification with payload: ${payload}`);
logger.debug(`Device token: ${deviceToken}`);
let subscriptionObject;
try {
subscriptionObject = JSON.parse(deviceToken);
logger.debug(`Parsed subscription object: ${JSON.stringify(subscriptionObject)}`);
} catch (parseError) {
logger.error(`Failed to parse device token: ${parseError}`);
throw new Error(`Invalid device token format: ${parseError}`);
}
const result: webpush.SendResult = await webpush.sendNotification(
subscriptionObject,
payload,
{
TTL: 24 * 60 * 60, // 24 hours
}
);
logger.debug(`Web push notification sent successfully:`);
logger.debug(result);
logger.info(`Web push notification sent successfully`);
} catch (error: any) {
logger.error(`Failed to send web push notification: ${error.message}`);
logger.error(error);
// If the subscription is no longer valid, remove it
if (error.statusCode === 410 || error.statusCode === 404) {

View File

@@ -7,7 +7,6 @@ import JSONFunctions from "../../Types/JSONFunctions";
import Typeof from "../../Types/Typeof";
import UniversalCookies, { CookieSetOptions } from "universal-cookie";
import CookieName from "../../Types/CookieName";
import { Logger } from "./Logger";
export default class Cookie {
public static clearAllCookies(): void {
@@ -65,7 +64,6 @@ export default class Cookie {
}
return value;
} catch (err) {
Logger.error(err as string);
return value;
}
}

View File

@@ -4,7 +4,6 @@ import Email from "../../Types/Email";
import { JSONObject, JSONValue } from "../../Types/JSON";
import JSONFunctions from "../../Types/JSONFunctions";
import Typeof from "../../Types/Typeof";
import { Logger } from "./Logger";
export default class LocalStorage {
public static setItem(key: string, value: JSONValue | Email | URL): void {
@@ -28,7 +27,6 @@ export default class LocalStorage {
}
return value;
} catch (err) {
Logger.error(err as string);
return value;
}
}

View File

@@ -4,7 +4,6 @@ import Email from "../../Types/Email";
import { JSONObject, JSONValue } from "../../Types/JSON";
import JSONFunctions from "../../Types/JSONFunctions";
import Typeof from "../../Types/Typeof";
import { Logger } from "./Logger";
export default class SessionStorage {
public static setItem(key: string, value: JSONValue | Email | URL): void {
@@ -28,7 +27,6 @@ export default class SessionStorage {
}
return value;
} catch (err) {
Logger.error(err as string);
return value;
}
}

View File

@@ -2,23 +2,62 @@
// Service Worker for OneUptime Push Notifications
self.addEventListener('push', function(event) {
if (event.data) {
const data = event.data.json();
const options = {
body: data.body,
icon: data.icon || '/icon-192x192.png',
badge: data.badge || '/badge-72x72.png',
tag: data.tag || 'oneuptime-notification',
requireInteraction: data.requireInteraction || false,
actions: data.actions || [],
data: data.data || {},
silent: false,
};
console.log('[ServiceWorker] OneUptime Push Notifications Service Worker Loaded');
self.addEventListener('push', function(event) {
console.log('[ServiceWorker] Push received:', event);
if (event.data) {
try {
const data = event.data.json();
console.log('[ServiceWorker] Push data:', data);
const options = {
body: data.body,
icon: data.icon || '/icon-192x192.png',
badge: data.badge || '/badge-72x72.png',
tag: data.tag || 'oneuptime-notification',
requireInteraction: data.requireInteraction || false,
actions: data.actions || [],
data: data.data || {},
silent: false,
renotify: true, // Allow renotification with same tag
};
console.log('[ServiceWorker] Showing notification with options:', options);
event.waitUntil(
self.registration.showNotification(data.title, options)
.then(() => {
console.log('[ServiceWorker] Notification shown successfully');
})
.catch((error) => {
console.error('[ServiceWorker] Error showing notification:', error);
})
);
} catch (error) {
console.error('[ServiceWorker] Error parsing push data:', error);
console.log('[ServiceWorker] Raw event data:', event.data ? event.data.text() : 'No data');
// Show a fallback notification
event.waitUntil(
self.registration.showNotification('OneUptime Notification', {
body: 'You have a new notification',
icon: '/icon-192x192.png',
tag: 'oneuptime-fallback'
})
);
}
} else {
console.log('[ServiceWorker] Push event received but no data');
// Show a fallback notification when no data is provided
event.waitUntil(
self.registration.showNotification(data.title, options)
self.registration.showNotification('OneUptime Notification', {
body: 'You have a new notification',
icon: '/icon-192x192.png',
tag: 'oneuptime-fallback'
})
);
}
});

View File

@@ -35,6 +35,7 @@
<link rel="icon" type="image/png" sizes="16x16" href="/dashboard/assets/img/favicons/favicon-16x16.png">
<link rel="mask-icon" href="/dashboard/assets/img/favicons/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#121212">
<script src="/dashboard/sw.js"></script>
<meta name="msapplication-TileImage" content="/dashboard/assets/img/favicons/mstile-144x144.png">
<meta name="theme-color" content="#121212">
<link rel="preconnect" href="https://fonts.googleapis.com">