# Identity Auth API ## Endpoints activos ```http GET /identity/account PATCH /identity/account POST /identity/account/change-password POST /identity/auth/login POST /identity/auth/refresh POST /identity/auth/logout GET /identity/auth/session GET /companies/available ``` ## Endpoints que no forman parte del diseño vigente No documentar ni crear como ruta válida: ```http GET /identity/companies GET /account/companies ``` Motivo: - `identity` no debe devolver fichas completas de empresa. - `companies` ya depende de `identity` para autenticación. - Un endpoint de ese tipo introduciría el ciclo `identity -> companies -> identity`. ## POST `/identity/auth/login` ### Request ```ts export type LoginWithPasswordRequestDTO = { email: string; password: string; }; ``` ### Response ```ts export type LoginWithPasswordResponseDTO = { access_token: string; refresh_token: string; account: AuthenticatedAccountDTO; }; ``` ```ts export type AuthenticatedAccountDTO = { id: string; email: string; name: string; avatar_url: string | null; language_code: string; }; ``` ### Notas - no requiere `Authorization` - no requiere `X-Company-Id` - no devuelve companies accesibles - no devuelve roles ni permisos - el access token no contiene `companyId` ## POST `/identity/auth/refresh` ### Request ```ts export type RefreshSessionRequestDTO = { refresh_token: string; }; ``` ### Response ```ts export type RefreshSessionResponseDTO = { access_token: string; refresh_token: string; }; ``` ### Notas - el refresh token se rota - el cliente debe reemplazar ambos tokens por los nuevos - no debe llevar `X-Company-Id` ## POST `/identity/auth/logout` ### Headers ```http Authorization: Bearer ``` ### Request ```ts export type LogoutRequestDTO = { refresh_token?: string; all_sessions?: boolean; }; ``` ### Response ```ts export type LogoutResponseDTO = { success: true; }; ``` ### Reglas - no debe llevar `X-Company-Id` - para logout normal, enviar el `refresh_token` actual - si logout falla por expiración de token, el frontend debe limpiar sesión igualmente ## GET `/identity/account` ### Headers ```http Authorization: Bearer ``` ### Response ```ts export type GetAccountProfileResponseDTO = { id: string; email: string; name: string; avatar_url: string | null; language_code: string; status: "active" | "disabled" | "pending_verification"; }; ``` ### Notas - no debe llevar `X-Company-Id` - representa la identidad global del usuario autenticado - no depende de company activa ## PATCH `/identity/account` ### Headers ```http Authorization: Bearer ``` ### Request ```ts export type UpdateAccountProfileRequestDTO = { email?: string; name?: string; avatar_url?: string | null; language_code?: string; }; ``` ### Response ```ts export type UpdateAccountProfileResponseDTO = { id: string; email: string; name: string; avatar_url: string | null; language_code: string; status: "active" | "disabled" | "pending_verification"; }; ``` ### Reglas - no debe llevar `X-Company-Id` - PATCH real: campo omitido no modifica - `avatar_url: null` limpia el avatar - el cambio de email en V1 es inmediato y no requiere verificación adicional - el backend valida unicidad de email - `avatar_url` sigue siendo solo una referencia externa; no existe upload en `identity` ## POST `/identity/account/change-password` ### Headers ```http Authorization: Bearer ``` ### Request ```ts export type ChangeAccountPasswordRequestDTO = { current_password: string; new_password: string; }; ``` ### Response ```ts export type ChangeAccountPasswordResponseDTO = { success: true; }; ``` ### Reglas - no debe llevar `X-Company-Id` - exige `current_password` - usa el hasher actual de `identity` - revoca todos los refresh tokens persistidos de la cuenta - no invalida de forma inmediata access tokens ya emitidos, porque hoy son stateless y no existe un subsistema de revocación inmediata de access tokens ## GET `/identity/auth/session` ### Headers ```http Authorization: Bearer ``` ### Response ```ts export type CurrentSessionResponseDTO = { account: AuthenticatedAccountDTO; }; ``` ### Notas - no debe llevar `X-Company-Id` ## GET `/companies/available` ### Headers ```http Authorization: Bearer ``` ### Response ```ts export type AvailableCompaniesResponseDTO = { companies: AvailableCompanyDTO[]; }; export type AvailableCompanyDTO = { id: string; legal_name: string; trade_name: string | null; tin: string | null; slug: string; email: string | null; phone: string | null; website: string | null; status: "active"; }; ``` ### Notas - usa autenticación, no tenant context - no requiere `X-Company-Id` - usa `requireIdentityAuthenticated(params)` - devuelve solo companies activas accesibles para la cuenta autenticada - no modifica sesión ni access token ## Errores esperados ```txt 400 -> request inválida o UUID de X-Company-Id mal formado 401 -> access token ausente/inválido/expirado o credenciales inválidas 401 -> cuenta no autenticable (`disabled` o `pending_verification`) 403 -> contexto tenant inválido, company no accesible o company no activa 409 -> conflicto de unicidad, por ejemplo email ya existente 500 -> error inesperado ``` ## Administración global de cuentas El dominio ya soporta enable/disable global de `Account`, pero no se documentan todavía endpoints HTTP administrativos operativos porque el runtime nuevo no dispone aún de un mecanismo inequívoco y cableado de autorización de administrador global. Pendiente explícito: - definir y cablear la autorización global real - entonces exponer enable/disable por HTTP