Skip to content

Docs: replaceInviteWithCredentials self-link use case (adding verified emails to existing person) #7

Description

@mitselek

TL;DR

The invite-acceptance code path in entu/api/routes/auth/index.get.js has TWO branches that call replaceInviteWithCredentials. The second one ("Same entity: clean up orphaned invite property") enables a useful self-link workflow that isn't documented as a supported pattern: an already-logged-in user can add additional entu_user entries (additional verified emails / OAuth providers) to their OWN person without admin intervention.

How the self-link flow works

  1. User clicks "Add login email" in the app (logged in as person P)
  2. App creates a placeholder entu_user property on P: { type: 'entu_user', invite: <token>, email: 'new@example.com' }
  3. App sends an email to new@example.com with an invite link containing a JWT referencing entity P
  4. User clicks link → e-mail OAuth flow → Entu's auth detects invite param → existingEntry.user._id === inviteData.entityId branch fires → replaceInviteWithCredentials swaps the placeholder with real { uid, email, provider: 'e-mail' }
  5. P now has two (or more) entu_user entries; future invitations/logins to either address resolve to P

Implication

Apps building on Entu don't need to build their own email-verification round-trip for "add another email to my profile" use cases. The existing invite mechanism handles it.

Polyphony adopted this for its email-trust model (see polyphony case study C6 — https://github.com/entu/research/blob/main/docs/case-studies/2026-05-polyphony-on-entu.md).

Suggested doc note

At https://www.entu.ee/api/authentication/ or https://www.entu.ee/configuration/users/: document the self-link pattern as a supported workflow:

  • "To add additional verified emails (or OAuth provider links) to an existing person, use the invite mechanism as a self-link: create a placeholder entu_user on the user's own person with an invite token, send the invite to the new address, the OAuth completion will swap the placeholder with real credentials."

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions