Files
api/services/nginx/app/tests/auth/TwoFactorAuthTest.php
T
Jeppe Bundgaard f6b526f4ef Add two-factor authentication support for users and subusers
- Extend `users_o` and `subusers_o` with `two_factor_enabled` and `two_factor_secret` properties.
- Implement methods for managing 2FA (`isTwoFactorEnabled`, `setTwoFactorSecret`, `verify_2fa_code`) in authentication logic.
- Add 2FA handling in login flows for both users and subusers, including token generation and validation.
- Introduce `totp` class for TOTP-based authentication, including QR code generation and code verification.
- Add test cases for 2FA functionality (`TwoFactorAuthTest.php`) and coverage for login scenarios with 2FA.
- Update OpenAPI specifications to include 2FA flows (`auth/2fa/setup`, `auth/2fa/enable`, `auth/2fa/verify`, `auth/2fa/disable`).
2026-02-23 17:00:18 +01:00

65 lines
2.5 KiB
PHP

<?php
if (!defined('WD')) {
define('WD', dirname(__DIR__, 2));
}
$_ENV['USE_ENV'] = 'true';
require_once WD . '/config.php';
require_once WD . '/classes/db.php';
require_once WD . '/classes/totp.php';
use classes\totp;
global $CONFIG_DB;
$db = new \classes\db($CONFIG_DB);
$db->connect();
function assert_true($condition, $message)
{
if ($condition) {
echo "✔ $message\n";
} else {
echo "✘ $message\n";
exit(1);
}
}
echo "Testing TOTP class...\n";
$totp = new totp();
$secret = $totp->generateSecret();
assert_true(strlen($secret) === 16, "Secret length is 16");
$code = $totp->getCode($secret);
assert_true(strlen($code) === 6, "Code length is 6");
assert_true($totp->verifyCode($secret, $code), "Verify current code");
assert_true(!$totp->verifyCode($secret, '000000'), "Reject invalid code");
echo "\nTesting 2FA columns on users table...\n";
$colCheck = $db->query("SELECT COUNT(*) AS cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = '".$CONFIG_DB['database']."' AND TABLE_NAME = 'users' AND COLUMN_NAME IN ('two_factor_secret','two_factor_enabled')");
$row = $db->fetch_assoc($colCheck);
assert_true((int)$row['cnt'] >= 2, "Users table has 2FA columns");
$setup_secret = $totp->generateSecret();
$valid_code = $totp->getCode($setup_secret);
assert_true($totp->verifyCode($setup_secret, $valid_code), "Verify code for generated secret");
echo "\nTesting 2FA for Subuser (Driver) via DB...\n";
$test_subuser_id = 999999;
$db->query("DELETE FROM subusers WHERE id = $test_subuser_id");
$pwd = password_hash('password123', PASSWORD_DEFAULT);
$db->query("INSERT INTO subusers (id, username, password, name, email, phone_country_code, phone) VALUES ($test_subuser_id, 'testdriver', '$pwd', 'Test Driver', 'driver@example.com', 45, 20123456)");
$sub_secret = $totp->generateSecret();
$sub_code = $totp->getCode($sub_secret);
assert_true($totp->verifyCode($sub_secret, $sub_code), "TOTP verifies subuser code");
$db->query("UPDATE subusers SET two_factor_secret = '$sub_secret', two_factor_enabled = 1 WHERE id = $test_subuser_id");
$res = $db->query("SELECT two_factor_enabled, two_factor_secret FROM subusers WHERE id = $test_subuser_id");
$row = $db->fetch_assoc($res);
assert_true((int)$row['two_factor_enabled'] === 1, "Subuser 2FA enabled flag persisted");
assert_true($row['two_factor_secret'] === $sub_secret, "Subuser secret persisted");
// Cleanup
$db->query("DELETE FROM subusers WHERE id = $test_subuser_id");
echo "\nTwoFactorAuthTest completed successfully!\n";