core: add chat items to indicate decryption failures due to ratchets being out of sync (#2175)
* core: add chat items to indicate decryption failures due to ratchets being out of sync * show ratchet errors in chat items, show all integrity errors * show decryption errors, tests * ios: chat items, remove item for duplicate messages * android: decryption errors chat items * eol
This commit is contained in:
1 parent
13cf1cc004
commit
aea526f69d
21 files changed
+480
-75
No files matched your search
@@ -17,9 +17,11 @@ import qualified Data.ByteString.Lazy.Char8 as LB
|
||||
import Simplex.Chat.Call
|
||||
import Simplex.Chat.Controller (ChatConfig (..))
|
||||
import Simplex.Chat.Options (ChatOpts (..))
|
||||
import Simplex.Chat.Store (agentStoreFile, chatStoreFile)
|
||||
import Simplex.Chat.Types (authErrDisableCount, sameVerificationCode, verificationCode)
|
||||
import qualified Simplex.Messaging.Crypto as C
|
||||
import System.Directory (copyFile, doesDirectoryExist, doesFileExist)
|
||||
import System.FilePath ((</>))
|
||||
import Test.Hspec
|
||||
|
||||
chatDirectTests :: SpecWith FilePath
|
||||
@@ -79,6 +81,8 @@ chatDirectTests = do
|
||||
sameVerificationCode "123 456 789" "12345 6789" `shouldBe` True
|
||||
it "mark contact verified" testMarkContactVerified
|
||||
it "mark group member verified" testMarkGroupMemberVerified
|
||||
describe "message errors" $ do
|
||||
it "show message decryption error and update count" testMsgDecryptError
|
||||
|
||||
testAddContact :: HasCallStack => SpecWith FilePath
|
||||
testAddContact = versionTestMatrix2 runTestAddContact
|
||||
@@ -1763,3 +1767,49 @@ testMarkGroupMemberVerified =
|
||||
alice <## "member ID: 2"
|
||||
alice <## "receiving messages via: localhost"
|
||||
alice <## "sending messages via: localhost"
|
||||
|
||||
testMsgDecryptError :: HasCallStack => FilePath -> IO ()
|
||||
testMsgDecryptError tmp =
|
||||
withNewTestChat tmp "alice" aliceProfile $ \alice -> do
|
||||
withNewTestChat tmp "bob" bobProfile $ \bob -> do
|
||||
connectUsers alice bob
|
||||
alice #> "@bob hi"
|
||||
bob <# "alice> hi"
|
||||
bob #> "@alice hey"
|
||||
alice <# "bob> hey"
|
||||
copyDb "bob" "bob_old"
|
||||
withTestChat tmp "bob" $ \bob -> do
|
||||
bob <## "1 contacts connected (use /cs for the list)"
|
||||
alice #> "@bob hello"
|
||||
bob <# "alice> hello"
|
||||
bob #> "@alice hello too"
|
||||
alice <# "bob> hello too"
|
||||
withTestChat tmp "bob_old" $ \bob -> do
|
||||
bob <## "1 contacts connected (use /cs for the list)"
|
||||
alice #> "@bob 1"
|
||||
bob <# "alice> decryption error, possibly due to the device change (header)"
|
||||
alice #> "@bob 2"
|
||||
alice #> "@bob 3"
|
||||
(bob </)
|
||||
bob ##> "/tail @alice 1"
|
||||
bob <# "alice> decryption error, possibly due to the device change (header, 3 messages)"
|
||||
bob #> "@alice 1"
|
||||
alice <# "bob> decryption error, possibly due to the device change (header)"
|
||||
bob #> "@alice 2"
|
||||
bob #> "@alice 3"
|
||||
(alice </)
|
||||
alice ##> "/tail @bob 1"
|
||||
alice <# "bob> decryption error, possibly due to the device change (header, 3 messages)"
|
||||
alice #> "@bob 4"
|
||||
bob <# "alice> decryption error, possibly due to the device change (header)"
|
||||
withTestChat tmp "bob" $ \bob -> do
|
||||
bob <## "1 contacts connected (use /cs for the list)"
|
||||
alice #> "@bob hello again"
|
||||
bob <# "alice> skipped message ID 5..8"
|
||||
bob <# "alice> hello again"
|
||||
bob #> "@alice received!"
|
||||
alice <# "bob> received!"
|
||||
where
|
||||
copyDb from to = do
|
||||
copyFile (chatStoreFile $ tmp </> from) (chatStoreFile $ tmp </> to)
|
||||
copyFile (agentStoreFile $ tmp </> from) (agentStoreFile $ tmp </> to)
|
||||
@@ -9,7 +9,10 @@ import Control.Concurrent (threadDelay)
|
||||
import Control.Concurrent.Async (concurrently_)
|
||||
import Control.Monad (when)
|
||||
import qualified Data.Text as T
|
||||
import Simplex.Chat.Store (agentStoreFile, chatStoreFile)
|
||||
import Simplex.Chat.Types (GroupMemberRole (..))
|
||||
import System.Directory (copyFile)
|
||||
import System.FilePath ((</>))
|
||||
import Test.Hspec
|
||||
|
||||
chatGroupTests :: SpecWith FilePath
|
||||
@@ -48,6 +51,8 @@ chatGroupTests = do
|
||||
it "leaving groups with unused host contacts deletes incognito profiles" testGroupLinkIncognitoUnusedHostContactsDeleted
|
||||
it "group link member role" testGroupLinkMemberRole
|
||||
it "leaving and deleting the group joined via link should NOT delete previously existing direct contacts" testGroupLinkLeaveDelete
|
||||
describe "group message errors" $ do
|
||||
it "show message decryption error and update count" testGroupMsgDecryptError
|
||||
|
||||
testGroup :: HasCallStack => SpecWith FilePath
|
||||
testGroup = versionTestMatrix3 runTestGroup
|
||||
@@ -1986,3 +1991,76 @@ testGroupLinkLeaveDelete =
|
||||
bob ##> "/contacts"
|
||||
bob <## "alice (Alice)"
|
||||
bob <## "cath (Catherine)"
|
||||
|
||||
testGroupMsgDecryptError :: HasCallStack => FilePath -> IO ()
|
||||
testGroupMsgDecryptError tmp =
|
||||
withNewTestChat tmp "alice" aliceProfile $ \alice -> do
|
||||
withNewTestChat tmp "cath" cathProfile $ \cath -> do
|
||||
withNewTestChat tmp "bob" bobProfile $ \bob -> do
|
||||
createGroup3 "team" alice bob cath
|
||||
alice #> "#team hi"
|
||||
[bob, cath] *<# "#team alice> hi"
|
||||
bob #> "#team hey"
|
||||
[alice, cath] *<# "#team bob> hey"
|
||||
copyDb "bob" "bob_old"
|
||||
withTestChat tmp "bob" $ \bob -> do
|
||||
bob <## "2 contacts connected (use /cs for the list)"
|
||||
bob <## "#team: connected to server(s)"
|
||||
alice #> "#team hello"
|
||||
[bob, cath] *<# "#team alice> hello"
|
||||
bob #> "#team hello too"
|
||||
[alice, cath] *<# "#team bob> hello too"
|
||||
withTestChat tmp "bob_old" $ \bob -> do
|
||||
bob <## "2 contacts connected (use /cs for the list)"
|
||||
bob <## "#team: connected to server(s)"
|
||||
alice #> "#team 1"
|
||||
bob <# "#team alice> decryption error, possibly due to the device change (header)"
|
||||
cath <# "#team alice> 1"
|
||||
alice #> "#team 2"
|
||||
cath <# "#team alice> 2"
|
||||
alice #> "#team 3"
|
||||
cath <# "#team alice> 3"
|
||||
(bob </)
|
||||
bob ##> "/tail #team 1"
|
||||
bob <# "#team alice> decryption error, possibly due to the device change (header, 3 messages)"
|
||||
bob #> "#team 1"
|
||||
alice <# "#team bob> decryption error, possibly due to the device change (header)"
|
||||
-- cath <# "#team bob> 1"
|
||||
bob #> "#team 2"
|
||||
cath <# "#team bob> incorrect message hash"
|
||||
cath <# "#team bob> 2"
|
||||
bob #> "#team 3"
|
||||
cath <# "#team bob> 3"
|
||||
(alice </)
|
||||
alice ##> "/tail #team 1"
|
||||
alice <# "#team bob> decryption error, possibly due to the device change (header, 3 messages)"
|
||||
alice #> "#team 4"
|
||||
(bob </)
|
||||
cath <# "#team alice> 4"
|
||||
bob ##> "/tail #team 4"
|
||||
bob
|
||||
<##? [ "#team alice> decryption error, possibly due to the device change (header, 4 messages)",
|
||||
"#team 1",
|
||||
"#team 2",
|
||||
"#team 3"
|
||||
]
|
||||
withTestChat tmp "bob" $ \bob -> do
|
||||
bob <## "2 contacts connected (use /cs for the list)"
|
||||
bob <## "#team: connected to server(s)"
|
||||
alice #> "#team hello again"
|
||||
bob <# "#team alice> skipped message ID 8..11"
|
||||
[bob, cath] *<# "#team alice> hello again"
|
||||
bob #> "#team received!"
|
||||
alice <# "#team bob> received!"
|
||||
bob #> "#team 4"
|
||||
alice <# "#team bob> 4"
|
||||
bob #> "#team 5"
|
||||
cath <# "#team bob> decryption error, possibly due to the device change (earlier message, 2 messages)"
|
||||
cath <# "#team bob> incorrect message hash"
|
||||
[alice, cath] *<# "#team bob> 5"
|
||||
bob #> "#team 6"
|
||||
[alice, cath] *<# "#team bob> 6"
|
||||
where
|
||||
copyDb from to = do
|
||||
copyFile (chatStoreFile $ tmp </> from) (chatStoreFile $ tmp </> to)
|
||||
copyFile (agentStoreFile $ tmp </> from) (agentStoreFile $ tmp </> to)
|
||||
@@ -272,6 +272,9 @@ getInAnyOrder f cc ls = do
|
||||
(<#) :: HasCallStack => TestCC -> String -> Expectation
|
||||
cc <# line = (dropTime <$> getTermLine cc) `shouldReturn` line
|
||||
|
||||
(*<#) :: HasCallStack => [TestCC] -> String -> Expectation
|
||||
ccs *<# line = concurrentlyN_ $ map (<# line) ccs
|
||||
|
||||
(?<#) :: HasCallStack => TestCC -> String -> Expectation
|
||||
cc ?<# line = (dropTime <$> getTermLine cc) `shouldReturn` "i " <> line
|
||||
|
||||
|
||||
Reference in new issue
Block a user