mirror of
				https://github.com/slawkens/myaac.git
				synced 2025-10-31 07:56:23 +01:00 
			
		
		
		
	Compare commits
	
		
			16 Commits
		
	
	
		
			v1.8.1
			...
			feature/2f
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | abee4b3962 | ||
|   | fbdb6890b9 | ||
|   | 041f58ed11 | ||
|   | 4eab805d26 | ||
|   | 3f24f961b1 | ||
|   | 0b86459940 | ||
|   | 03c7dd0002 | ||
|   | e435062025 | ||
|   | ecc9bd4042 | ||
|   | 797377e428 | ||
|   | 96b5df9d74 | ||
|   | b3dfc56c96 | ||
|   | 96d6e04bd2 | ||
|   | 9146eee327 | ||
|   | 3d97fa0719 | ||
|   | a66cafceab | 
| @@ -26,8 +26,8 @@ | |||||||
| if (version_compare(phpversion(), '8.1', '<')) die('PHP version 8.1 or higher is required.'); | if (version_compare(phpversion(), '8.1', '<')) die('PHP version 8.1 or higher is required.'); | ||||||
|  |  | ||||||
| const MYAAC = true; | const MYAAC = true; | ||||||
| const MYAAC_VERSION = '1.8.1'; | const MYAAC_VERSION = '1.8.2-dev'; | ||||||
| const DATABASE_VERSION = 45; | const DATABASE_VERSION = 46; | ||||||
| const TABLE_PREFIX = 'myaac_'; | const TABLE_PREFIX = 'myaac_'; | ||||||
| define('START_TIME', microtime(true)); | define('START_TIME', microtime(true)); | ||||||
| define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX')); | define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX')); | ||||||
|   | |||||||
| @@ -19,7 +19,8 @@ | |||||||
|         "symfony/var-dumper": "^6.4", |         "symfony/var-dumper": "^6.4", | ||||||
|         "filp/whoops": "^2.15", |         "filp/whoops": "^2.15", | ||||||
|         "maximebf/debugbar": "1.*", |         "maximebf/debugbar": "1.*", | ||||||
|         "guzzlehttp/guzzle": "7.9.3" |         "guzzlehttp/guzzle": "7.9.3", | ||||||
|  |         "spomky-labs/otphp": "^11.3" | ||||||
|     }, |     }, | ||||||
|     "require-dev": { |     "require-dev": { | ||||||
|         "phpstan/phpstan": "^1.10" |         "phpstan/phpstan": "^1.10" | ||||||
|   | |||||||
							
								
								
									
										151
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										151
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							| @@ -4,7 +4,7 @@ | |||||||
|         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", |         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", | ||||||
|         "This file is @generated automatically" |         "This file is @generated automatically" | ||||||
|     ], |     ], | ||||||
|     "content-hash": "5317e97a5025ebc2a977214bd3fa964c", |     "content-hash": "07419f6fe133f9bebc99557f3df843c8", | ||||||
|     "packages": [ |     "packages": [ | ||||||
|         { |         { | ||||||
|             "name": "brick/math", |             "name": "brick/math", | ||||||
| @@ -1556,6 +1556,73 @@ | |||||||
|             }, |             }, | ||||||
|             "time": "2018-02-13T20:26:39+00:00" |             "time": "2018-02-13T20:26:39+00:00" | ||||||
|         }, |         }, | ||||||
|  |         { | ||||||
|  |             "name": "paragonie/constant_time_encoding", | ||||||
|  |             "version": "v3.0.0", | ||||||
|  |             "source": { | ||||||
|  |                 "type": "git", | ||||||
|  |                 "url": "https://github.com/paragonie/constant_time_encoding.git", | ||||||
|  |                 "reference": "df1e7fde177501eee2037dd159cf04f5f301a512" | ||||||
|  |             }, | ||||||
|  |             "dist": { | ||||||
|  |                 "type": "zip", | ||||||
|  |                 "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/df1e7fde177501eee2037dd159cf04f5f301a512", | ||||||
|  |                 "reference": "df1e7fde177501eee2037dd159cf04f5f301a512", | ||||||
|  |                 "shasum": "" | ||||||
|  |             }, | ||||||
|  |             "require": { | ||||||
|  |                 "php": "^8" | ||||||
|  |             }, | ||||||
|  |             "require-dev": { | ||||||
|  |                 "phpunit/phpunit": "^9", | ||||||
|  |                 "vimeo/psalm": "^4|^5" | ||||||
|  |             }, | ||||||
|  |             "type": "library", | ||||||
|  |             "autoload": { | ||||||
|  |                 "psr-4": { | ||||||
|  |                     "ParagonIE\\ConstantTime\\": "src/" | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|  |             "notification-url": "https://packagist.org/downloads/", | ||||||
|  |             "license": [ | ||||||
|  |                 "MIT" | ||||||
|  |             ], | ||||||
|  |             "authors": [ | ||||||
|  |                 { | ||||||
|  |                     "name": "Paragon Initiative Enterprises", | ||||||
|  |                     "email": "security@paragonie.com", | ||||||
|  |                     "homepage": "https://paragonie.com", | ||||||
|  |                     "role": "Maintainer" | ||||||
|  |                 }, | ||||||
|  |                 { | ||||||
|  |                     "name": "Steve 'Sc00bz' Thomas", | ||||||
|  |                     "email": "steve@tobtu.com", | ||||||
|  |                     "homepage": "https://www.tobtu.com", | ||||||
|  |                     "role": "Original Developer" | ||||||
|  |                 } | ||||||
|  |             ], | ||||||
|  |             "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", | ||||||
|  |             "keywords": [ | ||||||
|  |                 "base16", | ||||||
|  |                 "base32", | ||||||
|  |                 "base32_decode", | ||||||
|  |                 "base32_encode", | ||||||
|  |                 "base64", | ||||||
|  |                 "base64_decode", | ||||||
|  |                 "base64_encode", | ||||||
|  |                 "bin2hex", | ||||||
|  |                 "encoding", | ||||||
|  |                 "hex", | ||||||
|  |                 "hex2bin", | ||||||
|  |                 "rfc4648" | ||||||
|  |             ], | ||||||
|  |             "support": { | ||||||
|  |                 "email": "info@paragonie.com", | ||||||
|  |                 "issues": "https://github.com/paragonie/constant_time_encoding/issues", | ||||||
|  |                 "source": "https://github.com/paragonie/constant_time_encoding" | ||||||
|  |             }, | ||||||
|  |             "time": "2024-05-08T12:36:18+00:00" | ||||||
|  |         }, | ||||||
|         { |         { | ||||||
|             "name": "peppeocchi/php-cron-scheduler", |             "name": "peppeocchi/php-cron-scheduler", | ||||||
|             "version": "v4.0", |             "version": "v4.0", | ||||||
| @@ -2102,6 +2169,88 @@ | |||||||
|             }, |             }, | ||||||
|             "time": "2019-03-08T08:55:37+00:00" |             "time": "2019-03-08T08:55:37+00:00" | ||||||
|         }, |         }, | ||||||
|  |         { | ||||||
|  |             "name": "spomky-labs/otphp", | ||||||
|  |             "version": "11.3.0", | ||||||
|  |             "source": { | ||||||
|  |                 "type": "git", | ||||||
|  |                 "url": "https://github.com/Spomky-Labs/otphp.git", | ||||||
|  |                 "reference": "2d8ccb5fc992b9cc65ef321fa4f00fefdb3f4b33" | ||||||
|  |             }, | ||||||
|  |             "dist": { | ||||||
|  |                 "type": "zip", | ||||||
|  |                 "url": "https://api.github.com/repos/Spomky-Labs/otphp/zipball/2d8ccb5fc992b9cc65ef321fa4f00fefdb3f4b33", | ||||||
|  |                 "reference": "2d8ccb5fc992b9cc65ef321fa4f00fefdb3f4b33", | ||||||
|  |                 "shasum": "" | ||||||
|  |             }, | ||||||
|  |             "require": { | ||||||
|  |                 "ext-mbstring": "*", | ||||||
|  |                 "paragonie/constant_time_encoding": "^2.0 || ^3.0", | ||||||
|  |                 "php": ">=8.1", | ||||||
|  |                 "psr/clock": "^1.0", | ||||||
|  |                 "symfony/deprecation-contracts": "^3.2" | ||||||
|  |             }, | ||||||
|  |             "require-dev": { | ||||||
|  |                 "ekino/phpstan-banned-code": "^1.0", | ||||||
|  |                 "infection/infection": "^0.26|^0.27|^0.28|^0.29", | ||||||
|  |                 "php-parallel-lint/php-parallel-lint": "^1.3", | ||||||
|  |                 "phpstan/phpstan": "^1.0", | ||||||
|  |                 "phpstan/phpstan-deprecation-rules": "^1.0", | ||||||
|  |                 "phpstan/phpstan-phpunit": "^1.0", | ||||||
|  |                 "phpstan/phpstan-strict-rules": "^1.0", | ||||||
|  |                 "phpunit/phpunit": "^9.5.26|^10.0|^11.0", | ||||||
|  |                 "qossmic/deptrac-shim": "^1.0", | ||||||
|  |                 "rector/rector": "^1.0", | ||||||
|  |                 "symfony/phpunit-bridge": "^6.1|^7.0", | ||||||
|  |                 "symplify/easy-coding-standard": "^12.0" | ||||||
|  |             }, | ||||||
|  |             "type": "library", | ||||||
|  |             "autoload": { | ||||||
|  |                 "psr-4": { | ||||||
|  |                     "OTPHP\\": "src/" | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|  |             "notification-url": "https://packagist.org/downloads/", | ||||||
|  |             "license": [ | ||||||
|  |                 "MIT" | ||||||
|  |             ], | ||||||
|  |             "authors": [ | ||||||
|  |                 { | ||||||
|  |                     "name": "Florent Morselli", | ||||||
|  |                     "homepage": "https://github.com/Spomky" | ||||||
|  |                 }, | ||||||
|  |                 { | ||||||
|  |                     "name": "All contributors", | ||||||
|  |                     "homepage": "https://github.com/Spomky-Labs/otphp/contributors" | ||||||
|  |                 } | ||||||
|  |             ], | ||||||
|  |             "description": "A PHP library for generating one time passwords according to RFC 4226 (HOTP Algorithm) and the RFC 6238 (TOTP Algorithm) and compatible with Google Authenticator", | ||||||
|  |             "homepage": "https://github.com/Spomky-Labs/otphp", | ||||||
|  |             "keywords": [ | ||||||
|  |                 "FreeOTP", | ||||||
|  |                 "RFC 4226", | ||||||
|  |                 "RFC 6238", | ||||||
|  |                 "google authenticator", | ||||||
|  |                 "hotp", | ||||||
|  |                 "otp", | ||||||
|  |                 "totp" | ||||||
|  |             ], | ||||||
|  |             "support": { | ||||||
|  |                 "issues": "https://github.com/Spomky-Labs/otphp/issues", | ||||||
|  |                 "source": "https://github.com/Spomky-Labs/otphp/tree/11.3.0" | ||||||
|  |             }, | ||||||
|  |             "funding": [ | ||||||
|  |                 { | ||||||
|  |                     "url": "https://github.com/Spomky", | ||||||
|  |                     "type": "github" | ||||||
|  |                 }, | ||||||
|  |                 { | ||||||
|  |                     "url": "https://www.patreon.com/FlorentMorselli", | ||||||
|  |                     "type": "patreon" | ||||||
|  |                 } | ||||||
|  |             ], | ||||||
|  |             "time": "2024-06-12T11:22:32+00:00" | ||||||
|  |         }, | ||||||
|         { |         { | ||||||
|             "name": "symfony/console", |             "name": "symfony/console", | ||||||
|             "version": "v6.4.17", |             "version": "v6.4.17", | ||||||
|   | |||||||
| @@ -10,6 +10,15 @@ CREATE TABLE `myaac_account_actions` | |||||||
| 	KEY (`account_id`) | 	KEY (`account_id`) | ||||||
| ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; | ||||||
|  |  | ||||||
|  | CREATE TABLE `myaac_account_email_codes` | ||||||
|  | ( | ||||||
|  | 	`id` int(11) NOT NULL AUTO_INCREMENT, | ||||||
|  | 	`account_id` int NOT NULL, | ||||||
|  | 	`code` varchar(6) NOT NULL, | ||||||
|  | 	`created_at` int NOT NULL, | ||||||
|  | 	PRIMARY KEY (`id`) | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; | ||||||
|  |  | ||||||
| CREATE TABLE `myaac_admin_menu` | CREATE TABLE `myaac_admin_menu` | ||||||
| ( | ( | ||||||
| 	`id` int NOT NULL AUTO_INCREMENT, | 	`id` int NOT NULL AUTO_INCREMENT, | ||||||
|   | |||||||
| @@ -42,45 +42,44 @@ if(!$error) { | |||||||
| 	$configToSave['cache_prefix'] = 'myaac_' . generateRandomString(8, true, false, true); | 	$configToSave['cache_prefix'] = 'myaac_' . generateRandomString(8, true, false, true); | ||||||
| 	$configToSave['database_auto_migrate'] = true; | 	$configToSave['database_auto_migrate'] = true; | ||||||
|  |  | ||||||
| 	if(!$error) { | 	$content = ''; | ||||||
| 		$content = ''; | 	$saved = Settings::saveConfig($configToSave, BASE . 'config.local.php', $content); | ||||||
| 		$saved = Settings::saveConfig($configToSave, BASE . 'config.local.php', $content); | 	if ($saved || file_exists(BASE . 'config.local.php')) { | ||||||
| 		if ($saved) { | 		success($locale['step_database_config_saved']); | ||||||
| 			success($locale['step_database_config_saved']); | 		$_SESSION['saved'] = true; | ||||||
| 			$_SESSION['saved'] = true; |  | ||||||
|  |  | ||||||
| 			require BASE . 'config.local.php'; | 		require BASE . 'config.local.php'; | ||||||
| 			require BASE . 'install/includes/config.php'; | 		require BASE . 'install/includes/config.php'; | ||||||
|  |  | ||||||
| 			if (!$error) { | 		if (!$error) { | ||||||
| 				require BASE . 'install/includes/database.php'; | 			require BASE . 'install/includes/database.php'; | ||||||
|  |  | ||||||
| 				if (isset($database_error)) { // we failed connect to the database | 			if (isset($database_error)) { // we failed connect to the database | ||||||
| 					error($database_error); | 				error($database_error); | ||||||
|  | 			} | ||||||
|  | 			else { | ||||||
|  | 				if (!$db->hasTable('accounts')) { | ||||||
|  | 					$tmp = str_replace('$TABLE$', 'accounts', $locale['step_database_error_table']); | ||||||
|  | 					error($tmp); | ||||||
|  | 					$error = true; | ||||||
| 				} | 				} | ||||||
| 				else { |  | ||||||
| 					if (!$db->hasTable('accounts')) { |  | ||||||
| 						$tmp = str_replace('$TABLE$', 'accounts', $locale['step_database_error_table']); |  | ||||||
| 						error($tmp); |  | ||||||
| 						$error = true; |  | ||||||
| 					} |  | ||||||
|  |  | ||||||
| 					if (!$error) { | 				if (!$error) { | ||||||
| 						$twig->display('install.installer.html.twig', array( | 					$twig->display('install.installer.html.twig', array( | ||||||
| 							'url' => 'tools/5-database.php', | 						'url' => 'tools/5-database.php', | ||||||
| 							'message' => $locale['loading_spinner'] | 						'message' => $locale['loading_spinner'] | ||||||
| 						)); | 					)); | ||||||
| 					} |  | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} else { |  | ||||||
| 			$_SESSION['config_content'] = $content; |  | ||||||
| 			unset($_SESSION['saved']); |  | ||||||
|  |  | ||||||
| 			$locale['step_database_error_file'] = str_replace('$FILE$', '<b>' . BASE . 'config.php</b>', $locale['step_database_error_file']); |  | ||||||
| 			error($locale['step_database_error_file'] . '<br/> |  | ||||||
| 				<textarea cols="70" rows="10">' . $content . '</textarea>'); |  | ||||||
| 		} | 		} | ||||||
|  | 	} else { | ||||||
|  | 		$error = true; | ||||||
|  | 		$_SESSION['config_content'] = $content; | ||||||
|  | 		unset($_SESSION['saved']); | ||||||
|  |  | ||||||
|  | 		$locale['step_database_error_file'] = str_replace('$FILE$', '<b>' . BASE . 'config.local.php</b>', $locale['step_database_error_file']); | ||||||
|  | 		error($locale['step_database_error_file'] . '<br/> | ||||||
|  | 			<textarea cols="70" rows="10">' . $content . '</textarea>'); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| ?> | ?> | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								system/migrations/46-account_email_codes.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								system/migrations/46-account_email_codes.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | CREATE TABLE `myaac_account_email_codes` | ||||||
|  | ( | ||||||
|  | 	`id` int(11) NOT NULL AUTO_INCREMENT, | ||||||
|  | 	`account_id` int NOT NULL, | ||||||
|  | 	`code` varchar(6) NOT NULL, | ||||||
|  | 	`created_at` int NOT NULL, | ||||||
|  | 	PRIMARY KEY (`id`) | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; | ||||||
							
								
								
									
										27
									
								
								system/migrations/46.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								system/migrations/46.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | |||||||
|  | <?php | ||||||
|  | // add the myaac_account_email_codes | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @var OTS_DB_MySQL $db | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | $up = function () use ($db) { | ||||||
|  | 	if (!$db->hasColumn('accounts', '2fa_type')) { | ||||||
|  | 		$db->addColumn('accounts', '2fa_type', "tinyint NOT NULL DEFAULT 0 AFTER `web_flags`"); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// add myaac_account_email_codes table | ||||||
|  | 	if (!$db->hasTable(TABLE_PREFIX . 'account_email_codes')) { | ||||||
|  | 		$db->exec(file_get_contents(__DIR__ . '/46-account_email_codes.sql')); | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | $down = function () use ($db) { | ||||||
|  | 	if ($db->hasColumn('accounts', '2fa_type')) { | ||||||
|  | 		$db->dropColumn('accounts', '2fa_type'); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	//if ($db->hasTable(TABLE_PREFIX . 'account_email_codes')) { | ||||||
|  | 	//	$db->dropTable(TABLE_PREFIX . 'account_email_codes'); | ||||||
|  | 	//} | ||||||
|  | }; | ||||||
							
								
								
									
										124
									
								
								system/pages/account/2fa.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								system/pages/account/2fa.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,124 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * 2-factor authentication | ||||||
|  |  * | ||||||
|  |  * @package   MyAAC | ||||||
|  |  * @author    Slawkens <slawkens@gmail.com> | ||||||
|  |  * @copyright 2019 MyAAC | ||||||
|  |  * @link      https://my-aac.org | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | use MyAAC\TwoFactorAuth\TwoFactorAuth; | ||||||
|  |  | ||||||
|  | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
|  |  | ||||||
|  | $title = 'Two Factor Authentication'; | ||||||
|  | require __DIR__ . '/base.php'; | ||||||
|  |  | ||||||
|  | csrfProtect(); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @var OTS_Account $account_logged | ||||||
|  |  */ | ||||||
|  | $step = $_REQUEST['step'] ?? ''; | ||||||
|  | $code = $_REQUEST['auth-code'] ?? ''; | ||||||
|  |  | ||||||
|  | if ((!setting('core.mail_enabled')) && ACTION == 'email-code') { | ||||||
|  | 	$twig->display('error_box.html.twig',  ['errors' => ['Account two-factor e-mail authentication disabled.']]); | ||||||
|  | 	return; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | if (!isset($account_logged) || !$account_logged->isLoaded()) { | ||||||
|  | 	$current_session = getSession('account'); | ||||||
|  | 	if($current_session) { | ||||||
|  | 		$account_logged = new OTS_Account(); | ||||||
|  | 		$account_logged->load($current_session); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | $twoFactorAuth = TwoFactorAuth::getInstance($account_logged); | ||||||
|  | $twig->addGlobal('account_logged', $account_logged); | ||||||
|  |  | ||||||
|  | if (ACTION == 'email-code') { | ||||||
|  | 	if ($step == 'resend') { | ||||||
|  | 		if ($twoFactorAuth->hasRecentEmailCode(15 * 60)) { | ||||||
|  | 			$errors = ['Sorry, one email per 15 minutes']; | ||||||
|  | 		} | ||||||
|  | 		else { | ||||||
|  | 			$twoFactorAuth->resendEmailCode(); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (!empty($errors)) { | ||||||
|  | 			$twig->display('error_box.html.twig',  ['errors' => $errors]); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		$twig->display('account.2fa.email.login.html.twig'); | ||||||
|  | 	} | ||||||
|  | 	else if ($step == 'activate') { | ||||||
|  | 		if (!$twoFactorAuth->hasRecentEmailCode(15 * 60)) { | ||||||
|  | 			$twoFactorAuth->resendEmailCode(); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (isset($_POST['save'])) { | ||||||
|  | 			if (!empty($code)) { | ||||||
|  | 				$twoFactorAuth->setAuthGateway(TwoFactorAuth::TYPE_EMAIL); | ||||||
|  | 				if ($twoFactorAuth->getAuthGateway()->verifyCode($code)) { | ||||||
|  | 					$serverName = configLua('serverName'); | ||||||
|  |  | ||||||
|  | 					$twoFactorAuth->enable(TwoFactorAuth::TYPE_EMAIL); | ||||||
|  | 					$twoFactorAuth->deleteOldCodes(); | ||||||
|  |  | ||||||
|  | 					$twig->display('success.html.twig', [ | ||||||
|  | 						'title' => 'Email Code Authentication Activated', | ||||||
|  | 						'description' => sprintf('You have successfully activated <b>email code authentication</b> for your account. This means an <b>email code</b> will be sent to the email address assigned to your account whenever you try to log in to the %s client or the %s website. In order to log in, you will need to enter the <b>most recent email code</b> you have received.', $serverName, $serverName) | ||||||
|  | 					]); | ||||||
|  |  | ||||||
|  | 					return; | ||||||
|  | 				} | ||||||
|  | 				else { | ||||||
|  | 					$errors[] = 'Invalid email code!'; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (!empty($errors)) { | ||||||
|  | 			$twig->display('error_box.html.twig', ['errors' => $errors]); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		$twig->display('account.2fa.email_code.html.twig', ['wrongCode' => count($errors) > 0]); | ||||||
|  | 	} | ||||||
|  | 	else if ($step == 'deactivate') { | ||||||
|  | 		//if (!$twoFactorAuth->hasRecentEmailCode(15 * 60)) { | ||||||
|  | 		//	$twoFactorAuth->resendEmailCode(); | ||||||
|  | 		//} | ||||||
|  |  | ||||||
|  | 		/*if (isset($_POST['save'])) { | ||||||
|  | 			if (!empty($code)) { | ||||||
|  | 				if ($twoFactorAuth->getAuthGateway()->verifyCode($code)) { | ||||||
|  | */ | ||||||
|  | 					$twoFactorAuth->disable(); | ||||||
|  | 					$twoFactorAuth->deleteOldCodes(); | ||||||
|  |  | ||||||
|  | 					$twig->display('success.html.twig', | ||||||
|  | 						[ | ||||||
|  | 							'title' => 'Email Code Authentication Deactivated', | ||||||
|  | 							'description' => 'You have successfully <b>deactivated</b> the <b>Email Code Authentication</b> for your account.' | ||||||
|  | 						] | ||||||
|  | 					); | ||||||
|  | 					/* | ||||||
|  | 				} | ||||||
|  | 				else { | ||||||
|  | 					$errors[] = 'Invalid email code!'; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		}*/ | ||||||
|  |  | ||||||
|  | 		/* | ||||||
|  | 		if (!empty($errors)) { | ||||||
|  | 			$twig->display('error_box.html.twig', ['errors' => $errors]); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		$twig->display('account.2fa.email.deactivate.html.twig', ['wrongCode' => count($errors) > 0]); | ||||||
|  | 		*/ | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -17,6 +17,10 @@ if(!$logged) | |||||||
| 	if(!empty($errors)) | 	if(!empty($errors)) | ||||||
| 		$twig->display('error_box.html.twig', array('errors' => $errors)); | 		$twig->display('error_box.html.twig', array('errors' => $errors)); | ||||||
|  |  | ||||||
|  | 	if (defined('HIDE_LOGIN_BOX') && HIDE_LOGIN_BOX) { | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	$twig->display('account.login.html.twig', array( | 	$twig->display('account.login.html.twig', array( | ||||||
| 		'redirect' => $_REQUEST['redirect'] ?? null, | 		'redirect' => $_REQUEST['redirect'] ?? null, | ||||||
| 		'account' => USE_ACCOUNT_NAME ? 'Name' : 'Number', | 		'account' => USE_ACCOUNT_NAME ? 'Name' : 'Number', | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| use MyAAC\RateLimit; | use MyAAC\RateLimit; | ||||||
|  | use MyAAC\TwoFactorAuth\TwoFactorAuth; | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
|  |  | ||||||
| @@ -50,8 +51,14 @@ if(!empty($login_account) && !empty($login_password)) | |||||||
| 		if (setting('core.account_mail_verify') && (int)$account_logged->getCustomField('email_verified') !== 1) { | 		if (setting('core.account_mail_verify') && (int)$account_logged->getCustomField('email_verified') !== 1) { | ||||||
| 			$errors[] = 'Your account is not verified. Please verify your email address. If the message is not coming check the SPAM folder in your E-Mail client.'; | 			$errors[] = 'Your account is not verified. Please verify your email address. If the message is not coming check the SPAM folder in your E-Mail client.'; | ||||||
| 		} else { | 		} else { | ||||||
| 			session_regenerate_id(); |  | ||||||
| 			setSession('account', $account_logged->getId()); | 			setSession('account', $account_logged->getId()); | ||||||
|  |  | ||||||
|  | 			$twoFactorAuth = TwoFactorAuth::getInstance($account_logged); | ||||||
|  | 			if (!$twoFactorAuth->process($login_account, $login_password, $remember_me, $_POST['auth-code'] ?? '')) { | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			session_regenerate_id(); | ||||||
| 			setSession('password', encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $login_password)); | 			setSession('password', encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $login_password)); | ||||||
| 			if($remember_me) { | 			if($remember_me) { | ||||||
| 				setSession('remember_me', true); | 				setSession('remember_me', true); | ||||||
|   | |||||||
| @@ -8,6 +8,9 @@ | |||||||
|  * @copyright 2019 MyAAC |  * @copyright 2019 MyAAC | ||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | use MyAAC\TwoFactorAuth\TwoFactorAuth; | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
|  |  | ||||||
| $title = 'Account Management'; | $title = 'Account Management'; | ||||||
| @@ -111,6 +114,8 @@ $twig->display('account.management.html.twig', array( | |||||||
| 	'account_registered' => $account_registered, | 	'account_registered' => $account_registered, | ||||||
| 	'account_rlname' => $account_rlname, | 	'account_rlname' => $account_rlname, | ||||||
| 	'account_location' => $account_location, | 	'account_location' => $account_location, | ||||||
|  | 	'twoFactorViews' => TwoFactorAuth::getInstance($account_logged)->getAccountManageViews(), | ||||||
|  |  | ||||||
| 	'actions' => $actions, | 	'actions' => $actions, | ||||||
| 	'players' => $account_players | 	'players' => $account_players, | ||||||
| )); | )); | ||||||
|   | |||||||
| @@ -94,19 +94,30 @@ $dispatcher = FastRoute\cachedDispatcher(function (FastRoute\RouteCollector $r) | |||||||
| 		$routesFinal[] = ['*', $page, '__database__/' . $page, 100]; | 		$routesFinal[] = ['*', $page, '__database__/' . $page, 100]; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	$routes = require SYSTEM . 'routes.php'; | ||||||
| 	Plugins::clearWarnings(); | 	Plugins::clearWarnings(); | ||||||
| 	foreach (Plugins::getRoutes() as $route) { |  | ||||||
| 		$routesFinal[] = [$route[0], $route[1], $route[2], $route[3] ?? 1000]; | 	foreach (Plugins::getRoutes() as $pluginRoute) { | ||||||
|  |  | ||||||
|  | 		$routesFinal[] = [$pluginRoute[0], $pluginRoute[1], $pluginRoute[2], $pluginRoute[3] ?? 1000]; | ||||||
|  |  | ||||||
|  | 		// Possibility to override routes with plugins pages, like characters.php | ||||||
|  | 		foreach ($routes as &$route) { | ||||||
|  | 			if (str_contains($pluginRoute[2], 'pages/' . $route[2])) { | ||||||
|  | 				$route[2] = $pluginRoute[2]; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| /* | /* | ||||||
| 		echo '<pre>'; | 		echo '<pre>'; | ||||||
| 		var_dump($route[1], $route[3], $route[2]); | 		var_dump($pluginRoute[1], $pluginRoute[3], $pluginRoute[2]); | ||||||
| 		echo '/<pre>'; | 		echo '/<pre>'; | ||||||
| */ | */ | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	$routes = require SYSTEM . 'routes.php'; |  | ||||||
| 	foreach ($routes as $route) { | 	foreach ($routes as $route) { | ||||||
| 		if (!str_contains($route[2], '__redirect__') && !str_contains($route[2], '__database__')) { | 		if (!str_contains($route[2], '__redirect__') && !str_contains($route[2], '__database__') | ||||||
|  | 			&& !str_contains($route[2], 'plugins/') | ||||||
|  | 		) { | ||||||
| 			if (!is_file(BASE . 'system/pages/' . $route[2])) { | 			if (!is_file(BASE . 'system/pages/' . $route[2])) { | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								system/src/Models/AccountEMailCode.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								system/src/Models/AccountEMailCode.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace MyAAC\Models; | ||||||
|  | use Illuminate\Database\Eloquent\Model; | ||||||
|  |  | ||||||
|  | class AccountEMailCode extends Model { | ||||||
|  |  | ||||||
|  | 	protected $table = TABLE_PREFIX . 'account_email_codes'; | ||||||
|  |  | ||||||
|  | 	public $timestamps = false; | ||||||
|  |  | ||||||
|  | 	protected $fillable = ['account_id', 'code', 'created_at']; | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										13
									
								
								system/src/TwoFactorAuth/Gateway/AppAuthGateway.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								system/src/TwoFactorAuth/Gateway/AppAuthGateway.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace MyAAC\TwoFactorAuth\Gateway; | ||||||
|  |  | ||||||
|  | use MyAAC\TwoFactorAuth\Interface\AuthGatewayInterface; | ||||||
|  |  | ||||||
|  | class AppAuthGateway extends BaseAuthGateway implements AuthGatewayInterface | ||||||
|  | { | ||||||
|  | 	public function verifyCode(string $code): bool | ||||||
|  | 	{ | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										12
									
								
								system/src/TwoFactorAuth/Gateway/BaseAuthGateway.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								system/src/TwoFactorAuth/Gateway/BaseAuthGateway.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace MyAAC\TwoFactorAuth\Gateway; | ||||||
|  |  | ||||||
|  | class BaseAuthGateway | ||||||
|  | { | ||||||
|  | 	protected \OTS_Account $account; | ||||||
|  |  | ||||||
|  | 	public function __construct(\OTS_Account $account) { | ||||||
|  | 		$this->account = $account; | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								system/src/TwoFactorAuth/Gateway/EmailAuthGateway.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								system/src/TwoFactorAuth/Gateway/EmailAuthGateway.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace MyAAC\TwoFactorAuth\Gateway; | ||||||
|  |  | ||||||
|  | use MyAAC\Models\AccountEMailCode; | ||||||
|  | use MyAAC\TwoFactorAuth\Interface\AuthGatewayInterface; | ||||||
|  | use MyAAC\TwoFactorAuth\TwoFactorAuth; | ||||||
|  |  | ||||||
|  | class EmailAuthGateway extends BaseAuthGateway implements AuthGatewayInterface | ||||||
|  | { | ||||||
|  | 	public function verifyCode(string $code): bool | ||||||
|  | 	{ | ||||||
|  | 		return AccountEMailCode::where('account_id', '=', $this->account->getId())->where('code', $code)->where('created_at', '>', time() - TwoFactorAuth::EMAIL_CODE_VALID_UNTIL)->first() !== null; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| @@ -0,0 +1,9 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace MyAAC\TwoFactorAuth\Interface; | ||||||
|  |  | ||||||
|  | interface AuthGatewayInterface | ||||||
|  | { | ||||||
|  | 	public function __construct(\OTS_Account $account); | ||||||
|  | 	public function verifyCode(string $code): bool; | ||||||
|  | } | ||||||
							
								
								
									
										183
									
								
								system/src/TwoFactorAuth/TwoFactorAuth.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								system/src/TwoFactorAuth/TwoFactorAuth.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,183 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace MyAAC\TwoFactorAuth; | ||||||
|  |  | ||||||
|  | use MyAAC\Models\AccountEMailCode; | ||||||
|  | use MyAAC\TwoFactorAuth\Gateway\AppAuthGateway; | ||||||
|  | use MyAAC\TwoFactorAuth\Gateway\EmailAuthGateway; | ||||||
|  |  | ||||||
|  | class TwoFactorAuth | ||||||
|  | { | ||||||
|  | 	const TYPE_NONE = 0; | ||||||
|  | 	const TYPE_EMAIL = 1; | ||||||
|  | 	const TYPE_APP = 2; | ||||||
|  | 	// maybe later | ||||||
|  | 	//const TYPE_SMS = 3; | ||||||
|  |  | ||||||
|  | 	const EMAIL_CODE_VALID_UNTIL = 24 * 60 * 60; | ||||||
|  |  | ||||||
|  | 	private static self $instance; | ||||||
|  |  | ||||||
|  | 	private \OTS_Account $account; | ||||||
|  | 	private int $authType; | ||||||
|  | 	private EmailAuthGateway|AppAuthGateway $authGateway; | ||||||
|  |  | ||||||
|  | 	public function __construct(\OTS_Account|int $account) { | ||||||
|  | 		if (is_int($account)) { | ||||||
|  | 			$this->account = new \OTS_Account(); | ||||||
|  | 			$this->account->load($account); | ||||||
|  | 		} | ||||||
|  | 		else { | ||||||
|  | 			$this->account = $account; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		$this->authType = (int)$this->account->getCustomField('2fa_type'); | ||||||
|  | 		$this->setAuthGateway($this->authType); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public static function getInstance($account = null): self | ||||||
|  | 	{ | ||||||
|  | 		if (!isset(self::$instance)) { | ||||||
|  | 			self::$instance = new self($account); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return self::$instance; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public function process($login_account, $login_password, $remember_me, $code): bool | ||||||
|  | 	{ | ||||||
|  | 		global $twig; | ||||||
|  |  | ||||||
|  | 		if (!$this->isActive()) { | ||||||
|  | 			return true; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (empty($code)) { | ||||||
|  | 			if ($this->authType == self::TYPE_EMAIL) { | ||||||
|  | 				if (!$this->hasRecentEmailCode(15 * 60)) { | ||||||
|  | 					$this->resendEmailCode(); | ||||||
|  | 					//success('Resent email.'); | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				define('HIDE_LOGIN_BOX', true); | ||||||
|  | 				$twig->display('account.2fa.email.login.html.twig', [ | ||||||
|  | 					'account_login' => $login_account, | ||||||
|  | 					'password_login' => $login_password, | ||||||
|  | 					'remember_me' => $remember_me, | ||||||
|  | 				]); | ||||||
|  | 			} | ||||||
|  | 			else { | ||||||
|  | 				echo 'Two Factor App Auth'; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if ($this->getAuthGateway()->verifyCode($code)) { | ||||||
|  | 			if ($this->authType === self::TYPE_EMAIL) { | ||||||
|  | 				$this->deleteOldCodes(); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			return true; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (setting('core.mail_enabled')) { | ||||||
|  | 			$mailBody = $twig->render('mail.account.2fa.email-code.wrong-attempt.html.twig'); | ||||||
|  |  | ||||||
|  | 			if (!_mail($this->account->getEMail(), configLua('serverName') . ' - Failed Two-Factor Authentication Attempt', $mailBody)) { | ||||||
|  | 				error('An error occurred while sending email. For Admin: More info can be found in system/logs/mailer-error.log'); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		define('HIDE_LOGIN_BOX', true); | ||||||
|  |  | ||||||
|  | 		$errors[] = 'Invalid email code!'; | ||||||
|  | 		$twig->display('error_box.html.twig', ['errors' => $errors]); | ||||||
|  |  | ||||||
|  | 		$twig->display('account.2fa.email.login.html.twig', | ||||||
|  | 			[ | ||||||
|  | 				'account_login' => $login_account, | ||||||
|  | 				'password_login' => $login_password, | ||||||
|  | 				'remember_me' => $remember_me, | ||||||
|  |  | ||||||
|  | 				'wrongCode' => true, | ||||||
|  | 			]); | ||||||
|  |  | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public function setAuthGateway(int $authType): void | ||||||
|  | 	{ | ||||||
|  | 		if ($authType === self::TYPE_EMAIL) { | ||||||
|  | 			$this->authGateway = new EmailAuthGateway($this->account); | ||||||
|  | 		} | ||||||
|  | 		else if ($authType === self::TYPE_APP) { | ||||||
|  | 			$this->authGateway = new AppAuthGateway($this->account); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public function getAccountManageViews(): array | ||||||
|  | 	{ | ||||||
|  | 		$twoFactorView = 'account.2fa.protected.html.twig'; | ||||||
|  | 		if ($this->authType == self::TYPE_EMAIL) { | ||||||
|  | 			$twoFactorView2 = 'account.2fa.email.activated.html.twig'; | ||||||
|  | 		} | ||||||
|  | 		elseif ($this->authType == self::TYPE_APP) { | ||||||
|  | 			$twoFactorView2 = 'account.2fa.app.activated.html.twig'; | ||||||
|  | 		} | ||||||
|  | 		else { | ||||||
|  | 			$twoFactorView = 'account.2fa.connect.html.twig'; | ||||||
|  | 			$twoFactorView2 = 'account.2fa.email.activate.html.twig'; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return [$twoFactorView, $twoFactorView2]; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public function enable(int $type): void { | ||||||
|  | 		$this->account->setCustomField('2fa_type', $type); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public function disable(): void { | ||||||
|  | 		$this->account->setCustomField('2fa_type', self::TYPE_NONE); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public function isActive(): bool { | ||||||
|  | 		return $this->authType != self::TYPE_NONE; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public function getAuthType(): int { | ||||||
|  | 		return $this->authType; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public function getAuthGateway(): AppAuthGateway|EmailAuthGateway  { | ||||||
|  | 		return $this->authGateway; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public function hasRecentEmailCode($since = self::EMAIL_CODE_VALID_UNTIL): bool { | ||||||
|  | 		return AccountEMailCode::where('account_id', '=', $this->account->getId())->where('created_at', '>', time() - $since)->first() !== null; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public function deleteOldCodes(): void { | ||||||
|  | 		AccountEMailCode::where('account_id', '=', $this->account->getId())->delete(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public function resendEmailCode(): void | ||||||
|  | 	{ | ||||||
|  | 		global $twig; | ||||||
|  |  | ||||||
|  | 		$newCode = generateRandomString(6, true, false, true); | ||||||
|  | 		AccountEMailCode::create([ | ||||||
|  | 			'account_id' => $this->account->getId(), | ||||||
|  | 			'code' => $newCode, | ||||||
|  | 			'created_at' => time(), | ||||||
|  | 		]); | ||||||
|  |  | ||||||
|  | 		$mailBody = $twig->render('mail.account.2fa.email-code.html.twig', [ | ||||||
|  | 			'code' => $newCode, | ||||||
|  | 		]); | ||||||
|  |  | ||||||
|  | 		if (!_mail($this->account->getEMail(), configLua('serverName') . ' - Requested Authentication Email Code', $mailBody)) { | ||||||
|  | 			error('An error occurred while sending email. For Admin: More info can be found in system/logs/mailer-error.log'); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										36
									
								
								system/templates/account.2fa.connect.html.twig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								system/templates/account.2fa.connect.html.twig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | |||||||
|  | <tr> | ||||||
|  | 	<td> | ||||||
|  | 		<div class="TableShadowContainerRightTop"> | ||||||
|  | 			<div class="TableShadowRightTop" style="background-image:url({{ template_path }}/images/global/content/table-shadow-rt.gif);"></div> | ||||||
|  | 		</div> | ||||||
|  | 		<div class="TableContentAndRightShadow" style="background-image:url({{ template_path }}/images/global/content/table-shadow-rm.gif);"> | ||||||
|  | 			<div class="TableContentContainer"> | ||||||
|  | 				<table class="TableContent" width="100%" style="border:1px solid #faf0d7;"> | ||||||
|  | 					<tbody><tr> | ||||||
|  | 						<td class="LabelV"><b>Connect your {{ config.lua.serverName }} account to an authenticator app!</b> | ||||||
|  | 							<div style="float: right; font-size: 1px;"> | ||||||
|  | 								<form action="{{ getLink('account/2fa') }}?action=email-code" method="post" style="margin: 0px; padding: 0px;"> | ||||||
|  | 									{{ csrf() }} | ||||||
|  | 									{% set button_name = 'Request' %} | ||||||
|  | 									{% include('buttons.base.html.twig') %} | ||||||
|  | 								</form> | ||||||
|  | 							</div> | ||||||
|  | 						</td> | ||||||
|  | 					</tr> | ||||||
|  | 					<tr> | ||||||
|  | 						<td> | ||||||
|  | 							<p>As a first step to connect an <b>authenticator app</b> to your account, click on "Request"! An email with a confirmation key will be sent to the email address assigned to your account.</p> | ||||||
|  | 						</td> | ||||||
|  | 					</tr> | ||||||
|  | 					</tbody> | ||||||
|  | 				</table> | ||||||
|  | 			</div> | ||||||
|  | 		</div> | ||||||
|  | 		<div class="TableShadowContainer"> | ||||||
|  | 			<div class="TableBottomShadow" style="background-image:url({{ template_path }}/images/global/content/table-shadow-bm.gif);"> | ||||||
|  | 				<div class="TableBottomLeftShadow" style="background-image:url({{ template_path }}/images/global/content/table-shadow-bl.gif);"></div> | ||||||
|  | 				<div class="TableBottomRightShadow" style="background-image:url({{ template_path }}/images/global/content/table-shadow-br.gif);"></div> | ||||||
|  | 			</div> | ||||||
|  | 		</div> | ||||||
|  | 	</td> | ||||||
|  | </tr> | ||||||
							
								
								
									
										37
									
								
								system/templates/account.2fa.email.activate.html.twig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								system/templates/account.2fa.email.activate.html.twig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | |||||||
|  | <tr> | ||||||
|  | 	<td> | ||||||
|  | 		<div class="TableShadowContainerRightTop"> | ||||||
|  | 			<div class="TableShadowRightTop" style="background-image:url({{ template_path }}/images/global/content/table-shadow-rt.gif);"></div> | ||||||
|  | 		</div> | ||||||
|  | 		<div class="TableContentAndRightShadow" style="background-image:url({{ template_path }}/images/global/content/table-shadow-rm.gif);"> | ||||||
|  | 			<div class="TableContentContainer"> | ||||||
|  | 				<table class="TableContent" width="100%" style="border:1px solid #faf0d7;"> | ||||||
|  | 					<tbody> | ||||||
|  | 					<tr> | ||||||
|  | 						<td class="LabelV"><b>Activate email code authentication for your account!</b> | ||||||
|  | 							<div style="float: right; font-size: 1px;"> | ||||||
|  | 								<form action="{{ getLink('account/2fa') }}?action=email-code&step=activate" method="post" style="margin: 0; padding: 0;"> | ||||||
|  | 									{{ csrf() }} | ||||||
|  | 									{% set button_name = 'Request' %} | ||||||
|  | 									{% include('buttons.base.html.twig') %} | ||||||
|  | 								</form> | ||||||
|  | 							</div> | ||||||
|  | 						</td> | ||||||
|  | 					</tr> | ||||||
|  | 					<tr> | ||||||
|  | 						<td> | ||||||
|  | 							<p>As a first step to activate <b>email code authentication</b> for your account, click on "Request"! An <b>email code</b> will be sent to the email address assigned to your account. You will be asked to enter this <b>email code</b> on the next page within 24 hours.</p> | ||||||
|  | 						</td> | ||||||
|  | 					</tr> | ||||||
|  | 					</tbody> | ||||||
|  | 				</table> | ||||||
|  | 			</div> | ||||||
|  | 		</div> | ||||||
|  | 		<div class="TableShadowContainer"> | ||||||
|  | 			<div class="TableBottomShadow" style="background-image:url({{ template_path }}/images/global/content/table-shadow-bm.gif);"> | ||||||
|  | 				<div class="TableBottomLeftShadow" style="background-image:url({{ template_path }}/images/global/content/table-shadow-bl.gif);"></div> | ||||||
|  | 				<div class="TableBottomRightShadow" style="background-image:url({{ template_path }}/images/global/content/table-shadow-br.gif);"></div> | ||||||
|  | 			</div> | ||||||
|  | 		</div> | ||||||
|  | 	</td> | ||||||
|  | </tr> | ||||||
							
								
								
									
										26
									
								
								system/templates/account.2fa.email.activated.html.twig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								system/templates/account.2fa.email.activated.html.twig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | |||||||
|  | <tr> | ||||||
|  | 	<td> | ||||||
|  | 		<div class="TableContentContainer "> | ||||||
|  | 			<table class="TableContent" width="100%" style="border:1px solid #faf0d7;"> | ||||||
|  | 				<tbody> | ||||||
|  | 				<tr> | ||||||
|  | 					<td> | ||||||
|  | 						<div style="float: right; width: 135px;"> | ||||||
|  | 							<form action="{{ getLink('account/2fa') }}?action=email-code" method="post" style="padding:0;margin:0;"> | ||||||
|  | 								{{ csrf() }} | ||||||
|  | 								<input type="hidden" name="step" value="deactivate"> | ||||||
|  | 								{% set button_name = 'Deactivate' %} | ||||||
|  | 								{{ include('buttons.base.html.twig') }} | ||||||
|  | 							</form> | ||||||
|  | 						</div> | ||||||
|  | 						<b>Two-Factor Email Code Authentication <span style="color: green">Activated</span>!</b> | ||||||
|  | 						<p>To deactivate <b>email code authentication</b>, click on the "Deactivate" button.</p> | ||||||
|  | 						<!--p>You will have to confirm the deactivation by entering an <b>email code</b> which will be sent | ||||||
|  | 							to the email address assigned to your account.</p--> | ||||||
|  | 					</td> | ||||||
|  | 				</tr> | ||||||
|  | 				</tbody> | ||||||
|  | 			</table> | ||||||
|  | 		</div> | ||||||
|  | 	</td> | ||||||
|  | </tr> | ||||||
							
								
								
									
										109
									
								
								system/templates/account.2fa.email.deactivate.html.twig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								system/templates/account.2fa.email.deactivate.html.twig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,109 @@ | |||||||
|  | {% set title = 'Deactivate Email Code Authentication' %} | ||||||
|  | {% set content %} | ||||||
|  | 	<table style="width:100%;"> | ||||||
|  | 		<tbody> | ||||||
|  | 		<tr> | ||||||
|  | 			<td> | ||||||
|  | 				<div class="TableContentContainer "> | ||||||
|  | 					<table class="TableContent" width="100%" style="border:1px solid #faf0d7;"> | ||||||
|  | 						<tbody> | ||||||
|  | 						<tr> | ||||||
|  | 							<td>To deactivate <b>two-factor email code authentication</b> for your account, enter the | ||||||
|  | 								received <b>email code</b> below. Note, however, that <b>email code authentication</b> | ||||||
|  | 								is an important security feature which helps to prevent any unauthorised access to your | ||||||
|  | 								Tibia account. | ||||||
|  | 							</td> | ||||||
|  | 						</tr> | ||||||
|  | 						</tbody> | ||||||
|  | 					</table> | ||||||
|  | 				</div> | ||||||
|  | 			</td> | ||||||
|  | 		</tr> | ||||||
|  | 		<tr> | ||||||
|  | 			<td> | ||||||
|  | 				<div class="TableContentContainer"> | ||||||
|  | 					<table class="TableContent" width="100%" style="border:1px solid #faf0d7;"> | ||||||
|  | 						<tbody> | ||||||
|  | 						<tr> | ||||||
|  | 							<td> | ||||||
|  | 								<div style="float: right;"> | ||||||
|  | 									<form | ||||||
|  | 										action="{{ getLink('account/2fa') }}?action=email-code&step=resend" | ||||||
|  | 										method="post" | ||||||
|  | 										style="padding:0;margin:0;" | ||||||
|  | 									> | ||||||
|  | 										{{ csrf() }} | ||||||
|  |  | ||||||
|  | 										{% set button_name = 'Resend Email Code' %} | ||||||
|  | 										{{ include('buttons.base.html.twig') }} | ||||||
|  | 									</form> | ||||||
|  | 								</div> | ||||||
|  | 								An <b>email code</b> has already been sent to the email address assigned to your | ||||||
|  | 								account. | ||||||
|  | 								Please check your email account's spam/junk filter and make sure that your mailbox is | ||||||
|  | 								not | ||||||
|  | 								full.<br>In case you need a new email code, you can request one by clicking on "Resend | ||||||
|  | 								Email | ||||||
|  | 								Code". | ||||||
|  | 							</td> | ||||||
|  | 						</tr> | ||||||
|  | 						</tbody> | ||||||
|  | 					</table> | ||||||
|  | 				</div> | ||||||
|  | 			</td> | ||||||
|  | 		</tr> | ||||||
|  | 		<tr> | ||||||
|  | 			<td> | ||||||
|  | 				<div class="TableContentContainer"> | ||||||
|  | 					<table class="TableContent" width="100%" style="border:1px solid #faf0d7;"> | ||||||
|  | 						<tbody> | ||||||
|  | 						<tr> | ||||||
|  | 							<td>To complete the deactivation of <b>email code authentication</b>, please enter the <b>email | ||||||
|  | 									code</b> you received at the email address assigned to your account. | ||||||
|  | 								<div style="margin-top: 15px; margin-bottom: 15px;"> | ||||||
|  | 									<div class="LabelV150 {{ wrongCode ? 'red' : '' }}" style="float:left;"><label | ||||||
|  | 											for="email-code">Email Code:</label></div> | ||||||
|  | 									<input form="form-code" id="auth-code" name="email-code" maxlength="15" | ||||||
|  | 										   autocomplete="off"> | ||||||
|  | 									{% if wrongCode %} | ||||||
|  | 										<br/> | ||||||
|  | 										<div class="LabelV150" style="float:left;">  </div> | ||||||
|  | 										<div class="FormFieldError">Invalid email code!</div> | ||||||
|  | 									{% endif %} | ||||||
|  | 								</div> | ||||||
|  | 							</td> | ||||||
|  | 						</tr> | ||||||
|  | 						</tbody> | ||||||
|  | 					</table> | ||||||
|  | 				</div> | ||||||
|  | 			</td> | ||||||
|  | 		</tr> | ||||||
|  | 		</tbody> | ||||||
|  | 	</table> | ||||||
|  | {% endset %} | ||||||
|  | {% include 'tables.headline.html.twig' %} | ||||||
|  | <table style="width: 100%;"> | ||||||
|  | 	<tbody> | ||||||
|  | 	<tr align="center" valign="top"> | ||||||
|  | 		<td> | ||||||
|  | 			<form id="form-code" method="post" action="{{ getLink('account/2fa') }}?action=email-code"> | ||||||
|  | 				{{ csrf() }} | ||||||
|  |  | ||||||
|  | 				<input type="hidden" name="step" value="deactivate"> | ||||||
|  | 				<input type="hidden" name="save" value="1"> | ||||||
|  |  | ||||||
|  | 				{% set button_name = 'Continue' %} | ||||||
|  | 				{% set button_color = 'green' %} | ||||||
|  | 				{{ include('buttons.submit.html.twig') }} | ||||||
|  | 			</form> | ||||||
|  | 		</td> | ||||||
|  | 		<td> | ||||||
|  | 			<form action="{{ getLink('account/manage') }}" method="post" style="padding:0;margin:0;"> | ||||||
|  | 				{{ csrf() }} | ||||||
|  | 				{% set button_color = 'blue' %} | ||||||
|  | 				{{ include('buttons.back.html.twig') }} | ||||||
|  | 			</form> | ||||||
|  | 		</td> | ||||||
|  | 	</tr> | ||||||
|  | 	</tbody> | ||||||
|  | </table> | ||||||
							
								
								
									
										92
									
								
								system/templates/account.2fa.email.login.html.twig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								system/templates/account.2fa.email.login.html.twig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | |||||||
|  | {% set title = 'Enter Email Code' %} | ||||||
|  | {% set content %} | ||||||
|  | <table style="width:100%;"> | ||||||
|  | 	<tbody> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> | ||||||
|  | 			<div class="TableContentContainer"> | ||||||
|  | 				<table class="TableContent" width="100%" style="border:1px solid #faf0d7;"> | ||||||
|  | 					<tbody> | ||||||
|  | 					<tr> | ||||||
|  | 						<td> | ||||||
|  | 							<div style="float: right;"> | ||||||
|  | 								<form | ||||||
|  | 										action="{{ getLink('account/2fa') }}?action=email-code&step=resend" | ||||||
|  | 										method="post" | ||||||
|  | 										style="padding:0;margin:0;" | ||||||
|  | 								> | ||||||
|  | 									{{ csrf() }} | ||||||
|  |  | ||||||
|  | 									{% set button_name = 'Resend Email Code' %} | ||||||
|  | 									{{ include('buttons.base.html.twig') }} | ||||||
|  | 								</form> | ||||||
|  | 							</div> | ||||||
|  | 							An <b>email code</b> has already been sent to the email address assigned to your account. | ||||||
|  | 							Please check your email account's spam/junk filter and make sure that your mailbox is not | ||||||
|  | 							full.<br>In case you need a new email code, you can request one by clicking on "Resend Email | ||||||
|  | 							Code". | ||||||
|  | 						</td> | ||||||
|  | 					</tr> | ||||||
|  | 					</tbody> | ||||||
|  | 				</table> | ||||||
|  | 			</div> | ||||||
|  | 		</td> | ||||||
|  | 	</tr> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> | ||||||
|  | 			<div class="TableContentContainer"> | ||||||
|  | 				<table class="TableContent" width="100%" style="border:1px solid #faf0d7;"> | ||||||
|  | 					<tbody> | ||||||
|  | 					<tr> | ||||||
|  | 						<td><b>Email code authentication is activated for your account.</b><br><br>Please enter the <b>most | ||||||
|  | 								recent email code</b> you have received in order to log in.<br> | ||||||
|  | 							<div style="margin-top: 15px; margin-bottom: 15px;"> | ||||||
|  | 								<div class="LabelV150 {{ wrongCode ? 'red' : '' }}" style="float:left;"><label for="email-code">Email Code:</label></div> | ||||||
|  | 								<input form="form-code" id="auth-code" name="auth-code" maxlength="15" autocomplete="off"> | ||||||
|  | 								{% if wrongCode %} | ||||||
|  | 									<br/> | ||||||
|  | 									<div class="LabelV150" style="float:left;">  </div> | ||||||
|  | 									<div class="FormFieldError">Invalid email code!</div> | ||||||
|  | 								{% endif %} | ||||||
|  | 							</div> | ||||||
|  | 						</td> | ||||||
|  | 					</tr> | ||||||
|  | 					</tbody> | ||||||
|  | 				</table> | ||||||
|  | 			</div> | ||||||
|  | 		</td> | ||||||
|  | 	</tr> | ||||||
|  | 	</tbody> | ||||||
|  | </table> | ||||||
|  | {% endset %} | ||||||
|  | {% include 'tables.headline.html.twig' %} | ||||||
|  | <table style="width: 100%;"> | ||||||
|  | 	<tbody> | ||||||
|  | 	<tr align="center" valign="top"> | ||||||
|  | 		<td> | ||||||
|  | 			<form id="form-code" method="post" action="{{ getLink('account/manage') }}"> | ||||||
|  | 				{{ csrf() }} | ||||||
|  |  | ||||||
|  | 				<input type="hidden" name="account_login" value="{{ account_login ?? '' }}" /> | ||||||
|  | 				<input type="hidden" name="password_login" value="{{ password_login ?? '' }}" /> | ||||||
|  | 				{% if remember_me %} | ||||||
|  | 					<input type="hidden" name="remember_me" value="true" /> | ||||||
|  | 				{% endif %} | ||||||
|  |  | ||||||
|  | 				<input type="hidden" name="step" value="verify"> | ||||||
|  | 				{% set button_name = 'Continue' %} | ||||||
|  | 				{% set button_color = 'green' %} | ||||||
|  | 				{{ include('buttons.submit.html.twig') }} | ||||||
|  | 			</form> | ||||||
|  | 		</td> | ||||||
|  | 		<td> | ||||||
|  | 			<form action="{{ getLink('account/manage') }}" method="post" style="padding:0;margin:0;"> | ||||||
|  | 				{{ csrf() }} | ||||||
|  |  | ||||||
|  | 				{% set button_color = 'blue' %} | ||||||
|  | 				{{ include('buttons.back.html.twig') }} | ||||||
|  | 			</form> | ||||||
|  | 		</td> | ||||||
|  | 	</tr> | ||||||
|  | 	</tbody> | ||||||
|  | </table> | ||||||
							
								
								
									
										110
									
								
								system/templates/account.2fa.email_code.html.twig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								system/templates/account.2fa.email_code.html.twig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | |||||||
|  | {% set title = 'Activate Email Code Authentication' %} | ||||||
|  |  | ||||||
|  | {% set content %} | ||||||
|  | <table style="width:100%;"> | ||||||
|  | 	<tbody> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> | ||||||
|  | 			<div class="TableContentContainer"> | ||||||
|  | 				<table class="TableContent" width="100%" style="border:1px solid #faf0d7;"> | ||||||
|  | 					<tbody> | ||||||
|  | 					<tr> | ||||||
|  | 						<td>Enter the email code below to activate <b>two-factor email code authentication</b>. Note | ||||||
|  | 							that this code is only valid for 24 hours.<br><br> | ||||||
|  | 							<div class="AttentionSign"><img src="{{ template_path }}/images/global/content/attentionsign.gif"></div> | ||||||
|  | 							<b>Note:</b> Once you have email code authentication activated, an <b>email code</b> will be | ||||||
|  | 							sent to the email address assigned to your account whenever you try to log in to the Tibia | ||||||
|  | 							client or the {{ config.lua.serverName }} website. In order to log in, you will need to enter the <b>most recent | ||||||
|  | 								email code</b> you have received. | ||||||
|  | 						</td> | ||||||
|  | 					</tr> | ||||||
|  | 					</tbody> | ||||||
|  | 				</table> | ||||||
|  | 			</div> | ||||||
|  | 		</td> | ||||||
|  | 	</tr> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> | ||||||
|  | 			<div class="TableContentContainer"> | ||||||
|  | 				<table class="TableContent" width="100%" style="border:1px solid #faf0d7;"> | ||||||
|  | 					<tbody> | ||||||
|  | 					<tr> | ||||||
|  | 						<td> | ||||||
|  | 							<div style="float: right;"> | ||||||
|  | 								<form action="{{ getLink('account/2fa') }}?action=email-code" | ||||||
|  | 									method="post" style="padding:0;margin:0;"> | ||||||
|  | 									{{ csrf() }} | ||||||
|  |  | ||||||
|  | 									{% if account_logged is defined %} | ||||||
|  | 										<input type="hidden" name="account_logged" value="{{ account_logged.getId() }}"> | ||||||
|  | 									{% endif %} | ||||||
|  | 									<input type="hidden" name="step" value="resend"> | ||||||
|  |  | ||||||
|  | 									{% set button_name = 'Resend Email Code' %} | ||||||
|  | 									{% include('buttons.base.html.twig') %} | ||||||
|  | 								</form> | ||||||
|  | 							</div> | ||||||
|  | 							An <b>email code</b> has already been sent to the email address assigned to your account. | ||||||
|  | 							Please check your email account's spam/junk filter and make sure that your mailbox is not | ||||||
|  | 							full.<br>In case you need a new email code, you can request one by clicking on "Resend Email | ||||||
|  | 							Code". | ||||||
|  | 						</td> | ||||||
|  | 					</tr> | ||||||
|  | 					</tbody> | ||||||
|  | 				</table> | ||||||
|  | 			</div> | ||||||
|  | 		</td> | ||||||
|  | 	</tr> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> | ||||||
|  | 			<div class="TableContentContainer"> | ||||||
|  | 				<table class="TableContent" width="100%" style="border:1px solid #faf0d7;"> | ||||||
|  | 					<tbody> | ||||||
|  | 					<tr> | ||||||
|  | 						<td>To complete the activation of email code authentication for your Tibia account, please enter | ||||||
|  | 							the email code you received at the email address assigned to your account. | ||||||
|  | 							<div style="margin-top: 15px; margin-bottom: 15px;"> | ||||||
|  | 								<div class="LabelV150 {{ wrongCode ? 'red' : '' }}" style="float:left;">Email Code:</div> | ||||||
|  | 								<input form="confirmActivateForm" name="auth-code" maxlength="6"> | ||||||
|  | 								{% if wrongCode %} | ||||||
|  | 									<br/> | ||||||
|  | 									<div class="LabelV150" style="float:left;">  </div> | ||||||
|  | 									<div class="FormFieldError">Invalid email code!</div> | ||||||
|  | 								{% endif %} | ||||||
|  | 							</div> | ||||||
|  | 						</td> | ||||||
|  | 					</tr> | ||||||
|  | 					</tbody> | ||||||
|  | 				</table> | ||||||
|  | 			</div> | ||||||
|  | 		</td> | ||||||
|  | 	</tr> | ||||||
|  | 	</tbody> | ||||||
|  | </table> | ||||||
|  | {% endset %} | ||||||
|  | {% include 'tables.headline.html.twig' %} | ||||||
|  | <br/> | ||||||
|  | <table style="width: 100%;"> | ||||||
|  | 	<tbody> | ||||||
|  | 	<tr align="center" valign="top"> | ||||||
|  | 		<td> | ||||||
|  | 			<form id="confirmActivateForm" action="{{ getLink('account/2fa') }}?action=email-code" method="post" style="padding:0;margin:0;"> | ||||||
|  | 				{{ csrf() }} | ||||||
|  |  | ||||||
|  | 				<input type="hidden" name="step" value="activate"> | ||||||
|  | 				<input type="hidden" name="save" value="1"> | ||||||
|  |  | ||||||
|  | 				{% set button_color = 'green' %} | ||||||
|  | 				{{ include('buttons.submit.html.twig') }} | ||||||
|  | 			</form> | ||||||
|  | 		</td> | ||||||
|  | 		<td> | ||||||
|  | 			<form action="{{ getLink('account/manage') }}" method="post" style="padding:0;margin:0;"> | ||||||
|  | 				{{ csrf() }} | ||||||
|  | 				{% set button_color = 'blue' %} | ||||||
|  | 				{{ include('buttons.back.html.twig') }} | ||||||
|  | 			</form> | ||||||
|  | 		</td> | ||||||
|  | 	</tr> | ||||||
|  | 	</tbody> | ||||||
|  | </table> | ||||||
							
								
								
									
										12
									
								
								system/templates/account.2fa.main.html.twig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								system/templates/account.2fa.main.html.twig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | {% set title = 'Two-Factor Authentication' %} | ||||||
|  |  | ||||||
|  | {% set content %} | ||||||
|  | <table style="width:100%;"> | ||||||
|  | 	<tbody> | ||||||
|  | 	{{ include(twoFactorViews[0]) }} | ||||||
|  | 	{{ include(twoFactorViews[1]) }} | ||||||
|  | 	</tbody> | ||||||
|  | </table> | ||||||
|  | {% endset %} | ||||||
|  | {% include('tables.headline.html.twig') %} | ||||||
|  | <br/> | ||||||
							
								
								
									
										18
									
								
								system/templates/account.2fa.protected.html.twig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								system/templates/account.2fa.protected.html.twig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | <tr> | ||||||
|  | 	<td> | ||||||
|  | 		<div class="TableContentContainer "> | ||||||
|  | 			<table class="TableContent" width="100%" style="border:1px solid #faf0d7;"> | ||||||
|  | 				<tbody> | ||||||
|  | 				<tr> | ||||||
|  | 					<td> | ||||||
|  | 						<div class="InTableRightButtonContainer"></div> | ||||||
|  | 						<b>Two-Factor Authenticator App</b> | ||||||
|  | 						<p>Your account is currently protected by email code authentication. If you prefer to use a <b>two-factor | ||||||
|  | 								authentication app</b>, you have to "Deactivate" email code authentication first.</p> | ||||||
|  | 					</td> | ||||||
|  | 				</tr> | ||||||
|  | 				</tbody> | ||||||
|  | 			</table> | ||||||
|  | 		</div> | ||||||
|  | 	</td> | ||||||
|  | </tr> | ||||||
| @@ -147,6 +147,9 @@ | |||||||
| 			{% include('buttons.base.html.twig') %} | 			{% include('buttons.base.html.twig') %} | ||||||
| 		</form> | 		</form> | ||||||
| 		<br/> | 		<br/> | ||||||
|  |  | ||||||
|  | 		{{ include('account.2fa.main.html.twig') }} | ||||||
|  |  | ||||||
| 		{{ hook('HOOK_ACCOUNT_MANAGE_BEFORE_ACCOUNT_LOGS') }} | 		{{ hook('HOOK_ACCOUNT_MANAGE_BEFORE_ACCOUNT_LOGS') }} | ||||||
| 		<a name="Account+Logs" ></a> | 		<a name="Account+Logs" ></a> | ||||||
| 		<h2>Account Logs</h2> | 		<h2>Account Logs</h2> | ||||||
|   | |||||||
							
								
								
									
										9
									
								
								system/templates/mail.account.2fa.email-code.html.twig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								system/templates/mail.account.2fa.email-code.html.twig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | Dear {{ config.lua.serverName}} player, | ||||||
|  | <br/><br/> | ||||||
|  | Your account is protected by email code authentication, and you requested a new email code: | ||||||
|  | <br/><br/> | ||||||
|  | <p>{{ code }}</p> | ||||||
|  | <br/> | ||||||
|  | Note that the code is only valid for 24 hours. | ||||||
|  | <br/><br/> | ||||||
|  | Kind Regards, | ||||||
| @@ -0,0 +1,5 @@ | |||||||
|  | Dear {{ config.lua.serverName}} player,<br/> | ||||||
|  | <br/> | ||||||
|  | A <strong>wrong two-factor authentication code</strong> was entered for your {{ config.lua.serverName}} account. If you simply mistyped the code, please try again.<br/> | ||||||
|  | <br/> | ||||||
|  | However, if this was <strong>not you</strong>, someone else may be trying to access your account. Since they already know your password, we strongly recommend that you <strong>change your password immediately</strong>. | ||||||
| @@ -290,6 +290,9 @@ | |||||||
| {% endset %} | {% endset %} | ||||||
| {% include 'tables.headline.html.twig' %} | {% include 'tables.headline.html.twig' %} | ||||||
| <br/> | <br/> | ||||||
|  |  | ||||||
|  | {{ include('account.2fa.main.html.twig') }} | ||||||
|  |  | ||||||
| {{ hook('HOOK_ACCOUNT_MANAGE_BEFORE_ACCOUNT_LOGS') }} | {{ hook('HOOK_ACCOUNT_MANAGE_BEFORE_ACCOUNT_LOGS') }} | ||||||
| <a name="Account+Logs" ></a> | <a name="Account+Logs" ></a> | ||||||
| <div class="TopButtonContainer"> | <div class="TopButtonContainer"> | ||||||
|   | |||||||
| @@ -943,6 +943,14 @@ img { | |||||||
|   font-size: 8pt; |   font-size: 8pt; | ||||||
|   color: red; |   color: red; | ||||||
| } | } | ||||||
|  | .AttentionSign img { | ||||||
|  | 	float: left; | ||||||
|  | 	top: 3px; | ||||||
|  | 	left: 8px; | ||||||
|  | 	width: 15px; | ||||||
|  | 	height: 13px; | ||||||
|  | 	margin-right: 5px; | ||||||
|  | } | ||||||
| .SmallBox { | .SmallBox { | ||||||
|   position: relative; |   position: relative; | ||||||
|   font-size: 1px; |   font-size: 1px; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user