Login Logout Screen - sebiboga/testlink-upgraded GitHub Wiki
The Login screen is a redeveloped, modern screen for authenticating users into TestLink. It replaces the legacy login page with a clean HTML+JavaScript interface backed by its own BFF (Backend-for-Frontend) API for authentication.
Path: entry point login.php (renders the modern page)
URL: gui/templates/auth/login.html
BFF: api/auth/index.php
Ref: Tracking issue #775

The modern login is a single-page Dashio-styled card:
| Section | Description |
|---|---|
| Heading | TestLink logo + "TestLink Sign In" |
| Fields | User ID + Password (localized placeholders) |
| Action | "SIGN IN" button |
| OAuth row | Optional provider buttons (shown only when configured) |
| Demo banner | Teal "this is a DEMO site" notice, only when demoMode is ON |
| Footer | "New user?" / "Lost password?" links + "Secure login" note |
Enter your User ID and Password and click SIGN IN. The page submits to the BFF
POST /api/auth/login over AJAX. On success the BFF creates the server-side session
(reusing the legacy doAuthorize() engine) and redirects the browser to the TestLink main
page (index.php?caller=login) or to a requested destination.
The page surfaces both pre-login notes and live authentication errors:
| State | Behavior |
|---|---|
note=logout |
Blue info banner "You have been logged out." |
note=expired |
Blue info banner "Session expired. Please log in again." |
| Wrong credentials | Red error "Invalid login or password."; password cleared |
| Empty fields | "Please enter both user ID and password." |

-
New user? Create account โ
/gui/templates/auth/firstLogin.html(modern sign-up form,POST /api/auth/signup). -
Lost password? โ
/gui/templates/auth/lostPassword.html(modern reset form,POST /api/auth/reset).

The links carry absolute hrefs because the login page is served via readfile() at
/login.php as well as directly at /gui/templates/auth/login.html โ a relative href would
resolve against / in the first context and 404. Fixed in
#1338; the sign-up flow was
verified end-to-end (new user created via POST /api/auth/signup, redirect back to login with
note=first banner).
Each link is gated by its own flag, as in the legacy template
login-model-marcobiedermann.tpl (the one config.inc.php selects):
-
New user? Create account renders only when
user_self_signupis enabled ($tlCfg->user_self_signup = TRUE;); the flag arrives asconfig.selfSignupfromGET /api/auth/config. With self-registration off the link is not advertised at all, instead of leading to the "self-registration is disabled on this site" refusal screen โ see Task #1050. -
Lost password? is independent of self-signup and is hidden only when the authentication
method manages passwords externally or demo mode is on (same gate as legacy
external_password_mgmt/demoMode). - The
|separator only appears when both links are visible, and the whole footer row stays hidden when neither is.

When the site runs in demo mode ($tlCfg->demoMode = ON; in custom_config.inc.php),
the login card shows a teal "This is a DEMO site" banner above the form, ported from
the legacy login-model-marcobiedermann.tpl block that rendered {$labels.demo_usage}:
{if $tlCfg->demoMode}
<div class="grid__container">{$labels.demo_usage}</div>
{/if}

| Item | Value |
|---|---|
| Trigger |
GET /api/auth/config โ "demoMode": true (api/auth/index.php, config_get('demoMode')) |
| Element |
#demoUsageBox in gui/templates/auth/login.html, class alert-box alert-demo
|
| Position | After the error/info notes, before the login fields (legacy order: note โ demo banner โ form) |
| Content | 4 lines - DEMO/RESPECT warning, re-install notice, data-deletion notice, "support our work" |
| Reveal |
#revealDemoNotice() waits for the locale bundle to settle (no English flash, no layout shift); if the bundle is unreachable or stalls past 1.5 s it strips data-i18n-html and shows the inline English fallback - the banner is never silently dropped and the bare key auth.demoUsage never reaches the screen |
| A11y |
role="status" aria-live="polite" so the post-load reveal is announced; decorative icon aria-hidden; #14524e on #e2f7f5 = 8.04:1 (WCAG AAA) |
| Styling | Teal #e2f7f5 with a 4 px #4ECDC4 left border; the 4th line is bold |
| i18n key |
auth.demoUsage, translated in all 10 bundles, injected with data-i18n-html so the legacy <br> / <b> markup survives |
The banner is independent from the error/info boxes: a redirect note and the demo banner are both visible at the same time, as in legacy.

Demo mode also hides the Lost password? link (same demoMode flag, legacy parity) โ
so a demo instance shows the warning banner and no password-recovery path at all.
Implemented in
#1047.
When OAuth servers are configured and enabled, the card shows provider buttons; the BFF
GET /api/auth/config returns the enabled provider list.
The navigation "Logout" link calls logout.php, which destroys the session and redirects to
login.php?note=logout (modern login with "You have been logged out." banner).
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/auth/config |
Public login-form config (self-signup, OAuth, pwd max len, sso flags) |
| GET | /api/auth/check |
Session validity + current login |
| POST | /api/auth/login |
Authenticate (form-encoded or JSON), creates session on success |
| POST | /api/auth/logout |
Destroy the session |
All POST routes are protected by the shared same-origin CSRF guard (_guard.php).
All labels, placeholders, links and messages use client-side TLi18n keys under the
auth.* namespace, present in all 10 locale bundles.
TestLink 2.0.1 ยท Login/Logout screen ยท Refs #775, #1047 (demo-mode notice)