Files
vidconf/frontend/src/api/auth.ts
Max Ronzhin 25ffd9e678
Some checks failed
CI / backend (push) Has been cancelled
CI / frontend (push) Has been cancelled
feat(auth): несколько эталонных mail-доменов для верификации регистрации
Настройка «Эталон mail-домена» теперь хранит список доменов вместо
одного — email при регистрации принимается, если совпадает с любым из
них. Старое значение в БД ({"domain": str|None}) читается прозрачно
(обратная совместимость без Alembic-миграции) и переписывается в новую
форму ({"domains": [...]}) при первом же сохранении настроек. В админке
добавление/удаление доменов — списком чипов; на экране регистрации
подсказка о несовпадении домена перечисляет все эталонные варианты.
2026-07-27 20:40:23 +03:00

82 lines
3.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* API-функции аутентификации.
*/
import { apiRequest } from '@/api/client'
export interface RegisterPayload {
email: string
name_user: string
password: string
/** Выбранная команда — только если выбор команды включён в настройках инстанса. */
team_id?: string | null
}
/** Команда, доступная для выбора на экране регистрации. */
export interface RegistrationTeamOption {
id: string
name: string
}
/** Параметры экрана регистрации — зависят от настройки инстанса `registration_team_choice`. */
export interface RegistrationOptions {
team_choice_enabled: boolean
teams: RegistrationTeamOption[]
/** Эталонные домены почты при включённой верификации (email подходит под любой), иначе пуст. */
email_domains: string[]
}
export interface CurrentUser {
id: string
email: string
name_user: string
role: string
/** URL загруженного аватара, `null` — показывается заглушка с инициалами (см. `Avatar`). */
avatar_url: string | null
team_id: string | null
team_name: string | null
}
export interface TokenResponse {
access_token: string
token_type: string
}
/** Регистрация нового пользователя. 409 — если email уже занят. */
export async function register(payload: RegisterPayload): Promise<void> {
await apiRequest('/auth/register', { method: 'POST', body: payload, skipAuthRefresh: true })
}
/**
* Параметры экрана регистрации — публичный эндпоинт, доступен без авторизации.
* Если выбор команды отключён в настройках инстанса, `teams` пуст.
*/
export async function getRegistrationOptions(): Promise<RegistrationOptions> {
return apiRequest<RegistrationOptions>('/auth/registration-options', { skipAuthRefresh: true })
}
/** Подтверждение почты по токену из письма. 400 — если ссылка просрочена/недействительна. */
export async function verifyEmail(token: string): Promise<void> {
await apiRequest('/auth/verify-email', { method: 'POST', body: { token }, skipAuthRefresh: true })
}
/**
* Вход по логину/паролю. Backend ждёт OAuth2-form-data (username=email).
* Refresh-токен приходит httpOnly cookie — тело ответа содержит только access.
*/
export async function login(email: string, password: string): Promise<TokenResponse> {
const form = new URLSearchParams()
form.set('username', email)
form.set('password', password)
return apiRequest<TokenResponse>('/auth/token', { method: 'POST', body: form, skipAuthRefresh: true })
}
/** Явный выход — инвалидирует refresh-сессию на backend. */
export async function logout(): Promise<void> {
await apiRequest('/auth/logout', { method: 'POST' })
}
/** Текущий пользователь по access-токену. */
export async function getMe(): Promise<CurrentUser> {
return apiRequest<CurrentUser>('/users/me')
}