diff --git a/cabal.project b/cabal.project index c66e079518..ac367016fe 100644 --- a/cabal.project +++ b/cabal.project @@ -21,7 +21,7 @@ constraints: zip +disable-bzip2 +disable-zstd source-repository-package type: git location: https://github.com/simplex-chat/simplexmq.git - tag: 551de8039fbfcbc75d8e2685a4c631a55ae28fb2 + tag: e7f483cf64ad5d44700c85cee9f1ba1c29946a20 source-repository-package type: git diff --git a/src/Simplex/Chat/Controller.hs b/src/Simplex/Chat/Controller.hs index 48f4ec9eec..277b6c3f14 100644 --- a/src/Simplex/Chat/Controller.hs +++ b/src/Simplex/Chat/Controller.hs @@ -90,7 +90,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) @@ -546,7 +546,7 @@ data ChatCommand | ClearContact ContactName | APIListContacts {userId :: UserId} | ListContacts - | APICreateMyAddress {userId :: UserId} + | APICreateMyAddress {userId :: UserId, srv_ :: Maybe SMPServerWithAuth} | CreateMyAddress | APIDeleteMyAddress {userId :: UserId} | DeleteMyAddress diff --git a/src/Simplex/Chat/Core.hs b/src/Simplex/Chat/Core.hs index cc3e49beb6..db5bdda5fd 100644 --- a/src/Simplex/Chat/Core.hs +++ b/src/Simplex/Chat/Core.hs @@ -73,11 +73,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 @@ -146,8 +146,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 @@ -157,7 +157,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 diff --git a/src/Simplex/Chat/Library/Commands.hs b/src/Simplex/Chat/Library/Commands.hs index 18ca626a46..ee1667821a 100644 --- a/src/Simplex/Chat/Library/Commands.hs +++ b/src/Simplex/Chat/Library/Commands.hs @@ -2328,7 +2328,7 @@ processChatCommand cxt nm = \case CRContactsList user <$> withFastStore' (\db -> getUserContacts db cxt user) ListContacts -> withUser $ \User {userId} -> processChatCommand cxt 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 @@ -2337,7 +2337,7 @@ processChatCommand cxt nm = \case gVar <- asks random rootKey@(rootPubKey, rootPrivKey) <- liftIO $ atomically $ C.generateKeyPair gVar let entityId = C.sha256Hash $ C.pubKeyBytes rootPubKey - (ccLink, preparedParams) <- withAgent $ \a -> prepareConnectionLink a (aUserId user) rootKey entityId True Nothing + (ccLink, preparedParams) <- withAgent $ \a -> prepareConnectionLink a (aUserId user) rootKey entityId True Nothing srv_ ccLink' <- shortenCreatedLink ccLink -- TODO [relays] relay: add identity, key to link data? userData <- @@ -2350,7 +2350,7 @@ processChatCommand cxt nm = \case withFastStore $ \db -> createUserContactLink db user connId ccLink'' subMode rootPrivKey pure $ CRUserContactLinkCreated user ccLink'' CreateMyAddress -> withUser $ \User {userId} -> - processChatCommand cxt nm $ APICreateMyAddress userId + processChatCommand cxt nm $ APICreateMyAddress userId Nothing APIDeleteMyAddress userId -> withUserId userId $ \user@User {profile = p} -> do conn <- withFastStore $ \db -> getUserAddressConnection db cxt user withChatLock "deleteMyAddress" $ do @@ -2596,7 +2596,7 @@ processChatCommand cxt nm = \case let entityId = C.sha256Hash $ C.pubKeyBytes rootPubKey crClientData = encodeJSON $ CRDataGroup groupLinkId -- prepare link with entityId as linkEntityId (no server request) - (ccLink, preparedParams) <- withAgent $ \a -> prepareConnectionLink a (aUserId user) rootKey entityId True (Just crClientData) + (ccLink, preparedParams) <- withAgent $ \a -> prepareConnectionLink a (aUserId user) rootKey entityId True (Just crClientData) Nothing ccLink' <- setShortLinkType CCTChannel <$> shortenCreatedLink ccLink sLnk <- case connShortLink' ccLink' of Just sl -> pure sl @@ -5546,7 +5546,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, diff --git a/src/Simplex/Chat/Library/Subscriber.hs b/src/Simplex/Chat/Library/Subscriber.hs index 52d70f1fae..63d049d472 100644 --- a/src/Simplex/Chat/Library/Subscriber.hs +++ b/src/Simplex/Chat/Library/Subscriber.hs @@ -4419,7 +4419,7 @@ runRelayRequestWorker a Worker {doWork} = do sigKeys <- liftIO $ atomically $ C.generateKeyPair gVar let crClientData = encodeJSON $ CRDataGroup groupLinkId -- prepare link with relayMemId as linkEntityId (no server request) - (ccLink, preparedParams) <- withAgent $ \a' -> prepareConnectionLink a' (aUserId user) sigKeys relayMemId True (Just crClientData) + (ccLink, preparedParams) <- withAgent $ \a' -> prepareConnectionLink a' (aUserId user) sigKeys relayMemId True (Just crClientData) Nothing ccLink' <- setShortLinkType CCTGroup <$> shortenCreatedLink ccLink sLnk <- case connShortLink' ccLink' of Just sl -> pure sl diff --git a/src/Simplex/Chat/Mobile.hs b/src/Simplex/Chat/Mobile.hs index 85074e93f4..502d02c940 100644 --- a/src/Simplex/Chat/Mobile.hs +++ b/src/Simplex/Chat/Mobile.hs @@ -262,6 +262,7 @@ mobileChatOpts dbOptions = deviceName = Nothing, chatRelay = False, webPreviewConfig = Nothing, + chatRelayServer = Nothing, highlyAvailable = False, yesToUpMigrations = False, migrationBackupPath = Just "", diff --git a/src/Simplex/Chat/Options.hs b/src/Simplex/Chat/Options.hs index a936f58848..f52bb2f15e 100644 --- a/src/Simplex/Chat/Options.hs +++ b/src/Simplex/Chat/Options.hs @@ -67,6 +67,7 @@ data CoreChatOpts = CoreChatOpts deviceName :: Maybe Text, chatRelay :: Bool, webPreviewConfig :: Maybe WebPreviewConfig, + chatRelayServer :: Maybe SMPServerWithAuth, highlyAvailable :: Bool, yesToUpMigrations :: Bool, migrationBackupPath :: Maybe FilePath, @@ -281,6 +282,14 @@ coreChatOptsP appDir defaultDbName = do (Just webDomain, Just webJsonDir) -> Just WebPreviewConfig {webDomain, webJsonDir, webCorsFile, webUpdateInterval, webPreviewItemCount} (Nothing, Nothing) -> Nothing _ -> errorWithoutStackTrace "--relay-web-domain and --relay-web-dir must both be provided" + 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" @@ -325,6 +334,9 @@ coreChatOptsP appDir defaultDbName = do deviceName, chatRelay, webPreviewConfig, + chatRelayServer = case chatRelayServer of + Just _ | not chatRelay -> error "--relay-address-server option requires --relay option" + _ -> chatRelayServer, highlyAvailable, yesToUpMigrations, migrationBackupPath,