[TikiWiki-commits] [Git][tikiwiki/tiki][master] [REF][DB] Rename Google2FA to TOTP2FA across the codebase and update related preferences
Benoit Grégoire (@benoitg) via TikiWiki-cvs <[email protected]>
| Newsgroups | gmane.comp.cms.tiki.cvs |
|---|---|
| Message-ID | <696a5303f0bf5_2c1930fe8795c8@gitlab-sidekiq-low-urgency-cpu-bound-v2-859b9cfb8-4llvp.mail> |
Benoit Grégoire pushed to branch master at Tiki Wiki CMS Groupware / Tiki
Commits:
9c0f58ab by Alvin Bauma at 2026-01-16T14:53:38+00:00
[REF][DB] Rename Google2FA to TOTP2FA across the codebase and update related preferences
---
* [REF][DB] Rename Google2FA to TOTP2FA across the codebase and update related preferences
See merge request tikiwiki/tiki!8797
- - - - -
8 changed files:
- + installer/schema/20251016_rename_google2fa_to_totp2fa_tiki.sql
- lib/core/TwoFactorAuth/Google2FA.php
- lib/core/TwoFactorAuth/TwoFactorAuth.php
- lib/prefs/global.php
- modules/mod-func-login_box.php
- templates/modules/mod-login_box.tpl
- templates/tiki-user_preferences.tpl
- tiki-user_preferences.php
Changes:
=====================================
installer/schema/20251016_rename_google2fa_to_totp2fa_tiki.sql
=====================================
@@ -0,0 +1 @@
+UPDATE `tiki_preferences` SET `value` = 'totp2FA' WHERE `name` = 'twoFactorAuthType' AND `value` = 'google2FA';
=====================================
lib/core/TwoFactorAuth/Google2FA.php
=====================================
@@ -23,7 +23,7 @@ class Google2FA implements TwoFactorAuthInterface
public function generateCode($user, $isEmail = true)
{
- // For Google2FA, code generation is typically done on the client-side
+ // For Google2FA/TOTP2FA, code generation is typically done on the client-side
return true;
}
=====================================
lib/core/TwoFactorAuth/TwoFactorAuth.php
=====================================
@@ -11,17 +11,31 @@ use TikiLib;
class TwoFactorAuth
{
- /** @var string string representation for google 2FA */
- public const GOOGLE_2FA = 'google2FA';
+ /** @var string string representation for totp 2FA */
+ public const TOTP_2FA = 'totp2FA';
/** @var string string representation for email 2FA */
public const EMAIL_2FA = 'email2FA';
/** @var string The default 2FA type */
- public const DEFAULT_2FA = self::GOOGLE_2FA;
-
- /** @var string[] The list of available 2FA types */
- public const AVAILABLE_2FA_TYPES = [self::GOOGLE_2FA, self::EMAIL_2FA];
+ public const DEFAULT_2FA = self::TOTP_2FA;
+
+ /**
+ * Map internal 2FA identifiers to their implementing classes.
+ *
+ * IMPORTANT:
+ * - The string identifiers (keys) are the values stored in prefs/DB for backward compatibility.
+ * - Class names follow PSR naming (Google2FA, Email2FA). Do NOT try to compute class names
+ * from the identifier (e.g., with ucfirst). Always use this map to avoid case issues
+ * and to keep the TOTP_2FA → Google2FA linkage explicit.
+ */
+ private const CLASS_BY_TYPE = [
+ self::TOTP_2FA => \Tiki\TwoFactorAuth\Google2FA::class,
+ self::EMAIL_2FA => \Tiki\TwoFactorAuth\Email2FA::class,
+ ];
+
+ /** @var string[] list of available 2FA type identifiers */
+ public const AVAILABLE_2FA_TYPES = [self::TOTP_2FA, self::EMAIL_2FA];
public static function getTwoFactorAuthTypeEnabled(): string
{
@@ -38,35 +52,36 @@ class TwoFactorAuth
public static function getTwoFactorAuthByType($type)
{
- $authType = ucfirst($type);
- $class = "\\Tiki\\TwoFactorAuth\\$authType";
-
- if (! in_array($type, self::AVAILABLE_2FA_TYPES, true) || ! class_exists($class)) {
- $errMsg = tr('Two factor auth type not found: ' . $type . ', Supported types are: ' . implode(', ', self::AVAILABLE_2FA_TYPES));
+ $class = self::CLASS_BY_TYPE[$type] ?? null;
+
+ if (! $class || ! in_array($type, self::AVAILABLE_2FA_TYPES, true) || ! class_exists($class)) {
+ $errMsg = tr(
+ 'Two factor auth type not found: %0. Supported types are: %1',
+ $type,
+ implode(', ', self::AVAILABLE_2FA_TYPES)
+ );
throw new TwoFactorAuthException($errMsg);
}
if (! in_array(TwoFactorAuthInterface::class, class_implements($class), true)) {
- $errMsg = tr('The class ' . $class . ' does not implement the required TwoFactorAuthInterface.');
+ $errMsg = tr('The class %0 does not implement the required TwoFactorAuthInterface.', $class);
throw new TwoFactorAuthException($errMsg);
}
- $twoFactorAuth = new $class();
-
- return $twoFactorAuth;
+ return new $class();
}
public static function isMFARequired($user)
{
global $prefs, $userlib;
- $mfaIntervalDaysPrefs = intval($prefs['twoFactorAuthIntervalDays']);
+ $mfaIntervalDaysPrefs = (int) $prefs['twoFactorAuthIntervalDays'];
$requireMfa = false;
- if ($prefs['twoFactorAuth'] == 'y') {
+ if ($prefs['twoFactorAuth'] === 'y') {
$userInfo = $userlib->get_user_info($user);
if (! empty($userInfo['twoFactorSecret'])) {
- $lastMfaDateDb = intval($userInfo['last_mfa_date']);
+ $lastMfaDateDb = (int) $userInfo['last_mfa_date'];
if ($mfaIntervalDaysPrefs > 0) {
if (empty($lastMfaDateDb) || (time() - $lastMfaDateDb) > ($mfaIntervalDaysPrefs * 86400)) {
$requireMfa = true;
@@ -85,12 +100,12 @@ class TwoFactorAuth
$userlib = TikiLib::lib('user');
$twoFAType = self::getTwoFactorAuthTypeEnabled();
- if ($twoFAType === self::GOOGLE_2FA) {
+ if ($twoFAType === self::TOTP_2FA) {
return $userlib->get_2_factor_secret($user);
} elseif ($twoFAType === self::EMAIL_2FA) {
return true;
- } else {
- throw new TwoFactorAuthException(tr('Unsupported 2FA type: ' . $twoFAType));
}
+
+ throw new TwoFactorAuthException(tr('Unsupported 2FA type: ' . $twoFAType));
}
}
=====================================
lib/prefs/global.php
=====================================
@@ -208,10 +208,10 @@ function prefs_global_list($partial = false)
'description' => tra('Type of 2FA to be used.'),
'type' => 'list',
'options' => [
- \Tiki\TwoFactorAuth\TwoFactorAuth::GOOGLE_2FA => tra('Google 2FA'),
+ \Tiki\TwoFactorAuth\TwoFactorAuth::TOTP_2FA => tra('Authenticator App (TOTP)'),
\Tiki\TwoFactorAuth\TwoFactorAuth::EMAIL_2FA => tra('Email 2FA'),
],
- 'default' => \Tiki\TwoFactorAuth\TwoFactorAuth::GOOGLE_2FA,
+ 'default' => \Tiki\TwoFactorAuth\TwoFactorAuth::TOTP_2FA,
],
'twoFactorAuthEmailTokenLength' => [
'name' => tra('Email 2FA Token Length'),
=====================================
modules/mod-func-login_box.php
=====================================
@@ -12,6 +12,8 @@ if (str_contains($_SERVER["SCRIPT_NAME"], basename(__FILE__))) {
//aris002 CHECK if we really can't avoid this?
require_once('lib/socnets/PrefsGen.php');
+
+use Tiki\TwoFactorAuth\TwoFactorAuth;
use TikiLib\Socnets\PrefsGen\PrefsGen;
/**
@@ -117,6 +119,8 @@ function module_login_box($mod_reference, &$module_params)
$smarty->assign('module_logo_instance', $module_logo_instance);
$smarty->assign('mode', $module_params['mode'] ?? 'module');
$smarty->assign('login_text_explanation', $tikilib->get_preference('login_text_explanation'));
+ $smarty->assign('EMAIL_2FA', TwoFactorAuth::EMAIL_2FA);
+ $smarty->assign('TOTP_2FA', TwoFactorAuth::TOTP_2FA);
$urlPrefix = in_array($prefs['https_login'], ['encouraged', 'required', 'force_nocheck']) ? $base_url_https : $base_url;
$smarty->assign('registration', 'n'); // stops the openid form appearing in the module, only on tiki-login_scr.php
=====================================
templates/modules/mod-login_box.tpl
=====================================
@@ -39,7 +39,7 @@ $(document).ready(function () {
if (!res) {
$(event.currentTarget).off('submit').submit();
} else {
- if (twoFAType === 'google2FA') {
+ if (twoFAType === '{{$TOTP_2FA}}') {
show2FactorInputElement(btn, event);
} else {
generate2FACode(username, btn, event);
@@ -181,7 +181,7 @@ $(document).ready(function () {
}
// If step > 1, or no user screen, or 2FA is effectively "n", just submit
- if (btnStep > 1 || isLoginScreen === 0 || (twoFASecret == 'n' && twoFAType === 'google2FA')) {
+ if (btnStep > 1 || isLoginScreen === 0 || (twoFASecret == 'n' && twoFAType === '{{$TOTP_2FA}}')) {
$(this).off('submit').submit();
return false;
}
@@ -445,7 +445,7 @@ $(".collapse-toggle", ".siteloginbar_popup .dropdown-menu").on("click", function
<div id="two_factor_div" class="my-3 {if $mode eq 'header'}mx-2{/if}" style="display: {if $create2FaCodeNormalLogin === 'y'} block; {else} none; {/if}">
<label for="login-2fa_{$module_logo_instance}">{tr}Two-factor authentication code:{/tr}</label>
<input type="text" name="twoFactorAuthCode" autocomplete="off" class="form-control" id="login-2fa_{$module_logo_instance}">
- {if $prefs.twoFactorAuthType eq 'email2FA'}
+ {if $prefs.twoFactorAuthType eq $EMAIL_2FA}
<small class="text-muted">{tr}Please type the 6 digit security code sent to your email address{/tr}</small>
<a class="mt-1 d-block" href="#" onclick="$('#loginbox-{{$module_logo_instance}}').data('normalLogin', '2fa-regen').submit()" title="{tr}Click here if you've not received the code and want to send a new one.{/tr}">{tr}I didn't receive the code{/tr}</a>
{else}
@@ -507,9 +507,9 @@ $(".collapse-toggle", ".siteloginbar_popup .dropdown-menu").on("click", function
|
{/if}
<li class="pass{if $mode eq 'popup'} dropdown-item{/if} list-item">
- <a href="tiki-login_scr.php?showTwoFactorForm" title="{if $prefs.twoFactorAuthType eq 'email2FA'}{tr}Login with 2FA{/tr}{else}{tr}Login with two-factor authenticator{/tr}{/if}">
+ <a href="tiki-login_scr.php?showTwoFactorForm" title="{if $prefs.twoFactorAuthType eq $EMAIL_2FA}{tr}Login with 2FA{/tr}{else}{tr}Login with two-factor authenticator{/tr}{/if}">
{if $mode eq 'popup'}
- {if $prefs.twoFactorAuthType eq 'email2FA'}{tr}Login with 2FA{/tr}{elseif $prefs.twoFactorAuthType eq 'google2FA'}{tr}Login with two-factor authenticator{/tr}{/if}
+ {if $prefs.twoFactorAuthType eq $EMAIL_2FA}{tr}Login with 2FA{/tr}{elseif $prefs.twoFactorAuthType eq $TOTP_2FA}{tr}Login with two-factor authenticator{/tr}{/if}
{/if}
</a>
</li>
=====================================
templates/tiki-user_preferences.tpl
=====================================
@@ -842,7 +842,7 @@
</div>
</div>
</div>
- <div class="col-md-7">
+ <div class="col-md-7 p-4">
<div class="d-flex mt-4">
<div class="well">
{tr}Install a soft token authenticator like FreeOTP or Google Authenticator from your application repository and use that app to scan this QR code. More information is available in the documentation.{/tr} <a href="https://en.wikipedia.org/wiki/Comparison_of_OTP_applications" target="_blank">{tr}Learn more about authenticator apps{/tr}</a>
=====================================
tiki-user_preferences.php
=====================================
@@ -94,6 +94,7 @@ use BaconQrCode\Renderer\Image\ImagickImageBackEnd;
use BaconQrCode\Renderer\RendererStyle\RendererStyle;
use BaconQrCode\Writer;
use Tiki\Lib\TikiDate;
+use Tiki\TwoFactorAuth\TwoFactorAuth;
// User preferences screen
if ($prefs['feature_userPreferences'] != 'y' && $prefs['change_password'] != 'y' && $tiki_p_admin_users != 'y') {
@@ -507,7 +508,7 @@ if (
}
}
-if (isset($_POST['twofactor']) && $access->checkCsrf() && $prefs['twoFactorAuthType'] == 'email2FA') {
+if (isset($_POST['twofactor']) && $access->checkCsrf() && $prefs['twoFactorAuthType'] == TwoFactorAuth::EMAIL_2FA) {
$tfaSecret = $userlib->update_2_factor_secret($user, 'y');
}
@@ -527,7 +528,7 @@ $smarty->assign('twoFactorSecret', $twoFactorSecret);
$userinfo = $userlib->get_user_info($userwatch);
$generate = isset($_REQUEST['tfagenerate']) || empty($tfaSecret);
-if ($prefs['twoFactorAuth'] == 'y' && $generate && $prefs['twoFactorAuthType'] == 'google2FA') {
+if ($prefs['twoFactorAuth'] == 'y' && $generate && $prefs['twoFactorAuthType'] == TwoFactorAuth::TOTP_2FA) {
$google2fa = new Google2FA();
if (empty($_SESSION['tfaSecret']) || $_SESSION['tfaSecret'] == $tfaSecret) {
$_SESSION['tfaSecret'] = $google2fa->generateSecretKey();
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/9c0f58ab0205212d28043f9f00f45b368cc663cd
--
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/9c0f58ab0205212d28043f9f00f45b368cc663cd
You're receiving this email because of your account on gitlab.com.
_______________________________________________
TikiWiki-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tikiwiki-cvs