Move installations to status-go

This commit moves the management of installations to status-go, and
migrates the data from realm.

Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
Andrea Maria Piana 2019-06-25 16:34:55 +02:00
parent e1bcaebd2c
commit 138ade3b8d
No known key found for this signature in database
GPG Key ID: AA6CCA6DE0E06424
22 changed files with 261 additions and 247 deletions

View File

@ -1,3 +1,3 @@
## DO NOT EDIT THIS FILE BY HAND. USE `scripts/update-status-go.sh <tag>` instead ## DO NOT EDIT THIS FILE BY HAND. USE `scripts/update-status-go.sh <tag>` instead
1bhwwmypb64kf180kp634jwfppd3h6yda3qyh2icj3lz7y10pgvp 0hrjppsayih655a7cz3cdl3yp5ff98cxxcrmzwlzsfaqj82jk7jp

View File

@ -1,3 +1,3 @@
## DO NOT EDIT THIS FILE BY HAND. USE `scripts/update-status-go.sh <tag>` instead ## DO NOT EDIT THIS FILE BY HAND. USE `scripts/update-status-go.sh <tag>` instead
v0.27.0-beta.1 v0.28.0-beta.0

View File

@ -99,7 +99,6 @@ var TopLevel = {
"DesktopNotification" : function () {}, "DesktopNotification" : function () {},
"DeviceEventEmitter" : function () {}, "DeviceEventEmitter" : function () {},
"Dimensions" : function () {}, "Dimensions" : function () {},
"disableInstallation" : function () {},
"dispatch" : function () {}, "dispatch" : function () {},
"displayNotification" : function () {}, "displayNotification" : function () {},
"dividedBy" : function () {}, "dividedBy" : function () {},
@ -108,7 +107,6 @@ var TopLevel = {
"dy" : function () {}, "dy" : function () {},
"ease" : function () {}, "ease" : function () {},
"Easing" : function () {}, "Easing" : function () {},
"enableInstallation" : function () {},
"enableVibration" : function () {}, "enableVibration" : function () {},
"encode" : function () {}, "encode" : function () {},
"encodeURIComponent" : function () {}, "encodeURIComponent" : function () {},

View File

@ -1015,45 +1015,6 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
StatusThreadPoolExecutor.getInstance().execute(r); 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);
}
@ReactMethod @ReactMethod
public void updateMailservers(final String enodes, final Callback callback) { public void updateMailservers(final String enodes, final Callback callback) {

View File

@ -330,22 +330,6 @@ void RCTStatus::extractGroupMembershipSignatures(QString signatures, double call
}, signatures, callbackId); }, 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() { void RCTStatus::setAdjustResize() {
} }

View File

@ -48,8 +48,6 @@ public:
Q_INVOKABLE void signMessage(QString rpcParams, double callbackId); Q_INVOKABLE void signMessage(QString rpcParams, double callbackId);
Q_INVOKABLE void signGroupMembership(QString content, double callbackId); Q_INVOKABLE void signGroupMembership(QString content, double callbackId);
Q_INVOKABLE void extractGroupMembershipSignatures(QString signatures, 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 updateMailservers(QString enodes, double callbackId); Q_INVOKABLE void updateMailservers(QString enodes, double callbackId);
Q_INVOKABLE void getNodesFromContract(QString url, QString address, double callbackId); Q_INVOKABLE void getNodesFromContract(QString url, QString address, double callbackId);
Q_INVOKABLE void chaosModeUpdate(bool on, double callbackId); Q_INVOKABLE void chaosModeUpdate(bool on, double callbackId);

View File

@ -425,30 +425,6 @@ RCT_EXPORT_METHOD(extractGroupMembershipSignatures:(NSString *)content
callback(@[result]); callback(@[result]);
} }
////////////////////////////////////////////////////////////////////
#pragma mark - EnableInstallation
//////////////////////////////////////////////////////////////////// enableInstallation
RCT_EXPORT_METHOD(enableInstallation:(NSString *)content
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"EnableInstallation() method called");
#endif
NSString *result = StatusgoEnableInstallation(content);
callback(@[result]);
}
////////////////////////////////////////////////////////////////////
#pragma mark - DisableInstallation
//////////////////////////////////////////////////////////////////// disableInstallation
RCT_EXPORT_METHOD(disableInstallation:(NSString *)content
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"DisableInstallation() method called");
#endif
NSString *result = StatusgoDisableInstallation(content);
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
#pragma mark - only android methods #pragma mark - only android methods
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -140,6 +140,7 @@
{:events [:accounts.login.callback/login-success] {:events [:accounts.login.callback/login-success]
:interceptors [(re-frame/inject-cofx :web3/get-web3) :interceptors [(re-frame/inject-cofx :web3/get-web3)
(re-frame/inject-cofx :data-store/get-all-mailservers) (re-frame/inject-cofx :data-store/get-all-mailservers)
(re-frame/inject-cofx :data-store/get-all-installations)
(re-frame/inject-cofx :data-store/transport) (re-frame/inject-cofx :data-store/transport)
(re-frame/inject-cofx :data-store/mailserver-topics)]} (re-frame/inject-cofx :data-store/mailserver-topics)]}
[{:keys [db web3] :as cofx} login-result] [{:keys [db web3] :as cofx} login-result]

