validate incoming message
- add validate method to StatusMessage protocol - spec all message types for use in validate method - use valid method after transit/decode step to reject invalid messages Signed-off-by: yenda <eric@status.im>
This commit is contained in:
parent
7a06a415c2
commit
81b2afebc1
|
@ -1,7 +1,9 @@
|
|||
(ns ^{:doc "DB spec and utils for the transport layer"}
|
||||
status-im.transport.db
|
||||
(:require-macros [status-im.utils.db :refer [allowed-keys]])
|
||||
(:require [cljs.spec.alpha :as spec]))
|
||||
(:require [cljs.spec.alpha :as spec]
|
||||
status-im.ui.screens.contacts.db
|
||||
[clojure.string :as s]))
|
||||
|
||||
;; required
|
||||
(spec/def ::ack (spec/coll-of string? :kind vector?))
|
||||
|
@ -35,3 +37,62 @@
|
|||
:fetch-history? true
|
||||
:resend? resend?
|
||||
:topic topic})
|
||||
|
||||
(spec/def ::profile-image :contact/photo-path)
|
||||
|
||||
(spec/def :chat/name (spec/nilable string?))
|
||||
|
||||
(spec/def :group-chat/admin :global/public-key)
|
||||
(spec/def :group-chat/participants (spec/coll-of :global/public-key :kind set?))
|
||||
(spec/def :group-chat/signature string?)
|
||||
|
||||
(spec/def :message.content/text (spec/and string? (complement s/blank?)))
|
||||
(spec/def :message.content/response-to string?)
|
||||
(spec/def :message.content/command-path (spec/tuple string? (spec/coll-of (spec/or :scope keyword? :chat-id string?) :kind set? :min-count 1)))
|
||||
(spec/def :message.content/params (spec/map-of keyword? any?))
|
||||
|
||||
(spec/def ::content (spec/conformer (fn [content]
|
||||
(cond
|
||||
(string? content) {:text content}
|
||||
(map? content) content
|
||||
:else :clojure.spec/invalid))))
|
||||
(spec/def ::content-type #{"text/plain" "command"})
|
||||
(spec/def ::message-type #{:group-user-message :public-group-user-message :user-message})
|
||||
(spec/def ::clock-value (spec/nilable pos-int?))
|
||||
(spec/def ::timestamp (spec/nilable pos-int?))
|
||||
|
||||
(spec/def :message/id string?)
|
||||
(spec/def :message/ids (spec/coll-of :message/id :kind set?))
|
||||
|
||||
(spec/def ::message (spec/or :message/contact-request :message/contact-request
|
||||
:message/contact-update :message/contact-update
|
||||
:message/contact-request-confirmed :message/contact-request-confirmed
|
||||
:message/message :message/message
|
||||
:message/message-seen :message/message-seen
|
||||
:message/group-membership-update :message/group-membership-update))
|
||||
|
||||
(spec/def :message/contact-request (spec/keys :req-un [:contact/name ::profile-image :contact/address :contact/fcm-token]))
|
||||
(spec/def :message/contact-update (spec/keys :req-un [:contact/name ::profile-image :contact/address :contact/fcm-token]))
|
||||
(spec/def :message/contact-request-confirmed (spec/keys :req-un [:contact/name ::profile-image :contact/address :contact/fcm-token]))
|
||||
(spec/def :message/new-contact-key (spec/keys :req-un [::sym-key ::topic ::message]))
|
||||
|
||||
(spec/def :message/message-seen (spec/keys :req-un [:message/ids]))
|
||||
|
||||
(spec/def :message/group-membership-update (spec/keys :req-un [:chat/chat-id :chat/name :group-chat/admin :group-chat/participants :group-chat/signature :message/message]))
|
||||
|
||||
(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]
|
||||
:req-opt [:message.content/response-to]))
|
||||
(spec/def :message.command/content (spec/keys :req-un [:message.content/command-path :message.content/params]))
|
||||
|
||||
(defmulti content-type :content-type)
|
||||
|
||||
(defmethod content-type "command" [_]
|
||||
(spec/merge :message/message-common
|
||||
(spec/keys :req-un [:message.command/content])))
|
||||
|
||||
(defmethod content-type :default [_]
|
||||
(spec/merge :message/message-common
|
||||
(spec/keys :req-un [:message.text/content])))
|
||||
|
||||
(spec/def :message/message (spec/multi-spec content-type :content-type))
|
||||
|
|
|
@ -28,9 +28,10 @@
|
|||
transit/deserialize)]
|
||||
(when (and sig status-message)
|
||||
(try
|
||||
(when-let [valid-message (message/validate status-message)]
|
||||
(fx/merge (assoc cofx :js-obj js-message)
|
||||
#(message/receive status-message (or chat-id sig) sig timestamp %)
|
||||
(update-last-received-from-inbox now-in-s timestamp ttl))
|
||||
#(message/receive valid-message (or chat-id sig) sig timestamp %)
|
||||
(update-last-received-from-inbox now-in-s timestamp ttl)))
|
||||
(catch :default e nil))))) ; ignore unknown message types
|
||||
|
||||
(defn- js-array->seq [array]
|
||||
|
|
|
@ -4,4 +4,5 @@
|
|||
(defprotocol StatusMessage
|
||||
"Protocol for the messages that are sent through the transport layer"
|
||||
(send [this chat-id cofx] "Method producing all effects necessary for sending the message record")
|
||||
(receive [this chat-id signature timestamp cofx] "Method producing all effects necessary for receiving the message record"))
|
||||
(receive [this chat-id signature timestamp cofx] "Method producing all effects necessary for receiving the message record")
|
||||
(validate [this] "Method returning the message if it is valid or nil if it is not"))
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
[status-im.transport.message.core :as message]
|
||||
[status-im.transport.message.v1.protocol :as protocol]
|
||||
[status-im.transport.utils :as transport.utils]
|
||||
[status-im.utils.fx :as fx]))
|
||||
[status-im.utils.fx :as fx]
|
||||
[cljs.spec.alpha :as spec]))
|
||||
|
||||
(defrecord ContactRequest [name profile-image address fcm-token]
|
||||
message/StatusMessage
|
||||
|
@ -23,7 +24,10 @@
|
|||
:on-success on-success}]}
|
||||
(protocol/init-chat {:chat-id chat-id
|
||||
:topic topic
|
||||
:resend? "contact-request"})))))
|
||||
:resend? "contact-request"}))))
|
||||
(validate [this]
|
||||
(when (spec/valid? :message/contact-request this)
|
||||
this)))
|
||||
|
||||
(defrecord ContactRequestConfirmed [name profile-image address fcm-token]
|
||||
message/StatusMessage
|
||||
|
@ -39,7 +43,10 @@
|
|||
:chat updated-chat})]}
|
||||
(protocol/send-with-pubkey {:chat-id chat-id
|
||||
:payload this
|
||||
:success-event success-event})))))
|
||||
:success-event success-event}))))
|
||||
(validate [this]
|
||||
(when (spec/valid? :message/contact-request-confirmed this)
|
||||
this)))
|
||||
|
||||
(fx/defn send-contact-update
|
||||
[{:keys [db] :as cofx} chat-id payload]
|
||||
|
@ -73,7 +80,10 @@
|
|||
(:contacts/contacts db))
|
||||
;;NOTE: chats with contacts use public-key as chat-id
|
||||
send-contact-update-fxs (map #(send-contact-update % this) contact-public-keys)]
|
||||
(apply fx/merge cofx send-contact-update-fxs))))
|
||||
(apply fx/merge cofx send-contact-update-fxs)))
|
||||
(validate [this]
|
||||
(when (spec/valid? :message/contact-update this)
|
||||
this)))
|
||||
|
||||
(fx/defn remove-chat-filter
|
||||
"Stops the filter for the given chat-id"
|
||||
|
@ -126,4 +136,7 @@
|
|||
;; dereferrencing it
|
||||
(remove-chat-filter chat-id)))
|
||||
;; if we don't save the key, we read the message directly
|
||||
(message/receive message chat-id chat-id timestamp cofx)))))
|
||||
(message/receive message chat-id chat-id timestamp cofx))))
|
||||
(validate [this]
|
||||
(when (spec/valid? :message/new-contact-key this)
|
||||
this)))
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
(ns status-im.transport.message.v1.core
|
||||
(:require [status-im.transport.message.core :as message]))
|
||||
(:require [status-im.transport.message.core :as message]
|
||||
[cljs.spec.alpha :as spec]))
|
||||
|
||||
(defrecord GroupMembershipUpdate
|
||||
[chat-id chat-name admin participants leaves version signature message]
|
||||
message/StatusMessage)
|
||||
message/StatusMessage
|
||||
(validate [this]
|
||||
(when (spec/valid? :message/group-membership-update this)
|
||||
this)))
|
||||
|
||||
(defrecord GroupLeave
|
||||
[]
|
||||
message/StatusMessage)
|
||||
message/StatusMessage
|
||||
(validate [this] this))
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
[status-im.transport.message.core :as message]
|
||||
[status-im.transport.message.v1.core :as transport]
|
||||
[status-im.transport.utils :as transport.utils]
|
||||
[status-im.utils.fx :as fx]))
|
||||
[status-im.utils.fx :as fx]
|
||||
[cljs.spec.alpha :as spec]))
|
||||
|
||||
(def ^:private whisper-opts
|
||||
{:ttl 10 ;; ttl of 10 sec
|
||||
|
@ -107,7 +108,10 @@
|
|||
:show? true
|
||||
:chat-id chat-id
|
||||
:from signature
|
||||
:js-obj (:js-obj cofx))]}))
|
||||
:js-obj (:js-obj cofx))]})
|
||||
(validate [this]
|
||||
(when (spec/valid? :message/message this)
|
||||
(spec/conform :message/message this))))
|
||||
|
||||
(defrecord MessagesSeen [message-ids]
|
||||
message/StatusMessage
|
||||
|
@ -120,4 +124,7 @@
|
|||
(send cofx {:chat-id chat-id
|
||||
:payload this})))
|
||||
(receive [this chat-id signature _ cofx]
|
||||
(chat/receive-seen cofx chat-id signature this)))
|
||||
(chat/receive-seen cofx chat-id signature this))
|
||||
(validate [this]
|
||||
(when (spec/valid? :message/message-seen this)
|
||||
this)))
|
||||
|
|
Loading…
Reference in New Issue