Files
mini-erp/mini-backend/docs/auth-flow.md
T
2026-08-17 11:58:38 -05:00

3.3 KiB

Flujo de Autenticación

Login

sequenceDiagram
    participant F as Frontend
    participant API as FastAPI
    participant S as core/session.py
    participant SAP_C as core/sap.py
    participant SAP as SAP Service Layer

    F->>API: POST /api/Login\n{Username, Password}
    Note over F,API: Username = webUser (U_WEB_USER)\nPassword = U_WEB_PASS

    API->>SAP_C: forward_to_sapb1(GET, "EmployeesInfo")\n$filter=U_WEB_USER eq '{webUser}'
    SAP_C->>SAP: GET /b1s/v1/EmployeesInfo?$filter=...
    SAP-->>SAP_C: {EmployeeID, FirstName, LastName, Active, U_WEB_PASS, ...}
    SAP_C-->>API: Employee data (o lista vacía)

    API->>API: ¿Existe empleado?\n¿Active == "tYES"?\n¿U_WEB_PASS == Password?
    alt Todo válido
        API->>S: create_employee_session(webUser, empId, first_name, last_name)
        S->>S: Genera token_urlsafe(32)\n(invalida token anterior del mismo webUser)
        S-->>API: token

        API->>SAP_C: ensure_sap_session()
        SAP_C->>SAP: POST /Login (manager creds)
        SAP-->>SAP_C: B1SESSION cookie
        SAP_C-->>API: OK

        API-->>F: 200 {message, token, username: FirstName, company: CompanyDB}
    else No existe / inactivo / password no coincide
        API-->>F: 401 (mensaje según el caso: "Usuario no registrado",\n"Usuario inactivo" o "Usuario o contraseña incorrectos")
    end

Logout

sequenceDiagram
    participant F as Frontend
    participant API as FastAPI
    participant S as core/session.py

    F->>API: POST /api/Logout\nX-Session-Token: <token>
    API->>S: remove_employee_session_by_token(token)
    S->>S: Elimina active_tokens[token]\ny employee_sessions[emp_id]
    S-->>API: OK
    API-->>F: 200 {message: "Sesión cerrada"}

Validación de Sesión (Middleware)

Cada petición a /api/* (excepto /api/Login) pasa por el session_middleware:

sequenceDiagram
    participant F as Frontend
    participant MW as session_middleware
    participant S as core/session.py
    participant R as Router

    F->>MW: Request /api/Items\nX-Session-Token: <token>

    MW->>S: validate_and_refresh_session(token)
    S->>S: Busca token en active_tokens

    alt Token válido
        S->>S: Actualiza last_activity
        S-->>MW: webUser
        MW->>MW: set_current_user(webUser, full_name, emp_id)\nrequest.state.webUser = webUser
        MW->>R: Continúa al router
        R-->>F: 200 Response
    else Token expirado (>30 min)
        S->>S: Elimina token y sesión
        S-->>MW: None
        MW-->>F: 401 Token expirado
    else Token no existe
        S-->>MW: None
        MW-->>F: 401 No autorizado
    end

Ciclo de Vida de la Sesión de Empleado

stateDiagram-v2
    [*] --> Activa: Login exitoso\ngenera token
    Activa --> Expirada: 30 min sin actividad
    Activa --> Cerrada: Logout explícito
    Expirada --> [*]
    Cerrada --> [*]

    note right of Activa
        Se refresca last_activity
        en cada petición válida
    end note

Mecanismo de Renovación

La sesión del empleado se renueva automáticamente en cada petición válida:

  1. El frontend envía X-Session-Token en el header
  2. validate_and_refresh_session() actualiza last_activity al timestamp actual
  3. El timeout de 30 minutos se mide desde la última actividad
  4. Si pasan 30 min sin peticiones, el token se invalida automáticamente