diff --git a/desktop/src/push-notifications.js b/desktop/src/push-notifications.js --- a/desktop/src/push-notifications.js +++ b/desktop/src/push-notifications.js @@ -12,6 +12,7 @@ import { isNormalStartup } from './handle-squirrel-event.js'; let windowsPushNotificationManager; +let windowsPushNotificationChannel; const windowsPushNotifEventEmitter = new EventEmitter(); if (process.platform === 'win32' && app.isPackaged && isNormalStartup()) { void (async () => { @@ -69,6 +70,9 @@ } } else if (process.platform === 'win32' && windowsPushNotificationManager) { try { + if (windowsPushNotificationChannel) { + windowsPushNotificationChannel.close(); + } const token = await new Promise((resolvePromise, reject) => { windowsPushNotificationManager.createChannelAsync( 'f09f4211-a998-40c1-a515-689e3faecb62', @@ -76,6 +80,7 @@ if (error) { reject(error); } + windowsPushNotificationChannel = result.channel; resolvePromise(result.channel.uri); }, ); diff --git a/lib/reducers/tunnelbroker-device-token-reducer.js b/lib/reducers/tunnelbroker-device-token-reducer.js --- a/lib/reducers/tunnelbroker-device-token-reducer.js +++ b/lib/reducers/tunnelbroker-device-token-reducer.js @@ -27,6 +27,11 @@ } else if (action.type === setTBDeviceTokenActionTypes.success) { const { deviceToken } = action.payload; return { ...state, tunnelbrokerToken: deviceToken }; + } else if ( + action.type === setTBDeviceTokenActionTypes.failed && + action.payload === 'InvalidDeviceTokenUpload' + ) { + return { ...state, localToken: null }; } else if (action.type === invalidateTunnelbrokerDeviceTokenActionType) { const { deviceToken } = action.payload; if (state.localToken !== deviceToken) { diff --git a/services/tunnelbroker/src/websockets/session.rs b/services/tunnelbroker/src/websockets/session.rs --- a/services/tunnelbroker/src/websockets/session.rs +++ b/services/tunnelbroker/src/websockets/session.rs @@ -21,10 +21,12 @@ use notifs::fcm::error::Error::FCMError as NotifsFCMError; use notifs::web_push::error::Error::WebPush as NotifsWebPushError; use notifs::wns::error::Error::WNSNotification as NotifsWNSError; +use reqwest::Url; use tokio::io::AsyncRead; use tokio::io::AsyncWrite; use tracing::{debug, error, info, trace}; use tunnelbroker_messages::bad_device_token::BadDeviceToken; +use tunnelbroker_messages::Platform; use tunnelbroker_messages::{ message_to_device_request_status::Failure, message_to_device_request_status::MessageSentStatus, session::DeviceTypes, @@ -84,6 +86,7 @@ MissingDeviceToken, InvalidDeviceToken, InvalidNotifProvider, + InvalidDeviceTokenUpload, } // Parse a session request and retrieve the device information @@ -304,6 +307,23 @@ MessageToTunnelbroker::SetDeviceTokenWithPlatform( token_with_platform, ) => { + if matches!(token_with_platform.platform, Platform::Windows) { + Url::parse(&token_with_platform.device_token) + .ok() + .filter(|url| { + url + .domain() + .is_some_and(|domain| domain.ends_with("notify.windows.com")) + }) + .ok_or_else(|| { + debug!( + device_token = &token_with_platform.device_token, + device_id = &self.device_info.device_id, + "Invalid Windows device token" + ); + SessionError::InvalidDeviceTokenUpload + })?; + } self .db_client .set_device_token(