View File

@ -27,3 +27,11 @@
[installation-id] [installation-id]
(save {:installation-id installation-id (save {:installation-id installation-id
:enabled? false})) :enabled? false}))
(defn delete
"Returns tx function for deleting an installation"
[id]
(fn [realm]
(core/delete realm
(core/get-by-field realm :installation :installation-id (name id)))))

View File

@ -25,6 +25,13 @@
"eth_newFilter" {:subscription? true} "eth_newFilter" {:subscription? true}
"eth_syncing" {} "eth_syncing" {}
"net_version" {} "net_version" {}
"shhext_enableInstallation" {}
"shhext_disableInstallation" {}
"shhext_getOurInstallations" {}
"shhext_setInstallationMetadata" {}
"shhext_loadFilters" {}
"shhext_loadFilter" {}
"shhext_removeFilters" {}
"status_joinPublicChat" {} "status_joinPublicChat" {}
"status_chats" {} "status_chats" {}
"status_startOneOnOneChat" {} "status_startOneOnOneChat" {}

View File

@ -1645,6 +1645,16 @@
(fn [cofx _] (fn [cofx _]
(pairing/send-installation-messages cofx))) (pairing/send-installation-messages cofx)))
(handlers/register-handler-fx
:pairing.callback/get-our-installations-success
(fn [cofx [_ installations]]
(pairing/load-installations cofx installations)))
(handlers/register-handler-fx
:pairing.callback/set-installation-metadata-success
(fn [cofx [_ installation-id metadata]]
(pairing/update-installation cofx installation-id metadata)))
(handlers/register-handler-fx (handlers/register-handler-fx
:set-initial-props :set-initial-props
(fn [cofx [_ initial-props]] (fn [cofx [_ initial-props]]

View File

@ -237,7 +237,6 @@
{:notifications/get-fcm-token nil} {:notifications/get-fcm-token nil}
(initialize-account-db address) (initialize-account-db address)
(contact/load-contacts) (contact/load-contacts)
(pairing/load-installations)
#(when (dev-mode? %) #(when (dev-mode? %)
(models.dev-server/start)) (models.dev-server/start))
(browser/initialize-browsers) (browser/initialize-browsers)

View File

@ -101,16 +101,6 @@
(def sign-group-membership native-module/sign-group-membership) (def sign-group-membership native-module/sign-group-membership)
(def enable-installation native-module/enable-installation)
(def load-filters native-module/load-filters)
(def load-filter native-module/load-filter)
(def remove-filters native-module/remove-filters)
(def disable-installation native-module/disable-installation)
(def update-mailservers native-module/update-mailservers) (def update-mailservers native-module/update-mailservers)
(def rooted-device? native-module/rooted-device?) (def rooted-device? native-module/rooted-device?)

View File

@ -144,38 +144,6 @@
(when (status) (when (status)
(.signGroupMembership (status) content callback))) (.signGroupMembership (status) content callback)))
(defn enable-installation [installation-id callback]
(when (status)
(.enableInstallation (status) installation-id callback)))
(defn disable-installation [installation-id callback]
(when (status)
(.disableInstallation (status) installation-id callback)))
(defn load-filters [chats callback]
(let [params {:jsonrpc "2.0"
:id 2
:method "shhext_loadFilters"
:params [chats]}
payload (.stringify js/JSON (clj->js params))]
(call-private-rpc payload callback)))
(defn load-filter [chat callback]
(let [params {:jsonrpc "2.0"
:id 2
:method "shhext_loadFilter"
:params [chat]}
payload (.stringify js/JSON (clj->js params))]
(call-private-rpc payload callback)))
(defn remove-filters [chats callback]
(let [params {:jsonrpc "2.0"
:id 2
:method "shhext_removeFilters"
:params [chats]}
payload (.stringify js/JSON (clj->js params))]
(call-private-rpc payload callback)))
(defn is24Hour [] (defn is24Hour []
(when (status) (when (status)
(.-is24Hour (status)))) (.-is24Hour (status))))

View File

