8000 feat(users): email invitations and remove people for good by adeelahmad · Pull Request #286 · adeelahmad/lense · GitHub
[go: up one dir, main page]

Skip to content

feat(users): email invitations and remove people for good - #286

Merged
adeelahmad merged 4 commits into
mainfrom
claude/project-thread-a40rui
Oct 15, 2026
Merged

adeelahmad merged 4 commits into
mainfrom
claude/project-thread-a40rui

Conversation

@adeelahmad
Copy link
Copy Markdown
Owner

Requested by Adeel · project thread

Description

Part 1 of the user manager and RBAC work. People already had list, create, roles per namespace, disable, sign-in links and passkey removal. What was missing:

  • Invitations by email. POST /users/{id}/signin-link?email=true emails the sign-in link (new invite.html template) when mail is set up, and answers emailed. The web app's Create account and Send a sign-in link dialogs ask for it. The link still shows so the admin can share it themselves. Without email=true nothing changes.
  • Remove for good. DELETE /users/{id} (People › Remove for good…) ends every way the person signs in (sessions, passkeys, links, connected accounts, API tokens, app grants, IIIF tokens). It also takes every role and permission, and deletes their private things (chats, own notes and highlights, unshared views and collections, unfinished uploads). What they shared stays under their name. The account is kept only as a marker with an .invalid email, so the same address can be invited again and the new account inherits nothing. It is refused for yourself and for the Matterbridge account. It is also refused when their passkeys are the last way into a vault, unless lose_vaults=true. The dialog offers Disable instead, since removing can't be undone.
  • Agents. Assistant admin tools list_people, invite_person and change_person (role in a namespace, disable or enable). They always wait for approval, even in a setup conversation. The assistant can't remove anyone.

Motivation and Context

Adeel asked for a user manager and RBAC. Custom roles with permissions come in the next PR.

Types of changes

  • New feature (non-breaking change which adds functionality)

Checklist:

  • The title is a Conventional Commit.
  • My code follows the code style of this project.
  • I added or updated tests (test_users.py, test_setup_assistant.py).
  • I updated docs/ (authentication.md "Removing someone", api.md, assistant.md).
  • CHANGELOG.md ## Unreleased.

Done questions

  1. Goal: part 1 of 2. The user manager is covered; RBAC follows in the next PR.
  2. Agents: yes. API with an admin key, plus assistant tools.
  3. Zero setup: yes. Email is used only when mail is already set up.
  4. Fewest clicks: yes. Creating an account emails the link in the same step.
  5. Configurable: n/a, there are no new settings.
  6. Light: yes, nothing heavy added.
  7. Private and secure: yes. Removal ends every credential. P-REMOVE was added and P-APPROVAL updated in the threat model, with YAML and JSON regenerated and the validator passing.
  8. Cost: n/a, no model calls.
  9. User decides: yes. Removal asks first and offers Disable. People changes made by the assistant always wait for approval. Defaults are unchanged.
  10. Upgrades: n/a. No stored shape changes for existing rows; removed_at is only set on removed accounts.
  11. Honest: yes, the docs describe only what is built.
  12. Tested and documented: yes. The OpenAPI client was regenerated with make openapi.
  13. Open: n/a.
  14. Reported: in the project thread.

Refine later: a bulk invite from a list of emails, and showing "invited, not signed in yet" as its own status in People.

🤖 Generated with Claude Code

https://claude.ai/code/session_013CspHV36KRyiRJ9LsFqK53


Generated by Claude Code

Admins' sign-in links can be emailed as an invitation when mail is set up
(?email=true; the web app asks for it). DELETE /users/{id} ends every way
someone signs in, takes their roles and private things, keeps what they
shared, and frees their email. The assistant gets list_people,
invite_person and change_person, which always wait for approval.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013CspHV36KRyiRJ9LsFqK53
@adeelahmad adeelahmad self-assigned this Oct 10, 2026
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013CspHV36KRyiRJ9LsFqK53
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013CspHV36KRyiRJ9LsFqK53
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013CspHV36KRyiRJ9LsFqK53
@adeelahmad
adeelahmad merged commit 8d83c7e into main Oct 15, 2026
11 checks passed
@adeelahmad
adeelahmad deleted the claude/project-thread-a40rui branch October 15, 2026 00:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0