Сделано подтверждение регистрации пользователей #22

This commit is contained in:
2026-05-27 21:44:13 +03:00
parent b78df927dd
commit 4444461ee3
17 changed files with 358 additions and 48 deletions
+3 -3
View File
@@ -42,7 +42,7 @@ create(Email, Password) ->
email = Email,
password_hash = PasswordHash,
role = user,
status = active,
status = pending,
reason = ?DEFAULT_REASON,
nickname = extract_nickname(Email),
avatar_url = ?DEFAULT_AVATAR_URL,
@@ -302,9 +302,9 @@ apply_updates(User, Updates) ->
-spec set_field(atom(), term(), #user{}) -> #user{}.
set_field(email, Value, U) -> U#user{email = Value};
set_field(password_hash, Value, U) -> U#user{password_hash = Value};
set_field(role, Value, U) when Value =:= user; Value =:= admin; Value =:= bot ->
set_field(role, Value, U) when Value =:= user; Value =:= bot ->
U#user{role = Value};
set_field(status, Value, U) when Value =:= active; Value =:= frozen; Value =:= deleted ->
set_field(status, Value, U) when Value =:= active; Value =:= frozen; Value =:= deleted; Value =:= pending ->
U#user{status = Value};
set_field(reason, Value, U) -> U#user{reason = Value};
set_field(nickname, Value, U) -> U#user{nickname = Value};
+58
View File
@@ -0,0 +1,58 @@
-module(core_verification).
-include("records.hrl").
-export([create_token/1, verify_token/1, get_or_create_token/1, delete_token/1]).
-define(TOKEN_LIFETIME_HOURS, 1).
%%%-------------------------------------------------------------------
%%% @doc Создаёт верификационный токен для пользователя.
%%% @end
%%%-------------------------------------------------------------------
-spec create_token(UserId :: binary()) -> {ok, Token :: binary(), ExpiresAt :: calendar:datetime()}.
create_token(UserId) ->
Token = infra_utils:generate_id(32),
Expires = calendar:gregorian_seconds_to_datetime(
calendar:datetime_to_gregorian_seconds(calendar:universal_time()) + ?TOKEN_LIFETIME_HOURS * 3600),
mnesia:dirty_write(#verification{token = Token, user_id = UserId, expires_at = Expires}),
{ok, Token, Expires}.
%%%-------------------------------------------------------------------
%%% @doc Проверяет токен. Возвращает `{ok, UserId}` или ошибку.
%%% @end
%%%-------------------------------------------------------------------
-spec verify_token(Token :: binary()) ->
{ok, UserId :: binary()} | {error, expired | not_found}.
verify_token(Token) ->
case mnesia:dirty_read(verification, Token) of
[#verification{user_id = UserId, expires_at = Expires}] ->
case Expires > calendar:universal_time() of
true -> {ok, UserId};
false -> {error, expired}
end;
[] -> {error, not_found}
end.
%%%-------------------------------------------------------------------
%%% @doc Возвращает существующий токен пользователя или создаёт новый.
%%% @end
%%%-------------------------------------------------------------------
-spec get_or_create_token(UserId :: binary()) ->
{ok, Token :: binary(), ExpiresAt :: calendar:datetime()} | {error, not_found}.
get_or_create_token(UserId) ->
case mnesia:dirty_match_object(#verification{user_id = UserId, _ = '_'}) of
[V] -> {ok, V#verification.token, V#verification.expires_at};
[] ->
case core_user:get_by_id(UserId) of
{ok, _} -> create_token(UserId);
Error -> Error
end
end.
%%%-------------------------------------------------------------------
%%% @doc Удаляет токен.
%%% @end
%%%-------------------------------------------------------------------
-spec delete_token(Token :: binary()) -> ok.
delete_token(Token) ->
mnesia:dirty_delete(verification, Token),
ok.