Bugfix Issue 657 Self Signup Duplicate Email - sebiboga/testlink-upgraded GitHub Wiki
Issue 657 โ Self-signup accepts duplicate email address (no uniqueness validation)
Issue: #657
Branch: fix/issue-657-duplicate-email ยท Commit: 252bbabb2 (fix)
Status: FIXED & VERIFIED (2026-08-25)
Symptom
The self-signup page (firstLogin.php?viewer=new) accepted a second user registration with the same email address as an existing user. No error was shown; the duplicate user was silently created.
Root cause chain
lib/functions/tlUser.class.php:623-626 โ checkDetails() validates login uniqueness via doesUserExist() but has no email uniqueness check.
firstLogin.php:48โ$user->writeToDB($db)โcheckDetails()called.checkDetails()checks email format (checkEmailAddress()at line 619) but never queries the DB for duplicate emails.- The static method
doesUserExistByEmail()exists at line 1111 but was never called. - No error constant or i18n string existed for duplicate email.
firstLogin.phphad a secondary bug: afterwriteToDB()returned an error, it still redirected tologin.phpwithout showing the error.
Why it breaks now: Original design omission from 1.9.20 โ not a regression.
Blast radius: All user creation paths through tlUser::writeToDB() + checkDetails() were affected: self-signup (firstLogin.php), admin user creation (usersEdit.php), XMLRPC user creation.
Fix
- Added
const E_EMAILALREADYEXISTS = -1024;totlUserclass constants (tlUser.class.php:122). - Added email uniqueness check in
checkDetails()(tlUser.class.php:628-631):if ($result >= tl::OK && !$this->dbID) { $result = self::doesUserExistByEmail($db,$this->emailAddress) ? self::E_EMAILALREADYEXISTS : tl::OK; } - Added error case in
getUserErrorMessage()(users.inc.php:267-269):case tlUser::E_EMAILALREADYEXISTS: $msg = lang_get('email_already_used'); break; - Added
email_already_usedi18n key to all 19 locale bundles. - Wrapped
firstLogin.phppost-writeToDB()block inif ($result >= tl::OK)so errors are displayed instead of silently redirected.
Verification matrix
| # | Check | Result |
|---|---|---|
| R1 | POST with duplicate email โ error message displayed | PASS |
| R2 | POST with unique email โ redirect to login.php | PASS |
| R3 | POST with duplicate login โ existing error still works | PASS |
| R4 | POST with empty email โ existing error still works | PASS |
| R5 | Browser: form displays error on duplicate email | PASS |
| R6 | DB: no two users share email | PASS |
| R7 | Event Viewer: no new Error/Warning entries | PASS |
Files changed
lib/functions/tlUser.class.php(+5 lines: constant + email check)lib/functions/users.inc.php(+4 lines: error case)firstLogin.php(+11 / -7 lines: result check wrapper)- 19 locale
strings.txtfiles (+1 line each:email_already_usedkey)