├── .gitignore ├── README.md ├── project.clj ├── resources └── public │ └── index.html └── src ├── clj └── reframe_auth0 │ └── core.clj └── cljs └── reframe_auth0 ├── auth0.cljs ├── config.cljs ├── core.cljs ├── db.cljs ├── events.cljs ├── subs.cljs └── views.cljs /.gitignore: -------------------------------------------------------------------------------- 1 | /*.log 2 | /target 3 | /*-init.clj 4 | /resources/public/js/compiled 5 | out 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # reframe-auth0 2 | 3 | A [re-frame](https://github.com/Day8/re-frame) application designed to demonstrate authentication using [Auth0](https://auth0.com/) 4 | 5 | Associated tutorials: 6 | - [Part 1](http://randomlurker.eu/clojurescript/re-frame/2017/05/22/re-frame-auth0-authentication.html) 7 | ## Development Mode 8 | 9 | ### Run application: 10 | 11 | ``` 12 | lein clean 13 | lein figwheel dev 14 | ``` 15 | 16 | Figwheel will automatically push cljs changes to the browser. 17 | 18 | Wait a bit, then browse to [http://localhost:3449](http://localhost:3449). 19 | 20 | ## Production Build 21 | 22 | 23 | To compile clojurescript to javascript: 24 | 25 | ``` 26 | lein clean 27 | lein cljsbuild once min 28 | ``` 29 | -------------------------------------------------------------------------------- /project.clj: -------------------------------------------------------------------------------- 1 | (defproject reframe-auth0 "0.1.0-SNAPSHOT" 2 | :dependencies [[org.clojure/clojure "1.8.0"] 3 | [org.clojure/clojurescript "1.9.229"] 4 | [reagent "0.6.0"] 5 | [re-frame "0.9.2"] 6 | [cljsjs/auth0-lock "10.16.0-0"]] 7 | 8 | :plugins [[lein-cljsbuild "1.1.4"]] 9 | 10 | :min-lein-version "2.5.3" 11 | 12 | :source-paths ["src/clj"] 13 | 14 | :clean-targets ^{:protect false} ["resources/public/js/compiled" "target"] 15 | 16 | :figwheel {:css-dirs ["resources/public/css"]} 17 | 18 | :profiles 19 | {:dev 20 | {:dependencies [[binaryage/devtools "0.8.2"]] 21 | 22 | :plugins [[lein-figwheel "0.5.9"]] 23 | }} 24 | 25 | :cljsbuild 26 | {:builds 27 | [{:id "dev" 28 | :source-paths ["src/cljs"] 29 | :figwheel {:on-jsload "reframe-auth0.core/mount-root"} 30 | :compiler {:main reframe-auth0.core 31 | :output-to "resources/public/js/compiled/app.js" 32 | :output-dir "resources/public/js/compiled/out" 33 | :asset-path "js/compiled/out" 34 | :source-map-timestamp true 35 | :preloads [devtools.preload] 36 | :external-config {:devtools/config {:features-to-install :all}} 37 | }} 38 | 39 | {:id "min" 40 | :source-paths ["src/cljs"] 41 | :compiler {:main reframe-auth0.core 42 | :output-to "resources/public/js/compiled/app.js" 43 | :optimizations :advanced 44 | :closure-defines {goog.DEBUG false} 45 | :pretty-print false}} 46 | 47 | 48 | ]} 49 | 50 | ) 51 | -------------------------------------------------------------------------------- /resources/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/clj/reframe_auth0/core.clj: -------------------------------------------------------------------------------- 1 | (ns reframe-auth0.core) 2 | -------------------------------------------------------------------------------- /src/cljs/reframe_auth0/auth0.cljs: -------------------------------------------------------------------------------- 1 | (ns reframe-auth0.auth0 2 | (:require [re-frame.core :as re-frame] 3 | [reframe-auth0.config :as config] 4 | [cljsjs.auth0-lock])) 5 | 6 | (def lock 7 | "The auth0 lock instance used to login and make requests to Auth0" 8 | (let [client-id (:client-id config/auth0) 9 | domain (:domain config/auth0) 10 | options (clj->js {})] 11 | (js/Auth0Lock. client-id domain options))) 12 | 13 | (defn handle-profile-response [error profile] * 14 | "Handle the response for Auth0 profile request" 15 | (let [profile-clj (js->clj profile :keywordize-keys true)] 16 | (re-frame/dispatch [::set-user-profile profile-clj]))) 17 | 18 | (defn on-authenticated 19 | "Function called by auth0 lock on authentication" 20 | [auth-result-js] 21 | (let [auth-result-clj (js->clj auth-result-js :keywordize-keys true) 22 | access-token (:accessToken auth-result-clj)] 23 | (re-frame/dispatch [::set-auth-result auth-result-clj]) 24 | (.getUserInfo lock access-token handle-profile-response))) 25 | 26 | (.on lock "authenticated" on-authenticated) 27 | 28 | ;;; events 29 | (re-frame/reg-event-db 30 | ::set-auth-result 31 | (fn [db [_ auth-result]] 32 | (assoc-in db [:user :auth-result] auth-result))) 33 | 34 | (re-frame/reg-event-db 35 | ::set-user-profile 36 | (fn [db [_ profile]] 37 | (assoc-in db [:user :profile] profile))) 38 | 39 | (re-frame/reg-event-db 40 | ::logout 41 | (fn [db [_ profile]] 42 | (dissoc db :user))) 43 | 44 | ;;; subscriptions 45 | (re-frame/reg-sub 46 | ::user-name 47 | (fn [db] 48 | (get-in db [:user :profile :name]))) 49 | -------------------------------------------------------------------------------- /src/cljs/reframe_auth0/config.cljs: -------------------------------------------------------------------------------- 1 | (ns reframe-auth0.config) 2 | 3 | (def debug? 4 | ^boolean goog.DEBUG) 5 | 6 | (def auth0 7 | {:client-id "xxxx" 8 | :domain "xxxx"}) -------------------------------------------------------------------------------- /src/cljs/reframe_auth0/core.cljs: -------------------------------------------------------------------------------- 1 | (ns reframe-auth0.core 2 | (:require [reagent.core :as reagent] 3 | [re-frame.core :as re-frame] 4 | [reframe-auth0.events] 5 | [reframe-auth0.subs] 6 | [reframe-auth0.auth0] 7 | [reframe-auth0.views :as views] 8 | [reframe-auth0.config :as config])) 9 | 10 | 11 | (defn dev-setup [] 12 | (when config/debug? 13 | (enable-console-print!) 14 | (println "dev mode"))) 15 | 16 | (defn mount-root [] 17 | (re-frame/clear-subscription-cache!) 18 | (reagent/render [views/main-panel] 19 | (.getElementById js/document "app"))) 20 | 21 | (defn ^:export init [] 22 | (re-frame/dispatch-sync [:initialize-db]) 23 | (dev-setup) 24 | (mount-root)) 25 | -------------------------------------------------------------------------------- /src/cljs/reframe_auth0/db.cljs: -------------------------------------------------------------------------------- 1 | (ns reframe-auth0.db) 2 | 3 | (def default-db 4 | {:name "re-frame"}) 5 | -------------------------------------------------------------------------------- /src/cljs/reframe_auth0/events.cljs: -------------------------------------------------------------------------------- 1 | (ns reframe-auth0.events 2 | (:require [re-frame.core :as re-frame] 3 | [reframe-auth0.db :as db])) 4 | 5 | (re-frame/reg-event-db 6 | :initialize-db 7 | (fn [_ _] 8 | db/default-db)) 9 | -------------------------------------------------------------------------------- /src/cljs/reframe_auth0/subs.cljs: -------------------------------------------------------------------------------- 1 | (ns reframe-auth0.subs 2 | (:require-macros [reagent.ratom :refer [reaction]]) 3 | (:require [re-frame.core :as re-frame])) 4 | 5 | (re-frame/reg-sub 6 | :name 7 | (fn [db] 8 | (:name db))) 9 | -------------------------------------------------------------------------------- /src/cljs/reframe_auth0/views.cljs: -------------------------------------------------------------------------------- 1 | (ns reframe-auth0.views 2 | (:require [re-frame.core :as re-frame] 3 | [reframe-auth0.auth0 :as auth0])) 4 | 5 | (defn button [text on-click] 6 | [:button 7 | {:type "button" 8 | :on-click on-click} 9 | text]) 10 | 11 | (def login-button 12 | (button "Log in" #(.show auth0/lock))) 13 | 14 | (def logout-button 15 | (button "Log out" #(re-frame/dispatch [::auth0/logout]))) 16 | 17 | (defn main-panel [] 18 | (let [name (re-frame/subscribe [:name]) 19 | user-name (re-frame/subscribe [::auth0/user-name])] 20 | (fn [] 21 | (if @user-name 22 | [:div 23 | [:div "Hello " @user-name " from " @name] 24 | logout-button] 25 | [:div 26 | [:div "Hello from " @name] 27 | login-button])))) 28 | --------------------------------------------------------------------------------