PhoenixKit.Users.Invitations (phoenix_kit v1.7.112)

Copy Markdown View Source

Context for organization invitation lifecycle management.

Handles creating, listing, accepting, declining, and cancelling invitations.

Token Security

Follows the UserToken pattern:

  • Raw token (32 bytes) is generated with :crypto.strong_rand_bytes/1
  • SHA-256 hash is stored in the database
  • URL-safe Base64 encoded raw token is sent via email or flash

Flow

  1. Admin calls create_invitation/3 — invitation is created, encoded_token returned
  2. For existing users: banner shown via list_pending_for_email/1 + InvitationHook
  3. For new users: invitation email with registration link containing encoded_token
  4. User accepts via accept_invitation_by_uuid/2 or declines via decline_invitation_by_uuid/1

Summary

Functions

Accepts an invitation by UUID in a single transaction.

Cancels a pending invitation by UUID (admin action).

Creates an invitation for the given email to join the organization.

Declines an invitation by UUID.

Looks up a pending, non-expired invitation by encoded token. Used during registration to show org name and store the token.

Lists all invitations for an organization, ordered by most recent first.

Lists pending, non-expired invitations for a given email. Preloads the :organization association for display in banners.

Functions

accept_invitation_by_uuid(invitation_uuid, user)

Accepts an invitation by UUID in a single transaction.

Sets invitation status to :accepted and links the user to the organization. Returns {:ok, {invitation, user}} on success.

Errors

  • {:error, :not_found} — invitation not found
  • {:error, :not_pending} — invitation is not in :pending status
  • {:error, :expired} — invitation has expired
  • {:error, reason} — database or validation error

cancel_invitation(invitation_uuid)

Cancels a pending invitation by UUID (admin action).

Only :pending invitations can be cancelled.

create_invitation(organization, email, invited_by)

Creates an invitation for the given email to join the organization.

Returns {:ok, invitation, encoded_token} on success. The encoded_token must be sent to the invitee (via email for new users, or the UI banner handles lookup by invitation uuid for existing users).

Validation

  • Cannot invite a user already belonging to an organization
  • Cannot create a duplicate pending invitation from the same org for the same email

decline_invitation_by_uuid(invitation_uuid)

Declines an invitation by UUID.

Only pending invitations can be declined.

get_by_token(encoded_token)

Looks up a pending, non-expired invitation by encoded token. Used during registration to show org name and store the token.

Returns {:ok, invitation} or {:error, :not_found | :invalid_token}.

list_invitations(organization_uuid)

Lists all invitations for an organization, ordered by most recent first.

list_pending_for_email(email)

Lists pending, non-expired invitations for a given email. Preloads the :organization association for display in banners.