Skip to content

Authentication and accounts

The web UI authenticates through a single session cookie and four routes: /login, /register, /password, and POST /logout. Authorization inside pages is derived from the signed-in account through the backend’s GetAuthorization call, not from the cookie alone.

A successful login sets an HTTP-only cookie named analytics_token:

  • Path=/ — sent with every request on the site;
  • HttpOnly — not readable by JavaScript;
  • SameSite=Strict — not sent on cross-site requests;
  • lifetime Max-Age equal to the access-token lifetime the server returns (24 hours).

The value is a JWT access token. Every subsequent backend call signs its request with Authorization: Bearer <token>. If the cookie is missing or invalid, protected pages redirect to /login.

GET /login renders the form; POST /login submits it. The form has two fields:

  • identifier — the username or email address;
  • password.

On success the cookie is set and the browser is redirected by authorization plane:

  • accounts that may open the admin panel land on /admin;
  • everyone else lands on / (Analytics).

A rejected login renders the error inline with 401 Unauthorized.

GET /register renders the form; POST /register submits it. The form mirrors the TUI client’s registration page exactly:

  • username;
  • email;
  • password;
  • password_confirmation;
  • timezone — defaults to Europe/Bratislava;
  • phone_country — defaults to SK.

Every field is trimmed and the country code is upper-cased before posting; the backend does the validation. There is no role field: every registration lands as the guest role, and roles are assigned later by an administrator.

GET /password renders the change form and requires a session (anonymous visitors are redirected to /login). POST /password submits:

  • current_password;
  • new_password;
  • new_password_confirmation.

Administrator-initiated password resets for other users are a separate feature, covered in Users.

POST /logout clears the cookie and redirects to /login. It only removes the client-side credential; see the caution above about the token itself.

Two layers protect the state-changing endpoints:

  1. the cookie is SameSite=Strict, so a cross-site browser request arrives without it and fails authentication;
  2. every POST handler rejects requests whose Sec-Fetch-Site header is cross-site with a plain 403 rather than a redirect to the login page.

The second check also covers forms that do not strictly require a session, so the refusal is uniform across the site.