Skip to content

Commit 2ca04e7

Browse files
committed
Implement client-side authentication.
1 parent 269b426 commit 2ca04e7

8 files changed

Lines changed: 460 additions & 7 deletions

File tree

deps.edn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
:aliases {:dev {:extra-paths ["dev"]
55
:jvm-opts ["-Dtrace"]
66
:extra-deps {org.clojure/clojurescript {:mvn/version "1.10.597"}
7+
org.clojure/core.async {:mvn/version "1.0.567"}
8+
com.wsscode/async {:mvn/version "1.0.2"}
79
thheller/shadow-cljs {:mvn/version "2.8.83"}
810
fulcrologic/fulcro-inspect {:mvn/version "2.2.5"}
911
binaryage/devtools {:mvn/version "0.9.10"}}}}}

package-lock.json

Lines changed: 367 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
"description": "",
55
"private": true,
66
"devDependencies": {
7+
"@auth0/auth0-spa-js": "^1.6.4",
8+
"minimist": "^1.2.2",
79
"react": "^16.13.0",
810
"react-dom": "^16.13.0",
9-
"shadow-cljs": "^2.8.83",
10-
"minimist": "^1.2.2"
11+
"semantic-ui-react": "^0.88.2",
12+
"shadow-cljs": "^2.8.83"
1113
},
1214
"author": "Chris O'Donnell",
1315
"license": "MIT"

resources/public/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
<title>My Gift List Rocks</title>
44
<meta charset="utf-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
6+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css" />
67
</head>
78
<body>
89
<div id="app"></div>

shadow-cljs.edn

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
1010
:modules {:main {:entries [rocks.mygiftlist.client]
1111
:init-fn rocks.mygiftlist.client/init}}
1212

13+
:closure-defines
14+
{rocks.mygiftlist.config/AUTH0_CLIENT_ID "heIlMgUZmvjI3muqPO3Ua5F5VpLgTpM3"
15+
rocks.mygiftlist.config/AUTH0_DOMAIN "mygiftlist-blog.auth0.com"
16+
rocks.mygiftlist.config/AUTH0_AUDIENCE "https://blog.mygiftlist.rocks"
17+
rocks.mygiftlist.config/AUTH0_CONNECTION "Username-Password-Authentication"}
18+
1319
:devtools {:watch-dir "resources/public"
1420
:after-load rocks.mygiftlist.client/refresh
1521
:preloads [com.fulcrologic.fulcro.inspect.preload
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
(ns rocks.mygiftlist.authentication
2+
(:require ["@auth0/auth0-spa-js" :as create-auth0-client]
3+
[com.wsscode.async.async-cljs :refer [go-promise <!p]]
4+
[rocks.mygiftlist.config :as config]))
5+
6+
(defonce auth0-client (atom nil))
7+
8+
(defn create-auth0-client! []
9+
(go-promise
10+
(reset! auth0-client
11+
(<!p (create-auth0-client
12+
#js {:domain config/AUTH0_DOMAIN
13+
:client_id config/AUTH0_CLIENT_ID
14+
:audience config/AUTH0_AUDIENCE
15+
:connection config/AUTH0_CONNECTION})))))
16+
17+
(defn is-authenticated? []
18+
(go-promise (<!p (.isAuthenticated @auth0-client))))
19+
20+
(defn login []
21+
(.loginWithRedirect @auth0-client
22+
#js {:redirect_uri (.. js/window -location -origin)}))
23+
24+
(defn handle-redirect-callback []
25+
(go-promise (<!p (.handleRedirectCallback @auth0-client))))
26+
27+
(defn logout []
28+
(.logout @auth0-client
29+
#js {:returnTo (.. js/window -location -origin)}))
30+
31+
(defn get-access-token []
32+
(go-promise (<!p (.getTokenSilently @auth0-client))))
33+
34+
(defn get-user-info []
35+
(go-promise (<!p (.getUser @auth0-client))))

src/rocks/mygiftlist/client.cljs

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,54 @@
11
(ns rocks.mygiftlist.client
22
(:require [rocks.mygiftlist.application :refer [SPA]]
3+
[rocks.mygiftlist.authentication :as auth]
34
[com.fulcrologic.fulcro.application :as app]
45
[com.fulcrologic.fulcro.components :as comp :refer [defsc]]
56
[com.fulcrologic.fulcro.dom :as dom]
7+
[com.fulcrologic.fulcro.mutations :refer [defmutation]]
8+
[clojure.core.async :refer [go <!]]
9+
[clojure.string :as str]
610
[taoensso.timbre :as log]))
711

8-
(defsc Root [this _]
9-
{:query []
10-
:initial-state {}}
12+
(defsc CurrentUser [this {:user/keys [id email]
13+
:ui/keys [loading] :as user}]
14+
{:query [:user/id :user/email :ui/loading]
15+
:ident (fn [] [:component/id :current-user])
16+
:initial-state {:ui/loading true}}
17+
(cond
18+
loading (dom/button :.ui.loading.primary.button)
19+
(and id email) (dom/button :.ui.primary.button
20+
{:onClick #(auth/logout)}
21+
"Logout")
22+
:else (dom/button :.ui.primary.button
23+
{:onClick #(auth/login)}
24+
"Login/Signup")))
25+
26+
(def ui-current-user (comp/factory CurrentUser))
27+
28+
(defsc Root [this {:root/keys [current-user]}]
29+
{:query [{:root/current-user (comp/get-query CurrentUser)}]
30+
:initial-state {:root/current-user {}}}
1131
(dom/div {}
12-
"Hello World"))
32+
(dom/div {} "Hello World")
33+
(ui-current-user current-user)))
34+
35+
(defmutation set-current-user [user]
36+
(action [{:keys [state]}]
37+
(swap! state assoc-in [:component/id :current-user] (assoc user :ui/loading false))))
1338

1439
(defn ^:export refresh []
1540
(log/info "Hot code reload...")
1641
(app/mount! SPA Root "app"))
1742

1843
(defn ^:export init []
1944
(log/info "Application starting...")
20-
(app/mount! SPA Root "app"))
45+
(app/mount! SPA Root "app")
46+
(go
47+
(<! (auth/create-auth0-client!))
48+
(when (str/includes? (.. js/window -location -search) "code=")
49+
(<! (auth/handle-redirect-callback))
50+
(.replaceState js/window.history #js {} js/document.title js/window.location.pathname))
51+
(if-let [authenticated (<! (auth/is-authenticated?))]
52+
(let [{:strs [sub email]} (js->clj (<! (auth/get-user-info)))]
53+
(comp/transact! SPA [(set-current-user {:user/id sub :user/email email})]))
54+
(comp/transact! SPA [(set-current-user {})]))))

src/rocks/mygiftlist/config.cljs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
(ns rocks.mygiftlist.config)
2+
3+
(goog-define AUTH0_DOMAIN "")
4+
(goog-define AUTH0_CLIENT_ID "")
5+
(goog-define AUTH0_AUDIENCE "")
6+
(goog-define AUTH0_CONNECTION "")

0 commit comments

Comments
 (0)