Packages

SDK for GameServer hooks development. Provides type specs, documentation, and IDE autocomplete for GameServer modules without requiring the full server.

Current section

Files

Jump to
game_server_sdk lib game_server accounts.ex
Raw

lib/game_server/accounts.ex

defmodule GameServer.Accounts do
@moduledoc ~S"""
The Accounts context.
## Usage
# Lookup by id or email
user = GameServer.Accounts.get_user(123)
user = GameServer.Accounts.get_user_by_email("me@example.com")
# Update a user
{:ok, user} = GameServer.Accounts.update_user(user, %{display_name: "NewName"})
# Search (paginated) and count
users = GameServer.Accounts.search_users("bob", page: 1, page_size: 25)
count = GameServer.Accounts.count_search_users("bob")
**Note:** This is an SDK stub. Calling these functions will raise an error.
The actual implementation runs on the GameServer.
"""
@doc ~S"""
Attach a device_id to an existing user record. Returns {:ok, user} or
{:error, changeset} if the device_id is already used.
"""
@spec attach_device_to_user(GameServer.Accounts.User.t(), String.t()) ::
{:ok, GameServer.Accounts.User.t()} | {:error, Ecto.Changeset.t()}
def attach_device_to_user(_user, _device_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.attach_device_to_user/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Broadcast a `friend_updated` event to all accepted friends.
Used when public user data changes: map presence, display name, avatar,
player metadata, ship metadata, lobby/party state, etc.
"""
@spec broadcast_friend_update(GameServer.Accounts.User.t()) :: :ok
def broadcast_friend_update(_user) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
:ok
_ ->
raise "GameServer.Accounts.broadcast_friend_update/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Broadcast a `member_updated` event to the user's current lobby and
party channels so other members see the profile change (display name, avatar,
metadata, etc.) in real-time.
This is fire-and-forget and safe to call even when the user is not in a lobby
or party.
"""
@spec broadcast_member_update(GameServer.Accounts.User.t()) :: :ok
def broadcast_member_update(_user) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
:ok
_ ->
raise "GameServer.Accounts.broadcast_member_update/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Broadcast that the given user has been updated.
This helper is intentionally small and only broadcasts a compact payload
intended for client consumption through the `user:<id>` topic.
"""
@spec broadcast_user_update(GameServer.Accounts.User.t()) :: :ok
def broadcast_user_update(_user) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
:ok
_ ->
raise "GameServer.Accounts.broadcast_user_update/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Stores `user` under the canonical user cache key (with the standard TTL).
Call after writes that update the user row outside this module (e.g. lobby
or party membership) so subsequent `get_user/1` reads stay warm and
consistent instead of serving the pre-write struct until the TTL expires.
"""
@spec cache_user(GameServer.Accounts.User.t()) :: GameServer.Accounts.User.t()
def cache_user(_user) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Accounts.cache_user/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Returns an `%Ecto.Changeset{}` for changing the user display_name.
"""
@spec change_user_display_name(GameServer.Accounts.User.t()) :: Ecto.Changeset.t()
def change_user_display_name(_user) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Accounts.change_user_display_name/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Returns an `%Ecto.Changeset{}` for changing the user display_name.
"""
@spec change_user_display_name(GameServer.Accounts.User.t(), map()) :: Ecto.Changeset.t()
def change_user_display_name(_user, _attrs) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Accounts.change_user_display_name/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Returns an `%Ecto.Changeset{}` for changing the user email.
See `GameServer.Accounts.User.email_changeset/3` for a list of supported options.
## Examples
iex> change_user_email(user)
%Ecto.Changeset{data: %User{}}
"""
@spec change_user_email(GameServer.Accounts.User.t()) :: Ecto.Changeset.t()
def change_user_email(_user) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Accounts.change_user_email/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Returns an `%Ecto.Changeset{}` for changing the user email.
See `GameServer.Accounts.User.email_changeset/3` for a list of supported options.
## Examples
iex> change_user_email(user)
%Ecto.Changeset{data: %User{}}
"""
@spec change_user_email(GameServer.Accounts.User.t(), map()) :: Ecto.Changeset.t()
def change_user_email(_user, _attrs) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Accounts.change_user_email/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Returns an `%Ecto.Changeset{}` for changing the user email.
See `GameServer.Accounts.User.email_changeset/3` for a list of supported options.
## Examples
iex> change_user_email(user)
%Ecto.Changeset{data: %User{}}
"""
@spec change_user_email(GameServer.Accounts.User.t(), map(), keyword()) :: Ecto.Changeset.t()
def change_user_email(_user, _attrs, _opts) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Accounts.change_user_email/3 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Returns an `%Ecto.Changeset{}` for changing the user password.
See `GameServer.Accounts.User.password_changeset/3` for a list of supported options.
## Examples
iex> change_user_password(user)
%Ecto.Changeset{data: %User{}}
"""
@spec change_user_password(GameServer.Accounts.User.t()) :: Ecto.Changeset.t()
def change_user_password(_user) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Accounts.change_user_password/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Returns an `%Ecto.Changeset{}` for changing the user password.
See `GameServer.Accounts.User.password_changeset/3` for a list of supported options.
## Examples
iex> change_user_password(user)
%Ecto.Changeset{data: %User{}}
"""
@spec change_user_password(GameServer.Accounts.User.t(), map()) :: Ecto.Changeset.t()
def change_user_password(_user, _attrs) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Accounts.change_user_password/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Returns an `%Ecto.Changeset{}` for changing the user password.
See `GameServer.Accounts.User.password_changeset/3` for a list of supported options.
## Examples
iex> change_user_password(user)
%Ecto.Changeset{data: %User{}}
"""
@spec change_user_password(GameServer.Accounts.User.t(), map(), keyword()) :: Ecto.Changeset.t()
def change_user_password(_user, _attrs, _opts) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Accounts.change_user_password/3 is a stub - only available at runtime on GameServer"
end
end
@doc false
@spec change_user_registration(GameServer.Accounts.User.t()) :: Ecto.Changeset.t()
def change_user_registration(_user) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Accounts.change_user_registration/1 is a stub - only available at runtime on GameServer"
end
end
@doc false
@spec change_user_registration(GameServer.Accounts.User.t(), map()) :: Ecto.Changeset.t()
def change_user_registration(_user, _attrs) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Accounts.change_user_registration/2 is a stub - only available at runtime on GameServer"
end
end
@doc false
@spec change_username(GameServer.Accounts.User.t()) :: Ecto.Changeset.t()
def change_username(_user) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Accounts.change_username/1 is a stub - only available at runtime on GameServer"
end
end
@doc false
@spec change_username(GameServer.Accounts.User.t(), map()) :: Ecto.Changeset.t()
def change_username(_user, _attrs) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Accounts.change_username/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Confirms a user's email by setting confirmed_at timestamp.
## Examples
iex> confirm_user(user)
{:ok, %User{}}
"""
@spec confirm_user(GameServer.Accounts.User.t()) ::
{:ok, GameServer.Accounts.User.t()} | {:error, Ecto.Changeset.t()}
def confirm_user(_user) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.confirm_user/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Confirm a user by an email confirmation token (context: "confirm").
Returns {:ok, user} when the token is valid and user was confirmed.
Returns {:error, :not_found} or {:error, :expired} when token is invalid/expired.
"""
@spec confirm_user_by_token(String.t()) ::
{:ok, GameServer.Accounts.User.t()} | {:error, :invalid | :not_found}
def confirm_user_by_token(_token) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.confirm_user_by_token/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Count users matching a username/display name query or exact id. Returns integer.
"""
@spec count_search_users(String.t()) :: non_neg_integer()
def count_search_users(_query) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
0
_ ->
raise "GameServer.Accounts.count_search_users/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Count users who are not yet activated (is_activated == false).
"""
@spec count_unactivated_users() :: non_neg_integer()
def count_unactivated_users() do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
0
_ ->
raise "GameServer.Accounts.count_unactivated_users/0 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Counts tokens for a given user.
"""
@spec count_user_tokens(Ecto.UUID.t()) :: non_neg_integer()
def count_user_tokens(_user_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
0
_ ->
raise "GameServer.Accounts.count_user_tokens/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Returns the total number of users.
"""
@spec count_users() :: non_neg_integer()
def count_users() do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
0
_ ->
raise "GameServer.Accounts.count_users/0 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Count users active in the last N days.
This metric is based on `users.updated_at` (any user record update,
including registration/creation), so it reflects all users and not just
session-token based authentication.
"""
@spec count_users_active_since(integer()) :: non_neg_integer()
def count_users_active_since(_days) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
0
_ ->
raise "GameServer.Accounts.count_users_active_since/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Count users currently marked as online.
"""
@spec count_users_online() :: non_neg_integer()
def count_users_online() do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
0
_ ->
raise "GameServer.Accounts.count_users_online/0 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Count users registered in the last N days.
"""
@spec count_users_registered_since(integer()) :: non_neg_integer()
def count_users_registered_since(_days) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
0
_ ->
raise "GameServer.Accounts.count_users_registered_since/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Count users with a password set (hashed_password not nil/empty).
"""
@spec count_users_with_password() :: non_neg_integer()
def count_users_with_password() do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
0
_ ->
raise "GameServer.Accounts.count_users_with_password/0 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Count users with non-empty provider id for a given provider field (e.g. :google_id)
"""
@spec count_users_with_provider(atom()) :: non_neg_integer()
def count_users_with_provider(_provider_field) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
0
_ ->
raise "GameServer.Accounts.count_users_with_provider/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Deletes a user and associated resources.
Returns `{:ok, user}` on success or `{:error, changeset}` on failure.
"""
@spec delete_user(GameServer.Accounts.User.t()) ::
{:ok, GameServer.Accounts.User.t()} | {:error, Ecto.Changeset.t()}
def delete_user(_user) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.delete_user/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Deletes the signed token with the given context.
"""
@spec delete_user_session_token(binary()) :: :ok
def delete_user_session_token(_token) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
:ok
_ ->
raise "GameServer.Accounts.delete_user_session_token/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Delivers the magic link login instructions to the given user.
"""
@spec deliver_login_instructions(GameServer.Accounts.User.t(), (String.t() -> String.t())) ::
{:ok, Swoosh.Email.t()} | {:error, term()}
def deliver_login_instructions(_user, _magic_link_url_fun) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, nil}
_ ->
raise "GameServer.Accounts.deliver_login_instructions/2 is a stub - only available at runtime on GameServer"
end
end
@doc false
@spec deliver_user_confirmation_instructions(GameServer.Accounts.User.t(), (String.t() -> String.t())) ::
{:ok, Swoosh.Email.t()} | {:error, :already_confirmed | term()}
def deliver_user_confirmation_instructions(_user, _confirmation_url_fun) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, nil}
_ ->
raise "GameServer.Accounts.deliver_user_confirmation_instructions/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
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: ...}}
"""
@spec deliver_user_update_email_instructions(
GameServer.Accounts.User.t(),
String.t(),
(String.t() -> String.t())
) :: {:ok, Swoosh.Email.t()} | {:error, term()}
def deliver_user_update_email_instructions(_user, _current_email, _update_email_url_fun) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, nil}
_ ->
raise "GameServer.Accounts.deliver_user_update_email_instructions/3 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Returns true when device-based auth is enabled. This checks the
application config `:game_server, :device_auth_enabled` and falls back
to the environment variable `DEVICE_AUTH_ENABLED`. If neither
is set, device auth is enabled by default.
"""
@spec device_auth_enabled?() :: boolean()
def device_auth_enabled?() do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
false
_ ->
raise "GameServer.Accounts.device_auth_enabled?/0 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Finds a user by Apple ID or creates a new user from OAuth data.
## Examples
iex> find_or_create_from_apple(%{apple_id: "123", email: "user@example.com"})
{:ok, %User{}}
"""
@spec find_or_create_from_apple(map()) ::
{:ok, GameServer.Accounts.User.t()} | {:error, Ecto.Changeset.t() | term()}
def find_or_create_from_apple(_attrs) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.find_or_create_from_apple/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Finds or creates a user associated with the given device_id.
If a user already exists with the device_id we return it. Otherwise we
create an anonymous confirmed user and attach the device_id.
"""
@spec find_or_create_from_device(String.t()) ::
{:ok, GameServer.Accounts.User.t()} | {:error, :disabled | Ecto.Changeset.t() | term()}
def find_or_create_from_device(_device_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.find_or_create_from_device/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Finds or creates a user associated with the given device_id.
If a user already exists with the device_id we return it. Otherwise we
create an anonymous confirmed user and attach the device_id.
"""
@spec find_or_create_from_device(String.t(), map()) ::
{:ok, GameServer.Accounts.User.t()} | {:error, :disabled | Ecto.Changeset.t() | term()}
def find_or_create_from_device(_device_id, _attrs) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.find_or_create_from_device/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Finds a user by Discord ID or creates a new user from OAuth data.
## Examples
iex> find_or_create_from_discord(%{discord_id: "123", email: "user@example.com"})
{:ok, %User{}}
"""
@spec find_or_create_from_discord(map()) ::
{:ok, GameServer.Accounts.User.t()} | {:error, Ecto.Changeset.t() | term()}
def find_or_create_from_discord(_attrs) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.find_or_create_from_discord/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Finds a user by Facebook ID or creates a new user from OAuth data.
## Examples
iex> find_or_create_from_facebook(%{facebook_id: "123", email: "user@example.com"})
{:ok, %User{}}
"""
@spec find_or_create_from_facebook(map()) ::
{:ok, GameServer.Accounts.User.t()} | {:error, Ecto.Changeset.t() | term()}
def find_or_create_from_facebook(_attrs) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.find_or_create_from_facebook/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Finds a user by Google ID or creates a new user from OAuth data.
## Examples
iex> find_or_create_from_google(%{google_id: "123", email: "user@example.com"})
{:ok, %User{}}
"""
@spec find_or_create_from_google(map()) ::
{:ok, GameServer.Accounts.User.t()} | {:error, Ecto.Changeset.t() | term()}
def find_or_create_from_google(_attrs) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.find_or_create_from_google/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Finds a user by Steam ID or creates a new user from Steam OpenID data.
## Examples
iex> find_or_create_from_steam(%{steam_id: "12345", email: "user@example.com"})
{:ok, %User{}}
"""
@spec find_or_create_from_steam(map()) ::
{:ok, GameServer.Accounts.User.t()} | {:error, Ecto.Changeset.t() | term()}
def find_or_create_from_steam(_attrs) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.find_or_create_from_steam/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Generates a session token.
"""
@spec generate_user_session_token(GameServer.Accounts.User.t()) :: binary()
def generate_user_session_token(_user) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Accounts.generate_user_session_token/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Returns a map of linked OAuth providers for the user.
Each provider is a boolean indicating whether that provider is linked.
"""
@spec get_linked_providers(GameServer.Accounts.User.t()) :: %{
google: boolean(),
facebook: boolean(),
discord: boolean(),
apple: boolean(),
steam: boolean(),
device: boolean()
}
def get_linked_providers(_user) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Accounts.get_linked_providers/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Gets a single user by ID.
Returns `nil` if the User does not exist.
## Examples
iex> get_user(123)
%User{}
iex> get_user(Ecto.UUID.generate())
nil
"""
@spec get_user(Ecto.UUID.t()) :: GameServer.Accounts.User.t() | nil
def get_user(_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
if :erlang.phash2(make_ref(), 2) == 0, do: nil, else: %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}
_ ->
raise "GameServer.Accounts.get_user/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Gets a single user.
Raises `Ecto.NoResultsError` if the User does not exist.
## Examples
iex> get_user!(123)
%User{}
iex> get_user!(456)
** (Ecto.NoResultsError)
"""
@spec get_user!(Ecto.UUID.t()) :: GameServer.Accounts.User.t()
def get_user!(_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Accounts.get_user!/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Get a user by their Apple ID.
Returns `%User{}` or `nil`.
"""
@spec get_user_by_apple_id(String.t()) :: GameServer.Accounts.User.t() | nil
def get_user_by_apple_id(_apple_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
if :erlang.phash2(make_ref(), 2) == 0, do: nil, else: %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}
_ ->
raise "GameServer.Accounts.get_user_by_apple_id/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Get a user by their Discord ID.
Returns `%User{}` or `nil`.
"""
@spec get_user_by_discord_id(String.t()) :: GameServer.Accounts.User.t() | nil
def get_user_by_discord_id(_discord_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
if :erlang.phash2(make_ref(), 2) == 0, do: nil, else: %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}
_ ->
raise "GameServer.Accounts.get_user_by_discord_id/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Gets a user by email.
## Examples
iex> get_user_by_email("foo@example.com")
%User{}
iex> get_user_by_email("unknown@example.com")
nil
"""
@spec get_user_by_email(String.t()) :: GameServer.Accounts.User.t() | nil
def get_user_by_email(_email) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
if :erlang.phash2(make_ref(), 2) == 0, do: nil, else: %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}
_ ->
raise "GameServer.Accounts.get_user_by_email/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Gets a user by email and password.
## Examples
iex> get_user_by_email_and_password("foo@example.com", "correct_password")
%User{}
iex> get_user_by_email_and_password("foo@example.com", "invalid_password")
nil
"""
@spec get_user_by_email_and_password(String.t(), String.t()) :: GameServer.Accounts.User.t() | nil
def get_user_by_email_and_password(_email, _password) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
if :erlang.phash2(make_ref(), 2) == 0, do: nil, else: %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}
_ ->
raise "GameServer.Accounts.get_user_by_email_and_password/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Get a user by their Facebook ID.
Returns `%User{}` or `nil`.
"""
@spec get_user_by_facebook_id(String.t()) :: GameServer.Accounts.User.t() | nil
def get_user_by_facebook_id(_facebook_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
if :erlang.phash2(make_ref(), 2) == 0, do: nil, else: %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}
_ ->
raise "GameServer.Accounts.get_user_by_facebook_id/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Get a user by their Google ID.
Returns `%User{}` or `nil`.
"""
@spec get_user_by_google_id(String.t()) :: GameServer.Accounts.User.t() | nil
def get_user_by_google_id(_google_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
if :erlang.phash2(make_ref(), 2) == 0, do: nil, else: %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}
_ ->
raise "GameServer.Accounts.get_user_by_google_id/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Gets the user with the given magic link token.
"""
@spec get_user_by_magic_link_token(String.t()) :: GameServer.Accounts.User.t() | nil
def get_user_by_magic_link_token(_token) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
if :erlang.phash2(make_ref(), 2) == 0, do: nil, else: %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}
_ ->
raise "GameServer.Accounts.get_user_by_magic_link_token/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Gets the user with the given signed token.
If the token is valid `{user, token_inserted_at}` is returned, otherwise `nil` is returned.
"""
@spec get_user_by_session_token(binary()) :: {GameServer.Accounts.User.t(), DateTime.t()} | nil
def get_user_by_session_token(_token) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
if :erlang.phash2(make_ref(), 2) == 0, do: nil, else: %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}
_ ->
raise "GameServer.Accounts.get_user_by_session_token/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Get a user by their Steam ID (steam_id).
Returns `%User{}` or `nil`.
"""
@spec get_user_by_steam_id(String.t()) :: GameServer.Accounts.User.t() | nil
def get_user_by_steam_id(_steam_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
if :erlang.phash2(make_ref(), 2) == 0, do: nil, else: %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}
_ ->
raise "GameServer.Accounts.get_user_by_steam_id/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Gets a user by their unique username handle (case-insensitive; usernames
are stored lowercase).
"""
@spec get_user_by_username(String.t()) :: GameServer.Accounts.User.t() | nil
def get_user_by_username(_username) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
if :erlang.phash2(make_ref(), 2) == 0, do: nil, else: %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}
_ ->
raise "GameServer.Accounts.get_user_by_username/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Returns whether the user has a password set.
"""
@spec has_password?(GameServer.Accounts.User.t()) :: boolean()
def has_password?(_user) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
false
_ ->
raise "GameServer.Accounts.has_password?/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Public cache invalidation for cross-module use (lobbies, parties, groups).
Accepts a user ID and clears both the primary and all index caches.
"""
@spec invalidate_user_cache_by_id(Ecto.UUID.t()) :: :ok
def invalidate_user_cache_by_id(_user_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
:ok
_ ->
raise "GameServer.Accounts.invalidate_user_cache_by_id/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Link an OAuth provider to an existing user account. Updates the user
via the provider's oauth changeset while being careful not to overwrite
existing email or avatars.
Example: link_account(user, %{discord_id: "123", profile_url: "https://..."}, :discord_id, &User.discord_oauth_changeset/2)
"""
@spec link_account(GameServer.Accounts.User.t(), map(), atom(), (GameServer.Accounts.User.t(), map() ->
Ecto.Changeset.t())) ::
{:ok, GameServer.Accounts.User.t()}
| {:error, Ecto.Changeset.t() | {:conflict, GameServer.Accounts.User.t()}}
def link_account(_user, _attrs, _provider_id_field, _changeset_fn) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Accounts.link_account/4 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Link a device_id to an existing user account. This allows the user to
authenticate using the device_id in addition to their OAuth providers.
Returns {:ok, user} on success or {:error, changeset} if the device_id
is already used by another account.
"""
@spec link_device_id(GameServer.Accounts.User.t(), String.t()) ::
{:ok, GameServer.Accounts.User.t()} | {:error, Ecto.Changeset.t()}
def link_device_id(_user, _device_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.link_device_id/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Lists tokens for a given user, optionally filtered by context.
"""
@spec list_user_tokens(
Ecto.UUID.t(),
keyword()
) :: [GameServer.Accounts.UserToken.t()]
def list_user_tokens(_user_id, _opts) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
[]
_ ->
raise "GameServer.Accounts.list_user_tokens/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
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 and no password is set.
In this case, the user gets confirmed, logged in, and all tokens -
including session ones - are expired. In theory, no other tokens
exist but we delete all of them for best security practices.
3. The user has not confirmed their email but a password is set.
This cannot happen in the default implementation but may be the
source of security pitfalls. See the "Mixing magic link and password registration" section of
`mix help phx.gen.auth`.
"""
@spec login_user_by_magic_link(String.t()) ::
{:ok, {GameServer.Accounts.User.t(), [GameServer.Accounts.UserToken.t()]}}
| {:error, :not_found | Ecto.Changeset.t() | term()}
def login_user_by_magic_link(_token) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Accounts.login_user_by_magic_link/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Registers a user.
## Attributes
See `t:GameServer.Types.user_registration_attrs/0` for available fields.
## Examples
iex> register_user(%{email: "user@example.com", password: "secret123"})
{:ok, %User{}}
iex> register_user(%{email: "invalid"})
{:error, %Ecto.Changeset{}}
"""
@spec register_user(GameServer.Types.user_registration_attrs()) ::
{:ok, GameServer.Accounts.User.t()} | {:error, Ecto.Changeset.t()}
def register_user(_attrs) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.register_user/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Register a user and send the confirmation email inside a DB transaction.
The function accepts a `confirmation_url_fun` which must be a function of arity 1
that receives the encoded token and returns the confirmation URL string.
If sending the confirmation email fails the transaction is rolled back and
`{:error, reason}` is returned. On success it returns `{:ok, user}`.
"""
@spec register_user_and_deliver(GameServer.Types.user_registration_attrs(), (String.t() -> String.t())) ::
{:ok, GameServer.Accounts.User.t()} | {:error, Ecto.Changeset.t() | term()}
def register_user_and_deliver(_attrs, _confirmation_url_fun) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.register_user_and_deliver/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Register a user and send the confirmation email inside a DB transaction.
The function accepts a `confirmation_url_fun` which must be a function of arity 1
that receives the encoded token and returns the confirmation URL string.
If sending the confirmation email fails the transaction is rolled back and
`{:error, reason}` is returned. On success it returns `{:ok, user}`.
"""
@spec register_user_and_deliver(
GameServer.Types.user_registration_attrs(),
(String.t() -> String.t()),
module()
) :: {:ok, GameServer.Accounts.User.t()} | {:error, Ecto.Changeset.t() | term()}
def register_user_and_deliver(_attrs, _confirmation_url_fun, _notifier) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.register_user_and_deliver/3 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Returns true when new accounts require manual admin activation before
they can log in. Reads from application config
`:game_server_core, :require_account_activation` which is set at boot
from the `REQUIRE_ACCOUNT_ACTIVATION` environment variable in `runtime.exs`.
Defaults to `false` when not configured.
"""
@spec require_account_activation?() :: boolean()
def require_account_activation?() do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
false
_ ->
raise "GameServer.Accounts.require_account_activation?/0 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Revokes every credential the user holds: all session tokens are deleted and
`token_version` is bumped, which invalidates all previously issued JWT
access and refresh tokens ("log out everywhere").
Returns `{:ok, {user, expired_tokens}}`.
"""
@spec revoke_all_tokens(GameServer.Accounts.User.t()) ::
{:ok, {GameServer.Accounts.User.t(), [GameServer.Accounts.UserToken.t()]}}
| {:error, Ecto.Changeset.t()}
def revoke_all_tokens(_user) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Accounts.revoke_all_tokens/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Revokes all session tokens for a user (mass logout).
"""
@spec revoke_all_user_sessions(Ecto.UUID.t()) :: {non_neg_integer(), nil}
def revoke_all_user_sessions(_user_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
0
_ ->
raise "GameServer.Accounts.revoke_all_user_sessions/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Search users by display name (case-insensitive prefix match) or exact numeric id.
Returns a list of User structs.
## Options
See `t:GameServer.Types.pagination_opts/0` for available options.
"""
@spec search_users(String.t()) :: [GameServer.Accounts.User.t()]
def search_users(_query) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
[]
_ ->
raise "GameServer.Accounts.search_users/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Search users by display name (case-insensitive prefix match) or exact numeric id.
Returns a list of User structs.
## Options
See `t:GameServer.Types.pagination_opts/0` for available options.
"""
@spec search_users(String.t(), GameServer.Types.pagination_opts()) :: [GameServer.Accounts.User.t()]
def search_users(_query, _opts) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
[]
_ ->
raise "GameServer.Accounts.search_users/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Serialize a user into the compact payload used by realtime updates.
"""
@spec serialize_user_payload(GameServer.Accounts.User.t()) :: map()
def serialize_user_payload(_user) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
%{}
_ ->
raise "GameServer.Accounts.serialize_user_payload/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Mark a user as offline and update last_seen_at.
Writes only on a real online→offline transition (see `set_user_online/1`).
Returns {:ok, user} on success.
"""
@spec set_user_offline(Ecto.UUID.t()) :: {:ok, GameServer.Accounts.User.t()} | {:error, term()}
def set_user_offline(_user_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.set_user_offline/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Mark a user as online and update last_seen_at.
Writes only on a real offline→online transition: reconnects and extra
tabs/sockets while already online are no-ops, so reconnect storms don't
hammer the `users` table (and the `after_user_online` hook fires once per
session, not once per socket).
Returns {:ok, user} on success.
"""
@spec set_user_online(Ecto.UUID.t()) :: {:ok, GameServer.Accounts.User.t()} | {:error, term()}
def set_user_online(_user_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.set_user_online/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Checks whether the user is in sudo mode.
The user is in sudo mode when the last authentication was done no further
than 20 minutes ago. The limit can be given as second argument in minutes.
"""
@spec sudo_mode?(GameServer.Accounts.User.t()) :: boolean()
def sudo_mode?(_user) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
false
_ ->
raise "GameServer.Accounts.sudo_mode?/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Checks whether the user is in sudo mode.
The user is in sudo mode when the last authentication was done no further
than 20 minutes ago. The limit can be given as second argument in minutes.
"""
@spec sudo_mode?(GameServer.Accounts.User.t(), integer()) :: boolean()
def sudo_mode?(_user, _minutes) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
false
_ ->
raise "GameServer.Accounts.sudo_mode?/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Updates `last_seen_at` to now for the given user. Fire-and-forget — errors are ignored.
Call on login (session or JWT) to track activity.
"""
@spec touch_last_seen(GameServer.Accounts.User.t()) :: :ok
def touch_last_seen(_user) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
:ok
_ ->
raise "GameServer.Accounts.touch_last_seen/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Lightweight version of `touch_last_seen/1` that accepts a user ID directly.
Performs a single UPDATE without loading the full struct first, setting
`last_seen_at` to now and `is_online` to true, then invalidates the cache.
Fire-and-forget — errors are ignored.
"""
@spec touch_last_seen_by_id(Ecto.UUID.t()) :: :ok
def touch_last_seen_by_id(_user_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
:ok
_ ->
raise "GameServer.Accounts.touch_last_seen_by_id/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Unlink the device_id from a user's account.
Returns {:ok, user} when successful or {:error, reason}.
Guard: we only allow unlinking when the user will still have at least
one authentication method remaining (OAuth provider or password).
This prevents users losing all login methods unexpectedly.
"""
@spec unlink_device_id(GameServer.Accounts.User.t()) ::
{:ok, GameServer.Accounts.User.t()} | {:error, :last_auth_method | Ecto.Changeset.t()}
def unlink_device_id(_user) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.unlink_device_id/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Unlink an OAuth provider from a user's account.
provider should be one of :discord, :apple, :google, :facebook.
This will return {:ok, user} when successful or {:error, reason}.
Guard: we only allow unlinking when the user will still have at least
one other social provider remaining. This prevents users losing all
social logins unexpectedly.
"""
@spec unlink_provider(GameServer.Accounts.User.t(), :discord | :apple | :google | :facebook | :steam) ::
{:ok, GameServer.Accounts.User.t()} | {:error, :last_provider | Ecto.Changeset.t() | term()}
def unlink_provider(_user, _provider) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.unlink_provider/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Updates a user with the given attributes.
This function applies the `User.admin_changeset/2` then updates the user and
broadcasts the update on success. It returns the same tuple shape as
`Repo.update/1` so callers can pattern-match as before.
## Attributes
See `t:GameServer.Types.user_update_attrs/0` for available fields.
## Examples
iex> update_user(user, %{display_name: "NewName"})
{:ok, %User{}}
iex> update_user(user, %{metadata: %{level: 5}})
{:ok, %User{}}
"""
@spec update_user(GameServer.Accounts.User.t(), GameServer.Types.user_update_attrs()) ::
{:ok, GameServer.Accounts.User.t()} | {:error, Ecto.Changeset.t()}
def update_user(_user, _attrs) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.update_user/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Updates the user's display name and broadcasts the change.
"""
@spec update_user_display_name(GameServer.Accounts.User.t(), map()) ::
{:ok, GameServer.Accounts.User.t()} | {:error, Ecto.Changeset.t()}
def update_user_display_name(_user, _attrs) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.update_user_display_name/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Updates the user email using the given token.
If the token matches, the user email is updated and the token is deleted.
"""
@spec update_user_email(GameServer.Accounts.User.t(), String.t()) ::
{:ok, GameServer.Accounts.User.t()} | {:error, :transaction_aborted}
def update_user_email(_user, _token) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.update_user_email/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Updates the user password.
Returns a tuple with the updated user, as well as a list of expired tokens.
## Examples
iex> update_user_password(user, %{password: ...})
{:ok, {%User{}, [...]}}
iex> update_user_password(user, %{password: "too short"})
{:error, %Ecto.Changeset{}}
"""
@spec update_user_password(GameServer.Accounts.User.t(), map()) ::
{:ok, {GameServer.Accounts.User.t(), [GameServer.Accounts.UserToken.t()]}}
| {:error, Ecto.Changeset.t()}
def update_user_password(_user, _attrs) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, nil}
_ ->
raise "GameServer.Accounts.update_user_password/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Updates the user's unique username handle and broadcasts the change.
Strict, unlike registration: an invalid or taken username returns
`{:error, changeset}` with no generated fallback, so the player can pick
again. Routed through the `before_user_update` hook pipeline, where games
can forbid changes entirely or reject names (profanity, reserved words).
"""
@spec update_username(GameServer.Accounts.User.t(), map()) ::
{:ok, GameServer.Accounts.User.t()} | {:error, Ecto.Changeset.t() | term()}
def update_username(_user, _attrs) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Accounts.User{id: 0, email: "", display_name: nil, metadata: %{}, is_admin: false, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Accounts.update_username/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Returns true when the given user is activated or when account activation
is not required. Returns false only when activation is required **and**
the user's `is_activated` flag is `false`.
"""
@spec user_activated?(GameServer.Accounts.User.t()) :: boolean()
def user_activated?(_user) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
false
_ ->
raise "GameServer.Accounts.user_activated?/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Returns true when `password` matches the user's current password.
"""
@spec valid_password?(GameServer.Accounts.User.t(), term()) :: boolean()
def valid_password?(_user, _password) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
false
_ ->
raise "GameServer.Accounts.valid_password?/2 is a stub - only available at runtime on GameServer"
end
end
end