Send your own messages
Adds a `chat-id` field in `content` map. The reason it has been added to the map instead of augmenting transit is that it would simplify the calculation of `message-id`, which in this case is consistent for both old & new clients. `chat-id` also represents the `chat-id` with respect of the sender, as in 1-to-1 chats that is asymmetric. Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
parent
4f401908c4
commit
693eae9cf9
2
.env
2
.env
|
@ -9,7 +9,7 @@ POW_TIME=1
|
|||
DEFAULT_NETWORK=mainnet_rpc
|
||||
DEBUG_WEBVIEW=1
|
||||
GROUP_CHATS_ENABLED=1
|
||||
PAIRING_ENABLED=0
|
||||
PAIRING_ENABLED=1
|
||||
CACHED_WEBVIEWS_ENABLED=1
|
||||
EXTENSIONS=1
|
||||
HARDWALLET_ENABLED=0
|
||||
|
|
|
@ -13,4 +13,4 @@ MAINNET_WARNING_ENABLED=1
|
|||
CACHED_WEBVIEWS_ENABLED=1
|
||||
EXTENSIONS=1
|
||||
PFS_ENCRYPTION_ENABLED=0
|
||||
PAIRING_ENABLED=0
|
||||
PAIRING_ENABLED=1
|
||||
|
|
|
@ -9,7 +9,7 @@ POW_TIME=1
|
|||
DEFAULT_NETWORK=mainnet_rpc
|
||||
DEBUG_WEBVIEW=1
|
||||
GROUP_CHATS_ENABLED=1
|
||||
PAIRING_ENABLED=0
|
||||
PAIRING_ENABLED=1
|
||||
MAINNET_WARNING_ENABLED=1
|
||||
EXTENSIONS=1
|
||||
PFS_ENCRYPTION_ENABLED=0
|
||||
|
|
6
Makefile
6
Makefile
|
@ -51,14 +51,14 @@ _prepare-mobile: ##@prepare Install mobile platform dependencies and prepare wor
|
|||
npm install
|
||||
|
||||
$(STATUS_GO_IOS_ARCH):
|
||||
cd $(RCTSTATUS_DIR) && curl -OL "$(GITHUB_URL)/v$(STATUS_GO_VER)/status-go-ios-$(STATUS_GO_VER).zip"
|
||||
cd $(RCTSTATUS_DIR) && curl -OL "$(GITHUB_URL)/$(STATUS_GO_VER)/status-go-ios.zip"
|
||||
|
||||
$(STATUS_GO_DRO_ARCH):
|
||||
mkdir -p $(ANDROID_LIBS_DIR)
|
||||
cd $(ANDROID_LIBS_DIR) && curl -OL "$(GITHUB_URL)/v$(STATUS_GO_VER)/status-go-$(STATUS_GO_VER).aar"
|
||||
cd $(ANDROID_LIBS_DIR) && curl -o status-go-$(STATUS_GO_VER).aar -OL "$(GITHUB_URL)/$(STATUS_GO_VER)/status-go-android.aar"
|
||||
|
||||
prepare-ios: $(STATUS_GO_IOS_ARCH) _prepare-mobile ##@prepare Install and prepare iOS-specific dependencies
|
||||
cd $(RCTSTATUS_DIR) && unzip -q -o status-go-ios-$(STATUS_GO_VER).zip
|
||||
cd $(RCTSTATUS_DIR) && unzip -q -o status-go-ios.zip
|
||||
ifeq ($(OS),Darwin)
|
||||
cd ios && pod install
|
||||
endif
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.16.4-4-gaf1f6eb5
|
||||
v0.16.3-9-g27700aa2
|
||||
|
|
|
@ -706,7 +706,6 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
|||
StatusThreadPoolExecutor.getInstance().execute(r);
|
||||
}
|
||||
|
||||
|
||||
@ReactMethod
|
||||
public void signGroupMembership(final String content, final Callback callback) {
|
||||
Log.d(TAG, "signGroupMembership");
|
||||
|
@ -727,6 +726,46 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
|||
StatusThreadPoolExecutor.getInstance().execute(r);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void enableInstallation(final String installationId, final Callback callback) {
|
||||
Log.d(TAG, "enableInstallation");
|
||||
if (!checkAvailability()) {
|
||||
callback.invoke(false);
|
||||
return;
|
||||
}
|
||||
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String result = Statusgo.EnableInstallation(installationId);
|
||||
|
||||
callback.invoke(result);
|
||||
}
|
||||
};
|
||||
|
||||
StatusThreadPoolExecutor.getInstance().execute(r);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void disableInstallation(final String installationId, final Callback callback) {
|
||||
Log.d(TAG, "disableInstallation");
|
||||
if (!checkAvailability()) {
|
||||
callback.invoke(false);
|
||||
return;
|
||||
}
|
||||
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String result = Statusgo.DisableInstallation(installationId);
|
||||
|
||||
callback.invoke(result);
|
||||
}
|
||||
};
|
||||
|
||||
StatusThreadPoolExecutor.getInstance().execute(r);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable
|
||||
Map<String, Object> getConstants() {
|
||||
|
|
|
@ -38,7 +38,7 @@ file (STRINGS "../../../STATUS_GO_VERSION" STATUS_GO_VERSION)
|
|||
ExternalProject_Add(StatusGo_ep
|
||||
PREFIX ${StatusGo_PREFIX}
|
||||
SOURCE_DIR ${StatusGo_SOURCE_DIR}
|
||||
URL https://github.com/status-im/status-go/releases/download/v${STATUS_GO_VERSION}/status-go-desktop-${STATUS_GO_VERSION}.zip
|
||||
URL https://github.com/status-im/status-go/releases/download/${STATUS_GO_VERSION}/status-go-desktop.zip
|
||||
BUILD_BYPRODUCTS ${StatusGo_STATIC_LIB}
|
||||
CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/${CONFIGURE_SCRIPT} ${GO_ROOT_PATH} ${StatusGo_ROOT} ${StatusGo_SOURCE_DIR}
|
||||
BUILD_COMMAND ""
|
||||
|
|
|
@ -215,6 +215,22 @@ void RCTStatus::extractGroupMembershipSignatures(QString signatures, double call
|
|||
}, signatures, callbackId);
|
||||
}
|
||||
|
||||
void RCTStatus::enableInstallation(QString installationId, double callbackId) {
|
||||
Q_D(RCTStatus);
|
||||
QtConcurrent::run([&](QString installationId, double callbackId) {
|
||||
const char* result = EnableInstallation(installationId.toUtf8().data());
|
||||
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
||||
}, installationId, callbackId);
|
||||
}
|
||||
|
||||
void RCTStatus::disableInstallation(QString installationId, double callbackId) {
|
||||
Q_D(RCTStatus);
|
||||
QtConcurrent::run([&](QString installationId, double callbackId) {
|
||||
const char* result = DisableInstallation(installationId.toUtf8().data());
|
||||
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
||||
}, installationId, callbackId);
|
||||
}
|
||||
|
||||
void RCTStatus::setAdjustResize() {
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,8 @@ public:
|
|||
Q_INVOKABLE void signMessage(QString rpcParams, double callbackId);
|
||||
Q_INVOKABLE void signGroupMembership(QString content, double callbackId);
|
||||
Q_INVOKABLE void extractGroupMembershipSignatures(QString signatures, double callbackId);
|
||||
Q_INVOKABLE void enableInstallation(QString installationId, double callbackId);
|
||||
Q_INVOKABLE void disableInstallation(QString installationId, double callbackId);
|
||||
|
||||
Q_INVOKABLE void setAdjustResize();
|
||||
Q_INVOKABLE void setAdjustPan();
|
||||
|
|
|
@ -277,6 +277,30 @@ RCT_EXPORT_METHOD(extractGroupMembershipSignatures:(NSString *)content
|
|||
callback(@[[NSString stringWithUTF8String: result]]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#pragma mark - EnableInstallation
|
||||
//////////////////////////////////////////////////////////////////// enableInstallation
|
||||
RCT_EXPORT_METHOD(enableInstallation:(NSString *)content
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"EnableInstallation() method called");
|
||||
#endif
|
||||
char * result = EnableInstallation((char *) [content UTF8String]);
|
||||
callback(@[[NSString stringWithUTF8String: result]]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#pragma mark - DisableInstallation
|
||||
//////////////////////////////////////////////////////////////////// disableInstallation
|
||||
RCT_EXPORT_METHOD(disableInstallation:(NSString *)content
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"DisableInstallation() method called");
|
||||
#endif
|
||||
char * result = DisableInstallation((char *) [content UTF8String]);
|
||||
callback(@[[NSString stringWithUTF8String: result]]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#pragma mark - only android methods
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
(protocol/enhance-send-parameters type parameter-map cofx))]
|
||||
{:chat-id chat-id
|
||||
:content-type constants/content-type-command
|
||||
:content {:command-path command-path
|
||||
:content {:chat-id chat-id
|
||||
:command-path command-path
|
||||
:params (or new-parameter-map parameter-map)}}))
|
||||
|
||||
(fx/defn validate-and-send
|
||||
|
|
|
@ -126,7 +126,8 @@
|
|||
{:db (assoc-in db [:chats current-chat-id :metadata :responding-to-message] nil)}
|
||||
(chat.message/send-message {:chat-id current-chat-id
|
||||
:content-type constants/content-type-text
|
||||
:content (cond-> {:text input-text}
|
||||
:content (cond-> {:chat-id current-chat-id
|
||||
:text input-text}
|
||||
reply-to-message
|
||||
(assoc :response-to reply-to-message))})
|
||||
(commands.input/set-command-reference nil)
|
||||
|
|
|
@ -103,7 +103,8 @@
|
|||
(update-in [:chats chat-id :messages] assoc message-id prepared-message)
|
||||
;; this will increase last-clock-value twice when sending our own messages
|
||||
(update-in [:chats chat-id :last-clock-value] (partial utils.clocks/receive clock-value)))
|
||||
(not current-chat?)
|
||||
(and (not current-chat?)
|
||||
(not= from (:current-public-key db)))
|
||||
(update-in [:chats chat-id :unviewed-messages] (fnil conj #{}) message-id))
|
||||
:data-store/tx [(messages-store/save-message-tx prepared-message)]}]
|
||||
(if batch?
|
||||
|
@ -193,18 +194,20 @@
|
|||
:accumulated []}
|
||||
messages)))
|
||||
|
||||
(defn valid-chat-id? [cofx {:keys [chat-id from message-type]}]
|
||||
"Validate chat-id and message-type"
|
||||
(case message-type
|
||||
:group-user-message (get-in cofx [:db :chats chat-id :contacts from])
|
||||
:public-group-user-message (get-in cofx [:db :chats chat-id :public?])
|
||||
:user-message (or (= (get-in cofx [:db :current-public-key]) from)
|
||||
(= chat-id from))
|
||||
false))
|
||||
(defn extract-chat-id [cofx {:keys [chat-id from message-type]}]
|
||||
"Validate and return a valid chat-id"
|
||||
(cond
|
||||
(and (= :group-user-message message-type)
|
||||
(get-in cofx [:db :chats chat-id :contacts from])) chat-id
|
||||
(and (= :public-group-user-message message-type)
|
||||
(get-in cofx [:db :chats chat-id :public?])) chat-id
|
||||
(and (= :user-message message-type)
|
||||
(= (get-in cofx [:db :current-public-key]) from)) chat-id
|
||||
(= :user-message message-type) from))
|
||||
|
||||
(fx/defn receive-many
|
||||
[{:keys [now] :as cofx} messages]
|
||||
(let [valid-messages (filter (partial valid-chat-id? cofx) messages)
|
||||
(let [valid-messages (keep #(when-let [chat-id (extract-chat-id cofx %)] (assoc % :chat-id chat-id)) messages)
|
||||
deduped-messages (filter-messages cofx valid-messages)
|
||||
chat->message (group-by :chat-id deduped-messages)
|
||||
chat-ids (keys chat->message)
|
||||
|
|
|
@ -18,7 +18,12 @@
|
|||
installation
|
||||
true)))
|
||||
|
||||
(defn confirm
|
||||
(defn enable
|
||||
[installation-id]
|
||||
(save {:installation-id installation-id
|
||||
:confirmed? true}))
|
||||
:enabled? true}))
|
||||
|
||||
(defn disable
|
||||
[installation-id]
|
||||
(save {:installation-id installation-id
|
||||
:enabled? false}))
|
||||
|
|
|
@ -199,6 +199,19 @@
|
|||
|
||||
(def v20 v19)
|
||||
|
||||
(def v21 [chat/v8
|
||||
transport/v7
|
||||
transport-inbox-topic/v1
|
||||
contact/v2
|
||||
message/v7
|
||||
mailserver/v11
|
||||
user-status/v1
|
||||
membership-update/v1
|
||||
installation/v2
|
||||
local-storage/v1
|
||||
browser/v8
|
||||
dapp-permissions/v9])
|
||||
|
||||
;; put schemas ordered by version
|
||||
(def schemas [{:schema v1
|
||||
:schemaVersion 1
|
||||
|
@ -259,4 +272,7 @@
|
|||
:migration migrations/v19}
|
||||
{:schema v20
|
||||
:schemaVersion 20
|
||||
:migration migrations/v20}])
|
||||
:migration migrations/v20}
|
||||
{:schema v21
|
||||
:schemaVersion 21
|
||||
:migration migrations/v21}])
|
||||
|
|
|
@ -4,3 +4,17 @@
|
|||
:primaryKey :installation-id
|
||||
:properties {:installation-id :string
|
||||
:confirmed? :bool}})
|
||||
|
||||
(def v2 {:name :installation
|
||||
:primaryKey :installation-id
|
||||
:properties {:installation-id :string
|
||||
:device-type {:type :string
|
||||
:optional true}
|
||||
:last-paired {:type :int
|
||||
:optional true}
|
||||
:has-bundle? {:type :bool
|
||||
:optional true
|
||||
:default false}
|
||||
:enabled? {:type :bool
|
||||
:optional true
|
||||
:default false}}})
|
||||
|
|
|
@ -119,7 +119,7 @@
|
|||
(log/debug "migrating v19 account database"))
|
||||
|
||||
(defn v20 [old-realm new-realm]
|
||||
(log/debug "migrating v19 account database")
|
||||
(log/debug "migrating v20 account database")
|
||||
(some-> new-realm
|
||||
(.objects "message")
|
||||
(.filtered (str "content-type = \"text/plain\""))
|
||||
|
@ -128,3 +128,5 @@
|
|||
new-content (message-content/enrich-content content)]
|
||||
(aset message "content" (pr-str new-content)))))))
|
||||
|
||||
(defn v21 [old-realm new-realm]
|
||||
(log/debug "migrating v21 account database"))
|
||||
|
|
|
@ -1104,12 +1104,30 @@
|
|||
|
||||
(handlers/register-handler-fx
|
||||
:pairing.ui/pair-devices-pressed
|
||||
[]
|
||||
(fn [cofx _]
|
||||
(pairing/start cofx)))
|
||||
(pairing/pair-installation cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:pairing.ui/synchronize-installation-pressed
|
||||
[]
|
||||
(fn [cofx _]
|
||||
(pairing/send-installation-message cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:pairing.ui/enable-installation-pressed
|
||||
(fn [cofx [_ installation-id]]
|
||||
(pairing/enable-fx cofx installation-id)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:pairing.ui/disable-installation-pressed
|
||||
(fn [cofx [_ installation-id]]
|
||||
(pairing/disable-fx cofx installation-id)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:pairing.callback/enable-installation-success
|
||||
(fn [cofx [_ installation-id]]
|
||||
(pairing/enable cofx installation-id)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:pairing.callback/disable-installation-success
|
||||
(fn [cofx [_ installation-id]]
|
||||
(pairing/disable cofx installation-id)))
|
||||
|
|
|
@ -110,7 +110,7 @@
|
|||
cofx
|
||||
{:shh/send-group-message {:web3 web3
|
||||
:src current-public-key
|
||||
:dsts (disj members current-public-key)
|
||||
:dsts members
|
||||
:success-event [:transport/message-sent
|
||||
chat-id
|
||||
(transport.utils/message-id (:message payload))
|
||||
|
|
|
@ -63,3 +63,7 @@
|
|||
(def extract-group-membership-signatures native-module/extract-group-membership-signatures)
|
||||
|
||||
(def sign-group-membership native-module/sign-group-membership)
|
||||
|
||||
(def enable-installation native-module/enable-installation)
|
||||
|
||||
(def disable-installation native-module/disable-installation)
|
||||
|
|
|
@ -142,6 +142,14 @@
|
|||
(when status
|
||||
(call-module #(.signGroupMembership status content callback))))
|
||||
|
||||
(defn enable-installation [installation-id callback]
|
||||
(when status
|
||||
(call-module #(.enableInstallation status installation-id callback))))
|
||||
|
||||
(defn disable-installation [installation-id callback]
|
||||
(when status
|
||||
(call-module #(.disableInstallation status installation-id callback))))
|
||||
|
||||
(defn is24Hour []
|
||||
(when status
|
||||
(.-is24Hour status)))
|
||||
|
|
|
@ -1,18 +1,31 @@
|
|||
(ns status-im.pairing.core
|
||||
(:require
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.utils.fx :as fx]
|
||||
[status-im.utils.config :as config]
|
||||
[status-im.utils.platform :as utils.platform]
|
||||
[status-im.transport.message.protocol :as protocol]
|
||||
[status-im.data-store.installations :as data-store.installations]
|
||||
[status-im.native-module.core :as native-module]
|
||||
[status-im.utils.identicon :as identicon]
|
||||
[status-im.data-store.contacts :as data-store.contacts]
|
||||
[status-im.transport.message.pairing :as transport.pairing]))
|
||||
|
||||
(defn start [cofx]
|
||||
(defn- parse-response [response-js]
|
||||
(-> response-js
|
||||
js/JSON.parse
|
||||
(js->clj :keywordize-keys true)))
|
||||
|
||||
(defn pair-installation [cofx]
|
||||
(let [installation-id (get-in cofx [:db :account/account :installation-id])
|
||||
device-type utils.platform/os]
|
||||
(protocol/send (transport.pairing/PairInstallation. installation-id device-type) nil cofx)))
|
||||
|
||||
(defn send-pair-installation [cofx payload]
|
||||
(let [{:keys [current-public-key web3]} (:db cofx)]
|
||||
{:shh/send-pairing-message {:web3 web3
|
||||
:src current-public-key
|
||||
:payload []}}))
|
||||
:payload payload}}))
|
||||
|
||||
(defn merge-contact [local remote]
|
||||
(let [[old-contact new-contact] (sort-by :last-updated [local remote])]
|
||||
|
@ -28,20 +41,26 @@
|
|||
|
||||
(def merge-contacts (partial merge-with merge-contact))
|
||||
|
||||
(defn handle-bundles-added [{:keys [db]} bundle]
|
||||
(fx/defn upsert-installation [{:keys [db]} {:keys [installation-id] :as new-installation}]
|
||||
(let [old-installation (get-in db [:pairing/installations installation-id])
|
||||
updated-installation (merge old-installation new-installation)]
|
||||
{:db (assoc-in db
|
||||
[:pairing/installations installation-id]
|
||||
updated-installation)
|
||||
:data-store/tx [(data-store.installations/save updated-installation)]}))
|
||||
|
||||
(defn handle-bundles-added [{:keys [db] :as cofx} bundle]
|
||||
(let [dev-mode? (get-in db [:account/account :dev-mode?])]
|
||||
(when (config/pairing-enabled? dev-mode?)
|
||||
(let [installation-id (:installationID bundle)
|
||||
new-installation {:installation-id installation-id
|
||||
:confirmed? false}]
|
||||
:has-bundle? true}]
|
||||
(when
|
||||
(and (= (:identity bundle)
|
||||
(:current-public-key db))
|
||||
(not= (get-in db [:account/account :installation-id]) installation-id)
|
||||
(not (get-in db [:pairing/installations installation-id])))
|
||||
{:db (assoc-in db
|
||||
[:pairing/installations installation-id]
|
||||
new-installation)
|
||||
:data-store/tx [(data-store.installations/save new-installation)]})))))
|
||||
(upsert-installation cofx new-installation))))))
|
||||
|
||||
(defn sync-installation-messages [{:keys [db]}]
|
||||
(let [contacts (:contacts/contacts db)]
|
||||
|
@ -49,6 +68,56 @@
|
|||
(fn [[k v]] (transport.pairing/SyncInstallation. {k (dissoc v :photo-path)}))
|
||||
contacts)))
|
||||
|
||||
(defn enable [{:keys [db]} installation-id]
|
||||
{:db (assoc-in db
|
||||
[:pairing/installations installation-id :enabled?]
|
||||
true)
|
||||
:data-store/tx [(data-store.installations/enable installation-id)]})
|
||||
|
||||
(defn disable [{:keys [db]} installation-id]
|
||||
{:db (assoc-in db
|
||||
[:pairing/installations installation-id :enabled?]
|
||||
false)
|
||||
:data-store/tx [(data-store.installations/disable installation-id)]})
|
||||
|
||||
(defn handle-enable-installation-response
|
||||
"Callback to dispatch on enable signature response"
|
||||
[installation-id response-js]
|
||||
(let [{:keys [error]} (parse-response response-js)]
|
||||
(if error
|
||||
(re-frame/dispatch [:pairing.callback/enable-installation-failed error])
|
||||
(re-frame/dispatch [:pairing.callback/enable-installation-success installation-id]))))
|
||||
|
||||
(defn handle-disable-installation-response
|
||||
"Callback to dispatch on disable signature response"
|
||||
[installation-id response-js]
|
||||
(let [{:keys [error]} (parse-response response-js)]
|
||||
(if error
|
||||
(re-frame/dispatch [:pairing.callback/disable-installation-failed error])
|
||||
(re-frame/dispatch [:pairing.callback/disable-installation-success installation-id]))))
|
||||
|
||||
(defn enable-installation! [installation-id]
|
||||
(native-module/enable-installation installation-id
|
||||
(partial handle-enable-installation-response installation-id)))
|
||||
|
||||
(defn disable-installation! [installation-id]
|
||||
(native-module/disable-installation installation-id
|
||||
(partial handle-disable-installation-response installation-id)))
|
||||
|
||||
(defn enable-fx [_ installation-id]
|
||||
{:pairing/enable-installation installation-id})
|
||||
|
||||
(defn disable-fx [_ installation-id]
|
||||
{:pairing/disable-installation installation-id})
|
||||
|
||||
(re-frame/reg-fx
|
||||
:pairing/enable-installation
|
||||
enable-installation!)
|
||||
|
||||
(re-frame/reg-fx
|
||||
:pairing/disable-installation
|
||||
disable-installation!)
|
||||
|
||||
(defn send-installation-message [cofx]
|
||||
;; The message needs to be broken up in chunks as we hit the whisper size limit
|
||||
(let [{:keys [current-public-key web3]} (:db cofx)
|
||||
|
@ -67,6 +136,16 @@
|
|||
{:db (assoc db :contacts/contacts new-contacts)
|
||||
:data-store/tx [(data-store.contacts/save-contacts-tx (vals new-contacts))]}))))
|
||||
|
||||
(defn handle-pair-installation [{:keys [db] :as cofx} {:keys [installation-id device-type]} timestamp sender]
|
||||
(let [dev-mode? (get-in db [:account/account :dev-mode?])]
|
||||
(when (and (config/pairing-enabled? dev-mode?)
|
||||
(= sender (get-in cofx [:db :current-public-key]))
|
||||
(not= (get-in db [:account/account :installation-id]) installation-id))
|
||||
(let [installation {:installation-id installation-id
|
||||
:device-type device-type
|
||||
:last-paired timestamp}]
|
||||
(upsert-installation cofx installation)))))
|
||||
|
||||
(fx/defn load-installations [{:keys [db all-installations]}]
|
||||
{:db (assoc db :pairing/installations (reduce
|
||||
(fn [acc {:keys [installation-id] :as i}]
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
(spec/def :request/attemps int?)
|
||||
(spec/def :request/cursor :global/not-empty-string)
|
||||
|
||||
(spec/def :pairing/installation-id :global/not-empty-string)
|
||||
(spec/def :pairing/device-type :global/not-empty-string)
|
||||
|
||||
(spec/def :transport.inbox.topic/last-request pos-int?)
|
||||
(spec/def :transport.inbox.topic/started-at pos-int?)
|
||||
(spec/def :transport.inbox.topic/chat-id (spec/or :keyword keyword?
|
||||
|
@ -105,6 +108,8 @@
|
|||
|
||||
(spec/def :message/group-membership-update (spec/keys :req-un [:group-chat/membership-updates :group-chat/chat-id]))
|
||||
(spec/def :message/sync-installation (spec/keys :req-un [:contacts/contacts]))
|
||||
(spec/def :message/pair-installation (spec/keys :req-un [:pairing/installation-id
|
||||
:pairing/device-type]))
|
||||
|
||||
(spec/def :message/message-common (spec/keys :req-un [::content-type ::message-type ::clock-value ::timestamp]))
|
||||
(spec/def :message.text/content (spec/keys :req-un [:message.content/text]
|
||||
|
|
|
@ -31,3 +31,8 @@
|
|||
protocol/StatusMessage
|
||||
(receive [this _ signature _ cofx]
|
||||
(pairing/handle-sync-installation cofx this signature)))
|
||||
|
||||
(extend-type transport.pairing/PairInstallation
|
||||
protocol/StatusMessage
|
||||
(receive [this _ signature timestamp cofx]
|
||||
(pairing/handle-pair-installation cofx this timestamp signature)))
|
||||
|
|
|
@ -9,3 +9,8 @@
|
|||
protocol/StatusMessage
|
||||
(send [this chat-id cofx]
|
||||
(group-chats/send-membership-update cofx this chat-id)))
|
||||
|
||||
(extend-type transport.pairing/PairInstallation
|
||||
protocol/StatusMessage
|
||||
(send [this _ cofx]
|
||||
(pairing/send-pair-installation cofx this)))
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
[taoensso.timbre :as log]))
|
||||
|
||||
(fx/defn receive-message
|
||||
[cofx now-in-s chat-id js-message]
|
||||
[cofx now-in-s filter-chat-id js-message]
|
||||
(let [{:keys [payload sig timestamp ttl]} (js->clj js-message :keywordize-keys true)
|
||||
status-message (-> payload
|
||||
transport.utils/to-utf8
|
||||
|
@ -20,7 +20,14 @@
|
|||
(try
|
||||
(when-let [valid-message (protocol/validate status-message)]
|
||||
(fx/merge (assoc cofx :js-obj js-message)
|
||||
#(protocol/receive valid-message (or chat-id sig) sig timestamp %)))
|
||||
#(protocol/receive valid-message
|
||||
(or
|
||||
filter-chat-id
|
||||
(get-in valid-message [:content :chat-id])
|
||||
sig)
|
||||
sig
|
||||
timestamp
|
||||
%)))
|
||||
(catch :default e nil))))) ; ignore unknown message types
|
||||
|
||||
(defn- js-array->seq [array]
|
||||
|
|
|
@ -3,6 +3,14 @@
|
|||
[status-im.transport.message.protocol :as protocol]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(defrecord PairInstallation
|
||||
[installation-id device-type]
|
||||
protocol/StatusMessage
|
||||
(validate [this]
|
||||
(if (spec/valid? :message/pair-installation this)
|
||||
this
|
||||
(log/warn "failed sync installation validation" (spec/explain :message/pair-installation this)))))
|
||||
|
||||
(defrecord SyncInstallation
|
||||
[contacts]
|
||||
protocol/StatusMessage
|
||||
|
|
|
@ -80,12 +80,14 @@
|
|||
(defrecord Message [content content-type message-type clock-value timestamp]
|
||||
StatusMessage
|
||||
(send [this chat-id cofx]
|
||||
(let [params {:chat-id chat-id
|
||||
:payload this
|
||||
:success-event [:transport/message-sent
|
||||
chat-id
|
||||
(transport.utils/message-id this)
|
||||
message-type]}]
|
||||
(let [dev-mode? (get-in cofx [:db :account/account :dev-mode?])
|
||||
current-public-key (get-in cofx [:db :current-public-key])
|
||||
params {:chat-id chat-id
|
||||
:payload this
|
||||
:success-event [:transport/message-sent
|
||||
chat-id
|
||||
(transport.utils/message-id this)
|
||||
message-type]}]
|
||||
(case message-type
|
||||
:public-group-user-message
|
||||
(if config/pfs-encryption-enabled?
|
||||
|
@ -103,7 +105,10 @@
|
|||
chat-id
|
||||
(:success-event params)
|
||||
this)
|
||||
(send-with-pubkey cofx params)))))
|
||||
(fx/merge cofx
|
||||
#(when (config/pairing-enabled? dev-mode?)
|
||||
(send-direct-message % current-public-key nil this))
|
||||
(send-with-pubkey params))))))
|
||||
(receive [this chat-id signature _ cofx]
|
||||
{:chat-received-message/add-fx
|
||||
[(assoc (into {} this)
|
||||
|
|
|
@ -94,6 +94,12 @@
|
|||
(rep [this {:keys [contacts]}]
|
||||
#js [contacts]))
|
||||
|
||||
(deftype PairInstallationHandler []
|
||||
Object
|
||||
(tag [this v] "p2")
|
||||
(rep [this {:keys [installation-id device-type]}]
|
||||
#js [installation-id device-type]))
|
||||
|
||||
(def writer (transit/writer :json
|
||||
{:handlers
|
||||
{contact/NewContactKey (NewContactKeyHandler.)
|
||||
|
@ -103,7 +109,8 @@
|
|||
protocol/Message (MessageHandler.)
|
||||
protocol/MessagesSeen (MessagesSeenHandler.)
|
||||
group-chat/GroupMembershipUpdate (GroupMembershipUpdateHandler.)
|
||||
pairing/SyncInstallation (SyncInstallationHandler.)}}))
|
||||
pairing/SyncInstallation (SyncInstallationHandler.)
|
||||
pairing/PairInstallation (PairInstallationHandler.)}}))
|
||||
|
||||
;;
|
||||
;; Reader handlers
|
||||
|
@ -156,7 +163,9 @@
|
|||
"g5" (fn [[chat-id membership-updates message]]
|
||||
(group-chat/GroupMembershipUpdate. chat-id membership-updates message))
|
||||
"p1" (fn [[contacts]]
|
||||
(pairing/SyncInstallation. contacts))}}))
|
||||
(pairing/SyncInstallation. contacts))
|
||||
"p2" (fn [[installation-id device-type]]
|
||||
(pairing/PairInstallation. installation-id device-type))}}))
|
||||
|
||||
(defn serialize
|
||||
"Serializes a record implementing the StatusMessage protocol using the custom writers"
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
:background-color :white})
|
||||
|
||||
(def installation-item-inner
|
||||
{:padding-horizontal 16})
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
:padding-horizontal 16})
|
||||
|
||||
(defstyle installation-item
|
||||
{:flex-direction :row
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.utils.config :as config]
|
||||
[status-im.utils.gfycat.core :as gfycat]
|
||||
[status-im.ui.components.button.view :as buttons]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
|
@ -14,19 +16,35 @@
|
|||
[status-im.ui.screens.pairing.styles :as styles]))
|
||||
|
||||
(defn synchronize-installation! [id]
|
||||
(re-frame/dispatch [:pairing.ui/synchronize-installation-pressed id]))
|
||||
#_(re-frame/dispatch [:pairing.ui/synchronize-installation-pressed id]))
|
||||
|
||||
(defn pair! []
|
||||
(re-frame/dispatch [:pairing.ui/pair-devices-pressed]))
|
||||
|
||||
(defn render-row [{:keys [installation-id]}]
|
||||
(defn enable-installation! [installation-id _]
|
||||
(re-frame/dispatch [:pairing.ui/enable-installation-pressed installation-id]))
|
||||
|
||||
(defn disable-installation! [installation-id _]
|
||||
(re-frame/dispatch [:pairing.ui/disable-installation-pressed installation-id]))
|
||||
|
||||
(defn render-row [{:keys [device-type enabled? installation-id]}]
|
||||
[react/touchable-highlight
|
||||
{:on-press #(synchronize-installation! installation-id)
|
||||
:accessibility-label :installation-item}
|
||||
[react/view styles/installation-item
|
||||
[react/view styles/installation-item-inner
|
||||
[react/text {:style styles/installation-item-name-text}
|
||||
installation-id]]]])
|
||||
[react/view
|
||||
[react/text {:style styles/installation-item-name-text}
|
||||
(str (gfycat/generate-gfy installation-id) " - " (or device-type
|
||||
"unknown"))]]
|
||||
[react/view
|
||||
(if enabled?
|
||||
[buttons/primary-button
|
||||
{:on-press (partial disable-installation! installation-id)}
|
||||
(i18n/label :t/enabled)]
|
||||
[buttons/secondary-button
|
||||
{:on-press (partial enable-installation! installation-id)}
|
||||
(i18n/label :t/disabled)])]]]])
|
||||
|
||||
(defn render-rows [installations]
|
||||
[react/view styles/wrapper
|
||||
|
|
|
@ -22,9 +22,7 @@
|
|||
(or dev-mode? platform/desktop?)))
|
||||
(defn pairing-enabled? [dev-mode?]
|
||||
(and (enabled? (get-config :PAIRING_ENABLED "0"))
|
||||
(or dev-mode? platform/desktop?)
|
||||
;; Hard disable as desktop ignores build parameters
|
||||
false))
|
||||
(or dev-mode? platform/desktop?)))
|
||||
(def mainnet-warning-enabled? (enabled? (get-config :MAINNET_WARNING_ENABLED 0)))
|
||||
(def pfs-encryption-enabled? (enabled? (get-config :PFS_ENCRYPTION_ENABLED "0")))
|
||||
(def in-app-notifications-enabled? (enabled? (get-config :IN_APP_NOTIFICATIONS_ENABLED 0)))
|
||||
|
|
|
@ -153,7 +153,7 @@
|
|||
(testing "our own message"
|
||||
(is (get-in (message/receive-many cofx [own-message]) [:db :chats "matching" :messages "1"])))
|
||||
(testing "a message with non matching chat-id"
|
||||
(is (= cofx (message/receive-many cofx [bad-chat-id-message]))))))
|
||||
(is (get-in (message/receive-many cofx [bad-chat-id-message]) [:db :chats "not-matching" :messages "1"])))))
|
||||
|
||||
(deftest receive-send-seen
|
||||
(let [cofx {:db {:chats {"chat-id" {}}
|
||||
|
|
|
@ -113,6 +113,28 @@
|
|||
(pairing/handle-sync-installation cofx sync-message "us")
|
||||
[:db :contacts/contacts])))))))
|
||||
|
||||
(deftest handle-pair-installation-test
|
||||
(with-redefs [config/pairing-enabled? (constantly true)]
|
||||
(let [cofx {:db {:current-public-key "us"
|
||||
:pairing/installations {"1" {:has-bundle? true
|
||||
:installation-id "1"}
|
||||
"2" {:has-bundle? false
|
||||
:installation-id "2"}}}}
|
||||
pair-message {:device-type "ios"
|
||||
:installation-id "1"}]
|
||||
(testing "not coming from us"
|
||||
(is (not (pairing/handle-pair-installation cofx pair-message 1 "not-us"))))
|
||||
(testing "coming from us"
|
||||
(is (= {"1" {:has-bundle? true
|
||||
:installation-id "1"
|
||||
:last-paired 1
|
||||
:device-type "ios"}
|
||||
"2" {:has-bundle? false
|
||||
:installation-id "2"}}
|
||||
(get-in
|
||||
(pairing/handle-pair-installation cofx pair-message 1 "us")
|
||||
[:db :pairing/installations])))))))
|
||||
|
||||
(deftest sync-installation-messages-test
|
||||
(testing "it creates a sync installation message"
|
||||
(let [cofx {:db {:current-public-key "us"
|
||||
|
@ -124,14 +146,14 @@
|
|||
|
||||
(deftest handle-bundles-added-test
|
||||
(with-redefs [config/pairing-enabled? (constantly true)]
|
||||
(let [installation-1 {:confirmed? true
|
||||
(let [installation-1 {:has-bundle? false
|
||||
:installation-id "installation-1"}
|
||||
cofx {:db {:current-public-key "us"
|
||||
:pairing/installations {"installation-1" installation-1}}}]
|
||||
(testing "new installations"
|
||||
(let [new-installation {:identity "us" :installationID "installation-2"}
|
||||
expected {"installation-1" installation-1
|
||||
"installation-2" {:confirmed? false
|
||||
"installation-2" {:has-bundle? true
|
||||
:installation-id "installation-2"}}]
|
||||
(is (= expected (get-in (pairing/handle-bundles-added cofx new-installation) [:db :pairing/installations])))))
|
||||
(testing "already existing installation"
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
"description": "Description",
|
||||
"devices": "Devices",
|
||||
"pair": "Pair devices",
|
||||
"enabled": "enabled",
|
||||
"disabled": "disabled",
|
||||
"currency-display-name-tzs": "Tanzanian Shilling",
|
||||
"currency-display-name-brl": "Brazil Real",
|
||||
"mainnet-network": "Main network",
|
||||
|
|
Loading…
Reference in New Issue