diff --git a/common.php b/common.php
index 6bb6be85..e26921c5 100644
--- a/common.php
+++ b/common.php
@@ -27,7 +27,7 @@ if (version_compare(phpversion(), '8.1', '<')) die('PHP version 8.1 or higher is
const MYAAC = true;
const MYAAC_VERSION = '1.8.3-dev';
-const DATABASE_VERSION = 45;
+const DATABASE_VERSION = 46;
const TABLE_PREFIX = 'myaac_';
define('START_TIME', microtime(true));
define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX'));
diff --git a/install/includes/schema.sql b/install/includes/schema.sql
index eccaee54..b53ffab2 100644
--- a/install/includes/schema.sql
+++ b/install/includes/schema.sql
@@ -1,4 +1,4 @@
-SET @myaac_database_version = 45;
+SET @myaac_database_version = 46;
CREATE TABLE `myaac_account_actions`
(
@@ -10,6 +10,15 @@ CREATE TABLE `myaac_account_actions`
KEY (`account_id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
+CREATE TABLE `myaac_account_emails_verify`
+(
+ `id` int NOT NULL AUTO_INCREMENT,
+ `account_id` int NOT NULL,
+ `hash` varchar(32) NOT NULL,
+ `sent_at` int NOT NULL DEFAULT 0,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
+
CREATE TABLE `myaac_admin_menu`
(
`id` int NOT NULL AUTO_INCREMENT,
diff --git a/install/tools/5-database.php b/install/tools/5-database.php
index b9ff587f..f97eca11 100644
--- a/install/tools/5-database.php
+++ b/install/tools/5-database.php
@@ -102,18 +102,13 @@ if(!$db->hasColumn('accounts', 'web_flags')) {
success($locale['step_database_adding_field'] . ' accounts.web_flags...');
}
-if(!$db->hasColumn('accounts', 'email_hash')) {
- if(query("ALTER TABLE `accounts` ADD `email_hash` VARCHAR(32) NOT NULL DEFAULT '' AFTER `web_flags`;"))
- success($locale['step_database_adding_field'] . ' accounts.email_hash...');
-}
-
if(!$db->hasColumn('accounts', 'email_verified')) {
- if(query("ALTER TABLE `accounts` ADD `email_verified` TINYINT(1) NOT NULL DEFAULT 0 AFTER `email_hash`;"))
+ if(query("ALTER TABLE `accounts` ADD `email_verified` TINYINT(1) NOT NULL DEFAULT 0 AFTER `web_flags`;"))
success($locale['step_database_adding_field'] . ' accounts.email_verified...');
}
if(!$db->hasColumn('accounts', 'email_new')) {
- if(query("ALTER TABLE `accounts` ADD `email_new` VARCHAR(255) NOT NULL DEFAULT '' AFTER `email_hash`;"))
+ if(query("ALTER TABLE `accounts` ADD `email_new` VARCHAR(255) NOT NULL DEFAULT '' AFTER `email_verified`;"))
success($locale['step_database_adding_field'] . ' accounts.email_new...');
}
diff --git a/system/migrations/46-account_emails_verify.sql b/system/migrations/46-account_emails_verify.sql
new file mode 100644
index 00000000..13d42b16
--- /dev/null
+++ b/system/migrations/46-account_emails_verify.sql
@@ -0,0 +1,8 @@
+CREATE TABLE `myaac_account_emails_verify`
+(
+ `id` int NOT NULL AUTO_INCREMENT,
+ `account_id` int NOT NULL,
+ `hash` varchar(32) NOT NULL,
+ `sent_at` int NOT NULL DEFAULT 0,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
diff --git a/system/migrations/46.php b/system/migrations/46.php
new file mode 100644
index 00000000..452527e5
--- /dev/null
+++ b/system/migrations/46.php
@@ -0,0 +1,24 @@
+hasColumn('accounts', 'email_hash')) {
+ $db->dropColumn('accounts', 'email_hash');
+ }
+
+ if (!$db->hasTable(TABLE_PREFIX . 'account_emails_verify')) {
+ $db->query(file_get_contents(__DIR__ . '/46-account_emails_verify.sql'));
+ }
+};
+
+$down = function () use ($db) {
+ if (!$db->hasColumn('accounts', 'email_hash')) {
+ $db->addColumn('accounts', 'email_hash', "varchar(32) NOT NULL DEFAULT ''");
+ }
+
+ if ($db->hasTable(TABLE_PREFIX . 'account_emails_verify')) {
+ $db->dropTable(TABLE_PREFIX . 'account_emails_verify');
+ }
+};
diff --git a/system/pages/account/confirm-email.php b/system/pages/account/confirm-email.php
index 615dd942..87183a3c 100644
--- a/system/pages/account/confirm-email.php
+++ b/system/pages/account/confirm-email.php
@@ -9,6 +9,7 @@
*/
use MyAAC\Models\Account;
+use MyAAC\Models\AccountEmailVerify;
defined('MYAAC') or die('Direct access not allowed!');
@@ -20,16 +21,20 @@ if(empty($hash)) {
return;
}
-if(!Account::where('email_hash', $hash)->exists()) {
- note("Your email couldn't be verified. Please contact staff to do it manually.");
+// by default link is valid for 30 days
+$accountEmailVerify = AccountEmailVerify::where('hash', $hash)->where('sent_at', '>', time() - 30 * 24 * 60 * 60)->first();
+if(!$accountEmailVerify) {
+ note("Wrong link or link has expired.");
}
else
{
- $accountModel = Account::where('email_hash', $hash)->where('email_verified', 0)->first();
+ $accountModel = Account::where('id', $accountEmailVerify->account_id)->where('email_verified', 0)->first();
if ($accountModel) {
$accountModel->email_verified = 1;
$accountModel->save();
+ AccountEmailVerify::where('account_id', $accountModel->id)->delete();
+
success('You have now verified your e-mail, this will increase the security of your account. Thank you for doing this. You can now log in.');
$account = new OTS_Account();
@@ -39,6 +44,6 @@ else
}
}
else {
- error('Link has expired.');
+ error('Your account is already verified.');
}
}
diff --git a/system/pages/account/create.php b/system/pages/account/create.php
index 7a0d3c56..9ffdf6f7 100644
--- a/system/pages/account/create.php
+++ b/system/pages/account/create.php
@@ -10,6 +10,7 @@
*/
use MyAAC\CreateCharacter;
+use MyAAC\Models\AccountEmailVerify;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Create Account';
@@ -244,7 +245,12 @@ if($save)
if(setting('core.mail_enabled') && setting('core.account_mail_verify'))
{
$hash = md5(generateRandomString(16, true, true) . $email);
- $new_account->setCustomField('email_hash', $hash);
+
+ AccountEmailVerify::create([
+ 'account_id' => $new_account->getId(),
+ 'hash' => $hash,
+ 'sent_at' => time(),
+ ]);
$verify_url = getLink('account/confirm-email/' . $hash);
$body_html = $twig->render('mail.account.verify.html.twig', array(
diff --git a/system/pages/account/login.php b/system/pages/account/login.php
index d6771c91..e18dacf4 100644
--- a/system/pages/account/login.php
+++ b/system/pages/account/login.php
@@ -48,7 +48,9 @@ if(!empty($login_account) && !empty($login_password))
)
{
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.';
+ $link = getLink('account/resend-email-verify');
+ $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.
' .
+ 'You can resend the Email here: ' . $link . '';
} else {
session_regenerate_id();
setSession('account', $account_logged->getId());
diff --git a/system/pages/account/resend-email-verify.php b/system/pages/account/resend-email-verify.php
new file mode 100644
index 00000000..ffccb548
--- /dev/null
+++ b/system/pages/account/resend-email-verify.php
@@ -0,0 +1,94 @@
+display('error_box.html.twig', ['errors' => $errors]);
+ $twig->display('account.back_button.html.twig', [
+ 'action' => getLink('account/resend-email-verify'),
+ ]);
+};
+
+if (!setting('core.mail_enabled') || !setting('core.account_mail_verify')) {
+ $errorWithBackButton('Resending email is not possible on this server.');
+ return;
+}
+
+$showForm = true;
+
+if (isset($_POST['submit']) && $_POST['submit'] == '1') {
+ $email = $_REQUEST['email'];
+
+ if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
+ $errorWithBackButton('Please enter valid Email.');
+ return;
+ }
+
+ $account = new OTS_Account();
+ $account->findByEMail($email);
+ if ($account->isLoaded()) {
+ if ($account->getCustomField('email_verified') == '1') {
+ $errorWithBackButton('This account is already verified! You can log in on the website.');
+ return;
+ }
+
+ $accountEmailVerify = AccountEmailVerify::where('account_id', $account->getId())->orderBy('sent_at', 'DESC')->first();
+ if ($accountEmailVerify && time() - $accountEmailVerify->sent_at < 60) {
+ $errorWithBackButton('Only one Email per minute is allowed. Please try again later.');
+ return;
+ }
+
+ $tmp_account = $email;
+ if (!config('account_login_by_email')) {
+ $tmp_account = (USE_ACCOUNT_NAME ? $account->getName() : $account->getId());
+ }
+
+ $hash = md5(generateRandomString(16, true, true) . $email);
+
+ AccountEmailVerify::create([
+ 'account_id' => $account->getId(),
+ 'hash' => $hash,
+ 'sent_at' => time(),
+ ]);
+
+ $verify_url = getLink('account/confirm-email/' . $hash);
+ $body_html = $twig->render('mail.account.resend-email-verify.html.twig', array(
+ 'account' => $tmp_account,
+ 'verify_url' => generateLink($verify_url, $verify_url, true)
+ ));
+
+ if (_mail($account->getEMail(), configLua('serverName') . ' - Verify Account', $body_html)) {
+ $message = "If account with this email exists - you will become an email with verification link.";
+ $showForm = false;
+ } else {
+ $message = "
An error occurred while sending email ({$email} )! Try again later. For Admin: More info can be found in system/logs/mailer-error.log
";
+ }
+ }
+ else {
+ $message = "
If account with this email exists - you will become an email with verification link.";
+ $showForm = false;
+ }
+
+ $twig->display('success.html.twig', array(
+ 'title' => 'Verify Email Sent',
+ 'description' => $message,
+ ));
+}
+
+//show errors if not empty
+if (!empty($errors)) {
+ $twig->display('error_box.html.twig', ['errors' => $errors]);
+ $twig->display('account.back_button.html.twig', [
+ 'action' => getLink('account/resend-email-verify'),
+ ]);
+}
+
+if ($showForm) {
+ $twig->display('account.resend-email-verify.html.twig');
+}
diff --git a/system/src/Models/AccountEmailVerify.php b/system/src/Models/AccountEmailVerify.php
new file mode 100644
index 00000000..8773750f
--- /dev/null
+++ b/system/src/Models/AccountEmailVerify.php
@@ -0,0 +1,15 @@
+
+{% set title = 'Resend Email' %}
+{% set background = config('darkborder') %}
+{% set content %}
+
+{% endset %}
+{% include 'tables.headline.html.twig' %}
+
+
diff --git a/system/templates/mail.account.resend-email-verify.html.twig b/system/templates/mail.account.resend-email-verify.html.twig
new file mode 100644
index 00000000..75bdab8b
--- /dev/null
+++ b/system/templates/mail.account.resend-email-verify.html.twig
@@ -0,0 +1,7 @@
+Hello {{ account }}!
+
+You requested to resend the verify Email on {{ config.lua.serverName }}!
+
+
+To verify your email address please click the link below:
+{{ verify_url|raw }}