core: api to abort connection switch; update simplexmq (#2544)
This commit is contained in:
parent
46c6f5e615
commit
6d3cb0ea2e
@ -7,7 +7,7 @@ constraints: zip +disable-bzip2 +disable-zstd
|
|||||||
source-repository-package
|
source-repository-package
|
||||||
type: git
|
type: git
|
||||||
location: https://github.com/simplex-chat/simplexmq.git
|
location: https://github.com/simplex-chat/simplexmq.git
|
||||||
tag: 89caf5572980b776bd750caa3c918ae4488612d8
|
tag: 2efe1496d2622a56656a6a00a2cc19005e754468
|
||||||
|
|
||||||
source-repository-package
|
source-repository-package
|
||||||
type: git
|
type: git
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"https://github.com/simplex-chat/simplexmq.git"."89caf5572980b776bd750caa3c918ae4488612d8" = "0glils00403s4xxl84xa22wylfsrcpjj5j3v7srqhrmikm1jds4p";
|
"https://github.com/simplex-chat/simplexmq.git"."2efe1496d2622a56656a6a00a2cc19005e754468" = "0syy10zn3ci1nbs00r0l5vhvqkwlqcgmmd5c196pch0xvrk5qbfi";
|
||||||
"https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38";
|
"https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38";
|
||||||
"https://github.com/kazu-yamamoto/http2.git"."b5a1b7200cf5bc7044af34ba325284271f6dff25" = "0dqb50j57an64nf4qcf5vcz4xkd1vzvghvf8bk529c1k30r9nfzb";
|
"https://github.com/kazu-yamamoto/http2.git"."b5a1b7200cf5bc7044af34ba325284271f6dff25" = "0dqb50j57an64nf4qcf5vcz4xkd1vzvghvf8bk529c1k30r9nfzb";
|
||||||
"https://github.com/simplex-chat/direct-sqlcipher.git"."34309410eb2069b029b8fc1872deb1e0db123294" = "0kwkmhyfsn2lixdlgl15smgr1h5gjk7fky6abzh8rng2h5ymnffd";
|
"https://github.com/simplex-chat/direct-sqlcipher.git"."34309410eb2069b029b8fc1872deb1e0db123294" = "0kwkmhyfsn2lixdlgl15smgr1h5gjk7fky6abzh8rng2h5ymnffd";
|
||||||
|
@ -1110,6 +1110,17 @@ processChatCommand = \case
|
|||||||
case memberConnId m of
|
case memberConnId m of
|
||||||
Just connId -> withAgent (\a -> switchConnectionAsync a "" connId) >> ok user
|
Just connId -> withAgent (\a -> switchConnectionAsync a "" connId) >> ok user
|
||||||
_ -> throwChatError CEGroupMemberNotActive
|
_ -> throwChatError CEGroupMemberNotActive
|
||||||
|
APIAbortSwitchContact contactId -> withUser $ \user -> do
|
||||||
|
ct <- withStore $ \db -> getContact db user contactId
|
||||||
|
connectionStats <- withAgent $ \a -> abortConnectionSwitch a $ contactConnId ct
|
||||||
|
pure $ CRContactSwitchAborted user ct connectionStats
|
||||||
|
APIAbortSwitchGroupMember gId gMemberId -> withUser $ \user -> do
|
||||||
|
(g, m) <- withStore $ \db -> (,) <$> getGroupInfo db user gId <*> getGroupMember db user gId gMemberId
|
||||||
|
case memberConnId m of
|
||||||
|
Just connId -> do
|
||||||
|
connectionStats <- withAgent $ \a -> abortConnectionSwitch a connId
|
||||||
|
pure $ CRGroupMemberSwitchAborted user g m connectionStats
|
||||||
|
_ -> throwChatError CEGroupMemberNotActive
|
||||||
APIGetContactCode contactId -> withUser $ \user -> do
|
APIGetContactCode contactId -> withUser $ \user -> do
|
||||||
ct@Contact {activeConn = conn@Connection {connId}} <- withStore $ \db -> getContact db user contactId
|
ct@Contact {activeConn = conn@Connection {connId}} <- withStore $ \db -> getContact db user contactId
|
||||||
code <- getConnectionCode (contactConnId ct)
|
code <- getConnectionCode (contactConnId ct)
|
||||||
@ -1164,6 +1175,8 @@ processChatCommand = \case
|
|||||||
GroupMemberInfo gName mName -> withMemberName gName mName APIGroupMemberInfo
|
GroupMemberInfo gName mName -> withMemberName gName mName APIGroupMemberInfo
|
||||||
SwitchContact cName -> withContactName cName APISwitchContact
|
SwitchContact cName -> withContactName cName APISwitchContact
|
||||||
SwitchGroupMember gName mName -> withMemberName gName mName APISwitchGroupMember
|
SwitchGroupMember gName mName -> withMemberName gName mName APISwitchGroupMember
|
||||||
|
AbortSwitchContact cName -> withContactName cName APIAbortSwitchContact
|
||||||
|
AbortSwitchGroupMember gName mName -> withMemberName gName mName APIAbortSwitchGroupMember
|
||||||
GetContactCode cName -> withContactName cName APIGetContactCode
|
GetContactCode cName -> withContactName cName APIGetContactCode
|
||||||
GetGroupMemberCode gName mName -> withMemberName gName mName APIGetGroupMemberCode
|
GetGroupMemberCode gName mName -> withMemberName gName mName APIGetGroupMemberCode
|
||||||
VerifyContact cName code -> withContactName cName (`APIVerifyContact` code)
|
VerifyContact cName code -> withContactName cName (`APIVerifyContact` code)
|
||||||
@ -2810,7 +2823,7 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do
|
|||||||
_ -> pure ()
|
_ -> pure ()
|
||||||
SWITCH qd phase cStats -> do
|
SWITCH qd phase cStats -> do
|
||||||
toView $ CRContactSwitch user ct (SwitchProgress qd phase cStats)
|
toView $ CRContactSwitch user ct (SwitchProgress qd phase cStats)
|
||||||
when (phase /= SPConfirmed) $ case qd of
|
when (phase `elem` [SPStarted, SPCompleted]) $ case qd of
|
||||||
QDRcv -> createInternalChatItem user (CDDirectSnd ct) (CISndConnEvent $ SCESwitchQueue phase Nothing) Nothing
|
QDRcv -> createInternalChatItem user (CDDirectSnd ct) (CISndConnEvent $ SCESwitchQueue phase Nothing) Nothing
|
||||||
QDSnd -> createInternalChatItem user (CDDirectRcv ct) (CIRcvConnEvent $ RCESwitchQueue phase) Nothing
|
QDSnd -> createInternalChatItem user (CDDirectRcv ct) (CIRcvConnEvent $ RCESwitchQueue phase) Nothing
|
||||||
OK ->
|
OK ->
|
||||||
@ -2989,7 +3002,7 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do
|
|||||||
checkSndInlineFTComplete conn msgId
|
checkSndInlineFTComplete conn msgId
|
||||||
SWITCH qd phase cStats -> do
|
SWITCH qd phase cStats -> do
|
||||||
toView $ CRGroupMemberSwitch user gInfo m (SwitchProgress qd phase cStats)
|
toView $ CRGroupMemberSwitch user gInfo m (SwitchProgress qd phase cStats)
|
||||||
when (phase /= SPConfirmed) $ case qd of
|
when (phase `elem` [SPStarted, SPCompleted]) $ case qd of
|
||||||
QDRcv -> createInternalChatItem user (CDGroupSnd gInfo) (CISndConnEvent . SCESwitchQueue phase . Just $ groupMemberRef m) Nothing
|
QDRcv -> createInternalChatItem user (CDGroupSnd gInfo) (CISndConnEvent . SCESwitchQueue phase . Just $ groupMemberRef m) Nothing
|
||||||
QDSnd -> createInternalChatItem user (CDGroupRcv gInfo m) (CIRcvConnEvent $ RCESwitchQueue phase) Nothing
|
QDSnd -> createInternalChatItem user (CDGroupRcv gInfo m) (CIRcvConnEvent $ RCESwitchQueue phase) Nothing
|
||||||
OK ->
|
OK ->
|
||||||
@ -4858,8 +4871,12 @@ chatCommandP =
|
|||||||
("/info " <|> "/i ") *> char_ '@' *> (ContactInfo <$> displayName),
|
("/info " <|> "/i ") *> char_ '@' *> (ContactInfo <$> displayName),
|
||||||
"/_switch #" *> (APISwitchGroupMember <$> A.decimal <* A.space <*> A.decimal),
|
"/_switch #" *> (APISwitchGroupMember <$> A.decimal <* A.space <*> A.decimal),
|
||||||
"/_switch @" *> (APISwitchContact <$> A.decimal),
|
"/_switch @" *> (APISwitchContact <$> A.decimal),
|
||||||
|
"/_abort switch #" *> (APIAbortSwitchGroupMember <$> A.decimal <* A.space <*> A.decimal),
|
||||||
|
"/_abort switch @" *> (APIAbortSwitchContact <$> A.decimal),
|
||||||
"/switch #" *> (SwitchGroupMember <$> displayName <* A.space <* char_ '@' <*> displayName),
|
"/switch #" *> (SwitchGroupMember <$> displayName <* A.space <* char_ '@' <*> displayName),
|
||||||
"/switch " *> char_ '@' *> (SwitchContact <$> displayName),
|
"/switch " *> char_ '@' *> (SwitchContact <$> displayName),
|
||||||
|
"/abort switch #" *> (AbortSwitchGroupMember <$> displayName <* A.space <* char_ '@' <*> displayName),
|
||||||
|
"/abort switch " *> char_ '@' *> (AbortSwitchContact <$> displayName),
|
||||||
"/_get code @" *> (APIGetContactCode <$> A.decimal),
|
"/_get code @" *> (APIGetContactCode <$> A.decimal),
|
||||||
"/_get code #" *> (APIGetGroupMemberCode <$> A.decimal <* A.space <*> A.decimal),
|
"/_get code #" *> (APIGetGroupMemberCode <$> A.decimal <* A.space <*> A.decimal),
|
||||||
"/_verify code @" *> (APIVerifyContact <$> A.decimal <*> optional (A.space *> textP)),
|
"/_verify code @" *> (APIVerifyContact <$> A.decimal <*> optional (A.space *> textP)),
|
||||||
|
@ -284,6 +284,8 @@ data ChatCommand
|
|||||||
| APIGroupMemberInfo GroupId GroupMemberId
|
| APIGroupMemberInfo GroupId GroupMemberId
|
||||||
| APISwitchContact ContactId
|
| APISwitchContact ContactId
|
||||||
| APISwitchGroupMember GroupId GroupMemberId
|
| APISwitchGroupMember GroupId GroupMemberId
|
||||||
|
| APIAbortSwitchContact ContactId
|
||||||
|
| APIAbortSwitchGroupMember GroupId GroupMemberId
|
||||||
| APIGetContactCode ContactId
|
| APIGetContactCode ContactId
|
||||||
| APIGetGroupMemberCode GroupId GroupMemberId
|
| APIGetGroupMemberCode GroupId GroupMemberId
|
||||||
| APIVerifyContact ContactId (Maybe Text)
|
| APIVerifyContact ContactId (Maybe Text)
|
||||||
@ -295,6 +297,8 @@ data ChatCommand
|
|||||||
| GroupMemberInfo GroupName ContactName
|
| GroupMemberInfo GroupName ContactName
|
||||||
| SwitchContact ContactName
|
| SwitchContact ContactName
|
||||||
| SwitchGroupMember GroupName ContactName
|
| SwitchGroupMember GroupName ContactName
|
||||||
|
| AbortSwitchContact ContactName
|
||||||
|
| AbortSwitchGroupMember GroupName ContactName
|
||||||
| GetContactCode ContactName
|
| GetContactCode ContactName
|
||||||
| GetGroupMemberCode GroupName ContactName
|
| GetGroupMemberCode GroupName ContactName
|
||||||
| VerifyContact ContactName (Maybe Text)
|
| VerifyContact ContactName (Maybe Text)
|
||||||
@ -403,6 +407,8 @@ data ChatResponse
|
|||||||
| CRNetworkConfig {networkConfig :: NetworkConfig}
|
| CRNetworkConfig {networkConfig :: NetworkConfig}
|
||||||
| CRContactInfo {user :: User, contact :: Contact, connectionStats :: ConnectionStats, customUserProfile :: Maybe Profile}
|
| CRContactInfo {user :: User, contact :: Contact, connectionStats :: ConnectionStats, customUserProfile :: Maybe Profile}
|
||||||
| CRGroupMemberInfo {user :: User, groupInfo :: GroupInfo, member :: GroupMember, connectionStats_ :: Maybe ConnectionStats}
|
| CRGroupMemberInfo {user :: User, groupInfo :: GroupInfo, member :: GroupMember, connectionStats_ :: Maybe ConnectionStats}
|
||||||
|
| CRContactSwitchAborted {user :: User, contact :: Contact, connectionStats :: ConnectionStats}
|
||||||
|
| CRGroupMemberSwitchAborted {user :: User, groupInfo :: GroupInfo, member :: GroupMember, connectionStats :: ConnectionStats}
|
||||||
| CRContactSwitch {user :: User, contact :: Contact, switchProgress :: SwitchProgress}
|
| CRContactSwitch {user :: User, contact :: Contact, switchProgress :: SwitchProgress}
|
||||||
| CRGroupMemberSwitch {user :: User, groupInfo :: GroupInfo, member :: GroupMember, switchProgress :: SwitchProgress}
|
| CRGroupMemberSwitch {user :: User, groupInfo :: GroupInfo, member :: GroupMember, switchProgress :: SwitchProgress}
|
||||||
| CRContactCode {user :: User, contact :: Contact, connectionCode :: Text}
|
| CRContactCode {user :: User, contact :: Contact, connectionCode :: Text}
|
||||||
|
@ -383,14 +383,18 @@ sndGroupEventToText = \case
|
|||||||
rcvConnEventToText :: RcvConnEvent -> Text
|
rcvConnEventToText :: RcvConnEvent -> Text
|
||||||
rcvConnEventToText = \case
|
rcvConnEventToText = \case
|
||||||
RCESwitchQueue phase -> case phase of
|
RCESwitchQueue phase -> case phase of
|
||||||
|
SPStarted -> "started changing address for you..."
|
||||||
|
SPConfirmed -> "confirmed changing address for you..."
|
||||||
|
SPSecured -> "secured new address for you..."
|
||||||
SPCompleted -> "changed address for you"
|
SPCompleted -> "changed address for you"
|
||||||
_ -> decodeLatin1 (strEncode phase) <> " changing address for you..."
|
|
||||||
|
|
||||||
sndConnEventToText :: SndConnEvent -> Text
|
sndConnEventToText :: SndConnEvent -> Text
|
||||||
sndConnEventToText = \case
|
sndConnEventToText = \case
|
||||||
SCESwitchQueue phase m -> case phase of
|
SCESwitchQueue phase m -> case phase of
|
||||||
|
SPStarted -> "started changing address" <> forMember m <> "..."
|
||||||
|
SPConfirmed -> "confirmed changing address" <> forMember m <> "..."
|
||||||
|
SPSecured -> "secured new address" <> forMember m <> "..."
|
||||||
SPCompleted -> "you changed address" <> forMember m
|
SPCompleted -> "you changed address" <> forMember m
|
||||||
_ -> decodeLatin1 (strEncode phase) <> " changing address" <> forMember m <> "..."
|
|
||||||
where
|
where
|
||||||
forMember member_ =
|
forMember member_ =
|
||||||
maybe "" (\GroupMemberRef {profile = Profile {displayName}} -> " for " <> displayName) member_
|
maybe "" (\GroupMemberRef {profile = Profile {displayName}} -> " for " <> displayName) member_
|
||||||
|
@ -47,6 +47,7 @@ import qualified Simplex.FileTransfer.Protocol as XFTP
|
|||||||
import Simplex.Messaging.Agent.Client (ProtocolTestFailure (..), ProtocolTestStep (..))
|
import Simplex.Messaging.Agent.Client (ProtocolTestFailure (..), ProtocolTestStep (..))
|
||||||
import Simplex.Messaging.Agent.Env.SQLite (NetworkConfig (..))
|
import Simplex.Messaging.Agent.Env.SQLite (NetworkConfig (..))
|
||||||
import Simplex.Messaging.Agent.Protocol
|
import Simplex.Messaging.Agent.Protocol
|
||||||
|
import Simplex.Messaging.Agent.Store (canAbortRcvSwitch)
|
||||||
import qualified Simplex.Messaging.Crypto as C
|
import qualified Simplex.Messaging.Crypto as C
|
||||||
import Simplex.Messaging.Encoding
|
import Simplex.Messaging.Encoding
|
||||||
import Simplex.Messaging.Encoding.String
|
import Simplex.Messaging.Encoding.String
|
||||||
@ -80,6 +81,8 @@ responseToView user_ ChatConfig {logLevel, showReactions, testView} liveItems ts
|
|||||||
CRNetworkConfig cfg -> viewNetworkConfig cfg
|
CRNetworkConfig cfg -> viewNetworkConfig cfg
|
||||||
CRContactInfo u ct cStats customUserProfile -> ttyUser u $ viewContactInfo ct cStats customUserProfile
|
CRContactInfo u ct cStats customUserProfile -> ttyUser u $ viewContactInfo ct cStats customUserProfile
|
||||||
CRGroupMemberInfo u g m cStats -> ttyUser u $ viewGroupMemberInfo g m cStats
|
CRGroupMemberInfo u g m cStats -> ttyUser u $ viewGroupMemberInfo g m cStats
|
||||||
|
CRContactSwitchAborted {} -> ["switch aborted"]
|
||||||
|
CRGroupMemberSwitchAborted {} -> ["switch aborted"]
|
||||||
CRContactSwitch u ct progress -> ttyUser u $ viewContactSwitch ct progress
|
CRContactSwitch u ct progress -> ttyUser u $ viewContactSwitch ct progress
|
||||||
CRGroupMemberSwitch u g m progress -> ttyUser u $ viewGroupMemberSwitch g m progress
|
CRGroupMemberSwitch u g m progress -> ttyUser u $ viewGroupMemberSwitch g m progress
|
||||||
CRConnectionVerified u verified code -> ttyUser u [plain $ if verified then "connection verified" else "connection not verified, current code is " <> code]
|
CRConnectionVerified u verified code -> ttyUser u [plain $ if verified then "connection verified" else "connection not verified, current code is " <> code]
|
||||||
@ -918,24 +921,46 @@ viewConnectionVerified (Just _) = "connection verified" -- TODO show verificatio
|
|||||||
viewConnectionVerified _ = "connection not verified, use " <> highlight' "/code" <> " command to see security code"
|
viewConnectionVerified _ = "connection not verified, use " <> highlight' "/code" <> " command to see security code"
|
||||||
|
|
||||||
viewConnectionStats :: ConnectionStats -> [StyledString]
|
viewConnectionStats :: ConnectionStats -> [StyledString]
|
||||||
viewConnectionStats ConnectionStats {rcvServers, sndServers} =
|
viewConnectionStats ConnectionStats {rcvQueuesInfo, sndQueuesInfo} =
|
||||||
["receiving messages via: " <> viewServerHosts rcvServers | not $ null rcvServers]
|
["receiving messages via: " <> viewRcvQueuesInfo rcvQueuesInfo | not $ null rcvQueuesInfo]
|
||||||
<> ["sending messages via: " <> viewServerHosts sndServers | not $ null sndServers]
|
<> ["sending messages via: " <> viewSndQueuesInfo sndQueuesInfo | not $ null sndQueuesInfo]
|
||||||
|
|
||||||
viewServers :: ProtocolTypeI p => (a -> ProtoServerWithAuth p) -> NonEmpty a -> [StyledString]
|
viewServers :: ProtocolTypeI p => (a -> ProtoServerWithAuth p) -> NonEmpty a -> [StyledString]
|
||||||
viewServers f = map (plain . B.unpack . strEncode . f) . L.toList
|
viewServers f = map (plain . B.unpack . strEncode . f) . L.toList
|
||||||
|
|
||||||
viewServerHosts :: [SMPServer] -> StyledString
|
viewRcvQueuesInfo :: [RcvQueueInfo] -> StyledString
|
||||||
viewServerHosts = plain . intercalate ", " . map showSMPServer
|
viewRcvQueuesInfo = plain . intercalate ", " . map showQueueInfo
|
||||||
|
where
|
||||||
|
showQueueInfo RcvQueueInfo {rcvServer, rcvSwitchStatus, canAbortSwitch} =
|
||||||
|
let switchCanBeAborted = if canAbortSwitch then ", can be aborted" else ""
|
||||||
|
in showSMPServer rcvServer
|
||||||
|
<> maybe "" (\s -> " (" <> showSwitchStatus s <> switchCanBeAborted <> ")") rcvSwitchStatus
|
||||||
|
showSwitchStatus = \case
|
||||||
|
RSSwitchStarted -> "switch started"
|
||||||
|
RSSendingQADD -> "switch started"
|
||||||
|
RSSendingQUSE -> "switch confirmed"
|
||||||
|
RSReceivedMessage -> "switch secured"
|
||||||
|
|
||||||
|
viewSndQueuesInfo :: [SndQueueInfo] -> StyledString
|
||||||
|
viewSndQueuesInfo = plain . intercalate ", " . map showQueueInfo
|
||||||
|
where
|
||||||
|
showQueueInfo SndQueueInfo {sndServer, sndSwitchStatus} =
|
||||||
|
showSMPServer sndServer
|
||||||
|
<> maybe "" (\s -> " (" <> showSwitchStatus s <> ")") sndSwitchStatus
|
||||||
|
showSwitchStatus = \case
|
||||||
|
SSSendingQKEY -> "switch started"
|
||||||
|
SSSendingQTEST -> "switch secured"
|
||||||
|
|
||||||
viewContactSwitch :: Contact -> SwitchProgress -> [StyledString]
|
viewContactSwitch :: Contact -> SwitchProgress -> [StyledString]
|
||||||
viewContactSwitch _ (SwitchProgress _ SPConfirmed _) = []
|
viewContactSwitch _ (SwitchProgress _ SPConfirmed _) = []
|
||||||
|
viewContactSwitch _ (SwitchProgress _ SPSecured _) = []
|
||||||
viewContactSwitch ct (SwitchProgress qd phase _) = case qd of
|
viewContactSwitch ct (SwitchProgress qd phase _) = case qd of
|
||||||
QDRcv -> [ttyContact' ct <> ": you " <> viewSwitchPhase phase]
|
QDRcv -> [ttyContact' ct <> ": you " <> viewSwitchPhase phase]
|
||||||
QDSnd -> [ttyContact' ct <> " " <> viewSwitchPhase phase <> " for you"]
|
QDSnd -> [ttyContact' ct <> " " <> viewSwitchPhase phase <> " for you"]
|
||||||
|
|
||||||
viewGroupMemberSwitch :: GroupInfo -> GroupMember -> SwitchProgress -> [StyledString]
|
viewGroupMemberSwitch :: GroupInfo -> GroupMember -> SwitchProgress -> [StyledString]
|
||||||
viewGroupMemberSwitch _ _ (SwitchProgress _ SPConfirmed _) = []
|
viewGroupMemberSwitch _ _ (SwitchProgress _ SPConfirmed _) = []
|
||||||
|
viewGroupMemberSwitch _ _ (SwitchProgress _ SPSecured _) = []
|
||||||
viewGroupMemberSwitch g m (SwitchProgress qd phase _) = case qd of
|
viewGroupMemberSwitch g m (SwitchProgress qd phase _) = case qd of
|
||||||
QDRcv -> [ttyGroup' g <> ": you " <> viewSwitchPhase phase <> " for " <> ttyMember m]
|
QDRcv -> [ttyGroup' g <> ": you " <> viewSwitchPhase phase <> " for " <> ttyMember m]
|
||||||
QDSnd -> [ttyGroup' g <> ": " <> ttyMember m <> " " <> viewSwitchPhase phase <> " for you"]
|
QDSnd -> [ttyGroup' g <> ": " <> ttyMember m <> " " <> viewSwitchPhase phase <> " for you"]
|
||||||
@ -952,8 +977,11 @@ viewSecurityCode name cmd code testView
|
|||||||
| otherwise = [name <> " security code:", plain code, "pass this code to your contact and use " <> highlight cmd <> " to verify"]
|
| otherwise = [name <> " security code:", plain code, "pass this code to your contact and use " <> highlight cmd <> " to verify"]
|
||||||
|
|
||||||
viewSwitchPhase :: SwitchPhase -> StyledString
|
viewSwitchPhase :: SwitchPhase -> StyledString
|
||||||
viewSwitchPhase SPCompleted = "changed address"
|
viewSwitchPhase = \case
|
||||||
viewSwitchPhase phase = plain (strEncode phase) <> " changing address"
|
SPStarted -> "started changing address"
|
||||||
|
SPConfirmed -> "confirmed changing address"
|
||||||
|
SPSecured -> "secured new address"
|
||||||
|
SPCompleted -> "changed address"
|
||||||
|
|
||||||
viewUserProfileUpdated :: Profile -> Profile -> [StyledString]
|
viewUserProfileUpdated :: Profile -> Profile -> [StyledString]
|
||||||
viewUserProfileUpdated Profile {displayName = n, fullName, image, contactLink, preferences} Profile {displayName = n', fullName = fullName', image = image', contactLink = contactLink', preferences = prefs'} =
|
viewUserProfileUpdated Profile {displayName = n, fullName, image, contactLink, preferences} Profile {displayName = n', fullName = fullName', image = image', contactLink = contactLink', preferences = prefs'} =
|
||||||
@ -1478,6 +1506,7 @@ viewChatError logLevel = \case
|
|||||||
DBErrorOpen e -> ["error opening database after encryption: " <> sqliteError' e]
|
DBErrorOpen e -> ["error opening database after encryption: " <> sqliteError' e]
|
||||||
e -> ["chat database error: " <> sShow e]
|
e -> ["chat database error: " <> sShow e]
|
||||||
ChatErrorAgent err entity_ -> case err of
|
ChatErrorAgent err entity_ -> case err of
|
||||||
|
CMD PROHIBITED -> [withConnEntity <> "error: command is prohibited"]
|
||||||
SMP SMP.AUTH ->
|
SMP SMP.AUTH ->
|
||||||
[ withConnEntity
|
[ withConnEntity
|
||||||
<> "error: connection authorization failed - this could happen if connection was deleted,\
|
<> "error: connection authorization failed - this could happen if connection was deleted,\
|
||||||
|
@ -49,7 +49,7 @@ extra-deps:
|
|||||||
# - simplexmq-1.0.0@sha256:34b2004728ae396e3ae449cd090ba7410781e2b3cefc59259915f4ca5daa9ea8,8561
|
# - simplexmq-1.0.0@sha256:34b2004728ae396e3ae449cd090ba7410781e2b3cefc59259915f4ca5daa9ea8,8561
|
||||||
# - ../simplexmq
|
# - ../simplexmq
|
||||||
- github: simplex-chat/simplexmq
|
- github: simplex-chat/simplexmq
|
||||||
commit: 89caf5572980b776bd750caa3c918ae4488612d8
|
commit: 2efe1496d2622a56656a6a00a2cc19005e754468
|
||||||
- github: kazu-yamamoto/http2
|
- github: kazu-yamamoto/http2
|
||||||
commit: b5a1b7200cf5bc7044af34ba325284271f6dff25
|
commit: b5a1b7200cf5bc7044af34ba325284271f6dff25
|
||||||
# - ../direct-sqlcipher
|
# - ../direct-sqlcipher
|
||||||
|
@ -73,9 +73,11 @@ chatDirectTests = do
|
|||||||
it "user profile privacy: hide profiles and notificaitons" testUserPrivacy
|
it "user profile privacy: hide profiles and notificaitons" testUserPrivacy
|
||||||
describe "chat item expiration" $ do
|
describe "chat item expiration" $ do
|
||||||
it "set chat item TTL" testSetChatItemTTL
|
it "set chat item TTL" testSetChatItemTTL
|
||||||
describe "queue rotation" $ do
|
describe "connection switch" $ do
|
||||||
it "switch contact to a different queue" testSwitchContact
|
it "switch contact to a different queue" testSwitchContact
|
||||||
|
it "stop switching contact to a different queue" testAbortSwitchContact
|
||||||
it "switch group member to a different queue" testSwitchGroupMember
|
it "switch group member to a different queue" testSwitchGroupMember
|
||||||
|
it "stop switching group member to a different queue" testAbortSwitchGroupMember
|
||||||
describe "connection verification code" $ do
|
describe "connection verification code" $ do
|
||||||
it "verificationCode function converts ByteString to series of digits" $ \_ ->
|
it "verificationCode function converts ByteString to series of digits" $ \_ ->
|
||||||
verificationCode (C.sha256Hash "abcd") `shouldBe` "61889 38426 63934 09576 96390 79389 84124 85253 63658 69469 70853 37788 95900 68296 20156 25"
|
verificationCode (C.sha256Hash "abcd") `shouldBe` "61889 38426 63934 09576 96390 79389 84124 85253 63658 69469 70853 37788 95900 68296 20156 25"
|
||||||
@ -1845,6 +1847,33 @@ testSwitchContact =
|
|||||||
bob #$> ("/_get chat @2 count=100", chat, chatFeatures <> [(0, "started changing address for you..."), (0, "changed address for you")])
|
bob #$> ("/_get chat @2 count=100", chat, chatFeatures <> [(0, "started changing address for you..."), (0, "changed address for you")])
|
||||||
alice <##> bob
|
alice <##> bob
|
||||||
|
|
||||||
|
testAbortSwitchContact :: HasCallStack => FilePath -> IO ()
|
||||||
|
testAbortSwitchContact tmp = do
|
||||||
|
withNewTestChat tmp "alice" aliceProfile $ \alice -> do
|
||||||
|
withNewTestChat tmp "bob" bobProfile $ \bob -> do
|
||||||
|
connectUsers alice bob
|
||||||
|
alice #$> ("/switch bob", id, "ok")
|
||||||
|
alice <## "bob: you started changing address"
|
||||||
|
-- repeat switch is prohibited
|
||||||
|
alice ##> "/switch bob"
|
||||||
|
alice <## "error: command is prohibited"
|
||||||
|
-- stop switch
|
||||||
|
alice #$> ("/abort switch bob", id, "switch aborted")
|
||||||
|
-- repeat switch stop is prohibited
|
||||||
|
alice ##> "/abort switch bob"
|
||||||
|
alice <## "error: command is prohibited"
|
||||||
|
withTestChatContactConnected tmp "bob" $ \bob -> do
|
||||||
|
bob <## "alice started changing address for you"
|
||||||
|
-- alice changes address again
|
||||||
|
alice #$> ("/switch bob", id, "ok")
|
||||||
|
alice <## "bob: you started changing address"
|
||||||
|
bob <## "alice started changing address for you"
|
||||||
|
bob <## "alice changed address for you"
|
||||||
|
alice <## "bob: you changed address"
|
||||||
|
alice #$> ("/_get chat @2 count=100", chat, chatFeatures <> [(1, "started changing address..."), (1, "started changing address..."), (1, "you changed address")])
|
||||||
|
bob #$> ("/_get chat @2 count=100", chat, chatFeatures <> [(0, "started changing address for you..."), (0, "started changing address for you..."), (0, "changed address for you")])
|
||||||
|
alice <##> bob
|
||||||
|
|
||||||
testSwitchGroupMember :: HasCallStack => FilePath -> IO ()
|
testSwitchGroupMember :: HasCallStack => FilePath -> IO ()
|
||||||
testSwitchGroupMember =
|
testSwitchGroupMember =
|
||||||
testChat2 aliceProfile bobProfile $
|
testChat2 aliceProfile bobProfile $
|
||||||
@ -1862,6 +1891,37 @@ testSwitchGroupMember =
|
|||||||
bob #> "#team hi"
|
bob #> "#team hi"
|
||||||
alice <# "#team bob> hi"
|
alice <# "#team bob> hi"
|
||||||
|
|
||||||
|
testAbortSwitchGroupMember :: HasCallStack => FilePath -> IO ()
|
||||||
|
testAbortSwitchGroupMember tmp = do
|
||||||
|
withNewTestChat tmp "alice" aliceProfile $ \alice -> do
|
||||||
|
withNewTestChat tmp "bob" bobProfile $ \bob -> do
|
||||||
|
createGroup2 "team" alice bob
|
||||||
|
alice #$> ("/switch #team bob", id, "ok")
|
||||||
|
alice <## "#team: you started changing address for bob"
|
||||||
|
-- repeat switch is prohibited
|
||||||
|
alice ##> "/switch #team bob"
|
||||||
|
alice <## "error: command is prohibited"
|
||||||
|
-- stop switch
|
||||||
|
alice #$> ("/abort switch #team bob", id, "switch aborted")
|
||||||
|
-- repeat switch stop is prohibited
|
||||||
|
alice ##> "/abort switch #team bob"
|
||||||
|
alice <## "error: command is prohibited"
|
||||||
|
withTestChatContactConnected tmp "bob" $ \bob -> do
|
||||||
|
bob <## "#team: connected to server(s)"
|
||||||
|
bob <## "#team: alice started changing address for you"
|
||||||
|
-- alice changes address again
|
||||||
|
alice #$> ("/switch #team bob", id, "ok")
|
||||||
|
alice <## "#team: you started changing address for bob"
|
||||||
|
bob <## "#team: alice started changing address for you"
|
||||||
|
bob <## "#team: alice changed address for you"
|
||||||
|
alice <## "#team: you changed address for bob"
|
||||||
|
alice #$> ("/_get chat #1 count=100", chat, [(0, "connected"), (1, "started changing address for bob..."), (1, "started changing address for bob..."), (1, "you changed address for bob")])
|
||||||
|
bob #$> ("/_get chat #1 count=100", chat, groupFeatures <> [(0, "connected"), (0, "started changing address for you..."), (0, "started changing address for you..."), (0, "changed address for you")])
|
||||||
|
alice #> "#team hey"
|
||||||
|
bob <# "#team alice> hey"
|
||||||
|
bob #> "#team hi"
|
||||||
|
alice <# "#team bob> hi"
|
||||||
|
|
||||||
testMarkContactVerified :: HasCallStack => FilePath -> IO ()
|
testMarkContactVerified :: HasCallStack => FilePath -> IO ()
|
||||||
testMarkContactVerified =
|
testMarkContactVerified =
|
||||||
testChat2 aliceProfile bobProfile $ \alice bob -> do
|
testChat2 aliceProfile bobProfile $ \alice bob -> do
|
||||||
|
Loading…
Reference in New Issue
Block a user