amber-backend/pb_migrations/1794500000_verify_link_to_web.js
Claude f72c9e7986 Finish confirming an email address on our own site
The verification email still pointed at pb.petruzalekr.cz/_/#/auth/..., the
PocketBase admin console. The previous pass left it there reasoning that nobody
had reached it yet; the accounts say otherwise. Registration fires a verification
email every time (auth_service.dart, fire and forget) and four of the nine
accounts are marked verified, so four family members have already landed in the
admin console and clicked a button in it.

?verify=<token> now confirms in Czech beside ?reset=. It confirms on page load
rather than behind a button: a provider that prefetches links only issues a GET,
the POST comes from the page's own script, and asking someone to press a second
button on a page they reached by pressing one is friction with nothing behind it.

Nothing is gated on verified. The users collection has an empty authRule and five
accounts, the owner's included, work fine without it. The flag stays because it
is the only evidence an address was typed correctly, which is exactly the
question that comes up when somebody reports a missing email. The failure copy
says so plainly, so an expired link reads as harmless rather than as a lockout.

Email-change is deliberately untouched: no surface can trigger it today.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 19:31:51 +02:00

55 lines
2.4 KiB
JavaScript

/// <reference path="../pb_data/types.d.ts" />
// Point the verification email at the site instead of the admin console.
//
// 1794000000 translated all three account emails but deliberately left
// verification and email-change aimed at `{APP_URL}/_/#/auth/…`, on the grounds
// that "nobody has hit those yet". That was wrong on the facts: the app fires a
// verification email on every registration (auth_service.dart, fire and forget),
// and four of the nine accounts carry `verified: 1` — four family members opened
// PocketBase's admin console and clicked a button in it.
//
// Nothing is gated on `verified`: the users collection has an empty authRule,
// and five accounts including the owner's work fine unverified. The flag is kept
// because it is the only evidence an address was typed correctly, which is
// exactly the question that comes up when somebody reports a missing email.
//
// amber.petruzalekr.cz/?verify=<token> now hosts the confirm step in Czech, the
// same way `?reset=` does.
//
// Email-change is left alone on purpose: no surface in the app or the site can
// trigger it today, so pointing it at a page nobody reaches would be motion
// without a reader.
const VERIFY_SUBJECT = "Ověření e-mailu pro Amber";
const VERIFY_BODY = `<p>Ahoj,</p>
<p>Potvrď prosím tímhle odkazem, že tenhle e-mail patří tobě:</p>
<p>
<a class="btn" href="https://amber.petruzalekr.cz/?verify={TOKEN}" target="_blank" rel="noopener">Potvrdit e-mail</a>
</p>
<p><i>Není to povinné. Bez potvrzení se přihlásíš úplně stejně, jen Richard
uvidí, že adresa opravdu funguje.</i></p>
<p>Amber</p>`;
// What 1794000000 set, so the down migration lands where it started rather than
// on PocketBase's English default.
const PREVIOUS_BODY = `<p>Ahoj,</p>
<p>Potvrď prosím tímhle odkazem, že tenhle e-mail patří tobě:</p>
<p>
<a class="btn" href="{APP_URL}/_/#/auth/confirm-verification/{TOKEN}" target="_blank" rel="noopener">Potvrdit e-mail</a>
</p>
<p>Amber</p>`;
migrate(
(app) => {
const users = app.findCollectionByNameOrId("users");
users.verificationTemplate.subject = VERIFY_SUBJECT;
users.verificationTemplate.body = VERIFY_BODY;
app.save(users);
},
(app) => {
const users = app.findCollectionByNameOrId("users");
users.verificationTemplate.subject = VERIFY_SUBJECT;
users.verificationTemplate.body = PREVIOUS_BODY;
app.save(users);
},
);