@ -3,6 +3,7 @@
[clojure.string :as string] [clojure.string :as string]
[status-im.i18n :as i18n] [status-im.i18n :as i18n]
[status-im.utils.fx :as fx] [status-im.utils.fx :as fx]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.contact.device-info :as device-info] [status-im.contact.device-info :as device-info]
[status-im.contact.db :as contact.db] [status-im.contact.db :as contact.db]
[status-im.ui.screens.navigation :as navigation] [status-im.ui.screens.navigation :as navigation]
@ -12,7 +13,6 @@
[status-im.accounts.model :as accounts.model] [status-im.accounts.model :as accounts.model]
[status-im.transport.message.protocol :as protocol] [status-im.transport.message.protocol :as protocol]
[status-im.data-store.installations :as data-store.installations] [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.utils.identicon :as identicon]
[status-im.contact.core :as contact] [status-im.contact.core :as contact]
[status-im.transport.filters.core :as transport.filters] [status-im.transport.filters.core :as transport.filters]
@ -20,17 +20,57 @@
[status-im.data-store.accounts :as data-store.accounts] [status-im.data-store.accounts :as data-store.accounts]
[status-im.transport.message.pairing :as transport.pairing])) [status-im.transport.message.pairing :as transport.pairing]))
(defn enable-installation-rpc [installation-id on-success on-failure]
(json-rpc/call {:method "shhext_enableInstallation"
:params [installation-id]
:on-success on-success
:on-failure on-failure}))
(defn disable-installation-rpc [installation-id on-success on-failure]
(json-rpc/call {:method "shhext_disableInstallation"
:params [installation-id]
:on-success on-success
:on-failure on-failure}))
(defn set-installation-metadata-rpc [installation-id metadata on-success on-failure]
(json-rpc/call {:method "shhext_setInstallationMetadata"
:params [installation-id metadata]
:on-success on-success
:on-failure on-failure}))
(defn get-our-installations-rpc [on-success on-failure]
(json-rpc/call {:method "shhext_getOurInstallations"
:params []
:on-success on-success
:on-failure on-failure}))
(def contact-batch-n 4) (def contact-batch-n 4)
(defn- parse-response [response-js] (defn compare-installation
(-> response-js "Sort installations, first by our installation-id, then on whether is
js/JSON.parse enabled, and last on timestamp value"
(js->clj :keywordize-keys true))) [our-installation-id a b]
(cond
(= our-installation-id (:installation-id a))
-1
(= our-installation-id (:installation-id b))
1
:else
(let [enabled-compare (compare (:enabled? b)
(:enabled? a))]
(if (not= 0 enabled-compare)
enabled-compare
(compare (:timestamp b)
(:timestamp a))))))
(defn sort-installations
[our-installation-id installations]
(sort (partial compare-installation our-installation-id) installations))
(defn pair-installation [cofx] (defn pair-installation [cofx]
(let [fcm-token (get-in cofx [:db :notifications :fcm-token]) (let [fcm-token (get-in cofx [:db :notifications :fcm-token])
installation-name (get-in cofx [:db :account/account :installation-name])
installation-id (get-in cofx [:db :account/account :installation-id]) installation-id (get-in cofx [:db :account/account :installation-id])
installation-name (get-in cofx [:db :pairing/installations installation-id :name])
device-type utils.platform/os] device-type utils.platform/os]
(protocol/send (transport.pairing/PairInstallation. installation-id device-type installation-name fcm-token) nil cofx))) (protocol/send (transport.pairing/PairInstallation. installation-id device-type installation-name fcm-token) nil cofx)))
@ -91,28 +131,48 @@
:on-cancel #(re-frame/dispatch [:pairing.ui/prompt-dismissed]) :on-cancel #(re-frame/dispatch [:pairing.ui/prompt-dismissed])
:on-accept #(re-frame/dispatch [:pairing.ui/prompt-accepted])}})) :on-accept #(re-frame/dispatch [:pairing.ui/prompt-accepted])}}))
(fx/defn upsert-installation [{:keys [db] :as cofx} {:keys [installation-id] :as new-installation}] (fx/defn set-name
(let [success-event [:message/messages-persisted [(or (:dedup-id cofx) (:js-obj cofx))]] "Set the name of the device"
old-installation (get-in db [:pairing/installations installation-id]) [{:keys [db] :as cofx} installation-name]
updated-installation (merge old-installation new-installation)] (let [fcm-token (get-in cofx [:db :notifications :fcm-token])
{:db (assoc-in db our-installation-id (get-in db [:account/account :installation-id])]
[:pairing/installations installation-id] {:pairing/set-installation-metadata [[our-installation-id {:name installation-name
updated-installation) :deviceType utils.platform/os
:data-store/tx [{:transaction (data-store.installations/save updated-installation) :fcmToken fcm-token}]]}))
:success-event success-event}]}))
(fx/defn migrate-installations
"Take the realm installations and move them to status-go, also move installation-name
to status-go, clean up after so it is run only once"
[{:keys [db] :as cofx} installations]
(let [installation-name (get-in db [:account/account :installation-name])]
(fx/merge cofx
{:pairing/set-installation-metadata
(map (fn [{:keys [installation-id name device-type fcm-token]}]
[installation-id {:name name
:deviceType device-type
:fcmToken fcm-token}])
installations)}
#(when-not (string/blank? installation-name)
(set-name % installation-name))
#(when-not (string/blank? installation-name)
(let [new-account (dissoc (:account/account (:db %)) :installation-name)]
{:db (assoc (:db %) :account/account new-account)
:data-store/base-tx [(data-store.accounts/save-account-tx new-account)]})))))
(fx/defn init [cofx old-installations]
(fx/merge cofx
{:pairing/get-our-installations []}
(migrate-installations old-installations)))
(defn handle-bundles-added [{:keys [db] :as cofx} bundle] (defn handle-bundles-added [{:keys [db] :as cofx} bundle]
(let [installation-id (:installationID bundle) (let [installation-id (:installationID bundle)]
new-installation {:installation-id installation-id
:has-bundle? true}]
(when (when
(and (= (:identity bundle) (and (= (:identity bundle)
(accounts.model/current-public-key cofx)) (accounts.model/current-public-key cofx))
(not= (get-in db [:account/account :installation-id]) installation-id) (not= (get-in db [:account/account :installation-id]) installation-id))
(not (get-in db [:pairing/installations installation-id])))
(fx/merge cofx (fx/merge cofx
(upsert-installation new-installation) (init [])
#(when-not (or (get-in % [:db :pairing/prompt-user-pop-up]) #(when-not (or (:pairing/prompt-user-pop-up db)
(= :installations (:view-id db))) (= :installations (:view-id db)))
(prompt-user-on-new-installation %)))))) (prompt-user-on-new-installation %))))))
@ -159,41 +219,54 @@
(fx/defn enable [{:keys [db]} installation-id] (fx/defn enable [{:keys [db]} installation-id]
{:db (assoc-in db {:db (assoc-in db
[:pairing/installations installation-id :enabled?] [:pairing/installations installation-id :enabled?]
true) true)})
:data-store/tx [(data-store.installations/enable installation-id)]})
(fx/defn disable [{:keys [db]} installation-id] (fx/defn disable [{:keys [db]} installation-id]
{:db (assoc-in db {:db (assoc-in db
[:pairing/installations installation-id :enabled?] [:pairing/installations installation-id :enabled?]
false) false)})
:data-store/tx [(data-store.installations/disable installation-id)]})
(defn handle-enable-installation-response (defn handle-enable-installation-response-success
"Callback to dispatch on enable signature response" "Callback to dispatch on enable signature response"
[installation-id response-js] [installation-id]
(let [{:keys [error]} (parse-response response-js)] (re-frame/dispatch [:pairing.callback/enable-installation-success installation-id]))
(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 (defn handle-disable-installation-response-success
"Callback to dispatch on disable signature response" "Callback to dispatch on disable signature response"
[installation-id response-js] [installation-id]
(let [{:keys [error]} (parse-response response-js)] (re-frame/dispatch [:pairing.callback/disable-installation-success installation-id]))
(if error
(re-frame/dispatch [:pairing.callback/disable-installation-failed error]) (defn handle-set-installation-metadata-response-success
(re-frame/dispatch [:pairing.callback/disable-installation-success installation-id])))) "Callback to dispatch on set-installation-metadata response"
[installation-id metadata]
(re-frame/dispatch [:pairing.callback/set-installation-metadata-success installation-id metadata]))
(defn handle-get-our-installations-response-success
"Callback to dispatch on get-our-installation response"
[result]
(re-frame/dispatch [:pairing.callback/get-our-installations-success result]))
(defn enable-installation! [installation-id] (defn enable-installation! [installation-id]
(native-module/enable-installation installation-id (enable-installation-rpc installation-id
(partial handle-enable-installation-response installation-id))) (partial handle-enable-installation-response-success installation-id)
nil))
(defn disable-installation! [installation-id] (defn disable-installation! [installation-id]
(native-module/disable-installation installation-id (disable-installation-rpc installation-id
(partial handle-disable-installation-response installation-id))) (partial handle-disable-installation-response-success installation-id)
nil))
(defn set-installation-metadata! [installation-id metadata]
(set-installation-metadata-rpc installation-id
metadata
(partial handle-set-installation-metadata-response-success installation-id metadata)
nil))
(defn get-our-installations []
(get-our-installations-rpc handle-get-our-installations-response-success nil))
(defn enable-fx [cofx installation-id] (defn enable-fx [cofx installation-id]
(if (< (count (filter :enabled? (get-in cofx [:db :pairing/installations]))) config/max-installations) (if (< (count (filter :enabled? (vals (get-in cofx [:db :pairing/installations])))) (inc config/max-installations))
{:pairing/enable-installation installation-id} {:pairing/enable-installation installation-id}
{:utils/show-popup {:title (i18n/label :t/pairing-maximum-number-reached-title) {:utils/show-popup {:title (i18n/label :t/pairing-maximum-number-reached-title)
@ -210,6 +283,16 @@
:pairing/disable-installation :pairing/disable-installation
disable-installation!) disable-installation!)
(re-frame/reg-fx
:pairing/set-installation-metadata
(fn [pairs]
(doseq [[installation-id metadata] pairs]
(set-installation-metadata! installation-id metadata))))
(re-frame/reg-fx
:pairing/get-our-installations
get-our-installations)
(fx/defn send-sync-installation [cofx payload] (fx/defn send-sync-installation [cofx payload]
(let [{:keys [web3]} (:db cofx) (let [{:keys [web3]} (:db cofx)
current-public-key (accounts.model/current-public-key cofx)] current-public-key (accounts.model/current-public-key cofx)]
@ -301,23 +384,31 @@
device-type]} timestamp sender] device-type]} timestamp sender]
(if (and (= sender (accounts.model/current-public-key cofx)) (if (and (= sender (accounts.model/current-public-key cofx))
(not= (get-in db [:account/account :installation-id]) installation-id)) (not= (get-in db [:account/account :installation-id]) installation-id))
(let [installation {:installation-id installation-id {:pairing/set-installation-metadata [[installation-id {:name name
:name name :deviceType device-type
:fcm-token fcm-token :fcmToken fcm-token}]]}
:device-type device-type
:last-paired timestamp}]
(upsert-installation cofx installation))
(confirm-message-processed cofx (or (:dedup-id cofx) (confirm-message-processed cofx (or (:dedup-id cofx)
(:js-obj cofx))))) (:js-obj cofx)))))
(fx/defn set-name [{:keys [db] :as cofx} installation-name] (fx/defn update-installation [{:keys [db]} installation-id metadata]
(let [new-account (assoc (get-in cofx [:db :account/account]) :installation-name installation-name)] {:db (update-in db [:pairing/installations installation-id]
{:db (assoc db :account/account new-account) assoc
:data-store/base-tx [(data-store.accounts/save-account-tx new-account)]})) :name (:name metadata)
:device-type (:deviceType metadata)
:fcmToken (:fcmToken metadata))
;; we count it as migrated, and delete it from realm
:data-store/tx [(data-store.installations/delete installation-id)]})
(fx/defn load-installations [{:keys [db all-installations]}] (fx/defn load-installations [{:keys [db]} installations]
{:db (assoc db :pairing/installations (reduce {:db (assoc db :pairing/installations (reduce
(fn [acc {:keys [installation-id] :as i}] (fn [acc {:keys [metadata id enabled] :as i}]
(assoc acc installation-id i)) (assoc acc id
{:installation-id id
:name (:name metadata)
:timestamp (:timestamp metadata)
:device-type (:deviceType metadata)
:fcm-token (:fcmToken metadata)
:enabled? enabled}))
{} {}
all-installations))}) installations))})

View File

@ -4,6 +4,7 @@
[re-frame.core :as re-frame] [re-frame.core :as re-frame]
[status-im.accounts.model :as accounts.model] [status-im.accounts.model :as accounts.model]
[status-im.accounts.db :as accounts.db] [status-im.accounts.db :as accounts.db]
[status-im.pairing.core :as pairing]
[status-im.browser.core :as browser] [status-im.browser.core :as browser]
[status-im.chat.commands.core :as commands] [status-im.chat.commands.core :as commands]
[status-im.chat.commands.input :as commands.input] [status-im.chat.commands.input :as commands.input]
@ -921,13 +922,15 @@
;;PAIRING ============================================================================================================== ;;PAIRING ==============================================================================================================
(re-frame/reg-sub (re-frame/reg-sub
:pairing/installations :pairing/installations
:<- [:get-pairing-installations] :<- [:get-pairing-installations]
(fn [installations] :<- [:pairing/installation-id]
(fn [[installations installation-id]]
(->> installations (->> installations
vals vals
(sort-by (comp unchecked-negate :last-paired))))) (pairing/sort-installations installation-id))))
(re-frame/reg-sub (re-frame/reg-sub
:pairing/installation-id :pairing/installation-id

View File

@ -6,6 +6,7 @@
[status-im.mailserver.core :as mailserver] [status-im.mailserver.core :as mailserver]
[status-im.transport.message.core :as message] [status-im.transport.message.core :as message]
[status-im.transport.filters.core :as transport.filters] [status-im.transport.filters.core :as transport.filters]
[status-im.pairing.core :as pairing]
[status-im.utils.publisher :as publisher] [status-im.utils.publisher :as publisher]
[status-im.utils.fx :as fx] [status-im.utils.fx :as fx]
[status-im.utils.handlers :as handlers] [status-im.utils.handlers :as handlers]
@ -38,10 +39,11 @@
- adding fixed shh discovery filter - adding fixed shh discovery filter
- restoring existing symetric keys along with their unique filters - restoring existing symetric keys along with their unique filters
- (optionally) initializing mailserver" - (optionally) initializing mailserver"
[{:keys [db web3] :as cofx}] [{:keys [db web3 all-installations] :as cofx}]
(fx/merge cofx (fx/merge cofx
(fetch-node-info-fx) (fetch-node-info-fx)
(transport.filters/load-filters) (transport.filters/load-filters)
(pairing/init all-installations)
(publisher/start-fx) (publisher/start-fx)
(mailserver/connect-to-mailserver) (mailserver/connect-to-mailserver)
(message/resend-contact-messages []))) (message/resend-contact-messages [])))

View File

@ -7,12 +7,24 @@
[status-im.utils.fx :as fx] [status-im.utils.fx :as fx]
[status-im.transport.utils :as utils] [status-im.transport.utils :as utils]
[status-im.data-store.accounts :as data-store.accounts] [status-im.data-store.accounts :as data-store.accounts]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.accounts.model :as accounts.model] [status-im.accounts.model :as accounts.model]
[status-im.utils.handlers :as handlers] [status-im.utils.handlers :as handlers]
[status-im.native-module.core :as status]
[status-im.mailserver.topics :as mailserver.topics] [status-im.mailserver.topics :as mailserver.topics]
[status-im.mailserver.core :as mailserver])) [status-im.mailserver.core :as mailserver]))
(defn load-filters-rpc [chats on-success on-failure]
(json-rpc/call {:method "shhext_loadFilters"
:params [chats]
:on-success on-success
:on-failure on-failure}))
(defn remove-filters-rpc [chats on-success on-failure]
(json-rpc/call {:method "shhext_removeFilters"
:params [chats]
:on-success on-success
:on-failure on-failure}))
;; fx functions ;; fx functions
(defn load-filter-fx [web3 filters] (defn load-filter-fx [web3 filters]
@ -360,10 +372,10 @@
(fn [filters] (fn [filters]
(log/debug "removing filters" filters) (log/debug "removing filters" filters)
(stop-watching! (map :filter filters)) (stop-watching! (map :filter filters))
(status/remove-filters (remove-filters-rpc
(map ->remove-filter-request filters) (map ->remove-filter-request filters)
(handlers/response-handler #(filters-removed! filters) #(filters-removed! filters)
#(log/error "remove-filters: failed error" %))))) #(log/error "remove-filters: failed error" %))))
(re-frame/reg-fx (re-frame/reg-fx
:filters/stop-filters :filters/stop-filters
@ -377,8 +389,8 @@
(when (seq ops) (when (seq ops)
(let [web3 (first (peek ops)) (let [web3 (first (peek ops))
filters (mapcat peek ops)] filters (mapcat peek ops)]
(status/load-filters (load-filters-rpc
filters filters
(handlers/response-handler #(add-filters! web3 #(add-filters! web3
(map responses->filters %)) (map responses->filters %))
#(log/error "load-filters: failed error" %))))))) #(log/error "load-filters: failed error" %))))))

View File

@ -76,19 +76,17 @@
[react/text {:style styles/qr-code-copy-text} [react/text {:style styles/qr-code-copy-text}
(i18n/label :copy-qr)]]]]])) (i18n/label :copy-qr)]]]]]))
(defn installations-section [your-installation-id (defn installations-section [installations]
your-installation-name
installations]
[react/view [react/view
(if (string/blank? your-installation-name) (if (string/blank? (-> installations first :name))
[pairing.views/edit-installation-name] [pairing.views/edit-installation-name]
[react/view [react/view
[pairing.views/pair-this-device] [pairing.views/pair-this-device]
[pairing.views/info-section] [pairing.views/info-section]
[pairing.views/sync-devices] [pairing.views/sync-devices]
[react/view {:style pairing.styles/installation-list} [react/view {:style pairing.styles/installation-list}
[pairing.views/your-device your-installation-id your-installation-name] [pairing.views/your-device (first installations)]
(for [installation installations] (for [installation (rest installations)]
^{:key (:installation-id installation)} ^{:key (:installation-id installation)}
[react/view {:style {:margin-bottom 10}} [react/view {:style {:margin-bottom 10}}
(pairing.views/render-row installation)])]])]) (pairing.views/render-row installation)])]])])
@ -222,14 +220,9 @@
:on-value-change #(re-frame/dispatch [:accounts.ui/toggle-device-to-device (not pfs?)])}]]]))) :on-value-change #(re-frame/dispatch [:accounts.ui/toggle-device-to-device (not pfs?)])}]]])))
(views/defview installations [] (views/defview installations []
(views/letsubs [installations [:pairing/installations] (views/letsubs [installations [:pairing/installations]]
installation-id [:pairing/installation-id]
installation-name [:pairing/installation-name]]
[react/scroll-view [react/scroll-view
(installations-section (installations-section installations)]))
installation-id
installation-name
installations)]))
(views/defview backup-recovery-phrase [] (views/defview backup-recovery-phrase []
[profile.recovery/backup-seed]) [profile.recovery/backup-seed])

View File

@ -96,17 +96,19 @@
(i18n/label :t/syncing-devices) (i18n/label :t/syncing-devices)
(i18n/label :t/sync-all-devices))]]]]]) (i18n/label :t/sync-all-devices))]]]]])
(defn your-device [installation-id installation-name] (defn your-device [{:keys [installation-id name device-type]}]
[react/view {:style styles/installation-item} [react/view {:style styles/installation-item}
[react/view {:style (styles/pairing-button true)} [react/view {:style (styles/pairing-button true)}
[icons/icon (if utils.platform/desktop? [icons/icon (if (= "desktop"
device-type)
:main-icons/desktop :main-icons/desktop
:main-icons/mobile) :main-icons/mobile)
(icon-style (styles/pairing-button-icon true))]] (icon-style (styles/pairing-button-icon true))]]
[react/view {:style styles/pairing-actions-text} [react/view {:style styles/pairing-actions-text}
[react/view [react/view
[react/text (str [react/text (str
installation-name name
" (" " ("
(i18n/label :t/you) (i18n/label :t/you)
", " ", "
@ -128,13 +130,13 @@
(icon-style (styles/pairing-button-icon enabled?))]] (icon-style (styles/pairing-button-icon enabled?))]]
[react/view {:style styles/pairing-actions-text} [react/view {:style styles/pairing-actions-text}
[react/view [react/view
[react/text (if (string/blank? name) [react/text (str
(str (if (string/blank? name)
(i18n/label :t/pairing-no-info) (i18n/label :t/pairing-no-info)
name)
" (" " ("
(subs installation-id 0 5) (subs installation-id 0 5)
")") ")")]]]
name)]]]
[react/view [react/view
(if utils.platform/ios? (if utils.platform/ios?
;; On IOS switches seems to be broken, they take up value of dev-mode? (so if dev mode is on they all show to be on). ;; On IOS switches seems to be broken, they take up value of dev-mode? (so if dev mode is on they all show to be on).
@ -145,11 +147,11 @@
:value enabled? :value enabled?
:on-value-change (partial toggle-enabled! installation-id enabled?)}])]]]) :on-value-change (partial toggle-enabled! installation-id enabled?)}])]]])
(defn render-rows [installation-id installation-name installations] (defn render-rows [installations]
[react/scroll-view {:style styles/wrapper} [react/scroll-view {:style styles/wrapper}
[your-device installation-id installation-name] [your-device (first installations)]
(when (seq installations) (when (seq (rest installations))
[list/flat-list {:data installations [list/flat-list {:data (rest installations)
:default-separator? false :default-separator? false
:key-fn :installation-id :key-fn :installation-id
:render-fn render-row}])]) :render-fn render-row}])])
@ -182,26 +184,24 @@
[react/touchable-highlight {:on-press #(.openURL (react/linking) "https://status.im/tutorials/pairing.html")} [react/touchable-highlight {:on-press #(.openURL (react/linking) "https://status.im/tutorials/pairing.html")}
[react/text {:style styles/info-section-text} (i18n/label :t/learn-more)]]]) [react/text {:style styles/info-section-text} (i18n/label :t/learn-more)]]])
(defn installations-list [installation-id installation-name installations] (defn installations-list [installations]
[react/view {:style styles/installation-list} [react/view {:style styles/installation-list}
[react/view {:style styles/paired-devices-title} [react/view {:style styles/paired-devices-title}
[react/text (i18n/label :t/paired-devices)]] [react/text (i18n/label :t/paired-devices)]]
(render-rows installation-id installation-name installations)]) (render-rows installations)])
(views/defview installations [] (views/defview installations []
(views/letsubs [installation-id [:pairing/installation-id] (views/letsubs [installations [:pairing/installations]]
installation-name [:pairing/installation-name]
installations [:pairing/installations]]
[react/view {:flex 1} [react/view {:flex 1}
[status-bar/status-bar] [status-bar/status-bar]
[toolbar/toolbar {} [toolbar/toolbar {}
toolbar/default-nav-back toolbar/default-nav-back
[toolbar/content-title (i18n/label :t/devices)]] [toolbar/content-title (i18n/label :t/devices)]]
[react/scroll-view {:style {:background-color :white}} [react/scroll-view {:style {:background-color :white}}
(if (string/blank? installation-name) (if (and false (string/blank? (-> installations first :name)))
[edit-installation-name] [edit-installation-name]
[react/view [react/view
[pair-this-device] [pair-this-device]
[info-section] [info-section]
[installations-list installation-id installation-name installations]])] [installations-list installations]])]
(when (seq installations) [footer syncing])])) (when (seq installations) [footer syncing])]))

