Config Check Security Notes 1814 - sebiboga/testlink-upgraded GitHub Wiki
Issue 1814 — Configuration Check / Security Notes screen + dashboard banner
The legacy app computed a batch of configuration security notes (install
directory still present, default admin password, LDAP/BTS/email/extension
checks) on startup and required an admin to act on them. TestLink 2.0.1 had
modernized every screen but the one that rendered those notes — so the notes
were computed on every legacy page and never displayed. Modernized now.
Legacy behaviour (1.9.20)
lib/functions/configCheck.php::getSecurityNotes() (:251) collects the notes
in a fixed check order:
checkForInstallDir—install_dirstill present ⇒ "Install directory should be removed!"checkForAdminDefaultPwd— admin's password unchanged ⇒ "You should change the default password for the 'admin' account!"checkForLDAPExtension— LDAP used butldapPHP extension missingcheckForBTSConnection— an issue tracker is configured but unreachablecheckForRepositoryDir— the repositorydir_pathis not writablecheckSchemaVersion— database schema differs from the expected versioncheckEmailConfig— email feature breaks down to the missing SMTP settings (tl_admin_email,from_email,return_path_email,smtp_host, …)checkForExtensions— PHP extensions required by the configuration
The note texts come from the server-side strings.txt of the session locale;
each note carries a stable code (install_dir, admin_pwd, bts_connection,
repository_dir, schema, email_config, extensions, …) that the UI uses as
a chip. Both the codes and the fixed check order are preserved 1:1 in the BFF.
The bug: when TL_WARNING_MODE is FILE or SILENT,
getSecurityNotes() nulls the notes after logging them, so the (hypothetical)
legacy UI showed nothing while the admin was told in tiny startup output that
warnings were written to a file. The BFF deliberately does not repeat that:
the modern screen always lists every note, whatever the mode.
Modern re-implementation
-
BFF
api/configcheck/index.php,GET|HEAD ?action=init(route verb guard →405+Allow: GET, HEAD;is_scalaraction guard →400 unknown_action; session gate before the DB connect →401 not_authenticatedfor anonymous). Response:{status:"ok", notes:[{code,text}], count, mode, file, appVersion, user_id, legacy_function}.legacy_functiondocuments thegetSecurityNotes()lineage; the optionallocaleshort code (houseassignLocale()pattern fromapi/cfields) localizes the note texts vialang_get(key, lang)with the usualstrings.txtcoverage fallback;fileonly when the mode writes one (FILE and the SILENT-only artifact).JSON_INVALID_UTF8_SUBSTITUTEkeeps the payload serializable for any note text. -
Screen
gui/templates/conf/configCheck.html(Dashio shell, standalone, no Smarty) — the same state layout used byexecNotesReadonly.html:- header + toolbar: warning-mode context, locale switcher, Refresh / Back / Close;
- meta strip: mode, destination file (
ccn.fileNonewhen the mode writes none),countwarnings, app version; modeInfoline +fileNoteline state both facts with{mode}/{file}interpolation (TLi18n.t(key, params),i18n.js:174);- notes card: one row per note, red-framed icon + code chip (
.text()+esc()escapes, neverinnerHTML); an empty list renders the "every check passed" success state; - states for
401(bounce tologin.phpwithdestination),403,404,400/405,500, plus a loading box. - session check first → the screen never flashes an error list at anonymous users.
-
Dashboard banner
gui/templates/mainpage/mainPage.html—#cfgCheckBannerfetches the same BFF and shows only whencount > 0: amber card,ccn.bannerTitle,ccn.bannerTextwith{count}interpolated, and a "View details" link opening the screen in a new tab (target="_blank",$actions->configCheckdeep link fromlib/functions/common.php). The fetch failure is silent by design — the dashboard must load regardless.
i18n
New keys ccn.title, ccn.headerSub, ccn.mode, ccn.file, ccn.fileNone,
ccn.count, ccn.appVersion, ccn.modeInfo, ccn.fileNote,
ccn.notesHeading, ccn.emptyMsg, ccn.bannerTitle, ccn.bannerText,
ccn.bannerLink, ccn.errorTitle, ccn.errorMsg, ccn.accessDenied*,
ccn.notFound*, ccn.badRequest* and footers.configCheck — added to all
10 bundles (de,en,es,fr,it,ja,pt,ro,ru,zh). Toolbar verbs reuse
common.refresh/common.back/common.close. The note rows themselves keep the
server-side strings.txt texts (legacy L10n), so nothing new is rendered as a
raw key; bash ai/verify_i18n_coverage.sh passes before commit.
Behaviour notes
- Notes are never dropped. The legacy FILE/SILENT nulling
(
configCheck.php:220-224semantics) is intentionally not reproduced, and themodeInfoline documents that choice on the screen. - Codes + check order are stable (BFF contract), chip text is the code itself — usable as a filter key.
- The banner is advisorial only: it appears on the dashboard and never blocks
navigation; anonymous/
403users simply don't get the banner.



Test suite
Suite — Issue #1814 in tmp/TLU_Test_Cases.md (11 cases, all PASS): BFF
payload/405/400/401, screen render, locale switch, Refresh/Back, dashboard
banner, console + Event Viewer clean, i18n gate.