cli: add --relay-address-server option for chat relay

New CLI flag --relay-address-server SERVER selects the SMP server used
for the chat relay address link created at startup. Only valid together
with --relay; errors out otherwise.

Threads Maybe SMPServerWithAuth through APICreateMyAddress to the new
agent createConnection parameter.
This commit is contained in:
shum
2026-05-04 12:27:49 +00:00
parent 45e4e23aa4
commit 8d45c2cca9
5 changed files with 29 additions and 16 deletions
+2 -2
View File
@@ -87,7 +87,7 @@ import Simplex.Messaging.Crypto.Ratchet (PQEncryption)
import Simplex.Messaging.Encoding.String
import Simplex.Messaging.Notifications.Protocol (DeviceToken (..), NtfTknStatus)
import Simplex.Messaging.Parsers (defaultJSON, dropPrefix, enumJSON, parseAll, parseString, sumTypeJSON)
import Simplex.Messaging.Protocol (AProtoServerWithAuth, AProtocolType (..), MsgId, NMsgMeta (..), NtfServer, ProtocolType (..), QueueId, SMPMsgMeta (..), SubscriptionMode (..), XFTPServer)
import Simplex.Messaging.Protocol (AProtoServerWithAuth, AProtocolType (..), MsgId, NMsgMeta (..), NtfServer, ProtocolType (..), QueueId, SMPMsgMeta (..), SMPServerWithAuth, SubscriptionMode (..), XFTPServer)
import Simplex.Messaging.TMap (TMap)
import Simplex.Messaging.Transport (TLS, TransportPeer (..), simplexMQVersion)
import Simplex.Messaging.Transport.Client (SocksProxyWithAuth, TransportHost)
@@ -488,7 +488,7 @@ data ChatCommand
| ClearContact ContactName
| APIListContacts {userId :: UserId}
| ListContacts
| APICreateMyAddress {userId :: UserId}
| APICreateMyAddress {userId :: UserId, srv_ :: Maybe SMPServerWithAuth}
| CreateMyAddress
| APIDeleteMyAddress {userId :: UserId}
| DeleteMyAddress
+5 -5
View File
@@ -69,11 +69,11 @@ simplexChatCore cfg@ChatConfig {confirmMigrations, testView, chatHooks} opts@Cha
exitFailure
runSimplexChat :: ChatConfig -> ChatOpts -> User -> ChatController -> (User -> ChatController -> IO ()) -> IO ()
runSimplexChat ChatConfig {testView} ChatOpts {coreOptions = CoreChatOpts {chatRelay, maintenance}} u cc@ChatController {config = ChatConfig {chatHooks}} chat
runSimplexChat ChatConfig {testView} ChatOpts {coreOptions = CoreChatOpts {chatRelay, chatRelayServer, maintenance}} u cc@ChatController {config = ChatConfig {chatHooks}} chat
| maintenance = wait =<< async (chat u cc)
| otherwise = do
a1 <- runReaderT (startChatController True True) cc
when (chatRelay && not testView) $ askCreateRelayAddress cc u
when (chatRelay && not testView) $ askCreateRelayAddress cc u chatRelayServer
forM_ (postStartHook chatHooks) ($ cc)
a2 <- async $ chat u cc
waitEither_ a1 a2
@@ -144,8 +144,8 @@ createActiveUser cc CoreChatOpts {chatRelay} = \case
Right (CRActiveUser user) -> pure user
r -> printResponseEvent (Nothing, Nothing) (config cc) r >> onError
askCreateRelayAddress :: ChatController -> User -> IO ()
askCreateRelayAddress cc@ChatController {chatStore} user =
askCreateRelayAddress :: ChatController -> User -> Maybe SMPServerWithAuth -> IO ()
askCreateRelayAddress cc@ChatController {chatStore} user@User {userId} srv_ =
withTransaction chatStore (\db -> runExceptT $ getUserAddress db user) >>= \case
Right _ -> pure ()
Left SEUserContactLinkNotFound -> promptCreate
@@ -155,7 +155,7 @@ askCreateRelayAddress cc@ChatController {chatStore} user =
promptCreate = do
ok <- onOffPrompt "Create relay address" True
when ok $
execChatCommand' CreateMyAddress 0 `runReaderT` cc >>= \case
execChatCommand' (APICreateMyAddress userId srv_) 0 `runReaderT` cc >>= \case
Right (CRUserContactLinkCreated _ address) -> do
putStrLn "Chat relay address is created:"
putStrLn $ addressStr address
+9 -9
View File
@@ -1929,7 +1929,7 @@ processChatCommand vr nm = \case
let userData = contactShortLinkData (userProfileDirect user incognitoProfile Nothing True) Nothing
userLinkData = UserInvLinkData userData
-- TODO [certs rcv]
(connId, (ccLink, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) True False SCMInvitation (Just userLinkData) Nothing IKPQOn subMode
(connId, (ccLink, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) True False SCMInvitation (Just userLinkData) Nothing Nothing IKPQOn subMode
ccLink' <- shortenCreatedLink ccLink
-- TODO PQ pass minVersion from the current range
conn <- withFastStore' $ \db -> createDirectConnection db user connId ccLink' Nothing ConnNew incognitoProfile subMode initialChatVersion PQSupportOn
@@ -1971,7 +1971,7 @@ processChatCommand vr nm = \case
| short = Just $ UserInvLinkData $ contactShortLinkData (userProfileDirect newUser Nothing Nothing True) Nothing
| otherwise = Nothing
-- TODO [certs rcv]
(agConnId, (ccLink, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId newUser) True False SCMInvitation userLinkData_ Nothing IKPQOn subMode
(agConnId, (ccLink, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId newUser) True False SCMInvitation userLinkData_ Nothing Nothing IKPQOn subMode
ccLink' <- shortenCreatedLink ccLink
conn' <- withFastStore' $ \db -> do
deleteConnectionRecord db user connId
@@ -2253,7 +2253,7 @@ processChatCommand vr nm = \case
CRContactsList user <$> withFastStore' (\db -> getUserContacts db vr user)
ListContacts -> withUser $ \User {userId} ->
processChatCommand vr nm $ APIListContacts userId
APICreateMyAddress userId -> withUserId userId $ \user@User {userChatRelay} -> do
APICreateMyAddress userId srv_ -> withUserId userId $ \user@User {userChatRelay} -> do
withFastStore' (\db -> runExceptT $ getUserAddress db user) >>= \case
Left SEUserContactLinkNotFound -> pure ()
Left e -> throwError $ ChatErrorStore e
@@ -2265,13 +2265,13 @@ processChatCommand vr nm = \case
| otherwise = contactShortLinkData (userProfileDirect user Nothing Nothing True) Nothing
userLinkData = UserContactLinkData UserContactData {direct = True, owners = [], relays = [], userData}
-- TODO [certs rcv]
(connId, (ccLink, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) True True SCMContact (Just userLinkData) Nothing IKPQOn subMode
(connId, (ccLink, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) True True SCMContact (Just userLinkData) Nothing srv_ IKPQOn subMode
ccLink' <- shortenCreatedLink ccLink
let ccLink'' = if isTrue userChatRelay then setShortLinkType CCTRelay ccLink' else ccLink'
withFastStore $ \db -> createUserContactLink db user connId ccLink'' subMode
pure $ CRUserContactLinkCreated user ccLink''
CreateMyAddress -> withUser $ \User {userId} ->
processChatCommand vr nm $ APICreateMyAddress userId
processChatCommand vr nm $ APICreateMyAddress userId Nothing
APIDeleteMyAddress userId -> withUserId userId $ \user@User {profile = p} -> do
conn <- withFastStore $ \db -> getUserAddressConnection db vr user
withChatLock "deleteMyAddress" $ do
@@ -2565,7 +2565,7 @@ processChatCommand vr nm = \case
gVar <- asks random
subMode <- chatReadVar subscriptionMode
-- TODO [certs rcv]
(agentConnId, (CCLink cReq _, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) True False SCMInvitation Nothing Nothing IKPQOff subMode
(agentConnId, (CCLink cReq _, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) True False SCMInvitation Nothing Nothing Nothing IKPQOff subMode
member <- withFastStore $ \db -> createNewContactMember db gVar user gInfo contact memRole agentConnId cReq subMode
sendInvitation member cReq
pure $ CRSentGroupInvitation user gInfo contact member
@@ -3006,7 +3006,7 @@ processChatCommand vr nm = \case
userLinkData = UserContactLinkData UserContactData {direct = True, owners = [], relays = [], userData}
crClientData = encodeJSON $ CRDataGroup groupLinkId
-- TODO [certs rcv]
(connId, (ccLink, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) True True SCMContact (Just userLinkData) (Just crClientData) IKPQOff subMode
(connId, (ccLink, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) True True SCMContact (Just userLinkData) (Just crClientData) Nothing IKPQOff subMode
ccLink' <- setShortLinkType CCTGroup <$> shortenCreatedLink ccLink
gVar <- asks random
gLink <- withFastStore $ \db -> createGroupLink db gVar user gInfo connId ccLink' groupLinkId mRole subMode
@@ -3047,7 +3047,7 @@ processChatCommand vr nm = \case
subMode <- chatReadVar subscriptionMode
-- TODO PQ should negotitate contact connection with PQSupportOn?
-- TODO [certs rcv]
(connId, (CCLink cReq _, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) True False SCMInvitation Nothing Nothing IKPQOff subMode
(connId, (CCLink cReq _, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) True False SCMInvitation Nothing Nothing Nothing IKPQOff subMode
-- [incognito] reuse membership incognito profile
ct <- withFastStore' $ \db -> createMemberContact db user connId cReq g m mConn subMode
void $ createChatItem user (CDDirectSnd ct) False CIChatBanner Nothing (Just epochStart)
@@ -5113,7 +5113,7 @@ chatCommandP =
("/fstatus " <|> "/fs ") *> (FileStatus <$> A.decimal),
"/_connect contact " *> (APIConnectContactViaAddress <$> A.decimal <*> incognitoOnOffP <* A.space <*> A.decimal),
"/simplex" *> (ConnectSimplex <$> incognitoP),
"/_address " *> (APICreateMyAddress <$> A.decimal),
"/_address " *> (APICreateMyAddress <$> A.decimal <*> optional (A.space *> strP)),
("/address" <|> "/ad") $> CreateMyAddress,
"/_delete_address " *> (APIDeleteMyAddress <$> A.decimal),
("/delete_address" <|> "/da") $> DeleteMyAddress,
+1
View File
@@ -254,6 +254,7 @@ mobileChatOpts dbOptions =
tbqSize = 4096,
deviceName = Nothing,
chatRelay = False,
chatRelayServer = Nothing,
highlyAvailable = False,
yesToUpMigrations = False,
migrationBackupPath = Just "",
+12
View File
@@ -66,6 +66,7 @@ data CoreChatOpts = CoreChatOpts
tbqSize :: Natural,
deviceName :: Maybe Text,
chatRelay :: Bool,
chatRelayServer :: Maybe SMPServerWithAuth,
highlyAvailable :: Bool,
yesToUpMigrations :: Bool,
migrationBackupPath :: Maybe FilePath,
@@ -239,6 +240,14 @@ coreChatOptsP appDir defaultDbName = do
( long "relay"
<> help "Run as a chat relay client"
)
chatRelayServer <-
optional $
option
strParse
( long "relay-address-server"
<> metavar "SERVER"
<> help "SMP server to use for chat relay address link (requires --relay)"
)
highlyAvailable <-
switch
( long "ha"
@@ -282,6 +291,9 @@ coreChatOptsP appDir defaultDbName = do
tbqSize,
deviceName,
chatRelay,
chatRelayServer = case chatRelayServer of
Just _ | not chatRelay -> error "--relay-address-server option requires --relay option"
_ -> chatRelayServer,
highlyAvailable,
yesToUpMigrations,
migrationBackupPath,