View File

@ -12,6 +12,7 @@
(def ^:private mergable-keys (def ^:private mergable-keys
#{:data-store/tx :data-store/base-tx :chat-received-message/add-fx #{:data-store/tx :data-store/base-tx :chat-received-message/add-fx
:shh/post :filters/load-filters :shh/post :filters/load-filters
:pairing/set-installation-metadata
:shh/send-direct-message :shh/remove-filter :shh/send-direct-message :shh/remove-filter
:shh/generate-sym-key-from-password :transport/confirm-messages-processed :shh/generate-sym-key-from-password :transport/confirm-messages-processed
:group-chats/extract-membership-signature :utils/dispatch-later :json-rpc/call}) :group-chats/extract-membership-signature :utils/dispatch-later :json-rpc/call})

View File

@ -229,17 +229,12 @@
(testing "not coming from us" (testing "not coming from us"
(is (not (:db (pairing/handle-pair-installation cofx pair-message 1 "not-us"))))) (is (not (:db (pairing/handle-pair-installation cofx pair-message 1 "not-us")))))
(testing "coming from us" (testing "coming from us"
(is (= {"1" {:has-bundle? true (is (= [["1"
:installation-id "1" {:name "name"
:fcm-token "fcm-token" :fcmToken "fcm-token"
:name "name" :deviceType "ios"}]]
:last-paired 1 (:pairing/set-installation-metadata
:device-type "ios"} (pairing/handle-pair-installation cofx pair-message 1 "us")))))))
"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 (deftest sync-installation-messages-test
(testing "it creates a sync installation message" (testing "it creates a sync installation message"
@ -306,10 +301,7 @@
expected {"installation-1" installation-1 expected {"installation-1" installation-1
"installation-2" {:has-bundle? true "installation-2" {:has-bundle? true
:installation-id "installation-2"}}] :installation-id "installation-2"}}]
(is (= expected (get-in (pairing/handle-bundles-added cofx new-installation) [:db :pairing/installations]))))) (is (:pairing/get-our-installations (pairing/handle-bundles-added cofx new-installation)))))
(testing "already existing installation"
(let [old-installation {:identity "us" :installationID "installation-1"}]
(is (not (pairing/handle-bundles-added cofx old-installation)))))
(testing "not from us" (testing "not from us"
(let [new-installation {:identity "not-us" :installationID "does-not-matter"}] (let [new-installation {:identity "not-us" :installationID "does-not-matter"}]
(is (not (pairing/handle-bundles-added cofx new-installation))))))) (is (not (pairing/handle-bundles-added cofx new-installation)))))))
@ -321,3 +313,23 @@
(testing "has paired devices" (testing "has paired devices"
(is (pairing/has-paired-installations? {:db {:pairing/installations {"1" {} (is (pairing/has-paired-installations? {:db {:pairing/installations {"1" {}
"2" {:enabled? true}}}})))) "2" {:enabled? true}}}}))))
(deftest sort-installations
(let [id "0"
expected [{:installation-id id
:timestamp (rand-int 200)
:enabled? false}
{:installation-id "1"
:timestamp 3
:enabled? true}
{:installation-id "2"
:timestamp 2
:enabled? true}
{:installation-id "3"
:timestamp 10
:enabled? false}
{:installation-id "4"
:timestamp 9
:enabled? false}]]
(is (= expected (pairing/sort-installations id (shuffle expected))))))