Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/TheSerchCp/SEAM/llms.txt

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

The Auth module is the entry point for every user interaction with SEAM. It handles credential validation on the client side, delegates the actual authentication to the backend over a REST call, and then wires the returned JWT into both the in-memory session state and the real-time EventBus WebSocket. All private routes are protected by a router-level guard that checks for a valid session before rendering any page.

Login flow

1

Validate the form

Before any network request is made, FormValidator runs client-side checks on the login form. The email field must be a valid e-mail address and the password field must satisfy the built-in password rule. The submit button stays disabled until both fields pass.
const loginValidator = new FormValidator('login-form', {
    email:    { required: true, email: true },
    password: { required: true, password: true }
}, { buttonId: 'btn-login' });
2

Call the login service

On a successful client validation, the page calls login(email, password) from auth.service.js. The service delegates to the repository which issues POST /auth/login.
// auth.service.js
export const login = async (email, password) => {
    const data = await AuthRepo.login(email, password);
    if (!data) return null;

    session.user         = data.user;
    session.token        = data.token;
    session.permissions  = new Set(data.permissions ?? []);
    session.sidebarItems = data.sidebarItems ?? [];

    localStorage.setItem('currentUser', JSON.stringify({
        user:         data.user,
        token:        data.token,
        permissions:  data.permissions  ?? [],
        sidebarItems: data.sidebarItems ?? [],
    }));

    // Connect the WebSocket with the JWT for real-time events
    EventBus.connect(data.token);

    return data;
};
3

Hydrate the in-memory session

The response object { user, token, permissions, sidebarItems } is destructured into the session singleton. permissions is stored as a Set<string> of nameUri strings for O(1) permission checks anywhere in the app.
4

Persist to localStorage

The same payload is serialised and written to localStorage under the key currentUser so the session survives a page reload.
{
  "user":         { "idUser": 1, "full_name": "Admin User", "email": "admin@example.com" },
  "token":        "<jwt>",
  "permissions":  ["ver_usuarios", "editar_usuarios", "ver_reportes"],
  "sidebarItems": [{ "label": "Usuarios", "hash": "#/users" }]
}
5

Open the WebSocket

EventBus.connect(data.token) authenticates the Socket.IO connection with the JWT so the server can route data:changed events back to this client. After login succeeds, the router redirects to #/home.
EventBus.connect(data.token);
// ...
location.hash = '/home';

API endpoints

MethodPathPurpose
POST/auth/loginExchange credentials for { user, token, permissions, sidebarItems }
POST/auth/registerRegister a new user account
// auth.repository.js
import { ApiClient } from '../core/ApiClient.js';

export const login    = (email, password) => {
    try { return ApiClient.post('/auth/login', { email, password }); }
    catch { return null; }
};
export const register = (data) => ApiClient.post('/auth/register', data);

Logout

Calling logout() is the inverse of login(): it disconnects the WebSocket, wipes localStorage, and nulls every field on the session singleton.
// auth.service.js
export const logout = () => {
    EventBus.disconnect();
    localStorage.removeItem('currentUser');
    session.user = session.token = session.permissions = session.sidebarItems = null;
};

Route guard

The router checks for an authenticated session before mounting any private page. If localStorage has no currentUser entry (or the entry is invalid), the user is immediately redirected to #/login. This guard runs on every hash-change event, so direct URL navigation cannot bypass it.
The session is rehydrated from localStorage on every page load so users do not have to log in again after a browser refresh. The JWT is re-attached to EventBus at hydration time.

Register form validation

The registration form uses its own FormValidator schema that adds a confirmPassword match rule on top of the login schema:
const registerValidator = new FormValidator('register-form', {
    email:           { required: true, email: true },
    password:        { required: true, password: true },
    confirmPassword: { required: true, password: true, match: 'password' }
});
The register card is removed from the DOM on page mount and only injected back when the user clicks the register navigation button (btn-to-register). Do not rely on its DOM nodes being present at initialisation time.

Build docs developers (and LLMs) love