[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
                                 &nbsp;|&nbsp;
                             {/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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.