Skip to content

Instantly share code, notes, and snippets.

@humorless
Created October 23, 2025 08:36
Show Gist options
  • Select an option

  • Save humorless/82cc46bba7d8d519c0418a4296f5435e to your computer and use it in GitHub Desktop.

Select an option

Save humorless/82cc46bba7d8d519c0418a4296f5435e to your computer and use it in GitHub Desktop.
  • layout-component (ornament fn)
    • handle CSS part
    • leverage query syntax to assign CSS to child structure
  • widget-component (ornament fn)
    • small, reusable, and self-contained UI elements)
  • presenter-fn (ordinary fn)
    • handle pure html structure (withouth CSS)
    • example: fail-page
  • container-fn (ordinary fn)
    • handle the data && logic behavior
    • example: verification-success
(ns co.gaiwan.oak.html.totp)
...

(o/defstyled totp-layout :div
  {:display         :flex
   :justify-content :center
   :align-items     :center
   :min-height      "100vh"}
  [:p
   {:text-align :center
    :margin-top 0}]
  ([& children]
   [:<>
    [w/leaf-bg]
    (into [w/full-center-card] children)]))

(defn fail-page [{:keys [next-uri]}]
  [totp-layout
   [:h1 "2FA Setup Failed"]
   [:p "Invalid code. Please check and re-enter."]
   [:a {:href next-uri} "Go back to 2FA setup page"]])

=====================================================
(ns co.gaiwan.oak.apis.totp)
...

(defn verification-success
  "Tell success, store secret as credential (upsert the record), remove the secret from
   the session"
  [{:keys [identity db session]} secret]
  (let [opts {:identity-id (:identity/id identity)
              :type "totp"
              :value secret}
        updated-session (dissoc session :totp/secret)]
    (if (credential/create-or-update! db opts)
      {:status 200
       :session updated-session
       :html/body
       [totp-html/success-page {:cred-save-success? true}]}
      {:status 200
       :html/body
       [totp-html/success-page {:cred-save-success? false}]})))
  1. Think about "user's view point" when designing the URL name.

  2. When using :html/body, using the hiccup/vector syntax is generally preferred. in this case it doesn't make a big difference, but if you also have a regular :body (for content negotiation), then the vector syntax will make the hiccup expansion lazy. That is: [fn-name ...] over (fn-name ...)

  3. Having fairly flat designs, but have selective skeumorphic elements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment