question about reCAPTCHA: is using/showing biff/recaptcha-disclosure required? I have been navigating and looking around for where it might say that u must display the ToS and Privacy Policy... but havent found anything.
Google mentions the requirement here: https://developers.google.com/recaptcha/docs/faq#id-like-to-hide-the-recaptcha-badge.-what-is-allowed
I am reaching a stage in my own app where I am looking to customize the auth code. Could I get some help on how to do this?
I have 2 questions:
1. for now, I am looking to be able to also add first / last name fields to the signup form. It looks like I could achieve this simply by providing a function for :biff.auth/new-user-tx when calling authentication-module. Is this correct?
2. if I want to further customize things and have the need to actually include the source into my own app, how would I do this? I see in https://github.com/jacobobryant/biff/blob/master/src/com/biffweb/impl/auth.clj https://github.com/jacobobryant/biff/blob/master/src/com/biffweb/impl/auth.clj#L7-L9 about copying the file into my own project. Quoting the entire ns macro here for clarity:
(ns com.biffweb.impl.auth
(:require [com.biffweb.impl.misc :as bmisc]
[com.biffweb.impl.rum :as brum]
[com.biffweb.impl.time :as btime]
[com.biffweb.impl.util :as butil]
[com.biffweb.impl.xtdb :as bxt]
;;; NOTE: if you copy this file into your own project, remove the
;;; above lines and replace them with the com.biffweb namespace:
;[com.biffweb :as biff]
[clj-http.client :as http]
[clojure.string :as str]
[rum.core :as rum]
[xtdb.api :as xt]))
the NOTE makes it seem like I should be doing something like this:
(ns com.my-app.auth
(:require [com.biffweb :as biff]
[clj-http.client :as http]
[clojure.string :as str]
[rum.core :as rum]
[xtdb.api :as xt]))
But what of the various calls in the rest of the file that make use of the aliases? e.g. brum/unsafe, bmisc/jwt-encrypt, etc.? for a start this is what I did (but it's not working):
• copied auth.clj to src/com/eelchat/auth.clj and changed the ns to com.eelchat.auth
• src/com/eelchat.clj: added [com.eelchat.auth :as auth] to :require, and also replaced (authentication-module {}) with app/modulefor 1, I just tried to define my own custom new-user-tx function in src/com/eelchat.clj; but this is not being called:
(defn new-user-tx [ctx email]
(println "our custom 'new-user-tx'")
(prn ctx))
(def modules
[app/module
(biff/authentication-module {:biff.auth/new-user-tx new-user-tx})
home/module
schema/module])
For 1: that should work (sort of--see below). note that new-user-tx won't get called until you click the signin link (or enter the 6-digit code, depending on which flow you're going through); i.e. it won't run immediately after you submit the form with your email address, because that's not when the user gets created. I just applied the following diff to the starter project and I see the following in the terminal:
diff --git a/starter/src/com/example.clj b/starter/src/com/example.clj
index 63fafb1..4377f15 100644
--- a/starter/src/com/example.clj
+++ b/starter/src/com/example.clj
@@ -15,9 +15,15 @@
[nrepl.cmdline :as nrepl-cmd])
(:gen-class))
+(defn new-user-tx [ctx email]
+ (println "our custom 'new-user-tx'")
+ [{:db/doc-type :user
+ :db.op/upsert {:user/email email}
+ :user/joined-at :db/now}])
+
(def modules
[app/module
- (biff/authentication-module {})
+ (biff/authentication-module {:biff.auth/new-user-tx new-user-tx})
home/module
schema/module
worker/module])
[qtp2057439381-40] INFO com.biffweb.impl.middleware - 348ms 303 post /auth/send-link
[qtp2057439381-34] INFO com.biffweb.impl.middleware - 4ms 200 get /link-sent?email=hello@example.com
TO: [{:email }]
SUBJECT: Sign up for My Application
We received a request to sign up to My Application using this email address. Click this link to sign up:
This link will expire in one hour. If you did not request this link, you can ignore this email.
To send emails instead of printing them to the console, add your API keys for MailerSend and Recaptcha to config.env.
[qtp2057439381-40] INFO com.biffweb.impl.middleware - 106ms 303 post /auth/send-link
[qtp2057439381-34] INFO com.biffweb.impl.middleware - 4ms 200 get /link-sent?email=test20240831@example.com
our custom 'new-user-tx'
[qtp2057439381-40] INFO com.biffweb.impl.middleware - 60ms 303 get /auth/verify-link/[...]
[bus-listener-1] INFO com.example.worker - WOAH there's a new user
[qtp2057439381-38] INFO com.biffweb.impl.middleware - 10ms 200 get /app
[qtp2057439381-40] INFO com.biffweb.impl.middleware - 1ms 101 get /app/chat
that being said: although you should be able to override new-user-tx in this way, a complication is that when that function does run, it doesn't have access to the first ring request where the user submitted the form: it gets called on the second request where they click the link/submit the code. So you have to do something more complicated to propagate the extra form params from the first request to the second request.
so even for this, you'll probably need to copy over the whole authentication module so you can customize it more heavily. For the email-link flow, you can include the params in the email link; for the 6-digit-code flow, you can include them in the redirect URL and put them in hidden fields in the second form.
I'm writing up a gist to do that; will post a link to that in a minute.Here's a HOWTO for adding extra fields to the signup form: https://gist.github.com/jacobobryant/4f143f678f5e52ba7f98d4af5402997c
for 2: yes, that's the right approach. for the aliased functions, you can change them all to e.g. biff/unsafe, biff/jwt-enrypt etc
> src/com/eelchat.clj: added [com.eelchat.auth :as auth] to :require, and also replaced (authentication-module {}) with app/module
do you mean replaced it with (com.eelchat.auth/authentication-module {})? that should work.
do you mean replaced it with (com.eelchat.auth/authentication-module {})? that should work.Yes. I was expecting for the user to be created on signup, pre-verification. But I see now that I misunderstood. Thanks for all the explanation and the help! much appreciated. gratitude-thank-youhey Jacob, I'm just now noticing how in auth.clj middleware is a vector of a vector (instead of a vector of functions), which I've never seen before.
So what I'm used to:
{:routes ... {:middleware [fn1 fn2]}}
What's new
{:routes ... [[wrap-options (merge default-options options)]]}
Would u mind explaining how this vector of a vector(s?) is used, and also point me to the code that actually processes this?
It's a reitit feature--I wasn't able to find much reitit documentation on it after a quick search, but the https://github.com/metosin/reitit/blob/master/doc/ring/data_driven_middleware.md on this page do demonstrate it at least.
If you have middleware that takes additional options besides just the handler, e.g.:
(defn my-middleware [handler additional-options]
(fn [request]
...))
Then you can do [my-middleware {:foo 1 :bar 2}] and the map will get passed in as additional-options. Doing my-middleware instead of [my-middleware ...] is basically just a short-hand for [my-middleware]. If you were doing plain ring stuff without reitit, you might instead compose the middleware like:
(def handler ...)
(def wrapped-handler (-> handler
(my-middleware {:foo 1 :bar 2})
...))
or in reitit, it's also equivalent to doing:
{:middleware [#(my-middleware % {:foo 1 :bar 2})]}
thank you Jacob. Cant say that I understand all of that.. but I will definitely look into the links and the examples.
> Doing my-middleware instead of [my-middleware ...] is basically just a short-hand for [my-middleware].
so {:middleware [fn1]} is the same as {:middleware [[fn1]]} ?
Hi! Any advice on where I can find release notes for v0.7.3? I was reading https://biffweb.com/docs/api/utilities/, found a reference from the start-system docstring, and was curious about the change. https://github.com/jacobobryant/biff/releases doesn't seem to have release notes for that version.
ah, I should update those to mention the v0.7.4 release notes instead: https://github.com/jacobobryant/biff/releases/tag/v0.7.4 looks like I tagged a commit as v0.7.3 but then made another small commit and tagged it as v0.7.4 before making the announcement.