VBT.Accounts.Token (vbt v0.1.0) View Source

Helpers for working with account-related one-time tokens.

This module can be used to generate and work with one-time tokens which are related to individual accounts. This can be useful to implement features such as password reset, where a confirmation link must be sent via an e-mail.

The create!/4 function can be invoked to generate an encoded and signed one-time token. This token can then be safely included in an e-mail link, or passed to the user via other channels. When the token needs to be used, the client code must invoke decode/3, and then use/4. See the documentation of these functions for details.

Link to this section Summary

Functions

Returns the account corresponding to the given token.

Performs the desired operation using the given one-time token.

Link to this section Types

Specs

account_id() :: any()

Specs

encoded() :: String.t()

Specs

max_age() :: pos_integer() | :infinity

Specs

operation_result() :: {:ok, any()} | {:error, any()}

Link to this section Functions

Link to this function

create!(account, type, max_age, config)

View Source

Specs

create!(Ecto.Schema.t() | nil, String.t(), max_age(), VBT.Accounts.config()) ::
  encoded()

Creates a new token.

The function returns a token which can be safely sent to remote client. When a client sends the token back, it can be verified and used with use/3.

The token will be valid for the max_age seconds.

This function always succeeds. If the account is nil, the token will still be generated. This approach is chosen to prevent user enumeration attack.

Link to this function

get_account(token, expected_type, config)

View Source

Specs

get_account(encoded(), String.t(), VBT.Accounts.config()) ::
  Ecto.Schema.t() | nil

Returns the account corresponding to the given token.

The account is returned only if:

  • the token exists in the database
  • the token has not been used
  • the token has not expired
  • the token type is expected_type
  • the token corresponds to an existing account

If any of the conditions above is not met, this function will return nil.

Link to this function

use(token, expected_type, operation, config)

View Source

Specs

use(encoded(), String.t(), (account_id() -> result), VBT.Accounts.config()) ::
  result | {:error, :invalid}
when result: operation_result()

Performs the desired operation using the given one-time token.

This function will mark the token as used, and perform the desired operation. This is done atomically, inside a transaction.

The operation function will receive the account id of the corresponding user.

If the token is not valid, the function will return an error. In this case, the token will not be marked as used. The token is valid if the following conditions are satisfied:

  • it hasn't expired
  • it hasn't been used
  • it corresponds to an existing account