Gamend.Accounts.Sessions (gamend_core v1.0.1296)

Copy Markdown View Source

Signing in and staying signed in: session and magic-link tokens, the emails that carry them, and listing or revoking a user's sessions.

Split out of Gamend.Accounts, which still exposes every function here under the same name. Revoking every token on a credential change stays there, next to the writes that trigger it.

Summary

Functions

Counts tokens for a given user.

Deletes the signed token with the given context.

Delivers the magic link login instructions to the given user.

Delivers the update email instructions to the given user.

Generates a session token.

Gets the user with the given magic link token.

Gets the user with the given signed token.

Lists tokens for a given user, optionally filtered by context.

Logs the user in by magic link.

Revokes all session tokens for a user (mass logout).

Functions

count_user_tokens(user_id)

@spec count_user_tokens(Ecto.UUID.t()) :: non_neg_integer()

Counts tokens for a given user.

delete_user_session_token(token)

@spec delete_user_session_token(binary()) :: :ok

Deletes the signed token with the given context.

deliver_login_instructions(user, magic_link_url_fun)

@spec deliver_login_instructions(Gamend.Accounts.User.t(), (String.t() -> String.t())) ::
  {:ok, Swoosh.Email.t()} | {:error, term()}

Delivers the magic link login instructions to the given user.

deliver_user_update_email_instructions(user, current_email, update_email_url_fun)

@spec deliver_user_update_email_instructions(
  Gamend.Accounts.User.t(),
  String.t(),
  (String.t() -> String.t())
) :: {:ok, Swoosh.Email.t()} | {:error, term()}

Delivers the update email instructions to the given user.

Examples

iex> deliver_user_update_email_instructions(user, current_email, &url(~p"/users/settings/confirm_email/#{&1}"))
{:ok, %{to: ..., body: ...}}

generate_user_session_token(user)

@spec generate_user_session_token(Gamend.Accounts.User.t()) :: binary()

Generates a session token.

get_user_by_session_token(token)

@spec get_user_by_session_token(binary()) ::
  {Gamend.Accounts.User.t(), DateTime.t()} | nil

Gets the user with the given signed token.

If the token is valid {user, token_inserted_at} is returned, otherwise nil is returned.

list_user_tokens(user_id, opts \\ [])

@spec list_user_tokens(Ecto.UUID.t(), keyword()) :: [Gamend.Accounts.UserToken.t()]

Lists tokens for a given user, optionally filtered by context.

login_user_by_magic_link(token)

@spec login_user_by_magic_link(String.t()) ::
  {:ok, {Gamend.Accounts.User.t(), [Gamend.Accounts.UserToken.t()]}}
  | {:error, :not_found | Ecto.Changeset.t() | term()}

Logs the user in by magic link.

There are three cases to consider:

  1. The user has already confirmed their email. They are logged in and the magic link is expired.

  2. The user has not confirmed their email. Opening the link proves they own the inbox, so the user gets confirmed, logged in, and all tokens - including session ones - are expired.

  3. As 2, with a password set: registered when POST /api/v1/register still took one, or a guest account given an email, and never confirmed. The password is removed as the email is confirmed. Whoever set it did so before anyone proved they own the inbox, so it may be someone else's, and kept it would sign them into the account its owner has just claimed (the "Mixing magic link and password registration" section of mix help phx.gen.auth). The owner sets a new one in settings. The confirmation email's link removes it the same way (Gamend.Accounts.confirm_user_by_token/1); its code sets the password.

revoke_all_user_sessions(user_id)

@spec revoke_all_user_sessions(Ecto.UUID.t()) :: {non_neg_integer(), nil}

Revokes all session tokens for a user (mass logout).