Update public/private keys for discoveries (#557)

This commit is contained in:
alwx 2017-01-02 18:45:39 +03:00 committed by Roman Volosovskyi
parent be5c6fe548
commit 9462088de8
9 changed files with 110 additions and 43 deletions

View File

@ -71,7 +71,7 @@
account' (assoc account :network (or acc-network network))] account' (assoc account :network (or acc-network network))]
(accounts-store/save account' true))) (accounts-store/save account' true)))
(defn send-account-update (defn broadcast-account-update
[{:keys [current-account-id current-public-key web3 accounts]} _] [{:keys [current-account-id current-public-key web3 accounts]} _]
(let [{:keys [name photo-path status]} (get accounts current-account-id) (let [{:keys [name photo-path status]} (get accounts current-account-id)
{:keys [updates-public-key updates-private-key]} (accounts current-account-id)] {:keys [updates-public-key updates-private-key]} (accounts current-account-id)]
@ -85,6 +85,19 @@
:status status :status status
:profile-image photo-path}}}}))) :profile-image photo-path}}}})))
(defn send-keys-update
[{:keys [current-account-id current-public-key web3 accounts contacts]} _]
(let [{:keys [name photo-path status]} (get accounts current-account-id)
{:keys [updates-public-key updates-private-key]} (accounts current-account-id)]
(doseq [id (u/identities contacts)]
(protocol/update-keys!
{:web3 web3
:message {:from current-public-key
:to id
:message-id (random/id)
:payload {:keypair {:public updates-public-key
:private updates-private-key}}}}))))
(register-handler (register-handler
:check-status-change :check-status-change
(u/side-effect! (u/side-effect!
@ -97,14 +110,27 @@
(when (seq hashtags) (when (seq hashtags)
(dispatch [:broadcast-status status hashtags])))))))) (dispatch [:broadcast-status status hashtags]))))))))
(defn account-update
[{:keys [current-account-id accounts] :as db} data]
(let [data (assoc data :last-updated (time/now-ms))
account (merge (get accounts current-account-id) data)]
(assoc-in db [:accounts current-account-id] account)))
(register-handler (register-handler
:account-update :account-update
(-> (fn [{:keys [current-account-id accounts] :as db} [_ data]] (-> (fn [db [_ data]]
(let [data (assoc data :last-updated (time/now-ms)) (account-update db data))
account (merge (get accounts current-account-id) data)] ((after save-account!))
(assoc-in db [:accounts current-account-id] account))) ((after broadcast-account-update))))
((after save-account!))
((after send-account-update)))) (register-handler
:account-update-keys
(-> (fn [db]
(let [{:keys [public private]} (protocol/new-keypair!)]
(account-update db {:updates-public-key public
:updates-private-key private})))
((after save-account!))
((after send-keys-update))))
(register-handler (register-handler
:send-account-update-if-needed :send-account-update-if-needed

View File

@ -231,14 +231,15 @@
(register-handler :set-contact-identity-from-qr set-contact-identity-from-qr) (register-handler :set-contact-identity-from-qr set-contact-identity-from-qr)
(register-handler :contact-update-received (register-handler
:contact-update-received
(u/side-effect! (u/side-effect!
(fn [{:keys [chats current-public-key] :as db} [_ {:keys [from payload]}]] (fn [{:keys [chats current-public-key] :as db} [_ {:keys [from payload]}]]
(when (not= current-public-key from) (when (not= current-public-key from)
(let [{:keys [content timestamp]} payload (let [{:keys [content timestamp]} payload
{:keys [status name profile-image]} (:profile content) {:keys [status name profile-image]} (:profile content)
prev-last-updated (get-in db [:contacts from :last-updated])] prev-last-updated (get-in db [:contacts from :last-updated])]
(if (<= prev-last-updated timestamp) (when (<= prev-last-updated timestamp)
(let [contact {:whisper-identity from (let [contact {:whisper-identity from
:name name :name name
:photo-path profile-image :photo-path profile-image
@ -249,12 +250,27 @@
(dispatch [:update-chat! {:chat-id from (dispatch [:update-chat! {:chat-id from
:name name}]))))))))) :name name}])))))))))
(register-handler :contact-online-received (register-handler
:update-keys-received
(u/side-effect!
(fn [db [_ {:keys [from payload]}]]
(let [{{:keys [public private]} :keypair
timestamp :timestamp} payload
prev-last-updated (get-in db [:contacts from :keys-last-updated])]
(when (<= prev-last-updated timestamp)
(let [contact {:whisper-identity from
:public-key public
:private-key private
:keys-last-updated timestamp}]
(dispatch [:update-contact! contact])))))))
(register-handler
:contact-online-received
(u/side-effect! (u/side-effect!
(fn [db [_ {:keys [from] (fn [db [_ {:keys [from]
{:keys [timestamp]} :payload}]] {{:keys [timestamp]} :content} :payload}]]
(let [prev-last-online (get-in db [:contacts from :last-online])] (let [prev-last-online (get-in db [:contacts from :last-online])]
(when (< prev-last-online timestamp) (when (and timestamp (< prev-last-online timestamp))
(protocol/reset-pending-messages! from) (protocol/reset-pending-messages! from)
(dispatch [:update-contact! {:whisper-identity from (dispatch [:update-contact! {:whisper-identity from
:last-online timestamp}])))))) :last-online timestamp}]))))))
@ -265,9 +281,11 @@
(fn [_ [_ {:keys [whisper-identity] :as contact}]] (fn [_ [_ {:keys [whisper-identity] :as contact}]]
(dispatch [:update-chat! {:chat-id whisper-identity (dispatch [:update-chat! {:chat-id whisper-identity
:pending-contact? true}]) :pending-contact? true}])
(dispatch [:update-contact! (assoc contact :pending true)])))) (dispatch [:update-contact! (assoc contact :pending true)])
(dispatch [:account-update-keys]))))
(register-handler :open-contact-menu (register-handler
:open-contact-menu
(u/side-effect! (u/side-effect!
(fn [_ [_ list-selection-fn {:keys [name] :as contact}]] (fn [_ [_ list-selection-fn {:keys [name] :as contact}]]
(list-selection-fn {:title name (list-selection-fn {:title name

View File

@ -3,24 +3,25 @@
(def schema {:name :contact (def schema {:name :contact
:primaryKey :whisper-identity :primaryKey :whisper-identity
:properties {:address {:type "string" :optional true} :properties {:address {:type "string" :optional true}
:whisper-identity "string" :whisper-identity "string"
:name {:type "string" :optional true} :name {:type "string" :optional true}
:photo-path {:type "string" :optional true} :photo-path {:type "string" :optional true}
:last-updated {:type "int" :default 0} :last-updated {:type "int" :default 0}
:last-online {:type "int" :default 0} :last-online {:type "int" :default 0}
:pending {:type "bool" :default false} :pending {:type "bool" :default false}
:status {:type "string" :optional true} :status {:type "string" :optional true}
:public-key {:type :string :public-key {:type :string
:optional true} :optional true}
:private-key {:type :string :private-key {:type :string
:optional true} :optional true}
:dapp? {:type :bool :keys-last-updated {:type "int" :default 0}
:default false} :dapp? {:type :bool
:dapp-url {:type :string :default false}
:optional true} :dapp-url {:type :string
:dapp-hash {:type :int :optional true}
:optional true}}}) :dapp-hash {:type :int
:optional true}}})
(defn migration [_ _] (defn migration [_ _]
(log/debug "migrating contact schema")) (log/debug "migrating contact schema"))

View File

@ -17,12 +17,6 @@
(assoc :tags []) (assoc :tags [])
(assoc :discoveries {})))) (assoc :discoveries {}))))
(defn identities [contacts]
(->> (map second contacts)
(remove (fn [{:keys [dapp? pending]}]
(or pending dapp?)))
(map :whisper-identity)))
(defmethod nav/preload-data! :discover (defmethod nav/preload-data! :discover
[db _] [db _]
(-> db (-> db
@ -46,7 +40,7 @@
:hashtags (vec hashtags) :hashtags (vec hashtags)
:profile {:name name :profile {:name name
:profile-image photo-path}}}] :profile-image photo-path}}}]
(doseq [id (identities contacts)] (doseq [id (u/identities contacts)]
(protocol/send-status! (protocol/send-status!
{:web3 web3 {:web3 web3
:message (assoc message :to id)})) :message (assoc message :to id)}))
@ -80,7 +74,7 @@
(register-handler :request-discoveries (register-handler :request-discoveries
(u/side-effect! (u/side-effect!
(fn [{:keys [current-public-key web3 contacts]}] (fn [{:keys [current-public-key web3 contacts]}]
(doseq [id (identities contacts)] (doseq [id (u/identities contacts)]
(when-not (protocol/message-pending? web3 :discoveries-request id) (when-not (protocol/message-pending? web3 :discoveries-request id)
(protocol/send-discoveries-request! (protocol/send-discoveries-request!
{:web3 web3 {:web3 web3

View File

@ -43,6 +43,7 @@
(def send-status! discoveries/send-status!) (def send-status! discoveries/send-status!)
(def send-discoveries-request! discoveries/send-discoveries-request!) (def send-discoveries-request! discoveries/send-discoveries-request!)
(def send-discoveries-response! discoveries/send-discoveries-response!) (def send-discoveries-response! discoveries/send-discoveries-response!)
(def update-keys! discoveries/update-keys!)
(def message-pending? d/message-pending?) (def message-pending? d/message-pending?)

View File

@ -29,7 +29,7 @@
message message
{:requires-ack? false {:requires-ack? false
:type :online :type :online
:payload {:timestamp (u/timestamp)} :payload {:content {:timestamp (u/timestamp)}}
:topics [(make-discover-topic (:from message))]})] :topics [(make-discover-topic (:from message))]})]
(d/add-pending-message! web3 message'))) (d/add-pending-message! web3 message')))
@ -105,6 +105,26 @@
(get-in message [:payload :profile])) (get-in message [:payload :profile]))
(update :payload dissoc :profile)))) (update :payload dissoc :profile))))
(s/def ::public string?)
(s/def ::private string?)
(s/def ::keypair (s/keys :req-un [::public ::private]))
(s/def :update-keys/payload
(s/keys :req-un [::keypair]))
(s/def :update-keys/message
(s/merge :protocol/message (s/keys :req-un [:update-keys/payload])))
(s/def :update-keys/options
(s/keys :req-un [:update-keys/message :options/web3]))
(defn update-keys!
[{:keys [web3 message] :as options}]
{:pre [(valid? :update-keys/options options)]}
(let [message (-> message
(assoc :type :update-keys
:requires-ack? false
:topics [(make-discover-topic (:from message))])
(assoc-in [:payload :timestamp] (u/timestamp)))]
(d/add-pending-message! web3 message)))
(s/def :status/payload (s/def :status/payload
(s/merge :message/payload (s/keys :req-un [::status]))) (s/merge :message/payload (s/keys :req-un [::status])))
(s/def :status/message (s/def :status/message

View File

@ -114,6 +114,7 @@
:discoveries-request (dispatch [:discoveries-request-received message]) :discoveries-request (dispatch [:discoveries-request-received message])
:discoveries-response (dispatch [:discoveries-response-received message]) :discoveries-response (dispatch [:discoveries-response-received message])
:profile (dispatch [:contact-update-received message]) :profile (dispatch [:contact-update-received message])
:update-keys (dispatch [:update-keys-received message])
:online (dispatch [:contact-online-received message]) :online (dispatch [:contact-online-received message])
:pending (dispatch [:pending-message-upsert message]) :pending (dispatch [:pending-message-upsert message])
:sent (let [{:keys [to id group-id]} message :sent (let [{:keys [to id group-id]} message

View File

@ -22,7 +22,7 @@
#{:group-message :group-invitation :add-group-identity #{:group-message :group-invitation :add-group-identity
:remove-group-identity :leave-group :update-group}) :remove-group-identity :leave-group :update-group})
(s/def :discover-message/type #{:online :status :discover :contact-request}) (s/def :discover-message/type #{:online :status :discover :contact-request :update-keys})
(s/def :message/type (s/def :message/type
(s/or :group :group-message/type (s/or :group :group-message/type

View File

@ -32,3 +32,9 @@
(re-seq #"#[^ !?,;:.]+" status))] (re-seq #"#[^ !?,;:.]+" status))]
(set (or hashtags []))) (set (or hashtags [])))
#{})) #{}))
(defn identities [contacts]
(->> (map second contacts)
(remove (fn [{:keys [dapp? pending]}]
(or pending dapp?)))
(map :whisper-identity)))