Login links + invitations — Zkrinet plugin
On Zkrinet: add the block under Building blocks in the panel — one click, your own code is untouched and a snapshot is taken first. The installation steps below apply if you run PocketBase yourself, for example after an export.
Log in with a link in an email instead of a password, and invite people with a link that creates the account for them. Tested against PocketBase 0.40.4. Requires the mejl plugin (for the invitations).
#Honestly, what is what
The login with a one-time code itself is PocketBase's own (OTP). The plugin turns it on, makes the email Swedish with a button, extends the validity to 15 minutes and adds a landing page. The invitations are our own addition.
#Install
Copy pb_hooks/ and pb_migrations/ (and the mejl plugin) into the project and restart. Set Application URL under Settings — the links in the emails are built from it.
#Log in with a link
From your app (PocketBase JS SDK):
await pb.collection("users").requestOTP("anna@exempel.se")
The user gets an email with a button. The link leads to a page with the button Logga in; when it is pressed the user is logged in and sent to the start page (/). The login is stored where the PocketBase JS SDK looks for it (pocketbase_auth), so your app is logged in immediately if it is on the same address as PocketBase. If your frontend is somewhere else: let the user type in the code from the email and call pb.collection("users").authWithOTP(otpId, kod).
#Invite
From your server (requires superuser):
POST /api/zk/inbjudan {"epost": "nisse@exempel.se", "namn": "Nisse", "dagar": 7}
Nisse gets an email. When he presses Gå med the account is created (verified) if it does not exist, and he is logged in. If the account already exists he is just logged in — the password is not changed.
#Security
- Scanner protection: the links never log in directly. Email scanners (e.g. Outlook's link protection) open links but do not press buttons.
- The one-time code works once and for 15 minutes. Invitations work once and for 1–30 days (default 7).
- The invitation code is stored only as a SHA-256 hash. Someone who reads the database cannot use it.
- The landing pages are sent with
Cache-Control: no-storeandReferrer-Policy: no-referrer.
#Limitations
- Only the
userscollection. - After login the user is sent to
/.