From 21b188b0b2f8cb5c7ae2527de616d61a7c55cdc7 Mon Sep 17 00:00:00 2001 From: Brandon Cohen Date: Thu, 12 Jun 2025 19:07:53 -0400 Subject: [PATCH] fix: better handling for active webpush subscription (#4146) fix: remove yarn from package manager fix: update openapi yml --- overseerr-api.yml | 6 ++--- server/routes/user/index.ts | 14 +++++----- .../UserNotificationsWebPush/DeviceItem.tsx | 19 ++++++------- .../UserNotificationsWebPush/index.tsx | 27 ++++++++++++------- 4 files changed, 36 insertions(+), 30 deletions(-) diff --git a/overseerr-api.yml b/overseerr-api.yml index b7d243edf..c48b6575f 100644 --- a/overseerr-api.yml +++ b/overseerr-api.yml @@ -3617,7 +3617,7 @@ paths: type: string userAgent: type: string - /user/{userId}/pushSubscription/{key}: + /user/{userId}/pushSubscription/{endpoint}: get: summary: Get web push notification settings for a user description: | @@ -3631,7 +3631,7 @@ paths: schema: type: number - in: path - name: key + name: endpoint required: true schema: type: string @@ -3663,7 +3663,7 @@ paths: schema: type: number - in: path - name: key + name: endpoint required: true schema: type: string diff --git a/server/routes/user/index.ts b/server/routes/user/index.ts index afca9bd78..8bcde7744 100644 --- a/server/routes/user/index.ts +++ b/server/routes/user/index.ts @@ -201,8 +201,8 @@ router.get<{ userId: number }>( } ); -router.get<{ userId: number; key: string }>( - '/:userId/pushSubscription/:key', +router.get<{ userId: number; endpoint: string }>( + '/:userId/pushSubscription/:endpoint', async (req, res, next) => { try { const userPushSubRepository = getRepository(UserPushSubscription); @@ -213,7 +213,7 @@ router.get<{ userId: number; key: string }>( }, where: { user: { id: req.params.userId }, - p256dh: req.params.key, + endpoint: req.params.endpoint, }, }); @@ -224,8 +224,8 @@ router.get<{ userId: number; key: string }>( } ); -router.delete<{ userId: number; key: string }>( - '/:userId/pushSubscription/:key', +router.delete<{ userId: number; endpoint: string }>( + '/:userId/pushSubscription/:endpoint', async (req, res, next) => { try { const userPushSubRepository = getRepository(UserPushSubscription); @@ -236,7 +236,7 @@ router.delete<{ userId: number; key: string }>( }, where: { user: { id: req.params.userId }, - p256dh: req.params.key, + endpoint: req.params.endpoint, }, }); @@ -245,7 +245,7 @@ router.delete<{ userId: number; key: string }>( } catch (e) { logger.error('Something went wrong deleting the user push subcription', { label: 'API', - key: req.params.key, + endpoint: req.params.endpoint, errorMessage: e.message, }); return next({ diff --git a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsWebPush/DeviceItem.tsx b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsWebPush/DeviceItem.tsx index 73bc8da37..c301916d7 100644 --- a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsWebPush/DeviceItem.tsx +++ b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsWebPush/DeviceItem.tsx @@ -29,13 +29,14 @@ const messages = defineMessages({ const DeviceItem = ({ disablePushNotifications, device }: DeviceItemProps) => { const intl = useIntl(); + const parsedUserAgent = UAParser(device.userAgent); return (
- {UAParser(device.userAgent).device.type === 'mobile' ? ( + {parsedUserAgent.device.type === 'mobile' ? ( ) : ( @@ -52,8 +53,8 @@ const DeviceItem = ({ disablePushNotifications, device }: DeviceItemProps) => { : 'N/A'}
- {device.userAgent - ? UAParser(device.userAgent).device.model + {device.userAgent && parsedUserAgent.device.model + ? parsedUserAgent.device.model : intl.formatMessage(messages.unknown)}
@@ -64,7 +65,7 @@ const DeviceItem = ({ disablePushNotifications, device }: DeviceItemProps) => { {intl.formatMessage(messages.operatingsystem)} - {device.userAgent ? UAParser(device.userAgent).os.name : 'N/A'} + {device.userAgent ? parsedUserAgent.os.name : 'N/A'}
@@ -72,9 +73,7 @@ const DeviceItem = ({ disablePushNotifications, device }: DeviceItemProps) => { {intl.formatMessage(messages.browser)} - {device.userAgent - ? UAParser(device.userAgent).browser.name - : 'N/A'} + {device.userAgent ? parsedUserAgent.browser.name : 'N/A'}
@@ -82,16 +81,14 @@ const DeviceItem = ({ disablePushNotifications, device }: DeviceItemProps) => { {intl.formatMessage(messages.engine)} - {device.userAgent - ? UAParser(device.userAgent).engine.name - : 'N/A'} + {device.userAgent ? parsedUserAgent.engine.name : 'N/A'}
disablePushNotifications(device.p256dh)} + onClick={() => disablePushNotifications(device.endpoint)} confirmText={intl.formatMessage(globalMessages.areyousure)} className="w-full" > diff --git a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsWebPush/index.tsx b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsWebPush/index.tsx index 885a4cb38..8a24a0c31 100644 --- a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsWebPush/index.tsx +++ b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsWebPush/index.tsx @@ -109,7 +109,7 @@ const UserWebPushSettings = () => { // Unsubscribes from the push manager // Deletes/disables corresponding push subscription from database - const disablePushNotifications = async (p256dh?: string) => { + const disablePushNotifications = async (endpoint?: string) => { if ('serviceWorker' in navigator && user?.id) { navigator.serviceWorker.getRegistration('/sw.js').then((registration) => { registration?.pushManager @@ -118,17 +118,21 @@ const UserWebPushSettings = () => { const parsedSub = JSON.parse(JSON.stringify(subscription)); await axios.delete( - `/api/v1/user/${user?.id}/pushSubscription/${ - p256dh ? p256dh : parsedSub.keys.p256dh - }` + `/api/v1/user/${user.id}/pushSubscription/${encodeURIComponent( + endpoint ?? parsedSub.endpoint + )}` ); - if (subscription && (p256dh === parsedSub.keys.p256dh || !p256dh)) { + + if ( + subscription && + (endpoint === parsedSub.endpoint || !endpoint) + ) { subscription.unsubscribe(); setWebPushEnabled(false); } addToast( intl.formatMessage( - p256dh + endpoint ? messages.subscriptiondeleted : messages.webpushhasbeendisabled ), @@ -141,7 +145,7 @@ const UserWebPushSettings = () => { .catch(function () { addToast( intl.formatMessage( - p256dh + endpoint ? messages.subscriptiondeleteerror : messages.disablingwebpusherror ), @@ -172,12 +176,17 @@ const UserWebPushSettings = () => { const parsedKey = JSON.parse(JSON.stringify(subscription)); const currentUserPushSub = await axios.get( - `/api/v1/user/${user.id}/pushSubscription/${parsedKey.keys.p256dh}` + `/api/v1/user/${ + user.id + }/pushSubscription/${encodeURIComponent( + parsedKey.endpoint + )}` ); - if (currentUserPushSub.data.p256dh !== parsedKey.keys.p256dh) { + if (currentUserPushSub.data.endpoint !== parsedKey.endpoint) { return; } + setWebPushEnabled(true); } else { setWebPushEnabled(false);