Adds Yodlee2 Option.
This commit is contained in:
@@ -9,19 +9,22 @@
|
|||||||
:invoice-email "invoices-staging@mail.app.integreatconsult.com"
|
:invoice-email "invoices-staging@mail.app.integreatconsult.com"
|
||||||
:data-bucket "data.staging.app.integreatconsult.com"
|
:data-bucket "data.staging.app.integreatconsult.com"
|
||||||
|
|
||||||
:yodlee-cobrand-name "50ec7e57-297d-4970-941e-1cb07b8dcb4e_ADMIN"
|
:yodlee-cobrand-name "restserver"
|
||||||
:yodlee-cobrand-login "G7T9kiwaG8rMiykdV4pckmQnfj4OM2pf"
|
:yodlee-cobrand-login "sbCobda48aa19712a83c3ca4e935dd5e5d46b1a"
|
||||||
:yodlee-cobrand-password "0a07ea32-1b5d-461b-ad0f-2752cdd77602"
|
:yodlee-cobrand-password "0a07ea32-1b5d-461b-ad0f-2752cdd77602"
|
||||||
|
:yodlee-user-login "sbMemda48aa19712a83c3ca4e935dd5e5d46b1a4"
|
||||||
:yodlee-client-user-new "e02b38f9-9865-4264-8e4f-6a5ac2c500b0_ADMIN"
|
|
||||||
:yodlee-client-id "l6sUyK2NEq3mwopISHlFGWUcJ1U8OUQd"
|
|
||||||
:yodlee-client-secret "wZQHoGEkv5AGG2ZH"
|
|
||||||
|
|
||||||
:yodlee-user-login "8I0mmq1wmAWSSpr9"
|
|
||||||
:yodlee-user-password "sbMemda48aa19712a83c3ca4e935dd5e5d46b1a4#123"
|
:yodlee-user-password "sbMemda48aa19712a83c3ca4e935dd5e5d46b1a4#123"
|
||||||
:yodlee-base-url "https://development.api.yodlee.com/ysl"
|
:yodlee-base-url "https://developer.api.yodlee.com/ysl"
|
||||||
:yodlee-app "10003600"
|
:yodlee-app "10003600"
|
||||||
:yodlee-fastlink "https://node.developer.yodlee.com/authenticate/restserver/?channelAppName=restserver"
|
:yodlee-fastlink "https://node.developer.yodlee.com/authenticate/restserver/?channelAppName=restserver"
|
||||||
:run-web? true
|
:run-web? true
|
||||||
:run-background? true
|
:run-background? true
|
||||||
|
|
||||||
|
|
||||||
|
:yodlee2-admin-user "e02b38f9-9865-4264-8e4f-6a5ac2c500b0_ADMIN"
|
||||||
|
:yodlee2-integreat-user "integreat-main"
|
||||||
|
:yodlee2-client-id "l6sUyK2NEq3mwopISHlFGWUcJ1U8OUQd"
|
||||||
|
:yodlee2-client-secret "wZQHoGEkv5AGG2ZH"
|
||||||
|
:yodlee2-base-url "https://development.api.yodlee.com/ysl"
|
||||||
|
:yodlee2-fastlink "https://fl4.preprod.yodlee.com/authenticate/USDevexPreProd2-195/fastlink/?channelAppName=usdevexpreprod2"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
:target :bundle
|
:target :bundle
|
||||||
:output-to "resources/public/js/compiled/app.js"
|
:output-to "resources/public/js/compiled/app.js"
|
||||||
:output-dir "resources/public/js/compiled/"
|
:output-dir "resources/public/js/compiled/"
|
||||||
:source-map "resources/public/js/compiled/app.js.map"
|
:source-map true
|
||||||
#_#_:pretty-print true
|
#_#_:pretty-print true
|
||||||
#_#_:pseudo-names true
|
#_#_:pseudo-names true
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
<link rel="stylesheet" href="/finance-font/style.css" />
|
<link rel="stylesheet" href="/finance-font/style.css" />
|
||||||
<link rel="stylesheet" href="/css/main.css" />
|
<link rel="stylesheet" href="/css/main.css" />
|
||||||
<link rel="stylesheet" href="https://unpkg.com/placeholder-loading/dist/css/placeholder-loading.min.css">
|
<link rel="stylesheet" href="https://unpkg.com/placeholder-loading/dist/css/placeholder-loading.min.css">
|
||||||
|
<script type='text/javascript' src='https://cdn.yodlee.com/fastlink/v4/initialize.js'></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"><div><nav class="navbar has-shadow is-fixed-top"><div class="container"><div class="navbar-brand"><a class="navbar-item" href="../"><img src="/img/logo.png"></a></div><div class="navbar-menu"><div class="navbar-burger burger" data-target="navMenu"><span></span><span></span><span></span></div></div></div></nav><div class="columns has-shadow" id="mail-app" style="margin-bottom: 0px; height: calc(100vh - 46px);"><aside class="column aside menu is-2 "><div class="main left-nav"><div></div></div></aside><div class="column messages hero " id="message-feed" style="overflow: auto;"><div class="inbox-messages"><div class="has-text-centered hero is-fullheight is-vertically-centered is-centered"><div class="hero-body"><div class="container"><div class="column is-4 is-offset-4 has-text-centered"><div class="loader is-loading is-active big is-centered"></div></div></div></div></div></div></div></div><div></div><div id="dz-hidden"></div></div></div>
|
<div id="app"><div><nav class="navbar has-shadow is-fixed-top"><div class="container"><div class="navbar-brand"><a class="navbar-item" href="../"><img src="/img/logo.png"></a></div><div class="navbar-menu"><div class="navbar-burger burger" data-target="navMenu"><span></span><span></span><span></span></div></div></div></nav><div class="columns has-shadow" id="mail-app" style="margin-bottom: 0px; height: calc(100vh - 46px);"><aside class="column aside menu is-2 "><div class="main left-nav"><div></div></div></aside><div class="column messages hero " id="message-feed" style="overflow: auto;"><div class="inbox-messages"><div class="has-text-centered hero is-fullheight is-vertically-centered is-centered"><div class="hero-body"><div class="container"><div class="column is-4 is-offset-4 has-text-centered"><div class="loader is-loading is-active big is-centered"></div></div></div></div></div></div></div></div><div></div><div id="dz-hidden"></div></div></div>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
[auto-ap.routes.graphql :as graphql]
|
[auto-ap.routes.graphql :as graphql]
|
||||||
[auto-ap.routes.invoices :as invoices]
|
[auto-ap.routes.invoices :as invoices]
|
||||||
[auto-ap.routes.yodlee :as yodlee]
|
[auto-ap.routes.yodlee :as yodlee]
|
||||||
|
[auto-ap.routes.yodlee2 :as yodlee2]
|
||||||
[buddy.auth.backends.token :refer [jws-backend]]
|
[buddy.auth.backends.token :refer [jws-backend]]
|
||||||
[buddy.auth.middleware :refer [wrap-authentication wrap-authorization]]
|
[buddy.auth.middleware :refer [wrap-authentication wrap-authorization]]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
@@ -54,6 +55,7 @@
|
|||||||
(context "/api" []
|
(context "/api" []
|
||||||
exports/routes
|
exports/routes
|
||||||
yodlee/routes
|
yodlee/routes
|
||||||
|
yodlee2/routes
|
||||||
invoices/routes
|
invoices/routes
|
||||||
graphql/routes
|
graphql/routes
|
||||||
auth/routes
|
auth/routes
|
||||||
|
|||||||
92
src/clj/auto_ap/routes/yodlee2.clj
Normal file
92
src/clj/auto_ap/routes/yodlee2.clj
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
(ns auto-ap.routes.yodlee2
|
||||||
|
(:require
|
||||||
|
[auto-ap.graphql :as graphql]
|
||||||
|
[clj-http.client :as http]
|
||||||
|
|
||||||
|
[auto-ap.yodlee.core2 :as yodlee]
|
||||||
|
[auto-ap.graphql.utils :refer [->graphql assert-admin]]
|
||||||
|
[auto-ap.routes.utils :refer [wrap-secure]]
|
||||||
|
[clj-time.coerce :refer [to-date]]
|
||||||
|
[ring.middleware.json :refer [wrap-json-response]]
|
||||||
|
[compojure.core :refer [GET POST context defroutes wrap-routes]]
|
||||||
|
[clojure.string :as str]
|
||||||
|
[config.core :refer [env]]
|
||||||
|
|
||||||
|
[clojure.tools.logging :as log]))
|
||||||
|
|
||||||
|
(defroutes routes
|
||||||
|
(wrap-routes
|
||||||
|
(context "/yodlee2" []
|
||||||
|
(GET "/fastlink" {:keys [query-params identity] :as request}
|
||||||
|
(assert-admin identity)
|
||||||
|
(let [token (yodlee/get-access-token)]
|
||||||
|
{:status 200
|
||||||
|
:headers {"Content-Type" "application/edn"}
|
||||||
|
:body (pr-str {:token token
|
||||||
|
:url (:yodlee2-fastlink env)}) }))
|
||||||
|
(GET "/accounts" {:keys [query-params identity] :as request}
|
||||||
|
(assert-admin identity)
|
||||||
|
(let [[session token] (yodlee/get-access-token)]
|
||||||
|
{:status 200
|
||||||
|
:headers {"Content-Type" "application/edn"}
|
||||||
|
:body (pr-str (yodlee/get-accounts)) }))
|
||||||
|
|
||||||
|
(GET "/provider-accounts" {:keys [query-params identity] :as request}
|
||||||
|
(assert-admin identity)
|
||||||
|
(log/info "working on provider accounts...")
|
||||||
|
{:status 200
|
||||||
|
:headers {"Content-Type" "application/edn"}
|
||||||
|
:body (pr-str @yodlee/in-memory-cache) })
|
||||||
|
(POST "/reauthenticate/:id" {:keys [query-params identity] {:keys [id]} :route-params
|
||||||
|
data :edn-params
|
||||||
|
:as request}
|
||||||
|
(assert-admin identity)
|
||||||
|
(try
|
||||||
|
(let [[session token] (yodlee/get-access-token)]
|
||||||
|
{:status 200
|
||||||
|
:headers {"Content-Type" "application/edn"}
|
||||||
|
:body (pr-str (yodlee/reauthenticate (Long/parseLong id) data)) })
|
||||||
|
(catch Exception e
|
||||||
|
(log/error e)
|
||||||
|
{:status 500
|
||||||
|
:headers {"Content-Type" "application/edn"}
|
||||||
|
:body (pr-str {:message (.getMessage e)
|
||||||
|
:error (.toString e)})})))
|
||||||
|
(POST "/provider-accounts/refresh/:id" {:keys [query-params identity] {:keys [id]} :route-params :as request}
|
||||||
|
(assert-admin identity)
|
||||||
|
(try
|
||||||
|
(let [[session token] (yodlee/get-access-token)]
|
||||||
|
(yodlee/refresh-provider-account (Long/parseLong id))
|
||||||
|
{:status 200
|
||||||
|
:headers {"Content-Type" "application/edn"}
|
||||||
|
:body (pr-str @yodlee/in-memory-cache) })
|
||||||
|
(catch Exception e
|
||||||
|
{:status 400
|
||||||
|
:headers {"Content-Type" "application/edn"}
|
||||||
|
:body (pr-str {:message (.getMessage e)
|
||||||
|
:error (.toString e)})})))
|
||||||
|
(POST "/provider-accounts/delete/:id" {:keys [query-params identity] {:keys [id]} :route-params :as request}
|
||||||
|
(assert-admin identity)
|
||||||
|
(try
|
||||||
|
(let [[session token] (yodlee/get-access-token)]
|
||||||
|
(yodlee/delete-provider-account (Long/parseLong id))
|
||||||
|
{:status 200
|
||||||
|
:headers {"Content-Type" "application/edn"}
|
||||||
|
:body (pr-str @yodlee/in-memory-cache) })
|
||||||
|
(catch Exception e
|
||||||
|
{:status 400
|
||||||
|
:headers {"Content-Type" "application/edn"}
|
||||||
|
:body (pr-str {:message (.getMessage e)
|
||||||
|
:error (.toString e)})})))
|
||||||
|
(POST "/provider-accounts/:id" {:keys [query-params identity] {:keys [id]} :route-params :as request}
|
||||||
|
(assert-admin identity)
|
||||||
|
(try
|
||||||
|
(let [[session token] (yodlee/get-access-token)]
|
||||||
|
{:status 200
|
||||||
|
:headers {"Content-Type" "application/edn"}
|
||||||
|
:body (pr-str (yodlee/update-yodlee (Long/parseLong id))) })
|
||||||
|
(catch Exception e
|
||||||
|
{:status 400
|
||||||
|
:headers {"Content-Type" "application/edn"}
|
||||||
|
:body (pr-str e)}))))
|
||||||
|
wrap-secure))
|
||||||
@@ -26,18 +26,22 @@
|
|||||||
false)}))
|
false)}))
|
||||||
|
|
||||||
(def base-headers {"Api-Version" "1.1"
|
(def base-headers {"Api-Version" "1.1"
|
||||||
"loginName" (:yodlee-client-user-new env)
|
"Cobrand-Name" (:yodlee-cobrand-name env)
|
||||||
"Content-Type" "application/json"})
|
"Content-Type" "application/json"})
|
||||||
|
|
||||||
(defn login-cobrand []
|
(defn login-cobrand []
|
||||||
(-> (str (:yodlee-base-url env) "/auth/token")
|
(-> (str (:yodlee-base-url env) "/cobrand/login")
|
||||||
(client/post (merge {:headers (assoc base-headers
|
(client/post (merge {:headers base-headers
|
||||||
"Content-Type" "application/x-www-form-urlencoded")
|
:body
|
||||||
:body (str "clientId=" (:yodlee-client-id env) " &secret=" (:yodlee-client-secret env))
|
(json/write-str {:cobrand {:cobrandLogin (:yodlee-cobrand-login env)
|
||||||
|
:cobrandPassword (:yodlee-cobrand-password env)
|
||||||
|
:locale "en_US"}})
|
||||||
:as :json}
|
:as :json}
|
||||||
other-config)
|
other-config)
|
||||||
)
|
)
|
||||||
:body))
|
:body
|
||||||
|
:session
|
||||||
|
:cobSession))
|
||||||
|
|
||||||
|
|
||||||
(defn login-user
|
(defn login-user
|
||||||
|
|||||||
301
src/clj/auto_ap/yodlee/core2.clj
Normal file
301
src/clj/auto_ap/yodlee/core2.clj
Normal file
@@ -0,0 +1,301 @@
|
|||||||
|
(ns auto-ap.yodlee.core2
|
||||||
|
(:require [clj-http.client :as client]
|
||||||
|
[auto-ap.utils :refer [by]]
|
||||||
|
[cemerick.url :as u]
|
||||||
|
[unilog.context :as lc]
|
||||||
|
[clojure.tools.logging :as log]
|
||||||
|
[clojure.data.json :as json]
|
||||||
|
[clojure.core.async :as async]
|
||||||
|
[config.core :refer [env]]
|
||||||
|
[mount.core :as mount]
|
||||||
|
[yang.scheduler :as scheduler]))
|
||||||
|
|
||||||
|
(defn auth-header
|
||||||
|
([cob-session] (str "Bearer " cob-session)))
|
||||||
|
|
||||||
|
(def other-config
|
||||||
|
(if (:yodlee2-proxy-host env)
|
||||||
|
{:proxy-host (:yodlee2-proxy-host env)
|
||||||
|
:proxy-port (:yodlee2-proxy-port env)
|
||||||
|
:retry-handler (fn [ex try-count http-context]
|
||||||
|
(log/error "yodlee Error." ex)
|
||||||
|
false)}
|
||||||
|
{:retry-handler (fn [ex try-count http-context]
|
||||||
|
(log/error "yodlee Error." ex)
|
||||||
|
false)}))
|
||||||
|
|
||||||
|
(def base-headers {"Api-Version" "1.1"
|
||||||
|
"Content-Type" "application/json"})
|
||||||
|
|
||||||
|
(defn login-cobrand []
|
||||||
|
(-> (str (:yodlee2-base-url env) "/auth/token")
|
||||||
|
(client/post (merge {:headers (assoc base-headers
|
||||||
|
"loginName" (:yodlee2-admin-user env)
|
||||||
|
"Content-Type" "application/x-www-form-urlencoded")
|
||||||
|
:body (str "clientId=" (:yodlee2-client-id env) " &secret=" (:yodlee2-client-secret env))
|
||||||
|
:as :json}
|
||||||
|
other-config)
|
||||||
|
)
|
||||||
|
:body
|
||||||
|
:token
|
||||||
|
:accessToken))
|
||||||
|
|
||||||
|
(defn login-user []
|
||||||
|
(-> (str (:yodlee2-base-url env) "/auth/token")
|
||||||
|
(client/post (merge {:headers (assoc base-headers
|
||||||
|
"loginName" (:yodlee2-integreat-user env)
|
||||||
|
"Content-Type" "application/x-www-form-urlencoded")
|
||||||
|
:body (str "clientId=" (:yodlee2-client-id env) " &secret=" (:yodlee2-client-secret env))
|
||||||
|
:as :json}
|
||||||
|
other-config)
|
||||||
|
)
|
||||||
|
:body
|
||||||
|
:token
|
||||||
|
:accessToken))
|
||||||
|
|
||||||
|
|
||||||
|
(defn get-accounts []
|
||||||
|
(let [cob-session (login-user)]
|
||||||
|
(-> (str (:yodlee2-base-url env) "/accounts")
|
||||||
|
(client/get (merge {:headers (merge base-headers {"Authorization" (str "Bearer " cob-session)})
|
||||||
|
:as :json}
|
||||||
|
other-config))
|
||||||
|
:body
|
||||||
|
:account)))
|
||||||
|
|
||||||
|
(defn get-accounts-for-provider-account [provider-account-id]
|
||||||
|
(try
|
||||||
|
(let [cob-session (login-user)]
|
||||||
|
(-> (str (:yodlee2-base-url env) "/accounts?providerAccountId=" provider-account-id)
|
||||||
|
(client/get (merge {:headers (merge base-headers {"Authorization" (auth-header cob-session)})
|
||||||
|
:as :json}
|
||||||
|
other-config))
|
||||||
|
:body
|
||||||
|
:account))
|
||||||
|
(catch Exception e
|
||||||
|
(log/error (str "Couldn't get accounts for provider account '" provider-account-id "'")
|
||||||
|
e)
|
||||||
|
[])))
|
||||||
|
|
||||||
|
(defn get-provider-accounts []
|
||||||
|
(let [cob-session (login-user)]
|
||||||
|
(-> (str (:yodlee2-base-url env) "/providerAccounts")
|
||||||
|
(-> (client/get (merge {:headers (merge base-headers {"Authorization" (auth-header cob-session )})
|
||||||
|
:as :json}
|
||||||
|
other-config))
|
||||||
|
:body
|
||||||
|
:providerAccount))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(defn get-transactions []
|
||||||
|
(let [cob-session (login-user)
|
||||||
|
batch-size 100
|
||||||
|
get-transaction-batch (fn [skip]
|
||||||
|
(-> (str (:yodlee2-base-url env) "/transactions?top=" batch-size "&skip=" skip)
|
||||||
|
|
||||||
|
|
||||||
|
(client/get (merge {:headers (merge base-headers {"Authorization" (auth-header cob-session)})
|
||||||
|
:as :json}
|
||||||
|
other-config))
|
||||||
|
:body
|
||||||
|
:transaction
|
||||||
|
))]
|
||||||
|
|
||||||
|
(loop [transactions []
|
||||||
|
skip 0]
|
||||||
|
(let [transaction-batch (get-transaction-batch skip)]
|
||||||
|
(if (seq transaction-batch)
|
||||||
|
(recur (concat transactions transaction-batch) (+ batch-size skip))
|
||||||
|
transactions)))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(defn get-provider-account [id]
|
||||||
|
(let [cob-session (login-user)
|
||||||
|
batch-size 100]
|
||||||
|
|
||||||
|
(-> (str (:yodlee2-base-url env) "/providerAccounts/" id)
|
||||||
|
|
||||||
|
(client/get (merge {:headers (merge base-headers {"Authorization" (auth-header cob-session)})
|
||||||
|
:as :json}
|
||||||
|
other-config))
|
||||||
|
:body
|
||||||
|
:providerAccount)))
|
||||||
|
|
||||||
|
(defn get-provider-account-detail [id]
|
||||||
|
(let [cob-session (login-user)]
|
||||||
|
|
||||||
|
(-> (str (:yodlee2-base-url env) "/providerAccounts/" id )
|
||||||
|
|
||||||
|
(client/get (merge {:headers (merge base-headers {"Authorization" (auth-header cob-session)})
|
||||||
|
:query-params {"include" "credentials,preferences"}
|
||||||
|
:as :json}
|
||||||
|
other-config))
|
||||||
|
:body
|
||||||
|
:providerAccount
|
||||||
|
first)))
|
||||||
|
|
||||||
|
(defn update-provider-account [pa]
|
||||||
|
(let [cob-session (login-user)]
|
||||||
|
|
||||||
|
(-> (str (:yodlee2-base-url env) "/providerAccounts?providerAccountIds=" pa)
|
||||||
|
|
||||||
|
(client/put (merge {:headers (merge base-headers {"Authorization" (auth-header cob-session)})
|
||||||
|
:body "{\"dataSetName\": [\"BASIC_AGG_DATA\"]}"
|
||||||
|
:as :json}
|
||||||
|
other-config)))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(defn get-specific-transactions [account]
|
||||||
|
(let [cob-session (login-user)
|
||||||
|
batch-size 100
|
||||||
|
get-transaction-batch (fn [skip]
|
||||||
|
(-> (str (:yodlee2-base-url env) "/transactions?top=" batch-size "&skip=" skip "&accountId=" account)
|
||||||
|
|
||||||
|
(client/get (merge {:headers (merge base-headers {"Authorization" (auth-header cob-session)})
|
||||||
|
:as :json}
|
||||||
|
other-config))
|
||||||
|
:body
|
||||||
|
:transaction
|
||||||
|
))]
|
||||||
|
|
||||||
|
(loop [transactions []
|
||||||
|
skip 0]
|
||||||
|
(let [transaction-batch (get-transaction-batch skip)]
|
||||||
|
(if (seq transaction-batch)
|
||||||
|
(recur (concat transactions transaction-batch) (+ batch-size skip))
|
||||||
|
transactions)))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn get-access-token []
|
||||||
|
(try
|
||||||
|
(let [cob-session (login-user)]
|
||||||
|
cob-session)
|
||||||
|
(catch Exception e
|
||||||
|
(log/error e)
|
||||||
|
(throw e))))
|
||||||
|
|
||||||
|
(defn create-user []
|
||||||
|
(let [cob-session (login-cobrand)]
|
||||||
|
(-> (str (:yodlee2-base-url env) "/user/register")
|
||||||
|
(client/post (merge {:headers (merge base-headers {"Authorization" (auth-header cob-session)})
|
||||||
|
:body (json/write-str {"user" {
|
||||||
|
"loginName" "integreat-main"
|
||||||
|
"email" "bryce@integreatconsult.com"
|
||||||
|
"name" {"first" "Bryce"
|
||||||
|
"last" "Covert"}
|
||||||
|
"address" {"address1" "200 Lincoln Ave"
|
||||||
|
"state" "CA"
|
||||||
|
"city" "Salinas"
|
||||||
|
"zip" "93901"
|
||||||
|
"country" "USA"}
|
||||||
|
"preferences" {"currency" "USD"
|
||||||
|
"timeZone" "GMT"
|
||||||
|
"dateFormat" "YYYY-MMM-DD"
|
||||||
|
"locale" "en_US"}}})
|
||||||
|
:as :json}
|
||||||
|
other-config))
|
||||||
|
:body)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(defn get-provider-accounts-with-details []
|
||||||
|
(let [provider-accounts (get-provider-accounts)]
|
||||||
|
(let [concurrent 20
|
||||||
|
output-chan (async/chan)]
|
||||||
|
(async/pipeline-blocking concurrent
|
||||||
|
output-chan
|
||||||
|
(map (fn [provider-account]
|
||||||
|
(lc/with-context {:provider-account-id (:id provider-account)}
|
||||||
|
(get-provider-account-detail (:id provider-account)))))
|
||||||
|
(async/to-chan provider-accounts))
|
||||||
|
(async/<!! (async/into [] output-chan)))))
|
||||||
|
|
||||||
|
(defn concurrent-get-accounts-for-providers [provider-account-ids]
|
||||||
|
(let [concurrent 20
|
||||||
|
output-chan (async/chan)]
|
||||||
|
(async/pipeline-blocking concurrent
|
||||||
|
output-chan
|
||||||
|
(map (fn [provider-account-id]
|
||||||
|
(lc/with-context {:provider-account-id provider-account-id}
|
||||||
|
[provider-account-id
|
||||||
|
(get-accounts-for-provider-account provider-account-id)])))
|
||||||
|
(async/to-chan provider-account-ids))
|
||||||
|
(async/<!! (async/into {} output-chan))))
|
||||||
|
|
||||||
|
(defn get-provider-accounts-with-accounts []
|
||||||
|
(let [provider-accounts (by :id (get-provider-accounts-with-details))
|
||||||
|
accounts (concurrent-get-accounts-for-providers (keys provider-accounts))]
|
||||||
|
(->> accounts
|
||||||
|
(reduce
|
||||||
|
(fn [provider-accounts [which accounts]]
|
||||||
|
(assoc-in provider-accounts [which :accounts] accounts))
|
||||||
|
provider-accounts)
|
||||||
|
vals)))
|
||||||
|
|
||||||
|
(mount/defstate in-memory-cache
|
||||||
|
:start (atom []))
|
||||||
|
|
||||||
|
(defn refresh-in-memory-cache []
|
||||||
|
(lc/with-context {:source "refreshing-in-memory-cache"}
|
||||||
|
(try
|
||||||
|
(log/info "Refreshing Yodlee in memory cache")
|
||||||
|
(reset! in-memory-cache (get-provider-accounts-with-accounts))
|
||||||
|
|
||||||
|
(catch Exception e
|
||||||
|
(log/error e)))))
|
||||||
|
|
||||||
|
(mount/defstate in-memory-cache-worker
|
||||||
|
:start (scheduler/every (* 5 60 1000) refresh-in-memory-cache)
|
||||||
|
:stop (scheduler/stop in-memory-cache-worker))
|
||||||
|
|
||||||
|
|
||||||
|
(defn refresh-provider-account [id]
|
||||||
|
(swap! in-memory-cache
|
||||||
|
(fn [i]
|
||||||
|
(-> (by :id i)
|
||||||
|
(assoc id (assoc (get-provider-account-detail id)
|
||||||
|
:accounts (get-accounts-for-provider-account id)))
|
||||||
|
vals))))
|
||||||
|
|
||||||
|
(defn delete-provider-account [id]
|
||||||
|
(let [cob-session (login-user)]
|
||||||
|
|
||||||
|
(-> (str (:yodlee2-base-url env) "/providerAccounts/" id )
|
||||||
|
|
||||||
|
(client/delete (merge {:headers (merge base-headers {"Authorization" (auth-header cob-session)})
|
||||||
|
:as :json}
|
||||||
|
other-config))
|
||||||
|
:body
|
||||||
|
:providerAccount
|
||||||
|
first))
|
||||||
|
(swap! in-memory-cache
|
||||||
|
(fn [i]
|
||||||
|
(-> (by :id i)
|
||||||
|
(dissoc id)
|
||||||
|
vals))))
|
||||||
|
|
||||||
|
(defn update-yodlee [id]
|
||||||
|
(update-provider-account id)
|
||||||
|
(refresh-provider-account id))
|
||||||
|
|
||||||
|
(defn reauthenticate [pa data]
|
||||||
|
(let [cob-session (login-cobrand)]
|
||||||
|
|
||||||
|
(try
|
||||||
|
|
||||||
|
(doto (-> (str (:yodlee2-base-url env) "/providerAccounts?providerAccountIds=" pa)
|
||||||
|
|
||||||
|
(client/put (merge {:headers (merge base-headers {"Authorization" (auth-header cob-session)})
|
||||||
|
:body (json/write-str data)
|
||||||
|
:as :json}
|
||||||
|
other-config)))
|
||||||
|
log/info)
|
||||||
|
(refresh-provider-account pa)
|
||||||
|
(catch Exception e
|
||||||
|
(log/error e)))))
|
||||||
@@ -14,7 +14,8 @@
|
|||||||
"reminders" :admin-reminders
|
"reminders" :admin-reminders
|
||||||
"vendors" :admin-vendors
|
"vendors" :admin-vendors
|
||||||
"excel-import" :admin-excel-import
|
"excel-import" :admin-excel-import
|
||||||
"yodlee" :admin-yodlee}
|
"yodlee" :admin-yodlee
|
||||||
|
"yodlee2" :admin-yodlee2}
|
||||||
"invoices/" {"" :invoices
|
"invoices/" {"" :invoices
|
||||||
"import" :import-invoices
|
"import" :import-invoices
|
||||||
"unpaid" :unpaid-invoices
|
"unpaid" :unpaid-invoices
|
||||||
|
|||||||
@@ -55,6 +55,11 @@
|
|||||||
[:a {:href (bidi/path-for routes/routes :admin-yodlee), :class (str "item" (active-when ap = :admin-yodlee))}
|
[:a {:href (bidi/path-for routes/routes :admin-yodlee), :class (str "item" (active-when ap = :admin-yodlee))}
|
||||||
[:span {:class "icon icon-saving-bank-1" :style {:font-size "25px"}}]
|
[:span {:class "icon icon-saving-bank-1" :style {:font-size "25px"}}]
|
||||||
[:span {:class "name"} "Yodlee Link"]]]
|
[:span {:class "name"} "Yodlee Link"]]]
|
||||||
|
|
||||||
|
[:li.menu-item
|
||||||
|
[:a {:href (bidi/path-for routes/routes :admin-yodlee2), :class (str "item" (active-when ap = :admin-yodlee2))}
|
||||||
|
[:span {:class "icon icon-saving-bank-1" :style {:font-size "25px"}}]
|
||||||
|
[:span {:class "name"} "Yodlee 2 Link"]]]
|
||||||
|
|
||||||
[:ul ]]
|
[:ul ]]
|
||||||
[:p.menu-label "History"]
|
[:p.menu-label "History"]
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
[auto-ap.views.pages.admin.excel-import :refer [admin-excel-import-page]]
|
[auto-ap.views.pages.admin.excel-import :refer [admin-excel-import-page]]
|
||||||
[auto-ap.views.pages.admin.users :refer [admin-users-page]]
|
[auto-ap.views.pages.admin.users :refer [admin-users-page]]
|
||||||
[auto-ap.views.pages.admin.yodlee :refer [admin-yodlee-page]]
|
[auto-ap.views.pages.admin.yodlee :refer [admin-yodlee-page]]
|
||||||
|
[auto-ap.views.pages.admin.yodlee2 :as yodlee2]
|
||||||
[auto-ap.entities.clients :as clients]))
|
[auto-ap.entities.clients :as clients]))
|
||||||
|
|
||||||
(defmulti page (fn [active-page] active-page))
|
(defmulti page (fn [active-page] active-page))
|
||||||
@@ -103,6 +104,9 @@
|
|||||||
(defmethod page :admin-yodlee [_]
|
(defmethod page :admin-yodlee [_]
|
||||||
(admin-yodlee-page))
|
(admin-yodlee-page))
|
||||||
|
|
||||||
|
(defmethod page :admin-yodlee2 [_]
|
||||||
|
(yodlee2/admin-yodlee-page))
|
||||||
|
|
||||||
(defmethod page :admin-accounts [_]
|
(defmethod page :admin-accounts [_]
|
||||||
(admin-accounts-page))
|
(admin-accounts-page))
|
||||||
|
|
||||||
|
|||||||
412
src/cljs/auto_ap/views/pages/admin/yodlee2.cljs
Normal file
412
src/cljs/auto_ap/views/pages/admin/yodlee2.cljs
Normal file
@@ -0,0 +1,412 @@
|
|||||||
|
(ns auto-ap.views.pages.admin.yodlee2
|
||||||
|
(:require [re-frame.core :as re-frame]
|
||||||
|
[auto-ap.forms :as forms]
|
||||||
|
[reagent.core :as reagent]
|
||||||
|
[clojure.string :as str]
|
||||||
|
[cljs-time.format :as f]
|
||||||
|
[cljs-time.core :as time]
|
||||||
|
[auto-ap.subs :as subs]
|
||||||
|
[auto-ap.events :as events]
|
||||||
|
[auto-ap.entities.clients :as entity]
|
||||||
|
[auto-ap.views.components.layouts :refer [side-bar-layout]]
|
||||||
|
[auto-ap.views.components.admin.side-bar :refer [admin-side-bar]]
|
||||||
|
[auto-ap.views.components.address :refer [address-field]]
|
||||||
|
[auto-ap.views.utils :refer [login-url dispatch-event dispatch-value-change bind-field horizontal-field str->date date->str with-user]]
|
||||||
|
[auto-ap.views.components.modal :as modal]
|
||||||
|
[auto-ap.status :as status]
|
||||||
|
[cljs.reader :as edn]
|
||||||
|
[auto-ap.routes :as routes]
|
||||||
|
[bidi.bidi :as bidi]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
::authentication
|
||||||
|
(fn [db]
|
||||||
|
(-> db ::yodlee :authentication)))
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
::can-submit
|
||||||
|
(fn [db]
|
||||||
|
true))
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
::loading?
|
||||||
|
(fn [db]
|
||||||
|
(-> db ::yodlee :loading?)))
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
::accounts
|
||||||
|
(fn [db]
|
||||||
|
(-> db ::yodlee :accounts)))
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
::accounts-loading?
|
||||||
|
(fn [db]
|
||||||
|
(-> db ::yodlee :accounts-loading?)))
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
::provider-accounts-loading?
|
||||||
|
(fn [db]
|
||||||
|
(-> db ::provider-accounts-loading?)))
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
::provider-accounts
|
||||||
|
(fn [db]
|
||||||
|
(-> db ::provider-accounts)))
|
||||||
|
|
||||||
|
(re-frame/reg-event-fx
|
||||||
|
::authenticate-with-yodlee
|
||||||
|
(fn [{:keys [db]} _]
|
||||||
|
{:db (assoc-in db [::yodlee :loading?] true)
|
||||||
|
:http {:token (:user db)
|
||||||
|
:method :get
|
||||||
|
:headers {"Content-Type" "application/edn"}
|
||||||
|
:uri (str "/api/yodlee2/fastlink")
|
||||||
|
:on-success [::authenticated]
|
||||||
|
:on-error [::save-error]}}))
|
||||||
|
|
||||||
|
(re-frame/reg-event-fx
|
||||||
|
::mounted
|
||||||
|
(fn [{:keys [db]} _]
|
||||||
|
{:db (-> db
|
||||||
|
(assoc ::yodlee {:provider-accounts-loading? true})
|
||||||
|
(assoc ::save-error nil)
|
||||||
|
(assoc ::provider-accounts [])
|
||||||
|
(assoc ::provider-accounts-loading? true))
|
||||||
|
:http {:token (:user db)
|
||||||
|
:method :get
|
||||||
|
:headers {"Content-Type" "application/edn"}
|
||||||
|
:uri (str "/api/yodlee2/provider-accounts")
|
||||||
|
:on-success [::got-provider-accounts]
|
||||||
|
:on-error [::save-error]}}))
|
||||||
|
|
||||||
|
(re-frame/reg-event-fx
|
||||||
|
::kicked
|
||||||
|
(fn [{:keys [db]} [_ id state]]
|
||||||
|
{:dispatch [::mounted]}))
|
||||||
|
|
||||||
|
(re-frame/reg-event-fx
|
||||||
|
::kicked
|
||||||
|
(fn [{:keys [db]} [_ id state]]
|
||||||
|
{:dispatch [::mounted]}))
|
||||||
|
|
||||||
|
(re-frame/reg-event-fx
|
||||||
|
::kick
|
||||||
|
(fn [{:keys [db]} [_ id]]
|
||||||
|
{:http {:token (:user db)
|
||||||
|
:method :post
|
||||||
|
:headers {"Content-Type" "application/edn"}
|
||||||
|
:uri (str "/api/yodlee2/provider-accounts/" id)
|
||||||
|
:on-success [::kicked id :kicked]
|
||||||
|
:on-error [::kicked id :errored]}}))
|
||||||
|
|
||||||
|
(re-frame/reg-event-fx
|
||||||
|
::got-accounts
|
||||||
|
(fn [{:keys [db]} [_ accounts]]
|
||||||
|
{:db (-> db
|
||||||
|
(assoc-in [::yodlee :accounts] accounts)
|
||||||
|
(assoc-in [::yodlee :accounts-loading?] false))}))
|
||||||
|
|
||||||
|
(re-frame/reg-event-fx
|
||||||
|
::got-provider-accounts
|
||||||
|
(fn [{:keys [db]} [_ accounts]]
|
||||||
|
{:db (-> db
|
||||||
|
(assoc-in [::provider-accounts] accounts)
|
||||||
|
(assoc-in [::provider-accounts-loading?] false))}))
|
||||||
|
|
||||||
|
(re-frame/reg-event-fx
|
||||||
|
::authenticated
|
||||||
|
(fn [{:keys [db]} [_ authentication]]
|
||||||
|
{:db (-> db
|
||||||
|
(assoc-in [::yodlee :authentication] authentication)
|
||||||
|
(assoc-in [::yodlee :loading?] false))}))
|
||||||
|
|
||||||
|
(re-frame/reg-event-fx
|
||||||
|
::authenticated-mfa
|
||||||
|
(fn [{:keys [db]} [_ provider-account-id authentication]]
|
||||||
|
{:db (-> db
|
||||||
|
(assoc-in [::yodlee :authentication] authentication)
|
||||||
|
(assoc-in [::yodlee :loading?] false)
|
||||||
|
(forms/stop-form [::mfa-form provider-account-id]))}))
|
||||||
|
|
||||||
|
(re-frame/reg-event-fx
|
||||||
|
::save-error
|
||||||
|
(fn [{:keys [db]} [_ authentication]]
|
||||||
|
{:db (assoc :db ::load-error "error")}))
|
||||||
|
|
||||||
|
(defn yodlee-link-button []
|
||||||
|
[:div
|
||||||
|
(let [authentication @(re-frame/subscribe [::authentication])
|
||||||
|
loading? @(re-frame/subscribe [::loading?])]
|
||||||
|
|
||||||
|
(if authentication
|
||||||
|
[:div
|
||||||
|
"Authentication successful!"
|
||||||
|
[:div#fa-spot]
|
||||||
|
[:button.button.is-primary {:on-click (fn []
|
||||||
|
#_(println #js {"fastLinkUrl" (:url authentication)
|
||||||
|
"accessToken" (:token authentication)
|
||||||
|
"params" #js { "configName" "Aggregation"}})
|
||||||
|
(.open (.-fastlink js/window)
|
||||||
|
(doto #js {"fastLinkURL" (:url authentication)
|
||||||
|
"accessToken" (:token authentication)
|
||||||
|
"params" #js { "configName" "Aggregation"}}
|
||||||
|
println)
|
||||||
|
"fa-spot")
|
||||||
|
)}[:span [:span.icon [:i.fa.fa-external-link]] " Go to yodlee"]]]
|
||||||
|
|
||||||
|
[:button.button.is-primary {:class (if loading? "is-loading" "") :on-click (dispatch-event [::authenticate-with-yodlee])} "Authenticate with Yodlee"]))])
|
||||||
|
|
||||||
|
(defn yodlee-date->date [d]
|
||||||
|
(try
|
||||||
|
(some-> d
|
||||||
|
(str->date (:date-time-no-ms f/formatters))
|
||||||
|
)
|
||||||
|
(catch js/Error e
|
||||||
|
nil)))
|
||||||
|
|
||||||
|
(defn yodlee-date->str [d]
|
||||||
|
(try
|
||||||
|
(or (some-> d
|
||||||
|
(str->date (:date-time-no-ms f/formatters))
|
||||||
|
date->str)
|
||||||
|
"N/A")
|
||||||
|
(catch js/Error e
|
||||||
|
"N/A")))
|
||||||
|
|
||||||
|
(defn yodlee-accounts-table [accounts]
|
||||||
|
(let [bank-accounts @(re-frame/subscribe [::bank-accounts-by-yodlee-account-id])]
|
||||||
|
[:div
|
||||||
|
[:table.table
|
||||||
|
[:thead
|
||||||
|
[:tr
|
||||||
|
[:th "Account Name"]
|
||||||
|
[:th "Account Number"]
|
||||||
|
[:th "Yodlee Account Number"]
|
||||||
|
[:th "Balance"]
|
||||||
|
[:th "Yodlee Status"]
|
||||||
|
[:th "Usage"]]]
|
||||||
|
[:tbody
|
||||||
|
|
||||||
|
(for [account accounts]
|
||||||
|
^{:key (:id account)} [:tr
|
||||||
|
[:td (:accountName account)]
|
||||||
|
[:td (:accountNumber account)]
|
||||||
|
[:td (:id account)]
|
||||||
|
[:td.has-text-right (:amount (:balance account))]
|
||||||
|
[:td (str/join ", " (map :additionalStatus (:dataset account)))]
|
||||||
|
[:td
|
||||||
|
(when-let [bank-accounts (get bank-accounts (:id account))]
|
||||||
|
[:div.tags
|
||||||
|
(for [bank-account bank-accounts]
|
||||||
|
^{:key (:id bank-account)}
|
||||||
|
[:div.tag (:name bank-account) " (" (:code bank-account) ")"])])]
|
||||||
|
])]]]))
|
||||||
|
|
||||||
|
(re-frame/reg-event-fx
|
||||||
|
::reauthenticate-mfa
|
||||||
|
[with-user ]
|
||||||
|
(fn [{:keys [user db]} [_ provider-account-id ]]
|
||||||
|
{:db (forms/loading db [::mfa-form provider-account-id])
|
||||||
|
:http {:token user
|
||||||
|
:method :post
|
||||||
|
:headers {"Content-Type" "application/edn"}
|
||||||
|
:uri (str "/api/yodlee2/reauthenticate/" provider-account-id )
|
||||||
|
:body {"loginForm"
|
||||||
|
{"row"
|
||||||
|
(->> (get-in db [::forms/forms [::mfa-form provider-account-id]])
|
||||||
|
:data
|
||||||
|
:login
|
||||||
|
(sort-by (fn [[k v]] k))
|
||||||
|
(map second)
|
||||||
|
(map (fn [row]
|
||||||
|
{"field"
|
||||||
|
(mapv (fn [[k v]]
|
||||||
|
{"id" k
|
||||||
|
"value" v})
|
||||||
|
row)})))}
|
||||||
|
"field"
|
||||||
|
(mapv (fn [[k v]]
|
||||||
|
{"id" k
|
||||||
|
"value" v})
|
||||||
|
(:mfa (:data (get-in db [::forms/forms [::mfa-form provider-account-id]]))))}
|
||||||
|
|
||||||
|
:on-success [::authenticated-mfa provider-account-id]
|
||||||
|
:on-error [::forms/save-error [::mfa-form provider-account-id] ]}}))
|
||||||
|
|
||||||
|
(re-frame/reg-event-fx
|
||||||
|
::provider-account-refreshed
|
||||||
|
(fn [{:keys [db]} [_ i result]]
|
||||||
|
|
||||||
|
{:db (assoc-in db [::provider-accounts] result)
|
||||||
|
:dispatch [::forms/form-closing [::refresh-provider-account i]]}))
|
||||||
|
|
||||||
|
(re-frame/reg-event-fx
|
||||||
|
::refresh-provider-account
|
||||||
|
[with-user ]
|
||||||
|
(fn [{:keys [user db]} [_ provider-account-id ]]
|
||||||
|
{:db (forms/loading db [::refresh-provider-account provider-account-id])
|
||||||
|
:http {:token user
|
||||||
|
:method :post
|
||||||
|
:headers {"Content-Type" "application/edn"}
|
||||||
|
:uri (str "/api/yodlee2/provider-accounts/refresh/" provider-account-id )
|
||||||
|
:body {}
|
||||||
|
:on-success [::provider-account-refreshed provider-account-id]
|
||||||
|
:on-error [::forms/save-error [::refresh-provider-account provider-account-id] ]}}))
|
||||||
|
|
||||||
|
(re-frame/reg-event-fx
|
||||||
|
::provider-account-deleted
|
||||||
|
(fn [{:keys [db]} [_ i result]]
|
||||||
|
{:db (assoc-in db [::provider-accounts] result)
|
||||||
|
:dispatch-n [[::forms/form-closing [::refresh-provider-account i]]
|
||||||
|
[::modal/modal-closed ]]}))
|
||||||
|
|
||||||
|
(re-frame/reg-event-fx
|
||||||
|
::delete-provider-account
|
||||||
|
[with-user ]
|
||||||
|
(fn [{:keys [user db]} [_ provider-account-id ]]
|
||||||
|
{:http {:token user
|
||||||
|
:method :post
|
||||||
|
:owns-state {:single ::delete-provider-account}
|
||||||
|
:headers {"Content-Type" "application/edn"}
|
||||||
|
:uri (str "/api/yodlee2/provider-accounts/delete/" provider-account-id )
|
||||||
|
:body {}
|
||||||
|
:on-success [::provider-account-deleted provider-account-id]
|
||||||
|
:on-error [::forms/save-error [::delete-provider-account provider-account-id] ]}}))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(re-frame/reg-event-fx
|
||||||
|
::delete-requested
|
||||||
|
[with-user]
|
||||||
|
(fn [{:keys [user db]} [_ account-id]]
|
||||||
|
{:dispatch
|
||||||
|
[::modal/modal-requested {:title "Delete Provider account "
|
||||||
|
:body [:div "Are you sure you want to delete provider account " account-id "?"]
|
||||||
|
:confirm {:value "Delete provider account"
|
||||||
|
:status-from [::status/single ::delete-provider-account]
|
||||||
|
:class "is-danger"
|
||||||
|
:on-click (dispatch-event [::delete-provider-account account-id])
|
||||||
|
:close-event [::status/completed ::delete-provider-account]}
|
||||||
|
:cancel? true}]}))
|
||||||
|
|
||||||
|
|
||||||
|
(defn delete-button [account-id]
|
||||||
|
[:button.button
|
||||||
|
{:on-click (dispatch-event [::delete-requested account-id])}
|
||||||
|
[:span.icon [:i.fa.fa-times]]])
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
::bank-accounts-by-yodlee-account-id
|
||||||
|
:<- [::subs/bank-accounts]
|
||||||
|
(fn [bank-accounts]
|
||||||
|
(group-by :yodlee-account-id bank-accounts)))
|
||||||
|
|
||||||
|
(defn yodlee-provider-accounts-table []
|
||||||
|
(let [bank-accounts @(re-frame/subscribe [::bank-accounts-by-yodlee-account-id])]
|
||||||
|
|
||||||
|
(if @(re-frame/subscribe [::provider-accounts-loading?])
|
||||||
|
[:div "Loading..."]
|
||||||
|
[:div.columns
|
||||||
|
[:div.column.is-half
|
||||||
|
(doall
|
||||||
|
(for [account @(re-frame/subscribe [::provider-accounts])
|
||||||
|
:let [{:keys [error status] :as g} @(re-frame/subscribe [::forms/form [::refresh-provider-account (:id account)]])
|
||||||
|
total-usages (mapcat (comp bank-accounts :id) (:accounts account))]]
|
||||||
|
|
||||||
|
^{:key (:id account)}
|
||||||
|
[:div.card {:style {:margin-bottom "1em"}}
|
||||||
|
[:div.card-header
|
||||||
|
[:div.card-header-title "Provider account " (:id account)]
|
||||||
|
[:div.card-header-icon
|
||||||
|
(when (seq total-usages)
|
||||||
|
[:div.tags
|
||||||
|
[:div.tag.is-primary (count total-usages) " usages"]])]
|
||||||
|
[:div.card-header-icon
|
||||||
|
[delete-button (:id account)]]
|
||||||
|
[:div.card-header-icon
|
||||||
|
(cond
|
||||||
|
(= :loading status) [:button.button.is-disabled.is-loading [:i.fa.fa-refresh]]
|
||||||
|
error [:button.button.is-disabled [:span.icon [:i.fa.fa-exclamation-triangle]]]
|
||||||
|
:else
|
||||||
|
[:button.button
|
||||||
|
{:on-click (dispatch-event [::refresh-provider-account (:id account)])}
|
||||||
|
[:span.icon [:i.fa.fa-refresh]]])]]
|
||||||
|
[:div.card-content
|
||||||
|
|
||||||
|
(if (> (some-> (-> account :dataset first :lastUpdated)
|
||||||
|
(yodlee-date->date )
|
||||||
|
(time/interval (time/now))
|
||||||
|
(time/in-days ))
|
||||||
|
1)
|
||||||
|
[:div.notification.is-info.is-light
|
||||||
|
[:div.level
|
||||||
|
[:div.level-left
|
||||||
|
[:div.level-item
|
||||||
|
[:p
|
||||||
|
"This account was last updated on "
|
||||||
|
(yodlee-date->str (-> account :dataset first :lastUpdated))
|
||||||
|
", and last attempted "
|
||||||
|
(yodlee-date->str (-> account :dataset first :lastUpdateAttempt))
|
||||||
|
"."]]]
|
||||||
|
[:div.level-right [:button.button.is-success {:on-click (dispatch-event [::kick (:id account)] )} "Sync yodlee with bank" ]]]
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
[yodlee-accounts-table (:accounts account)]
|
||||||
|
(if (not= (-> account :dataset first :additionalStatus)
|
||||||
|
"AVAILABLE_DATA_RETRIEVED")
|
||||||
|
[:div
|
||||||
|
[:div.notification.is-info.is-warning
|
||||||
|
[:div.level
|
||||||
|
[:div.level-left
|
||||||
|
[:div.level-item
|
||||||
|
"This provider account's status is '"
|
||||||
|
(-> account :dataset first :additionalStatus)
|
||||||
|
"'. If this is in error, it might help to try reauthenticating by filling out the form below."]]]]
|
||||||
|
(let [{error :error account-data :data } @(re-frame/subscribe [::forms/form [::mfa-form (:id account)]])
|
||||||
|
change-event [::forms/change [::mfa-form (:id account)]]
|
||||||
|
{:keys [form-inline field field-holder raw-field error-notification submit-button]} (forms/vertical-form {:can-submit [::can-submit]
|
||||||
|
:change-event change-event
|
||||||
|
:submit-event [::reauthenticate-mfa (:id account)]
|
||||||
|
:id [::mfa-form (:id account)]} )]
|
||||||
|
(form-inline {:title "Reauthenticate"}
|
||||||
|
[:<>
|
||||||
|
(error-notification)
|
||||||
|
(doall
|
||||||
|
(for [[row i] (map vector (-> account :loginForm last :row) (range))
|
||||||
|
f (:field row)
|
||||||
|
:let [options (map :optionValue (:option f))]]
|
||||||
|
^{:key (:id f)}
|
||||||
|
[:div
|
||||||
|
(field (:label row)
|
||||||
|
[:input.input {:type "text" :field [:login i (:id f)]}])
|
||||||
|
(if (seq options)
|
||||||
|
[:ul
|
||||||
|
(for [o options]
|
||||||
|
^{:key o}
|
||||||
|
[:li [:pre o]])])]))
|
||||||
|
(doall
|
||||||
|
(for [f (-> account :field)]
|
||||||
|
^{:key (:id f)}
|
||||||
|
(field (:label f)
|
||||||
|
[:input.input {:type "text" :mfa [:form (:id f)] :value (-> f :field first :value)}])))
|
||||||
|
(submit-button "Reauthenticate")]))])]]))]])))
|
||||||
|
|
||||||
|
|
||||||
|
(defn admin-yodlee-content []
|
||||||
|
[(with-meta
|
||||||
|
(fn []
|
||||||
|
[:div
|
||||||
|
[:h1.title "Yodlee provider accounts"]
|
||||||
|
|
||||||
|
[yodlee-provider-accounts-table]
|
||||||
|
[yodlee-link-button]])
|
||||||
|
{:component-did-mount (fn []
|
||||||
|
(re-frame/dispatch [::mounted]))})])
|
||||||
|
|
||||||
|
(defn admin-yodlee-page []
|
||||||
|
[side-bar-layout {:side-bar [admin-side-bar {}]
|
||||||
|
:main [admin-yodlee-content]}])
|
||||||
Reference in New Issue
Block a user