2018-09-06 12:04:12 +02:00
|
|
|
(ns status-im.mailserver.core
|
2018-08-22 23:31:22 +02:00
|
|
|
(:require [clojure.string :as string]
|
2018-09-06 12:04:12 +02:00
|
|
|
[re-frame.core :as re-frame]
|
2018-08-22 23:31:22 +02:00
|
|
|
[status-im.data-store.mailservers :as data-store.mailservers]
|
2018-09-06 12:04:12 +02:00
|
|
|
[status-im.i18n :as i18n]
|
|
|
|
[status-im.fleet.core :as fleet]
|
|
|
|
[status-im.accounts.update.core :as accounts.update]
|
2018-09-24 17:59:02 +02:00
|
|
|
[status-im.utils.fx :as fx]
|
|
|
|
[status-im.ui.screens.navigation :as navigation]))
|
2018-06-01 10:04:48 +02:00
|
|
|
|
2018-05-29 12:16:22 +02:00
|
|
|
(def enode-address-regex #"enode://[a-zA-Z0-9]+\@\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b:(\d{1,5})")
|
|
|
|
(def enode-url-regex #"enode://[a-zA-Z0-9]+:(.+)\@\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b:(\d{1,5})")
|
|
|
|
|
2018-06-01 10:04:48 +02:00
|
|
|
(defn- extract-address-components [address]
|
|
|
|
(rest (re-matches #"enode://(.*)@(.*)" address)))
|
|
|
|
|
2018-05-29 12:16:22 +02:00
|
|
|
(defn- extract-url-components [address]
|
|
|
|
(rest (re-matches #"enode://(.*?):(.*)@(.*)" address)))
|
|
|
|
|
|
|
|
(defn valid-enode-url? [address]
|
|
|
|
(re-matches enode-url-regex address))
|
|
|
|
|
|
|
|
(defn valid-enode-address? [address]
|
|
|
|
(re-matches enode-address-regex address))
|
|
|
|
|
2018-06-01 10:04:48 +02:00
|
|
|
(defn build-url [address password]
|
|
|
|
(let [[initial host] (extract-address-components address)]
|
|
|
|
(str "enode://" initial ":" password "@" host)))
|
|
|
|
|
2018-09-24 17:59:02 +02:00
|
|
|
(fx/defn set-input [{:keys [db]} input-key value]
|
2018-06-01 10:04:48 +02:00
|
|
|
{:db (update
|
|
|
|
db
|
|
|
|
:mailservers/manage
|
|
|
|
assoc
|
|
|
|
input-key
|
|
|
|
{:value value
|
|
|
|
:error (case input-key
|
|
|
|
:id false
|
|
|
|
:name (string/blank? value)
|
2018-05-29 12:16:22 +02:00
|
|
|
:url (not (valid-enode-url? value)))})})
|
2018-06-01 10:04:48 +02:00
|
|
|
|
2018-06-13 15:37:51 +02:00
|
|
|
(defn- address->mailserver [address]
|
|
|
|
(let [[enode password url :as response] (extract-url-components address)]
|
|
|
|
(cond-> {:address (if (seq response)
|
|
|
|
(str "enode://" enode "@" url)
|
|
|
|
address)
|
|
|
|
:user-defined true}
|
|
|
|
password (assoc :password password))))
|
|
|
|
|
|
|
|
(defn- build [id mailserver-name address]
|
|
|
|
(assoc (address->mailserver address)
|
2018-09-18 10:13:35 +02:00
|
|
|
:id id
|
2018-06-13 15:37:51 +02:00
|
|
|
:name mailserver-name))
|
|
|
|
|
2018-09-24 17:59:02 +02:00
|
|
|
(defn connected? [{:keys [db]} id]
|
2018-06-13 15:37:51 +02:00
|
|
|
(= (:inbox/current-id db) id))
|
2018-06-01 10:04:48 +02:00
|
|
|
|
2018-09-24 17:59:02 +02:00
|
|
|
(defn fetch [{:keys [db] :as cofx} id]
|
2018-09-04 14:15:50 +02:00
|
|
|
(get-in db [:inbox/wnodes (fleet/current-fleet db) id]))
|
2018-06-13 15:37:51 +02:00
|
|
|
|
|
|
|
(defn fetch-current [{:keys [db] :as cofx}]
|
2018-09-24 17:59:02 +02:00
|
|
|
(fetch cofx (:inbox/current-id db)))
|
2018-06-13 15:37:51 +02:00
|
|
|
|
2018-07-13 08:04:02 +02:00
|
|
|
(defn preferred-mailserver-id [{:keys [db] :as cofx}]
|
2018-09-04 14:15:50 +02:00
|
|
|
(get-in db [:account/account :settings :wnode (fleet/current-fleet db)]))
|
2018-07-13 08:04:02 +02:00
|
|
|
|
|
|
|
(defn- round-robin
|
|
|
|
"Find the choice and pick the next one, default to first if not found"
|
|
|
|
[choices current-id]
|
|
|
|
(let [next-index (reduce
|
|
|
|
(fn [index choice]
|
|
|
|
(if (= current-id choice)
|
|
|
|
(reduced (inc index))
|
|
|
|
(inc index)))
|
|
|
|
0
|
|
|
|
choices)]
|
|
|
|
(nth choices
|
|
|
|
(mod
|
|
|
|
next-index
|
|
|
|
(count choices)))))
|
|
|
|
|
2018-06-13 15:37:51 +02:00
|
|
|
(defn selected-or-random-id
|
2018-07-13 08:04:02 +02:00
|
|
|
"Use the preferred mailserver if set & exists, otherwise picks one randomly
|
|
|
|
if current-id is not set, else round-robin"
|
2018-06-13 15:37:51 +02:00
|
|
|
[{:keys [db] :as cofx}]
|
2018-09-04 14:15:50 +02:00
|
|
|
(let [current-fleet (fleet/current-fleet db)
|
|
|
|
current-id (:inbox/current-id db)
|
|
|
|
preference (preferred-mailserver-id cofx)
|
|
|
|
choices (-> db :inbox/wnodes current-fleet keys)]
|
2018-06-13 15:37:51 +02:00
|
|
|
(if (and preference
|
2018-09-24 17:59:02 +02:00
|
|
|
(fetch cofx preference))
|
2018-06-13 15:37:51 +02:00
|
|
|
preference
|
2018-07-13 08:04:02 +02:00
|
|
|
(if current-id
|
|
|
|
(round-robin choices current-id)
|
|
|
|
(rand-nth choices)))))
|
2018-06-01 10:04:48 +02:00
|
|
|
|
|
|
|
(def default? (comp not :user-defined fetch))
|
|
|
|
|
2018-09-24 17:59:02 +02:00
|
|
|
(fx/defn delete
|
|
|
|
[{:keys [db] :as cofx} id]
|
2018-09-06 12:04:12 +02:00
|
|
|
(merge (when-not (or
|
2018-09-24 17:59:02 +02:00
|
|
|
(default? cofx id)
|
|
|
|
(connected? cofx id))
|
2018-09-06 12:04:12 +02:00
|
|
|
{:db (update-in db [:inbox/wnodes (fleet/current-fleet db)] dissoc id)
|
|
|
|
:data-store/tx [(data-store.mailservers/delete-tx id)]})
|
|
|
|
{:dispatch [:navigate-back]}))
|
2018-06-01 10:04:48 +02:00
|
|
|
|
2018-09-24 17:59:02 +02:00
|
|
|
(fx/defn set-current-mailserver
|
|
|
|
[{:keys [db] :as cofx}]
|
|
|
|
{:db (assoc db :inbox/current-id
|
|
|
|
(selected-or-random-id cofx))})
|
2018-06-13 15:37:51 +02:00
|
|
|
|
2018-09-24 17:59:02 +02:00
|
|
|
(fx/defn add-custom-mailservers
|
|
|
|
[{:keys [db]} mailservers]
|
2018-09-04 14:15:50 +02:00
|
|
|
{:db (reduce (fn [db {:keys [id fleet] :as mailserver}]
|
|
|
|
(assoc-in db [:inbox/wnodes fleet id]
|
2018-06-13 15:37:51 +02:00
|
|
|
(-> mailserver
|
2018-09-04 14:15:50 +02:00
|
|
|
(dissoc :fleet)
|
2018-06-13 15:37:51 +02:00
|
|
|
(assoc :user-defined true))))
|
|
|
|
db
|
|
|
|
mailservers)})
|
|
|
|
|
2018-09-24 17:59:02 +02:00
|
|
|
(fx/defn edit [{:keys [db] :as cofx} id]
|
2018-06-01 10:04:48 +02:00
|
|
|
(let [{:keys [id
|
|
|
|
address
|
|
|
|
password
|
2018-09-24 17:59:02 +02:00
|
|
|
name]} (fetch cofx id)
|
|
|
|
url (when address (build-url address password))]
|
|
|
|
(fx/merge cofx
|
|
|
|
(set-input :id id)
|
|
|
|
(set-input :url (str url))
|
|
|
|
(set-input :name (str name))
|
|
|
|
(navigation/navigate-to-cofx :edit-mailserver nil))))
|
|
|
|
|
|
|
|
(fx/defn upsert
|
2018-09-24 18:27:04 +02:00
|
|
|
[{{:mailservers/keys [manage] :account/keys [account] :as db} :db
|
|
|
|
random-id-generator :random-id-generator :as cofx}]
|
2018-06-01 10:04:48 +02:00
|
|
|
(let [{:keys [name url id]} manage
|
2018-09-04 14:15:50 +02:00
|
|
|
current-fleet (fleet/current-fleet db)
|
2018-06-01 10:04:48 +02:00
|
|
|
mailserver (build
|
|
|
|
(or (:value id)
|
2018-09-24 18:27:04 +02:00
|
|
|
(keyword (string/replace (random-id-generator) "-" "")))
|
2018-06-01 10:04:48 +02:00
|
|
|
(:value name)
|
|
|
|
(:value url))
|
2018-09-24 17:59:02 +02:00
|
|
|
current (connected? cofx (:id mailserver))]
|
2018-06-01 10:04:48 +02:00
|
|
|
{:db (-> db
|
|
|
|
(dissoc :mailservers/manage)
|
2018-09-04 14:15:50 +02:00
|
|
|
(assoc-in [:inbox/wnodes current-fleet (:id mailserver)] mailserver))
|
2018-06-01 10:04:48 +02:00
|
|
|
:data-store/tx [{:transaction
|
|
|
|
(data-store.mailservers/save-tx (assoc
|
|
|
|
mailserver
|
2018-09-04 14:15:50 +02:00
|
|
|
:fleet
|
|
|
|
current-fleet))
|
2018-06-01 10:04:48 +02:00
|
|
|
;; we naively logout if the user is connected to the edited mailserver
|
2018-09-06 12:04:12 +02:00
|
|
|
:success-event (when current [:accounts.logout.ui/logout-confirmed])}]
|
2018-06-01 10:04:48 +02:00
|
|
|
:dispatch [:navigate-back]}))
|
2018-09-06 12:04:12 +02:00
|
|
|
|
2018-09-24 17:59:02 +02:00
|
|
|
(fx/defn show-connection-confirmation
|
|
|
|
[{:keys [db]} mailserver-id]
|
2018-09-06 12:04:12 +02:00
|
|
|
(let [current-fleet (fleet/current-fleet db)]
|
|
|
|
{:ui/show-confirmation
|
|
|
|
{:title (i18n/label :t/close-app-title)
|
|
|
|
:content (i18n/label :t/connect-wnode-content
|
|
|
|
{:name (get-in db [:inbox/wnodes current-fleet mailserver-id :name])})
|
|
|
|
:confirm-button-text (i18n/label :t/close-app-button)
|
|
|
|
:on-accept #(re-frame/dispatch [:mailserver.ui/connect-confirmed current-fleet mailserver-id])
|
|
|
|
:on-cancel nil}}))
|
|
|
|
|
2018-09-24 17:59:02 +02:00
|
|
|
(fx/defn show-delete-confirmation
|
|
|
|
[{:keys [db]} mailserver-id]
|
2018-09-06 12:04:12 +02:00
|
|
|
{:ui/show-confirmation
|
|
|
|
{:title (i18n/label :t/delete-mailserver-title)
|
|
|
|
:content (i18n/label :t/delete-mailserver-are-you-sure)
|
|
|
|
:confirm-button-text (i18n/label :t/delete-mailserver)
|
|
|
|
:on-accept #(re-frame/dispatch [:mailserver.ui/delete-confirmed mailserver-id])}})
|
|
|
|
|
2018-09-24 17:59:02 +02:00
|
|
|
(fx/defn save-settings
|
|
|
|
[{:keys [db] :as cofx} current-fleet mailserver-id]
|
2018-09-06 12:04:12 +02:00
|
|
|
(let [settings (get-in db [:account/account :settings])]
|
2018-09-24 17:59:02 +02:00
|
|
|
(accounts.update/update-settings cofx
|
|
|
|
(assoc-in settings [:wnode current-fleet] mailserver-id)
|
|
|
|
{:success-event [:accounts.update.callback/save-settings-success]})))
|
2018-09-06 12:04:12 +02:00
|
|
|
|
2018-09-24 17:59:02 +02:00
|
|
|
(fx/defn set-url-from-qr
|
|
|
|
[cofx url]
|
2018-09-06 12:04:12 +02:00
|
|
|
(assoc (set-input :url url cofx)
|
|
|
|
:dispatch [:navigate-back]))
|