From 99f4cdaf51e03b722924c5a4849f4b6842f21b09 Mon Sep 17 00:00:00 2001 From: JRoberts <8711996+jr-simplex@users.noreply.github.com> Date: Fri, 6 Jan 2023 18:48:19 +0400 Subject: [PATCH 1/3] check token status when sending verification notification --- src/Simplex/Messaging/Notifications/Server.hs | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/Simplex/Messaging/Notifications/Server.hs b/src/Simplex/Messaging/Notifications/Server.hs index 54b30e0f92..142741676b 100644 --- a/src/Simplex/Messaging/Notifications/Server.hs +++ b/src/Simplex/Messaging/Notifications/Server.hs @@ -257,24 +257,30 @@ ntfPush s@NtfPushServer {pushQ} = forever $ do (tkn@NtfTknData {ntfTknId, token = DeviceToken pp _, tknStatus}, ntf) <- atomically (readTBQueue pushQ) liftIO $ logDebug $ "sending push notification to " <> T.pack (show pp) status <- readTVarIO tknStatus - case (status, ntf) of - (_, PNVerification _) -> - -- TODO check token status - deliverNotification pp tkn ntf >>= \case - Right _ -> do - status_ <- atomically $ stateTVar tknStatus $ \status' -> if status' == NTActive then (Nothing, NTActive) else (Just NTConfirmed, NTConfirmed) - forM_ status_ $ \status' -> withNtfLog $ \sl -> logTokenStatus sl ntfTknId status' - _ -> pure () - (NTActive, PNCheckMessages) -> + case ntf of + PNVerification _ + | status /= NTInvalid && status /= NTExpired -> + deliverNotification pp tkn ntf >>= \case + Right _ -> do + status_ <- atomically $ stateTVar tknStatus $ \status' -> if status' == NTActive then (Nothing, NTActive) else (Just NTConfirmed, NTConfirmed) + forM_ status_ $ \status' -> withNtfLog $ \sl -> logTokenStatus sl ntfTknId status' + _ -> pure () + | otherwise -> logError "bad notification token status" + PNCheckMessages -> withActiveTkn status $ do void $ deliverNotification pp tkn ntf - (NTActive, PNMessage {}) -> do + PNMessage {} -> withActiveTkn status $ do stats <- asks serverStats atomically $ updatePeriodStats (activeTokens stats) ntfTknId void $ deliverNotification pp tkn ntf incNtfStat ntfDelivered - _ -> - liftIO $ logError "bad notification token status" + -- not used in production + PNAlert _ -> withActiveTkn status $ do + void $ deliverNotification pp tkn ntf where + withActiveTkn :: NtfTknStatus -> M () -> M () + withActiveTkn status action + | status == NTActive = action + | otherwise = liftIO $ logError "bad notification token status" deliverNotification :: PushProvider -> NtfTknData -> PushNotification -> M (Either PushProviderError ()) deliverNotification pp tkn@NtfTknData {ntfTknId, tknStatus} ntf = do deliver <- liftIO $ getPushClient s pp From d0deb080889c859d0906bc456b695ecc2694b368 Mon Sep 17 00:00:00 2001 From: JRoberts <8711996+jr-simplex@users.noreply.github.com> Date: Fri, 6 Jan 2023 18:57:29 +0400 Subject: [PATCH 2/3] update comments --- src/Simplex/Messaging/Agent.hs | 2 +- src/Simplex/Messaging/Notifications/Server.hs | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Simplex/Messaging/Agent.hs b/src/Simplex/Messaging/Agent.hs index e5c964b0d4..391f49405e 100644 --- a/src/Simplex/Messaging/Agent.hs +++ b/src/Simplex/Messaging/Agent.hs @@ -504,7 +504,7 @@ joinConnSrv c connId asyncMode enableNtfs (CRInvitationUri ConnReqUriData {crAge unless duplexHS . void $ enqueueMessage c cData' sq SMP.noMsgFlags HELLO pure connId' Left e -> do - -- TODO recovery for failure on network timeout, see rfcs/2022-04-20-smp-conf-timeout-recovery.md + -- possible improvement: recovery for failure on network timeout, see rfcs/2022-04-20-smp-conf-timeout-recovery.md unless asyncMode $ withStore' c (`deleteConn` connId') throwError e where diff --git a/src/Simplex/Messaging/Notifications/Server.hs b/src/Simplex/Messaging/Notifications/Server.hs index 142741676b..5f60142b1b 100644 --- a/src/Simplex/Messaging/Notifications/Server.hs +++ b/src/Simplex/Messaging/Notifications/Server.hs @@ -367,13 +367,11 @@ verifyNtfTransmission (sig_, signed, (corrId, entId, _)) cmd = do s_ <- atomically $ findNtfSubscription st smpQueue case s_ of Nothing -> do - -- TODO move active token check here to differentiate error t_ <- atomically $ getActiveNtfToken st tknId verifyToken' t_ $ VRVerified (NtfReqNew corrId (ANE SSubscription sub)) Just s@NtfSubData {tokenId = subTknId} -> if subTknId == tknId then do - -- TODO move active token check here to differentiate error t_ <- atomically $ getActiveNtfToken st subTknId verifyToken' t_ $ verifiedSubCmd s c else pure $ maybe False (dummyVerifyCmd signed) sig_ `seq` VRFailed @@ -381,7 +379,6 @@ verifyNtfTransmission (sig_, signed, (corrId, entId, _)) cmd = do s_ <- atomically $ getNtfSubscription st entId case s_ of Just s@NtfSubData {tokenId = subTknId} -> do - -- TODO move active token check here to differentiate error t_ <- atomically $ getActiveNtfToken st subTknId verifyToken' t_ $ verifiedSubCmd s c _ -> pure $ maybe False (dummyVerifyCmd signed) sig_ `seq` VRFailed From cc5a0352b0bb839d31786ca6fa7e2565af4c6074 Mon Sep 17 00:00:00 2001 From: JRoberts <8711996+jr-simplex@users.noreply.github.com> Date: Fri, 6 Jan 2023 19:04:36 +0400 Subject: [PATCH 3/3] checkActiveTkn --- src/Simplex/Messaging/Notifications/Server.hs | 11 ++++------- .../Messaging/Notifications/Server/Push/APNS.hs | 6 +++--- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/Simplex/Messaging/Notifications/Server.hs b/src/Simplex/Messaging/Notifications/Server.hs index 5f60142b1b..7afb3c407e 100644 --- a/src/Simplex/Messaging/Notifications/Server.hs +++ b/src/Simplex/Messaging/Notifications/Server.hs @@ -266,19 +266,16 @@ ntfPush s@NtfPushServer {pushQ} = forever $ do forM_ status_ $ \status' -> withNtfLog $ \sl -> logTokenStatus sl ntfTknId status' _ -> pure () | otherwise -> logError "bad notification token status" - PNCheckMessages -> withActiveTkn status $ do + PNCheckMessages -> checkActiveTkn status $ do void $ deliverNotification pp tkn ntf - PNMessage {} -> withActiveTkn status $ do + PNMessage {} -> checkActiveTkn status $ do stats <- asks serverStats atomically $ updatePeriodStats (activeTokens stats) ntfTknId void $ deliverNotification pp tkn ntf incNtfStat ntfDelivered - -- not used in production - PNAlert _ -> withActiveTkn status $ do - void $ deliverNotification pp tkn ntf where - withActiveTkn :: NtfTknStatus -> M () -> M () - withActiveTkn status action + checkActiveTkn :: NtfTknStatus -> M () -> M () + checkActiveTkn status action | status == NTActive = action | otherwise = liftIO $ logError "bad notification token status" deliverNotification :: PushProvider -> NtfTknData -> PushNotification -> M (Either PushProviderError ()) diff --git a/src/Simplex/Messaging/Notifications/Server/Push/APNS.hs b/src/Simplex/Messaging/Notifications/Server/Push/APNS.hs index 01a41c1ec9..5221d7dbc2 100644 --- a/src/Simplex/Messaging/Notifications/Server/Push/APNS.hs +++ b/src/Simplex/Messaging/Notifications/Server/Push/APNS.hs @@ -97,7 +97,7 @@ readECPrivateKey f = do data PushNotification = PNVerification NtfRegCode | PNMessage PNMessageData - | PNAlert Text + -- | PNAlert Text | PNCheckMessages deriving (Show) @@ -287,14 +287,14 @@ apnsNotification NtfTknData {tknDhSecret} nonce paddedLen = \case PNMessage pnMessageData -> encrypt (strEncode pnMessageData) $ \ntfData -> apn apnMutableContent . Just $ J.object ["nonce" .= nonce, "message" .= ntfData] - PNAlert text -> Right $ apn (apnAlert $ APNSAlertText text) Nothing + -- PNAlert text -> Right $ apn (apnAlert $ APNSAlertText text) Nothing PNCheckMessages -> Right $ apn APNSBackground {contentAvailable = 1} . Just $ J.object ["checkMessages" .= True] where encrypt :: ByteString -> (Text -> APNSNotification) -> Either C.CryptoError APNSNotification encrypt ntfData f = f . safeDecodeUtf8 . U.encode <$> C.cbEncrypt tknDhSecret nonce ntfData paddedLen apn aps notificationData = APNSNotification {aps, notificationData} apnMutableContent = APNSMutableContent {mutableContent = 1, alert = APNSAlertText "Encrypted message or another app event", category = Just ntfCategoryCheckMessage} - apnAlert alert = APNSAlert {alert, badge = Nothing, sound = Nothing, category = Nothing} + -- apnAlert alert = APNSAlert {alert, badge = Nothing, sound = Nothing, category = Nothing} apnsRequest :: APNSPushClient -> ByteString -> APNSNotification -> IO Request apnsRequest c tkn ntf@APNSNotification {aps} = do