Should fix most of the authentication issues

This commit is contained in:
2023-09-05 23:08:22 -07:00
parent a6e4080746
commit a56d3b0b84
22 changed files with 506 additions and 179 deletions

View File

@@ -19,7 +19,8 @@
[mount.core :as mount]
[clojure.java.io :as io]
[datomic.db :refer [id-literal]]
[datomic.function :refer [construct]])
[datomic.function :refer [construct]]
[auto-ap.logging :as alog])
(:import
(java.util UUID)))
@@ -579,8 +580,6 @@
(defn add-sorter-fields [q sort-map args]
(reduce
(fn [q {:keys [sort-key] :as z}]
(prn z)
(println (class sort-key))
(merge-query q
{:query {:find [(symbol (str "?sort-" sort-key))]
:where (sort-map
@@ -896,3 +895,22 @@
(defn query2 [query]
(apply dc/q (:query query) (:args query)))
(defn observable-q [query]
nil)
(defn observable-query [query]
(mu/with-context {:query (:query query)
:args (:args query)
:query-stats true
:io-context ::hello}
(mu/trace ::query
[]
(let [query-results (dc/query {:query (:query query)
:args (:args query)
:query-stats true
:io-context ::hello})]
(alog/info ::query-stats
:io-stats (:io-stats query-results)
:query-stats (:query-stats query-results))
(:ret query-results)))))

View File

@@ -6,13 +6,13 @@
apply-sort-3
conn
merge-query
pull-many
query2]]
[auto-ap.graphql.utils :refer [limited-clients]]
observable-query
pull-many]]
[auto-ap.graphql.utils :refer [extract-client-ids]]
[clj-time.coerce :as c]
[clojure.set :refer [rename-keys]]
[clojure.tools.logging :as log]
[datomic.api :as dc]))
[datomic.api :as dc]
[clj-time.coerce :as coerce]))
(defn <-datomic [result]
(-> result
@@ -38,18 +38,25 @@
(defn raw-graphql-ids
([args] (raw-graphql-ids (dc/db conn) args))
([db args]
(let [check-number-like (try (Long/parseLong (:check-number-like args)) (catch Exception _ nil))
(let [valid-clients (extract-client-ids (:clients args)
(:client-id args)
(when (:client-code args)
[:client/code (:client-code args)]))
check-number-like (try (Long/parseLong (:check-number-like args)) (catch Exception _ nil))
query (if (:exact-match-id args)
{:query {:find '[?e]
:in '[$ ?e [?c ...]]
:where '[[?e :payment/client ?c]]}
:args [db
(:exact-match-id args)
(map :db/id (:clients args))]}
valid-clients]}
(cond-> {:query {:find []
:in ['$]
:where []}
:args [db]}
:in '[$ [?clients ?start ?end]]
:where '[[(iol-ion.query/scan-payments $ ?clients ?start ?end) [[?e _ ?sort-default] ...]]]}
:args [db
[valid-clients
(some-> (:start (:date-range args)) coerce/to-date)
(some-> (:end (:date-range args)) coerce/to-date)]]}
(:sort args) (add-sorter-fields {"client" ['[?e :payment/client ?c]
'[?c :client/name ?sort-client]]
"vendor" ['[?e :payment/vendor ?v]
@@ -66,23 +73,6 @@
:where []}
:args [(:exact-match-id args)]})
true
(merge-query {:query {:in ['[?xx ...]]
:where ['[?e :payment/client ?xx]]}
:args [(map :db/id (:clients args))]})
(:client-id args)
(merge-query {:query {:in ['?client-id]
:where ['[?e :payment/client ?client-id]]}
:args [(:client-id args)]})
(:client-code args)
(merge-query {:query {:in ['?client-code]
:where ['[?e :payment/client ?client-id]
'[?client-id :client/code ?client-code]]}
:args [(:client-code args)]})
(:vendor-id args)
(merge-query {:query {:in ['?vendor-id]
:where ['[?e :payment/vendor ?vendor-id]]}
@@ -133,18 +123,6 @@
(merge-query {:query {:in ['?status]
:where ['[?e :payment/status ?status]]}
:args [(:status args)]})
(:start (:date-range args))
(merge-query {:query {:in '[?start-date]
:where ['[?e :payment/date ?date]
'[(>= ?date ?start-date)]]}
:args [(c/to-date (:start (:date-range args)))]})
(:end (:date-range args))
(merge-query {:query {:in '[?end-date]
:where ['[?e :payment/date ?date]
'[(<= ?date ?end-date)]]}
:args [(c/to-date (:end (:date-range args)))]})
(:payment-type args)
(merge-query {:query {:in '[?payment-type]
@@ -157,12 +135,10 @@
:args [check-number-like]})
true
(merge-query {:query {:find ['?sort-default '?e]
:where ['[?e :payment/date ?sort-default]]}})))]
(merge-query {:query {:find ['?sort-default '?e]}})))]
(log/info query)
(cond->> (query2 query)
(cond->> (observable-query query)
true (apply-sort-3 (assoc args :default-asc? false))
true (apply-pagination args)))))

View File

@@ -4,13 +4,14 @@
:refer [add-sorter-fields
apply-pagination
query2
observable-query
apply-sort-3
conn
merge-query
pull-many]]
[auto-ap.datomic.accounts :as d-accounts]
[auto-ap.datomic.vendors :as d-vendors]
[auto-ap.graphql.utils :refer [limited-clients]]
[auto-ap.graphql.utils :refer [limited-clients extract-client-ids]]
[auto-ap.time-utils :refer [next-dom]]
[clj-time.coerce :as coerce]
[clj-time.core :as time]
@@ -48,18 +49,27 @@
([args]
(raw-graphql-ids (dc/db conn) args))
([db args]
(let [query
(let [valid-clients (extract-client-ids (:clients args)
(:client-id args)
(when (:client-code args)
[:client/code (:client-code args)]))
query
(if (:exact-match-id args)
{:query {:find '[?e]
:in '[$ ?e [?c ...]]
:where '[[?e :invoice/client ?c]]}
:args [db
(:exact-match-id args)
(map :db/id (:clients args))]}
valid-clients]}
(cond-> {:query {:find []
:in ['$]
:where []}
:args [db]}
:in '[$ [?clients ?start ?end]]
:where '[
[(iol-ion.query/scan-invoices $ ?clients ?start ?end) [[?e _ ?sort-default] ...]]
]}
:args [db
[valid-clients
(some-> (:start (:date-range args)) coerce/to-date)
(some-> (:end (:date-range args)) coerce/to-date)]]}
(:client-id args)
@@ -81,15 +91,9 @@
:args [ (cond-> (:original-id args)
(string? (:original-id args)) Long/parseLong )]})
(:start (:date-range args)) (merge-query {:query {:in '[?start-date]
:where ['[?e :invoice/date ?date]
'[(>= ?date ?start-date)]]}
:args [(coerce/to-date (:start (:date-range args)))]})
(:end (:date-range args)) (merge-query {:query {:in '[?end-date]
:where ['[?e :invoice/date ?date]
'[(<= ?date ?end-date)]]}
:args [(coerce/to-date (:end (:date-range args)))]})
(:start (:due-range args)) (merge-query {:query {:in '[?start-due]
:where ['[?e :invoice/due ?due]
@@ -100,10 +104,7 @@
:where ['[?e :invoice/due ?due]
'[(<= ?due ?end-due)]]}
:args [(coerce/to-date (:end (:due-range args)))]})
true
(merge-query {:query {:in ['[?xx ...]]
:where ['[?e :invoice/client ?xx]]}
:args [ (map :db/id (:clients args))]})
(:import-status args)
(merge-query {:query {:in ['?import-status]
@@ -175,10 +176,8 @@
"outstanding-balance" ['[?e :invoice/outstanding-balance ?sort-outstanding-balance]]}
args)
true
(merge-query {:query {:find ['?sort-default '?e ]
:where ['[?e :invoice/client]
'[?e :invoice/date ?sort-default]]}}) ))]
(->> (query2 query)
(merge-query {:query {:find ['?sort-default '?e ]}}) ))]
(->> (observable-query query)
(apply-sort-3 args)
(apply-pagination args)))))

View File

@@ -6,31 +6,33 @@
apply-sort-3
conn
merge-query
pull-many
query2]]
observable-query
pull-many]]
[auto-ap.datomic.accounts :as d-accounts]
[auto-ap.graphql.utils :refer [limited-clients]]
[clj-time.coerce :as c]
[auto-ap.graphql.utils :refer [extract-client-ids]]
[clj-time.coerce :as coerce]
[datomic.api :as dc]))
(defn raw-graphql-ids [db args]
(let [query
(let [valid-clients (extract-client-ids (:clients args)
(:client-id args)
(when (:client-code args)
[:client/code (:client-code args)]))
query
(if (:exact-match-id args)
{:query {:find '[?e]
:in '[$ ?e [?c ...]]
:where '[[?e :journal-entry/client ?c]]}
:args [db
(:exact-match-id args)
(map :db/id (:clients args))]}
valid-clients]}
(cond-> {:query {:find []
:in ['$ ]
:where []}
:args [db]}
true
(merge-query {:query {:in ['[?xx ...]]
:where ['[?e :journal-entry/client ?xx]]}
:args [(set (map :db/id (:clients args)))]})
:in ['$ '[?clients ?start ?end]]
:where '[[(iol-ion.query/scan-ledger $ ?clients ?start ?end) [[?e _ ?sort-default] ...]]]}
:args [db
[valid-clients
(some-> (:start (:date-range args)) coerce/to-date)
(some-> (:end (:date-range args)) coerce/to-date)]]}
(:only-external args)
(merge-query {:query {:where ['(not [?e :journal-entry/original-entity ])]}})
@@ -51,23 +53,6 @@
:where ['[?e :journal-entry/vendor ?vendor-id]]}
:args [(:vendor-id args)]})
(:client-code args)
(merge-query {:query {:in ['?client-code]
:where ['[?e :journal-entry/client ?client-id]
'[?client-id :client/code ?client-code]]}
:args [(:client-code args)]})
(:start (:date-range args))
(merge-query {:query {:in ['?start-date]
:where ['[?e :journal-entry/date ?date]
'[(>= ?date ?start-date)]]}
:args [(c/to-date (:start (:date-range args)))]})
(:end (:date-range args))
(merge-query {:query {:in ['?end-date]
:where ['[?e :journal-entry/date ?date]
'[(<= ?date ?end-date)]]}
:args [(c/to-date (:end (:date-range args)))]})
(or (seq (:numeric-code args))
(:bank-account-id args)
@@ -130,8 +115,8 @@
args)
true
(merge-query {:query {:find ['?sort-default '?e] :where ['[?e :journal-entry/date ?sort-default]]}})))]
(->> (query2 query)
(merge-query {:query {:find ['?sort-default '?e]}})))]
(->> (observable-query query)
(apply-sort-3 (update args :sort conj {:sort-key "default-2" :asc true}))
(apply-pagination args))))
@@ -144,7 +129,7 @@
{:account-client-override/client [:db/id]}]}
{:bank-account/type [*]}]}]}]
ids)
(map #(update % :journal-entry/date c/from-date))
(map #(update % :journal-entry/date coerce/from-date))
(map (fn [je]
(update je :journal-entry/line-items
(fn [jels]

View File

@@ -6,13 +6,12 @@
apply-sort-3
conn
merge-query
pull-many
query2]]
observable-query
pull-many]]
[auto-ap.datomic.accounts :as d-accounts]
[auto-ap.graphql.utils :refer [limited-clients]]
[auto-ap.graphql.utils :refer [extract-client-ids]]
[clj-time.coerce :as coerce]
[clojure.string :as str]
[clojure.tools.logging :as log]
[datomic.api :as dc]))
(defn potential-duplicate-ids [db args]
@@ -41,7 +40,11 @@
(defn raw-graphql-ids
([args] (raw-graphql-ids (dc/db conn) args))
([db args]
(let [potential-duplicates (potential-duplicate-ids db args)
(let [valid-clients (extract-client-ids (:clients args)
(:client-id args)
(when (:client-code args)
[:client/code (:client-code args)]))
potential-duplicates (potential-duplicate-ids db args)
query
(if (:exact-match-id args)
(cond-> {:query {:find '[?e]
@@ -49,21 +52,19 @@
:where '[[?e :transaction/client ?c]]}
:args [db
(:exact-match-id args)
(map :db/id (:clients args))]})
valid-clients]})
(cond-> {:query {:find []
:in ['$ ]
:where []}
:args [db]}
:in '[$ [?clients ?start ?end]]
:where '[[(iol-ion.query/scan-transactions $ ?clients ?start ?end) [[?e _ ?sort-default] ...]]]}
:args [db
[valid-clients
(some-> (:start (:date-range args)) coerce/to-date)
(some-> (:end (:date-range args)) coerce/to-date)]]}
(:potential-duplicates args)
(merge-query {:query {:in '[[?e ...]]}
:args [potential-duplicates]})
true
(merge-query {:query {:in ['[?xx ...]]
:where ['[?e :transaction/client ?xx]]}
:args [(set (map :db/id (:clients args)))]})
(:bank-account-id args)
(merge-query {:query {:in ['?bank-account-id]
:where ['[?e :transaction/bank-account ?bank-account-id]]}
@@ -80,11 +81,6 @@
'[?accounts :transaction-account/account ?account-id]]}
:args [(:account-id args)]})
(:client-id args)
(merge-query {:query {:in ['?client-id]
:where ['[?e :transaction/client ?client-id]]}
:args [(:client-id args)]})
(:vendor-id args)
(merge-query {:query {:in ['?vendor-id]
:where ['[?e :transaction/vendor ?vendor-id]]}
@@ -103,29 +99,11 @@
'[(<= ?a ?amount-lte)]]}
:args [(:amount-lte args)]})
(:start (:date-range args))
(merge-query {:query {:in ['?start-date]
:where ['[?e :transaction/date ?date]
'[(>= ?date ?start-date)]]}
:args [(coerce/to-date (:start (:date-range args)))]})
(:end (:date-range args))
(merge-query {:query {:in ['?end-date]
:where ['[?e :transaction/date ?date]
'[(<= ?date ?end-date)]]}
:args [(coerce/to-date (:end (:date-range args)))]})
(:approval-status args)
(merge-query {:query {:in ['?approval-status]
:where ['[?e :transaction/approval-status ?approval-status]]}
:args [(:approval-status args)]})
(:client-code args)
(merge-query {:query {:in ['?client-code]
:where ['[?e :transaction/client ?client-id]
'[?client-id :client/code ?client-code]]}
:args [(:client-code args)]})
(:original-id args)
(merge-query {:query {:in ['?original-id]
:where ['[?e :transaction/client ?c]
@@ -174,10 +152,8 @@
true
(merge-query {:query {:find ['?sort-default '?e]
:where ['[?e :transaction/id]
'[?e :transaction/date ?sort-default]
'(not [?e :transaction/approval-status :transaction-approval-status/suppressed])]}})))]
(log/info "query is" query)
(cond->> (query2 query)
(cond->> (observable-query query)
true (apply-sort-3 (assoc args :default-asc? false))
true (apply-pagination args)))))

View File

@@ -36,7 +36,8 @@
[com.walmartlabs.lacinia.schema :as schema]
[datomic.api :as dc]
[unilog.context :as lc]
[yang.time :refer [time-it]])
[yang.time :refer [time-it]]
[auto-ap.routes.auth :as auth])
(:import
(clojure.lang IPersistentMap)))
@@ -243,7 +244,8 @@
:profile_image_url {:type 'String}
:email {:type 'String}
:role {:type :role}
:clients {:type '(list :client)}}}
:clients {:type '(list :client)}
:impersonate_jwt {:type 'String}}}
:csv
{:fields {:csv_content_b64 {:type 'String}}}
@@ -622,7 +624,10 @@
(defn get-user [context args _]
(assert-admin (:id context))
(let [users (d-users/get-graphql args)]
(let [users (->> (d-users/get-graphql args)
(map (fn [u]
(assoc u :impersonate_jwt
(auth/user->jwt u "FAKE_TOKEN")))))]
(->graphql users)))

View File

@@ -53,7 +53,8 @@
(defn get-transaction-page [context args _]
(let [args (assoc (:filters args)
:clients (:clients context))
:clients (:clients context)
:id (:id context))
_ (assert-filtered-enough args)
[transactions transactions-count] (d-transactions/get-graphql (update (<-graphql args) :approval-status enum->keyword "transaction-approval-status"))
transactions (map ->graphql (map approval-status->graphql transactions))]

View File

@@ -5,10 +5,12 @@
[auto-ap.time :as atime]
[buddy.auth :refer [throw-unauthorized]]
[datomic.api :as dc]
[iol-ion.query :refer [entid]]
[clojure.walk :as walk]
[com.walmartlabs.lacinia.util :refer [attach-resolvers]]
[clojure.tools.logging :as log]
[com.brunobonacci.mulog :as mu]))
[com.brunobonacci.mulog :as mu]
[clojure.set :as set]))
(defn snake->kebab [s]
@@ -163,6 +165,29 @@
resolver-key (trace-query resolver-key resolver-fn))
)
{}
m))
m)))
)
(defn extract-client-ids [user-clients & possible-clients]
(let [coerce-client-ids (fn coerce-client-ids [x]
(cond (and (map? x)
(:db/id x))
[(:db/id x)]
(nat-int? x)
[x]
(and (vector? x)
(= :client/code (first x)))
[(entid (dc/db conn) x)]
(sequential? x)
(map x coerce-client-ids)
:else
[]))
user-client-ids (set (mapcat coerce-client-ids user-clients))
extra-client-ids (set (mapcat coerce-client-ids possible-clients))]
(if (seq extra-client-ids)
(set/intersection user-client-ids extra-client-ids)
user-client-ids)))

View File

@@ -179,7 +179,8 @@
[handler]
(fn [request]
(let [x-clients (-> request :session :client-selection)
identity (-> request :session :identity)
identity (or (-> request :identity)
(-> request :session :identity))
ideal-ids (set (cond
(or (= :all x-clients)
(nil? x-clients))
@@ -235,6 +236,26 @@
(into new-session)
(assoc :client-selection x-clients))))))))
(defn wrap-gunzip-jwt
[handler]
(fn [{:keys [session] :as request}]
(let [request (if-let [gz-clients (some-> request :identity :gz-clients)]
(try
(assoc-in request [:identity :user/clients]
(auth/gunzip gz-clients))
(catch Exception e
(alog/error :cant-gunzip-clients
:error e)
request))
request)]
(handler request))))
#_(defn wrap-pprint-session
[handler]
(fn [request]
(clojure.pprint/pprint (:session request))
(handler request)))
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
(def app
(-> route-handler
@@ -242,16 +263,19 @@
(wrap-guess-route)
(wrap-hydrate-clients)
(wrap-store-client-in-session)
(wrap-gunzip-jwt)
(wrap-authorization auth-backend)
(wrap-authentication auth-backend
(session-backend {:authfn (fn [auth]
(dissoc auth :exp))}))
#_(wrap-pprint-session)
(wrap-idle-session-timeout)
(wrap-session {:store (cookie-store
{:key
(byte-array
[42, 52, -31, 105, -126, -33, -118, -69, -82, -59, -15, -69, -38, 103, -102, -1])} )})
(wrap-reload)
(wrap-params)
(mp/wrap-multipart-params)

View File

@@ -6,7 +6,9 @@
[clj-time.core :as time]
[clojure.tools.logging :as log]
[config.core :refer [env]]
[com.brunobonacci.mulog :as mu]))
[com.brunobonacci.mulog :as mu]
[clojure.java.io :as io]
[clojure.edn :as edn]))
(def google-client-id "264081895820-0nndcfo3pbtqf30sro82vgq5r27h8736.apps.googleusercontent.com")
(def google-client-secret "OC-WemHurPXYpuIw5cT-B90g")
@@ -20,6 +22,50 @@
(:jwt-secret env)
{:alg :hs512}))
(defn gzip [data]
(let [data (pr-str data)
raw (java.io.ByteArrayOutputStream.)]
(with-open [output (-> raw
(io/output-stream)
(java.util.zip.GZIPOutputStream.))]
(io/copy data output))
(.encodeToString (java.util.Base64/getEncoder) (.toByteArray raw))))
(defn gunzip [b64]
(let [raw-bytes (.decode (java.util.Base64/getDecoder) b64)
raw (java.io.ByteArrayInputStream. raw-bytes)
out (java.io.ByteArrayOutputStream.)]
(with-open [compressed (-> raw
(io/input-stream)
(java.util.zip.GZIPInputStream.))]
(io/copy compressed out))
(edn/read-string (.toString out))))
(defn user->jwt [user oauth-token]
(let [auth (cond-> {:user (:user/name user)
:exp (time/plus (time/now) (time/days 30))
:db/id (:db/id user)
:user/role (name (:user/role user))
:user/name (:user/name user)}
(= "admin" (name (:user/role user)))
(assoc :gz-clients (->> (:user/clients user)
(map (fn [c]
(select-keys c [:client/code :db/id :client/locations])))
gzip))
(not= "admin" (name (:user/role user)))
(assoc :user/clients
(->> (:user/clients user)
(map (fn [c]
(select-keys c [:client/code :db/id :client/locations]))))))]
(when (and user oauth-token)
(jwt/sign auth
(:jwt-secret env)
{:alg :hs512}))))
(defn oauth [{{:strs [code state]} :query-params {:strs [host]} :headers :as request}]
(try
(let [auth (-> "https://accounts.google.com/o/oauth2/token"
@@ -43,25 +89,15 @@
:user/email (:email profile)
:user/profile-image-url (:picture profile)
:user/name (:name profile)})
auth {:user (:name profile)
:exp (time/plus (time/now) (time/days 30))
:db/id (:db/id user)
:user/clients (map (fn [c]
(select-keys c [:client/code :db/id :client/locations]))
(:user/clients user))
:user/role (name (:user/role user))
:user/name (:name profile)}
_ (mu/log ::logged-in-as
:auth auth)]
;; TODO - these namespaces are not being transmitted/deserialized properly
(if (and token user)
(let [jwt (jwt/sign auth
(:jwt-secret env)
{:alg :hs512})]
{:status 301
:headers {"Location" (str (or (not-empty state) "/") "?jwt=" jwt)}
:session {:identity (dissoc auth :exp)}})
(if-let [jwt (user->jwt user token)]
{:status 301
:headers {"Location" (str (or (not-empty state) "/") "?jwt=" jwt)}
:session {:identity (dissoc auth :exp)}}
{:status 401
:body "Couldn't authenticate"}))
(catch Exception e

View File

@@ -4,7 +4,7 @@
[auto-ap.routes :as routes]
[auto-ap.utils :refer [by]]
[auto-ap.views.pages.data-page :as data-page]
[auto-ap.views.utils :refer [parse-jwt with-user]]
[auto-ap.views.utils :refer [parse-jwt with-user gunzip]]
[bidi.bidi :as bidi]
[clojure.string :as str]
[clojure.edn :as edn]
@@ -12,10 +12,18 @@
[re-frame.core :as re-frame]
[auto-ap.ssr-routes :as ssr-routes]
[cemerick.url :as url]
[auto-ap.subs :as subs]))
[auto-ap.subs :as subs]
[pako]))
(defn jwt->data [token]
(js->clj (.parse js/JSON (b64/decodeString (second (str/split token #"\." ))))))
(let [raw (js->clj (.parse js/JSON (b64/decodeString (second (str/split token #"\." )))))
gz-clients (or (:gz-clients raw)
(get raw "gz-clients"))]
(cond-> raw
gz-clients (assoc "user/clients" (gunzip gz-clients)))))
(defn client-query []

View File

@@ -56,6 +56,11 @@
(when (= "admin" (:user/role @user))
[:a {:class "navbar-item" :href (bidi/path-for routes/routes :admin)} "Administration"])
[:hr {:class "navbar-divider"}]
[:a.navbar-item {:on-click (fn []
(.removeItem js/localStorage "last-client-id" nil)
(.setItem js/localStorage "last-selected-clients" ":all")
(.reload (.-location js/document ) true))}
"Full Refresh"]
[:a.navbar-item {:on-click (fn [e] (.preventDefault e) (re-frame/dispatch [::events/logout]))} "Logout"]]]
[:a.navbar-item {:href (login-url)} "Login"])))

View File

@@ -39,6 +39,7 @@
[:name
:profile_image_url
:email
:impersonate_jwt
:id
:role
[:clients [:id :name]]]]]}

View File

@@ -32,7 +32,7 @@
[grid/header-cell {} "Email"]
[grid/header-cell {} "Role"]
[grid/header-cell {} "Clients"]
[grid/header-cell {:style {:width (action-cell-width 1)}}]]]
[grid/header-cell {:style {:width (action-cell-width 5)}}]]]
[grid/body
(for [{:keys [id name role clients] :as c} (:data page)]
^{:key (str name "-" id)}
@@ -50,6 +50,14 @@
[grid/cell {} role]
[grid/cell {} (str/join ", " (map :name clients))]
[grid/cell {}
[:a.button {:on-click (fn []
(.setItem js/localStorage "jwt" (:impersonate-jwt c))
(.removeItem js/localStorage "last-client-id" nil)
(.removeItem js/localStorage "last-selected-clients" nil)
(.reload (.-location js/document ) true))}
"Impersonate"]
[buttons/fa-icon {:event [::form/editing c]
:icon "fa-pencil"}]]])]]
]))

View File

@@ -8,10 +8,14 @@
[:div.column.is-8.is-offset-2.has-text-centered
[:div.box.slideInFromBelow
[:img {:src "http://www.integreatconsult.com/wp-content/uploads/2016/11/logo.png"}]
[:img {:src "/img/logo.png"}]
[:div.notification.is-danger.is-light "An unexpected error has occured. "
[:a {:on-click #(.reload (.-location js/document )) } "Click here"]
" to try again."]]
[:div [:a {:on-click (fn []
(.removeItem js/localStorage "last-client-id" nil)
(.removeItem js/localStorage "last-selected-clients" nil)
(.reload (.-location js/document ) true)) } "Click here"]
" to try again."]
[:div "If the error continues, please try " [:a {:href "/login"} "logging in"] " again."]]]
[:p.has-text-gray
"Copyright Integreat 2020"]]]]]]
)

View File

@@ -11,7 +11,8 @@
[react-transition-group :as react-transition-group]
#_{:clj-kondo/ignore [:unused-namespace]}
[react :as react]
[reagent.core :as r])
[reagent.core :as r]
[pako])
(:import
(goog.i18n NumberFormat)
(goog.i18n.NumberFormat Format)))
@@ -297,13 +298,25 @@
:else
x))
(defn gunzip [b64]
(let [raw-byte-array (->> b64
js/atob
(map (fn [z] (.charCodeAt z 0)))
clj->js
(js/Uint8Array.))]
(or (edn/read-string (pako/inflate raw-byte-array #js {"to" "string"}))
nil)))
(defn parse-jwt [jwt]
(when-let [json (some-> jwt
(str/split #"\.")
second
base64/decodeString)]
(js->clj (.parse js/JSON json) :keywordize-keys true)))
(let [raw (js->clj (.parse js/JSON json) :keywordize-keys true)
gz-clients (or (:gz-clients raw)
(get raw "gz-clients"))]
(cond-> raw
gz-clients (assoc :user/clients (gunzip gz-clients))))))
(defn coerce-float [f]
(cond (str/blank? f)