diff --git a/bots/api/TYPES.md b/bots/api/TYPES.md index 3343a746a3..ec071e8c3a 100644 --- a/bots/api/TYPES.md +++ b/bots/api/TYPES.md @@ -951,9 +951,6 @@ NoRcvFileUser: UserUnknown: - type: "userUnknown" -ActiveUserExists: -- type: "activeUserExists" - UserExists: - type: "userExists" - contactName: string diff --git a/bots/src/API/Docs/Commands.hs b/bots/src/API/Docs/Commands.hs index 4cce44e588..114e7012c7 100644 --- a/bots/src/API/Docs/Commands.hs +++ b/bots/src/API/Docs/Commands.hs @@ -254,6 +254,7 @@ cliCommands = "SetAddressSettings", "SetBotCommands", "SetChatTTL", + "SetClientService", "SetContactFeature", "SetContactTimedMessages", "SetGroupFeature", diff --git a/bots/src/API/Docs/Events.hs b/bots/src/API/Docs/Events.hs index 4a49551a54..a53aa25541 100644 --- a/bots/src/API/Docs/Events.hs +++ b/bots/src/API/Docs/Events.hs @@ -180,6 +180,7 @@ undocumentedEvents = "CEvtGroupMemberSwitch", "CEvtHostConnected", "CEvtHostDisconnected", + "CEvtServiceSubStatus", "CEvtSubscriptionStatus", "CEvtNewRemoteHost", "CEvtNoMemberContactCreating", diff --git a/packages/simplex-chat-client/types/typescript/src/types.ts b/packages/simplex-chat-client/types/typescript/src/types.ts index 55bc6b1920..7ab77b8705 100644 --- a/packages/simplex-chat-client/types/typescript/src/types.ts +++ b/packages/simplex-chat-client/types/typescript/src/types.ts @@ -967,7 +967,6 @@ export type ChatErrorType = | ChatErrorType.NoSndFileUser | ChatErrorType.NoRcvFileUser | ChatErrorType.UserUnknown - | ChatErrorType.ActiveUserExists | ChatErrorType.UserExists | ChatErrorType.DifferentActiveUser | ChatErrorType.CantDeleteActiveUser @@ -1043,7 +1042,6 @@ export namespace ChatErrorType { | "noSndFileUser" | "noRcvFileUser" | "userUnknown" - | "activeUserExists" | "userExists" | "differentActiveUser" | "cantDeleteActiveUser" @@ -1139,10 +1137,6 @@ export namespace ChatErrorType { type: "userUnknown" } - export interface ActiveUserExists extends Interface { - type: "activeUserExists" - } - export interface UserExists extends Interface { type: "userExists" contactName: string diff --git a/src/Simplex/Chat/Store/SQLite/Migrations/agent_query_plans.txt b/src/Simplex/Chat/Store/SQLite/Migrations/agent_query_plans.txt index d1c8579e01..ca3803bc39 100644 --- a/src/Simplex/Chat/Store/SQLite/Migrations/agent_query_plans.txt +++ b/src/Simplex/Chat/Store/SQLite/Migrations/agent_query_plans.txt @@ -420,6 +420,17 @@ Plan: SCAN ntf_tokens_to_delete USE TEMP B-TREE FOR DISTINCT +Query: + SELECT c.service_cert_hash, c.service_cert, c.service_priv_key, c.service_id + FROM client_services c + JOIN servers s ON c.host = s.host AND c.port = s.port + WHERE c.user_id = ? AND c.host = ? AND c.port = ? + AND COALESCE(c.server_key_hash, s.key_hash) = ? + +Plan: +SEARCH s USING PRIMARY KEY (host=? AND port=?) +SEARCH c USING INDEX idx_server_certs_user_id_host_port (user_id=? AND host=? AND port=?) + Query: SELECT c.service_id, c.service_queue_count, c.service_queue_ids_hash FROM client_services c @@ -523,6 +534,19 @@ Query: Plan: SEARCH conn_confirmations USING COVERING INDEX idx_conn_confirmations_conn_id (conn_id=?) +Query: + INSERT INTO client_services + (user_id, host, port, server_key_hash, service_cert_hash, service_cert, service_priv_key) + VALUES (?,?,?,?,?,?,?) + ON CONFLICT (user_id, host, port, server_key_hash) + DO UPDATE SET + service_cert_hash = EXCLUDED.service_cert_hash, + service_cert = EXCLUDED.service_cert, + service_priv_key = EXCLUDED.service_priv_key, + service_id = NULL + +Plan: + Query: INSERT INTO connections (user_id, conn_id, conn_mode, smp_agent_version, enable_ntfs, pq_support, duplex_handshake) VALUES (?,?,?,?,?,?,?) @@ -655,6 +679,21 @@ Query: Plan: SEARCH snd_file_chunk_replica_recipients USING INDEX idx_snd_file_chunk_replica_recipients_snd_file_chunk_replica_id (snd_file_chunk_replica_id=?) +Query: + UPDATE client_services + SET service_id = ? + FROM servers s + WHERE client_services.user_id = ? + AND client_services.host = ? + AND client_services.port = ? + AND s.host = client_services.host + AND s.port = client_services.port + AND COALESCE(client_services.server_key_hash, s.key_hash) = ? + +Plan: +SEARCH s USING PRIMARY KEY (host=? AND port=?) +SEARCH client_services USING COVERING INDEX idx_server_certs_user_id_host_port (user_id=? AND host=? AND port=?) + Query: UPDATE conn_confirmations SET accepted = 1, @@ -744,6 +783,16 @@ Query: Plan: SEARCH rcv_queues USING PRIMARY KEY (host=? AND port=? AND rcv_id=?) +Query: + UPDATE rcv_queues + SET rcv_service_assoc = 0 + FROM connections c + WHERE c.conn_id = rcv_queues.conn_id AND c.user_id = ? + +Plan: +SEARCH c USING COVERING INDEX idx_connections_user (user_id=?) +SEARCH rcv_queues USING COVERING INDEX idx_rcv_queue_id (conn_id=?) + Query: UPDATE rcv_queues SET status = ? @@ -898,6 +947,18 @@ SEARCH s USING PRIMARY KEY (host=? AND port=?) SEARCH q USING PRIMARY KEY (host=? AND port=?) SEARCH c USING PRIMARY KEY (conn_id=?) +Query: + SELECT c.user_id, q.conn_id, q.host, q.port, COALESCE(q.server_key_hash, s.key_hash), q.rcv_id, q.rcv_private_key, q.status, c.enable_ntfs, q.client_notice_id, + q.rcv_queue_id, q.rcv_primary, q.replace_rcv_queue_id + FROM rcv_queues q + JOIN servers s ON q.host = s.host AND q.port = s.port + JOIN connections c ON q.conn_id = c.conn_id + WHERE c.deleted = 0 AND q.deleted = 0 AND c.user_id = ? AND q.host = ? AND q.port = ? AND COALESCE(q.server_key_hash, s.key_hash) = ? AND q.rcv_service_assoc = 0 +Plan: +SEARCH s USING PRIMARY KEY (host=? AND port=?) +SEARCH q USING PRIMARY KEY (host=? AND port=?) +SEARCH c USING PRIMARY KEY (conn_id=?) + Query: SELECT c.user_id, q.conn_id, q.host, q.port, COALESCE(q.server_key_hash, s.key_hash), q.rcv_id, q.rcv_private_key, q.status, c.enable_ntfs, q.client_notice_id, q.rcv_queue_id, q.rcv_primary, q.replace_rcv_queue_id @@ -910,6 +971,10 @@ SEARCH q USING INDEX idx_rcv_queues_to_subscribe (to_subscribe=? AND host=? AND SEARCH c USING PRIMARY KEY (conn_id=?) SEARCH s USING PRIMARY KEY (host=? AND port=?) +Query: DELETE FROM client_services WHERE user_id = ? +Plan: +SEARCH client_services USING COVERING INDEX idx_server_certs_user_id_host_port (user_id=?) + Query: DELETE FROM commands WHERE command_id = ? Plan: SEARCH commands USING INTEGER PRIMARY KEY (rowid=?) @@ -1255,6 +1320,10 @@ Query: UPDATE rcv_queues SET rcv_primary = ?, replace_rcv_queue_id = ? WHERE con Plan: SEARCH rcv_queues USING COVERING INDEX idx_rcv_queue_id (conn_id=? AND rcv_queue_id=?) +Query: UPDATE rcv_queues SET rcv_service_assoc = 1 WHERE rcv_id = ? +Plan: +SCAN rcv_queues USING COVERING INDEX idx_rcv_queues_client_notice_id + Query: UPDATE rcv_queues SET to_subscribe = 0 WHERE to_subscribe = 1 Plan: SEARCH rcv_queues USING COVERING INDEX idx_rcv_queues_to_subscribe (to_subscribe=?) diff --git a/src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt b/src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt index d4eb821a41..f920cda23f 100644 --- a/src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt +++ b/src/Simplex/Chat/Store/SQLite/Migrations/chat_query_plans.txt @@ -4866,6 +4866,14 @@ Query: Plan: SEARCH user_contact_links USING INTEGER PRIMARY KEY (rowid=?) +Query: + UPDATE users + SET client_service = ? + WHERE user_id = ? + +Plan: +SEARCH users USING INTEGER PRIMARY KEY (rowid=?) + Query: UPDATE users SET view_pwd_hash = ?, view_pwd_salt = ?, show_ntfs = ? diff --git a/tests/ChatClient.hs b/tests/ChatClient.hs index adcc3955af..c574a1e8f2 100644 --- a/tests/ChatClient.hs +++ b/tests/ChatClient.hs @@ -429,9 +429,11 @@ testChatN :: HasCallStack => ChatConfig -> ChatOpts -> [Profile] -> (HasCallStac testChatN cfg opts ps test params = bracket (getTestCCs $ zip ps [1 ..]) endTests test where + useClientServices = False + -- useClientServices = True getTestCCs :: [(Profile, Int)] -> IO [TestCC] getTestCCs [] = pure [] - getTestCCs ((p, db) : envs') = (:) <$> createTestChat params cfg opts (show db) False p <*> getTestCCs envs' + getTestCCs ((p, db) : envs') = (:) <$> createTestChat params cfg opts (show db) useClientServices p <*> getTestCCs envs' endTests tcs = do mapConcurrently_ (