175 lines
3.5 KiB
Markdown
175 lines
3.5 KiB
Markdown
# Frontend Auth And Company Selection
|
|
|
|
## Runtime actual
|
|
|
|
El frontend ERP usa el runtime nuevo:
|
|
|
|
```txt
|
|
@erp/identity/client
|
|
IdentityAuthSessionProvider
|
|
DataSourceProvider
|
|
Axios compartido
|
|
```
|
|
|
|
No debe usarse `@erp/auth/client` como runtime nuevo.
|
|
|
|
## Flujo actual
|
|
|
|
```txt
|
|
login
|
|
-> GET /identity/auth/session
|
|
-> GET /companies/available
|
|
-> resolver empresa activa
|
|
-> auto-selección si hay una sola empresa
|
|
-> selector si hay varias
|
|
-> /no-companies si no hay empresas
|
|
-> X-Company-Id en rutas tenant-scoped
|
|
```
|
|
|
|
## Login
|
|
|
|
El login usa:
|
|
|
|
```http
|
|
POST /identity/auth/login
|
|
```
|
|
|
|
Tras login correcto:
|
|
|
|
- se guardan `accessToken` y `refreshToken`
|
|
- se limpia cualquier `activeCompanyId` previo
|
|
- se carga `GET /companies/available`
|
|
- se resuelve el redirect autenticado según companies disponibles
|
|
|
|
## Session restore
|
|
|
|
Si existe `accessToken` persistido:
|
|
|
|
1. se llama `GET /identity/auth/session`
|
|
2. se hidrata la sesión autenticada
|
|
3. se llama `GET /companies/available`
|
|
4. se resuelve `activeCompanyId` persistido o auto-selección
|
|
|
|
Si la restauración falla:
|
|
|
|
- se limpia la sesión
|
|
- se limpia `activeCompanyId`
|
|
|
|
## Selección de empresa
|
|
|
|
### Cero empresas
|
|
|
|
Si `companies.length === 0`:
|
|
|
|
- se muestra `/no-companies`
|
|
- no existe `activeCompanyId`
|
|
- no se envía `X-Company-Id`
|
|
- sigue disponible el logout
|
|
|
|
### Una empresa
|
|
|
|
Si `companies.length === 1`:
|
|
|
|
- se selecciona automáticamente
|
|
- se guarda `activeCompanyId`
|
|
- no se muestra `/company-selection`
|
|
- se continúa al área privada
|
|
|
|
### Varias empresas
|
|
|
|
Si `companies.length > 1`:
|
|
|
|
- se muestra `/company-selection`
|
|
- no existe `activeCompanyId` hasta elegir
|
|
- el usuario selecciona company
|
|
- se guarda `activeCompanyId`
|
|
- se continúa al área privada
|
|
|
|
### `activeCompanyId` persistido ya no disponible
|
|
|
|
Si el `activeCompanyId` persistido ya no aparece en `GET /companies/available`:
|
|
|
|
- con `0` companies -> `/no-companies`
|
|
- con `1` company -> auto-selección de la disponible
|
|
- con varias companies -> `/company-selection`
|
|
|
|
## `GET /companies/available`
|
|
|
|
Endpoint actual:
|
|
|
|
```http
|
|
GET /companies/available
|
|
Authorization: Bearer <access_token>
|
|
```
|
|
|
|
No requiere:
|
|
|
|
- `X-Company-Id`
|
|
|
|
No usa:
|
|
|
|
- `requireIdentityTenant(params)`
|
|
|
|
Devuelve:
|
|
|
|
```ts
|
|
export type AvailableCompaniesResponseDTO = {
|
|
companies: AvailableCompanyDTO[];
|
|
};
|
|
```
|
|
|
|
## Headers
|
|
|
|
### No deben llevar `X-Company-Id`
|
|
|
|
```txt
|
|
POST /identity/auth/login
|
|
POST /identity/auth/refresh
|
|
POST /identity/auth/logout
|
|
GET /identity/auth/session
|
|
GET /companies/available
|
|
```
|
|
|
|
### Sí deben llevar `X-Company-Id`
|
|
|
|
Rutas tenant-scoped como:
|
|
|
|
- `/customers`
|
|
- `/catalogs/*`
|
|
- `/customer-invoices/*`
|
|
- `/factuges`
|
|
|
|
siempre que exista `activeCompanyId`.
|
|
|
|
## Refresh automático sobre `401`
|
|
|
|
El frontend implementa refresh automático global sobre Axios.
|
|
|
|
Comportamiento:
|
|
|
|
1. una request autenticada recibe `401`
|
|
2. si existe `refreshToken`, se llama `POST /identity/auth/refresh`
|
|
3. se guardan los nuevos tokens
|
|
4. se reintenta una única vez la request original
|
|
5. si refresh falla, se limpia la sesión y se redirige a `/login`
|
|
|
|
## Reglas implementadas
|
|
|
|
- retry único por request con `_retry`
|
|
- refresh concurrente único con `refreshPromise` compartida
|
|
- varias requests `401` esperan el mismo refresh
|
|
- login `401` no dispara refresh
|
|
- refresh `401` no intenta refrescarse a sí mismo
|
|
- `/identity/auth/refresh` no lleva `X-Company-Id`
|
|
- la request tenant-scoped reintentada conserva `X-Company-Id`
|
|
|
|
## Endpoints excluidos de tenant header y refresh
|
|
|
|
```txt
|
|
/identity/auth/login
|
|
/identity/auth/refresh
|
|
/identity/auth/logout
|
|
/identity/auth/session
|
|
/companies/available
|
|
```
|