pdombkins makes rose_lawyer's invite flow fit for corporate inboxes

This fork turns basic account access into a more credible collaboration portal for organisations that invite colleagues by email.

securityworkflow

The key change fixes a familiar corporate snag: security scanners can open an emailed invite before its recipient does, accidentally consuming a one-time link. pdombkins routes acceptance through a deliberate step, so an automated scan does not lock out the person who was invited.

The account layer now also covers the practical work around access:

  • Password resets for users who lose access.
  • Invite resends when an email needs another attempt.
  • Clearer invitation status after someone has joined.
  • Admin controls over account settings and who holds administrator access.
  • Email notifications switched on by default.
So what Legal teams rolling out an internal tool should care because reliable invitations and clean admin controls are where adoption often stalls.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?

Commits in this thread

6 commits from pdombkins/rose_lawyer, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
5f7b7fd6 feat: add collaboration portal with invite-only user management Peter Dombkins 2026-07-04 ↗ GitHub
aaaa1477 Add password reset flow (reset-password page + forgot-password link on login) Peter Dombkins 2026-07-24 ↗ GitHub
240c4cf8 fix(auth): scanner-proof invite links via /accept + force resend Peter Dombkins 2026-07-28 ↗ GitHub
commit body
Mail gateways redeemed Supabase single-use action_links on delivery,
burning invites for the whole LAWS3850 cohort. Email a token_hash to an
inert /accept page instead; verifyOtp runs only on click. Also fix the
invite target filter (loadActivatedEmails, not profile rows) and add
force resend to recover falsely-activated accounts.
aa12542c chore(db): default email_notifications to true Peter Dombkins 2026-07-28 ↗ GitHub
Nobody had ever opted in (0/39), so sendEmailIfEnabled() had never sent
a notification email. Already applied to the live project.
be224f81 feat(account): admin-only settings, drop usage tab, single sign-out Peter Dombkins 2026-07-28 ↗ GitHub
commit body
Student accounts are managed centrally, so /account/* is now gated on
isAdmin (same guard as /admin) and the sidebar hides the entry point.
Removes the Usage tab and BudgetBanner - there is no usage plan. Sign
out now lives only in the sidebar, so it stays reachable for users who
can no longer open Settings.
504f7284 Fix accepted invitations showing as pending; allow removing an admin Peter Dombkins 2026-08-02 ↗ GitHub
commit body
invitations.accepted_at has no writer - /accept redeems the token straight
against Supabase in the browser, so nothing server-side ever marked an
invitation accepted and all 38 rows were null. The pending list filtered on
that column, so everyone who had ever been invited stayed on it, including
users who were signed in and shown as active.

GET /admin/invitations now derives the answer from auth activation, the same
signal the group invite endpoint uses, and stamps the rows it settles with the
real activation time so the data converges. Chosen over a callback from the
accept page, which would only have fixed invitations sent afterwards.

Separately, the Remove control was hidden for any admin, leaving an admin
account impossible to delete from the UI. The backend has only ever refused
self-deletion; the button is now gated the same way.

Capture this thread into my fork

Download a single Markdown prompt that tells Claude how to port every commit above into your working tree — adapting paths and structure to match your repo. Run it via claude -p < capture-thread-946.md from inside the repo you want the changes in.

⬇ Download capture-thread-946.md