@@ -58,6 +58,7 @@ import Simplex.Messaging.Protocol (EntityId (..), ErrorType (..), ProtocolServer
5858import qualified Simplex.Messaging.Protocol as SMP
5959import Simplex.Messaging.Server
6060import Simplex.Messaging.Server.Control (CPClientRole (.. ))
61+ import Simplex.Messaging.Server.QueueStore (RoundedSystemTime , getSystemDate )
6162import Simplex.Messaging.Server.Stats (PeriodStats (.. ), PeriodStatCounts (.. ), periodStatCounts , updatePeriodStats )
6263import Simplex.Messaging.TMap (TMap )
6364import qualified Simplex.Messaging.TMap as TM
@@ -435,17 +436,19 @@ ntfPush s@NtfPushServer {pushQ} = forever $ do
435436 liftIO $ logDebug $ " sending push notification to " <> T. pack (show pp)
436437 status <- readTVarIO tknStatus
437438 case ntf of
438- PNVerification _
439- | status /= NTInvalid && status /= NTExpired ->
440- deliverNotification pp tkn ntf >>= \ case
441- Right _ -> do
442- status_ <- atomically $ stateTVar tknStatus $ \ case
443- NTActive -> (Nothing , NTActive )
444- NTConfirmed -> (Nothing , NTConfirmed )
445- _ -> (Just NTConfirmed , NTConfirmed )
446- forM_ status_ $ \ status' -> withNtfLog $ \ sl -> logTokenStatus sl ntfTknId status'
447- _ -> pure ()
448- | otherwise -> logError " bad notification token status"
439+ PNVerification _ -> case status of
440+ NTInvalid _ -> logError $ " bad notification token status: " <> tshow status
441+ -- TODO nothing makes token "expired" on the server
442+ NTExpired -> logError $ " bad notification token status: " <> tshow status
443+ _ ->
444+ deliverNotification pp tkn ntf >>= \ case
445+ Right _ -> do
446+ status_ <- atomically $ stateTVar tknStatus $ \ case
447+ NTActive -> (Nothing , NTActive )
448+ NTConfirmed -> (Nothing , NTConfirmed )
449+ _ -> (Just NTConfirmed , NTConfirmed )
450+ forM_ status_ $ \ status' -> withNtfLog $ \ sl -> logTokenStatus sl ntfTknId status'
451+ _ -> pure ()
449452 PNCheckMessages -> checkActiveTkn status $ do
450453 void $ deliverNotification pp tkn ntf
451454 PNMessage {} -> checkActiveTkn status $ do
@@ -459,7 +462,7 @@ ntfPush s@NtfPushServer {pushQ} = forever $ do
459462 | status == NTActive = action
460463 | otherwise = liftIO $ logError " bad notification token status"
461464 deliverNotification :: PushProvider -> NtfTknData -> PushNotification -> M (Either PushProviderError () )
462- deliverNotification pp tkn ntf = do
465+ deliverNotification pp tkn@ NtfTknData {ntfTknId} ntf = do
463466 deliver <- liftIO $ getPushClient s pp
464467 liftIO (runExceptT $ deliver tkn ntf) >>= \ case
465468 Right _ -> pure $ Right ()
@@ -468,14 +471,14 @@ ntfPush s@NtfPushServer {pushQ} = forever $ do
468471 PPRetryLater -> retryDeliver
469472 PPCryptoError _ -> err e
470473 PPResponseError _ _ -> err e
471- PPTokenInvalid -> updateTknStatus tkn NTInvalid >> err e
474+ PPTokenInvalid r -> updateTknStatus tkn ( NTInvalid $ Just r) >> err e
472475 PPPermanentError -> err e
473476 where
474477 retryDeliver :: M (Either PushProviderError () )
475478 retryDeliver = do
476479 deliver <- liftIO $ newPushClient s pp
477480 liftIO (runExceptT $ deliver tkn ntf) >>= either err (pure . Right )
478- err e = logError (T. pack $ " Push provider error (" <> show pp <> " ): " <> show e) $> Left e
481+ err e = logError (" Push provider error (" <> tshow pp <> " , " <> tshow ntfTknId <> " ): " <> tshow e) $> Left e
479482
480483updateTknStatus :: NtfTknData -> NtfTknStatus -> M ()
481484updateTknStatus NtfTknData {ntfTknId, tknStatus} status = do
@@ -509,13 +512,17 @@ receive th@THandle {params = THandleParams {thAuth}} NtfServerClient {rcvQ, sndQ
509512 where
510513 cmdAction t@ (_, _, (corrId, entId, cmdOrError)) =
511514 case cmdOrError of
512- Left e -> pure $ Left (corrId, entId, NRErr e)
515+ Left e -> do
516+ logError $ " invalid client request: " <> tshow e
517+ pure $ Left (corrId, entId, NRErr e)
513518 Right cmd ->
514- verified <$> verifyNtfTransmission ((,C. cbNonce (SMP. bs corrId)) <$> thAuth) t cmd
519+ verified =<< verifyNtfTransmission ((,C. cbNonce (SMP. bs corrId)) <$> thAuth) t cmd
515520 where
516521 verified = \ case
517- VRVerified req -> Right req
518- VRFailed -> Left (corrId, entId, NRErr AUTH )
522+ VRVerified req -> pure $ Right req
523+ VRFailed -> do
524+ logError " unauthorized client request"
525+ pure $ Left (corrId, entId, NRErr AUTH )
519526 write q = mapM_ (atomically . writeTBQueue q) . L. nonEmpty
520527
521528send :: Transport c => THandleNTF c 'TServer -> NtfServerClient -> IO ()
@@ -524,7 +531,7 @@ send h@THandle {params} NtfServerClient {sndQ, sndActiveAt} = forever $ do
524531 void . liftIO $ tPut h $ L. map (\ t -> Right (Nothing , encodeTransmission params t)) ts
525532 atomically . (writeTVar sndActiveAt $! ) =<< liftIO getSystemTime
526533
527- data VerificationResult = VRVerified NtfRequest | VRFailed
534+ data VerificationResult = VRVerified ( Maybe NtfTknData , NtfRequest ) | VRFailed
528535
529536verifyNtfTransmission :: Maybe (THandleAuth 'TServer, C. CbNonce ) -> SignedTransmission ErrorType NtfCmd -> NtfCmd -> M VerificationResult
530537verifyNtfTransmission auth_ (tAuth, authorized, (corrId, entId, _)) cmd = do
@@ -538,34 +545,34 @@ verifyNtfTransmission auth_ (tAuth, authorized, (corrId, entId, _)) cmd = do
538545 Just t@ NtfTknData {tknVerifyKey}
539546 | k == tknVerifyKey -> verifiedTknCmd t c
540547 | otherwise -> VRFailed
541- _ -> VRVerified (NtfReqNew corrId (ANE SToken tkn))
548+ Nothing -> VRVerified (Nothing , NtfReqNew corrId (ANE SToken tkn))
542549 else VRFailed
543550 NtfCmd SToken c -> do
544- t_ <- atomically $ getNtfToken st entId
551+ t_ <- liftIO $ getNtfTokenIO st entId
545552 verifyToken t_ (`verifiedTknCmd` c)
546553 NtfCmd SSubscription c@ (SNEW sub@ (NewNtfSub tknId smpQueue _)) -> do
547554 s_ <- atomically $ findNtfSubscription st smpQueue
548555 case s_ of
549556 Nothing -> do
550557 t_ <- atomically $ getActiveNtfToken st tknId
551- verifyToken' t_ $ VRVerified (NtfReqNew corrId (ANE SSubscription sub))
558+ verifyToken' t_ $ VRVerified (t_, NtfReqNew corrId (ANE SSubscription sub))
552559 Just s@ NtfSubData {tokenId = subTknId} ->
553560 if subTknId == tknId
554561 then do
555562 t_ <- atomically $ getActiveNtfToken st subTknId
556- verifyToken' t_ $ verifiedSubCmd s c
563+ verifyToken' t_ $ verifiedSubCmd t_ s c
557564 else pure $ maybe False (dummyVerifyCmd auth_ authorized) tAuth `seq` VRFailed
558- NtfCmd SSubscription PING -> pure $ VRVerified $ NtfReqPing corrId entId
565+ NtfCmd SSubscription PING -> pure $ VRVerified ( Nothing , NtfReqPing corrId entId)
559566 NtfCmd SSubscription c -> do
560- s_ <- atomically $ getNtfSubscription st entId
567+ s_ <- liftIO $ getNtfSubscriptionIO st entId
561568 case s_ of
562569 Just s@ NtfSubData {tokenId = subTknId} -> do
563570 t_ <- atomically $ getActiveNtfToken st subTknId
564- verifyToken' t_ $ verifiedSubCmd s c
571+ verifyToken' t_ $ verifiedSubCmd t_ s c
565572 _ -> pure $ maybe False (dummyVerifyCmd auth_ authorized) tAuth `seq` VRFailed
566573 where
567- verifiedTknCmd t c = VRVerified (NtfReqCmd SToken (NtfTkn t) (corrId, entId, c))
568- verifiedSubCmd s c = VRVerified (NtfReqCmd SSubscription (NtfSub s) (corrId, entId, c))
574+ verifiedTknCmd t c = VRVerified (Just t, NtfReqCmd SToken (NtfTkn t) (corrId, entId, c))
575+ verifiedSubCmd t_ s c = VRVerified (t_, NtfReqCmd SSubscription (NtfSub s) (corrId, entId, c))
569576 verifyToken :: Maybe NtfTknData -> (NtfTknData -> VerificationResult ) -> M VerificationResult
570577 verifyToken t_ positiveVerificationResult =
571578 pure $ case t_ of
@@ -579,11 +586,18 @@ verifyNtfTransmission auth_ (tAuth, authorized, (corrId, entId, _)) cmd = do
579586
580587client :: NtfServerClient -> NtfSubscriber -> NtfPushServer -> M ()
581588client NtfServerClient {rcvQ, sndQ} NtfSubscriber {newSubQ, smpAgent = ca} NtfPushServer {pushQ, intervalNotifiers} =
582- forever $
589+ forever $ do
590+ ts <- liftIO getSystemDate
583591 atomically (readTBQueue rcvQ)
584- >>= mapM processCommand
592+ >>= mapM ( \ (tkn_, req) -> updateTokenDate ts tkn_ >> processCommand req)
585593 >>= atomically . writeTBQueue sndQ
586594 where
595+ updateTokenDate :: RoundedSystemTime -> Maybe NtfTknData -> M ()
596+ updateTokenDate ts' = mapM_ $ \ NtfTknData {ntfTknId, tknUpdatedAt} -> do
597+ let t' = Just ts'
598+ t <- atomically $ swapTVar tknUpdatedAt t'
599+ unless (t' == t) $ withNtfLog $ \ s -> logUpdateTokenTime s ntfTknId ts'
600+
587601 processCommand :: NtfRequest -> M (Transmission NtfResponse )
588602 processCommand = \ case
589603 NtfReqNew corrId (ANE SToken newTkn@ (NewNtfTkn token _ dhPubKey)) -> do
@@ -593,7 +607,8 @@ client NtfServerClient {rcvQ, sndQ} NtfSubscriber {newSubQ, smpAgent = ca} NtfPu
593607 let dhSecret = C. dh' dhPubKey srvDhPrivKey
594608 tknId <- getId
595609 regCode <- getRegCode
596- tkn <- atomically $ mkNtfTknData tknId newTkn ks dhSecret regCode
610+ ts <- liftIO $ getSystemDate
611+ tkn <- liftIO $ mkNtfTknData tknId newTkn ks dhSecret regCode ts
597612 atomically $ addNtfToken st tknId tkn
598613 atomically $ writeTBQueue pushQ (tkn, PNVerification regCode)
599614 withNtfLog (`logCreateToken` tkn)
0 commit comments