Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/fredy-rizo/despacho-frontend/llms.txt

Use this file to discover all available pages before exploring further.

Lex Consultoría’s frontend implements a JWT-based authentication flow: the user submits credentials to a REST endpoint, the server returns a signed token, and the client stores that token in localStorage for inclusion in all subsequent protected API calls. Three utility functions in src/tools/User.jsvalidateUser, ValidateSession, and getDataUser — centralize all session logic so no page needs to re-implement token parsing or role checking from scratch.

Login Flow

1

User submits credentials

The signInComponent.vue collects an email address and password through a Quasar form. On submission the authsignUp handler fires and sends the credentials as JSON to the login endpoint:
// src/components/users/auth/signInComponent.vue — authsignUp()
const res = await fetch("http://localhost:2101/api/lawyer/user/login", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    email: email.value,
    password: password1.value,
  }),
})

const data = await res.json()
2

Token is stored in localStorage

When the response includes a token field the value is persisted under the key "token". No additional parsing or verification happens on the client side — the raw JWT string is stored as-is.
if (data?.token) {
  localStorage.setItem("token", data.token)
}
3

Success notification and redirect

A Quasar Notify toast confirms the login, and Vue Router pushes the user to /dashboard:
$q.notify({
  type: "positive",
  message: "Ingreso exitoso",
  position: "bottom-right",
})

router.push("/dashboard")
4

Failure handling

If the server response does not contain a token (wrong password, unknown email, etc.) a negative notification is shown and the user stays on the login page:
$q.notify({
  type: "negative",
  message: "Credenciales incorrectas",
  position: "bottom-right",
})
Network-level failures (server unreachable, CORS error) are caught separately and display "Error en el servidor".
The JWT token is stored in localStorage, which is accessible to any JavaScript running on the page. If the application ever renders third-party scripts or is vulnerable to XSS, the token can be exfiltrated. For higher-security requirements consider storing short-lived tokens in memory and using httpOnly cookies for refresh tokens.

Role System

Every user object stored under localStorage.getItem("user") includes a roles array. Each role entry has a name string and a numeric value:
ValueNameDescription
1usuarioStandard authenticated user. Passes role checks when rol 1 is required.
2adminAdministrator. Bypasses all role checksvalidateUser returns the user+token object immediately without inspecting allowed roles.
4InvitadoGuest. Default role applied by getDataUser when localStorage contains no user entry.

validateUser(data) — Pre-Request Role Check

Call validateUser before any protected fetch to confirm the current session is authorized for the required role. It reads both "user" and "token" from localStorage, short-circuits for admins, and performs an intersection check for everyone else. Signature
validateUser(data: { rol: number | number[] }): { ...userFields, token: string } | false
Parameters
data.rol
number | number[]
required
A single role value or an array of role values that are permitted to make this request. Example: { rol: 1 } allows standard users; { rol: [1, 4] } allows both users and guests.
Returns the user object merged with the current token string if the session passes, or false if the user lacks the required role. Source
// src/tools/User.js
export const validateUser = (data) => {
  const dataUser = JSON.parse(
    localStorage.getItem("user")
      ? localStorage.getItem("user")
      : '{"id":"1","name":"Invitado","roles":[{"name":"usuario","value":"1"}]}',
  )
  const token = localStorage.getItem("token")

  if (dataUser.roles && dataUser.roles[0].value == 2) {
    return { ...dataUser, token }
  }

  // Permitir rol simple o múltiples
  const userRoles = dataUser.roles.map((r) => Number(r.value))
  const allowedRoles = Array.isArray(data.rol) ? data.rol.map(Number) : [Number(data.rol)]

  const hasRole = allowedRoles.some((r) => userRoles.includes(r))

  return hasRole ? { ...dataUser, token } : false
}

ValidateSession(res, router) — Post-Response Session Check

Call ValidateSession immediately after parsing an API response to detect token expiry or permission errors. If the backend returns HTTP-style codes 401 or 403 inside the JSON body, the function clears the session and redirects to /login. Signature
ValidateSession(res: { code: number | string }, router: Router): boolean
Parameters
res
object
required
The parsed JSON response object from the API. Must contain a code field that the server sets to 401 (unauthenticated) or 403 (forbidden) when the token is invalid or expired.
router
Router
required
The Vue Router instance obtained from useRouter(). Used to programmatically navigate to /login on session failure.
Returns true when the session is still valid; false after redirecting and clearing storage. Source
// src/tools/User.js
export const ValidateSession = (res, router) => {
  if (res.code == "403" || res.code == 403 || res.code == "401" || res.code == 401) {
    router.push({ path: "/login" })
    localStorage.clear()
    return false
  }
  return true
}
The loose equality checks (==) intentionally handle both string and numeric code values, since some API responses serialize the code as a string (e.g., "401") rather than a number.

getDataUser() — Hydrate Session State

Call getDataUser at component mount when you need the full user profile without gating on a specific role. It reads "user" and "token" from localStorage and, if no user entry exists, seeds localStorage with a default guest object before returning it. This ensures every part of the app always receives a coherent user object. Signature
getDataUser(): { id, name, address, phone_number, email, type, roles, token }
Returns the user profile object spread-merged with the current token. For unauthenticated visitors the returned object represents the guest default. Source
// src/tools/User.js
export const getDataUser = () => {
  const dataUser = JSON.parse(
    localStorage.getItem("user")
      ? localStorage.getItem("user")
      : '{"id":"1", "name": "Invitado", "address": "Indefinido", "phone_number": "1234567890", "email": "Invitado@email.com", "type":0, "roles":[{"name":"Invitado", "value":"4"}]}',
  )
  const token = localStorage.getItem("token")
  localStorage.setItem("user", JSON.stringify(dataUser))
  return { ...dataUser, token }
}

Guest Fallbacks

Each function has its own built-in fallback for when localStorage contains no "user" entry. validateUser uses a minimal fallback with role value "1" (usuario):
{
  "id": "1",
  "name": "Invitado",
  "roles": [{ "name": "usuario", "value": "1" }]
}
getDataUser uses a richer fallback with role value "4" (Invitado):
{
  "id": "1",
  "name": "Invitado",
  "address": "Indefinido",
  "phone_number": "1234567890",
  "email": "Invitado@email.com",
  "type": 0,
  "roles": [{ "name": "Invitado", "value": "4" }]
}
Because validateUser’s fallback carries role value "1", an unauthenticated visitor will pass a { rol: 1 } check when no "user" key is present in localStorage. Always ensure protected pages set the user entry during sign-in so that the actual authenticated role is used for all subsequent checks.

Usage Example — Dashboard Pre-Flight Check

dashboardPage.vue demonstrates the complete pattern: validate role before building headers, then call ValidateSession on every API response.
// src/pages/users/whoWeAre/dashboardPage.vue
import { validateUser, ValidateSession } from "../../../tools/User"

// Called before every fetch — returns headers or redirects
const getAuthHeaders = () => {
  const user = validateUser({ rol: 1 })
  if (!user) return router.push("/login")

  const headers = new Headers()
  headers.append("authorization", "Bearer " + user.token)
  headers.append("Content-Type", "application/json")
  return headers
}

// Called after every response — clears session on 401/403
const cargarReservas = async (modo = "all") => {
  loading.value = true
  const headers = getAuthHeaders()
  if (!headers) return

  let url = ""

  if (modo === "all")   url = "http://localhost:2101/api/form/reserve/list/reservation-all"
  if (modo === "true")  url = "http://localhost:2101/api/form/reserve/list/reservation-true"
  if (modo === "false") url = "http://localhost:2101/api/form/reserve/list/reservation-false"

  try {
    const res = await fetch(url, { method: "POST", headers })
    const data = await res.json()

    if (!ValidateSession(data, router)) return   // ← session check

    reservas.value = data?.data || []
  } catch (e) {
    console.error("Error cargando reservas:", e)
  }

  loading.value = false
}
Always check the return value of getAuthHeaders() before proceeding. Because router.push() is asynchronous, the function may return undefined after initiating the redirect — skipping the if (!headers) return guard would cause a runtime error when trying to pass undefined as fetch headers.

Build docs developers (and LLMs) love