mirror of
https://github.com/slawkens/myaac.git
synced 2025-10-13 17:24:54 +02:00
Feature/resend email verify (#333)
* feat: Resend Email Verify + rework the whole concept, based on new table for email hashes This make it possible that every email will work, not matter if first or last * Nothing important: change variable name * Change message
This commit is contained in:
@@ -27,7 +27,7 @@ if (version_compare(phpversion(), '8.1', '<')) die('PHP version 8.1 or higher is
|
|||||||
|
|
||||||
const MYAAC = true;
|
const MYAAC = true;
|
||||||
const MYAAC_VERSION = '1.8.3-dev';
|
const MYAAC_VERSION = '1.8.3-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'));
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
SET @myaac_database_version = 45;
|
SET @myaac_database_version = 46;
|
||||||
|
|
||||||
CREATE TABLE `myaac_account_actions`
|
CREATE TABLE `myaac_account_actions`
|
||||||
(
|
(
|
||||||
@@ -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_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`
|
CREATE TABLE `myaac_admin_menu`
|
||||||
(
|
(
|
||||||
`id` int NOT NULL AUTO_INCREMENT,
|
`id` int NOT NULL AUTO_INCREMENT,
|
||||||
|
@@ -102,18 +102,13 @@ if(!$db->hasColumn('accounts', 'web_flags')) {
|
|||||||
success($locale['step_database_adding_field'] . ' 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(!$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...');
|
success($locale['step_database_adding_field'] . ' accounts.email_verified...');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$db->hasColumn('accounts', 'email_new')) {
|
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...');
|
success($locale['step_database_adding_field'] . ' accounts.email_new...');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
8
system/migrations/46-account_emails_verify.sql
Normal file
8
system/migrations/46-account_emails_verify.sql
Normal file
@@ -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;
|
24
system/migrations/46.php
Normal file
24
system/migrations/46.php
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @var OTS_DB_MySQL $db
|
||||||
|
*/
|
||||||
|
|
||||||
|
$up = function () use ($db) {
|
||||||
|
if ($db->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');
|
||||||
|
}
|
||||||
|
};
|
@@ -9,6 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use MyAAC\Models\Account;
|
use MyAAC\Models\Account;
|
||||||
|
use MyAAC\Models\AccountEmailVerify;
|
||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
defined('MYAAC') or die('Direct access not allowed!');
|
||||||
|
|
||||||
@@ -20,16 +21,20 @@ if(empty($hash)) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!Account::where('email_hash', $hash)->exists()) {
|
// by default link is valid for 30 days
|
||||||
note("Your email couldn't be verified. Please contact staff to do it manually.");
|
$accountEmailVerify = AccountEmailVerify::where('hash', $hash)->where('sent_at', '>', time() - 30 * 24 * 60 * 60)->first();
|
||||||
|
if(!$accountEmailVerify) {
|
||||||
|
note("Wrong link or link has expired.");
|
||||||
}
|
}
|
||||||
else
|
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) {
|
if ($accountModel) {
|
||||||
$accountModel->email_verified = 1;
|
$accountModel->email_verified = 1;
|
||||||
$accountModel->save();
|
$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 <a href=' . getLink('account/manage') . '>log in</a>.');
|
success('You have now verified your e-mail, this will increase the security of your account. Thank you for doing this. You can now <a href=' . getLink('account/manage') . '>log in</a>.');
|
||||||
|
|
||||||
$account = new OTS_Account();
|
$account = new OTS_Account();
|
||||||
@@ -39,6 +44,6 @@ else
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
error('Link has expired.');
|
error('Your account is already verified.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use MyAAC\CreateCharacter;
|
use MyAAC\CreateCharacter;
|
||||||
|
use MyAAC\Models\AccountEmailVerify;
|
||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
defined('MYAAC') or die('Direct access not allowed!');
|
||||||
$title = 'Create Account';
|
$title = 'Create Account';
|
||||||
@@ -244,7 +245,12 @@ if($save)
|
|||||||
if(setting('core.mail_enabled') && setting('core.account_mail_verify'))
|
if(setting('core.mail_enabled') && setting('core.account_mail_verify'))
|
||||||
{
|
{
|
||||||
$hash = md5(generateRandomString(16, true, true) . $email);
|
$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);
|
$verify_url = getLink('account/confirm-email/' . $hash);
|
||||||
$body_html = $twig->render('mail.account.verify.html.twig', array(
|
$body_html = $twig->render('mail.account.verify.html.twig', array(
|
||||||
|
@@ -48,7 +48,9 @@ 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.';
|
$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.<br/>' .
|
||||||
|
'You can resend the Email here: <a href="' . $link . '">' . $link . '</a>';
|
||||||
} else {
|
} else {
|
||||||
session_regenerate_id();
|
session_regenerate_id();
|
||||||
setSession('account', $account_logged->getId());
|
setSession('account', $account_logged->getId());
|
||||||
|
94
system/pages/account/resend-email-verify.php
Normal file
94
system/pages/account/resend-email-verify.php
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use MyAAC\Models\AccountEmailVerify;
|
||||||
|
|
||||||
|
defined('MYAAC') or die('Direct access not allowed!');
|
||||||
|
|
||||||
|
$title = 'Resend Email';
|
||||||
|
|
||||||
|
$errorWithBackButton = function ($msg) use ($twig) {
|
||||||
|
$errors = [$msg];
|
||||||
|
|
||||||
|
$twig->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 <a href=' . getLink('account/manage') . '>log in</a> 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 = "<p class='error'>An error occurred while sending email (<b>{$email}</b> )! Try again later. For Admin: More info can be found in system/logs/mailer-error.log</p>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$message = "<br />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');
|
||||||
|
}
|
15
system/src/Models/AccountEmailVerify.php
Normal file
15
system/src/Models/AccountEmailVerify.php
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace MyAAC\Models;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class AccountEmailVerify extends Model
|
||||||
|
{
|
||||||
|
|
||||||
|
protected $table = TABLE_PREFIX . 'account_emails_verify';
|
||||||
|
|
||||||
|
public $timestamps = false;
|
||||||
|
|
||||||
|
protected $fillable = ['account_id', 'hash', 'sent_at'];
|
||||||
|
|
||||||
|
}
|
45
system/templates/account.resend-email-verify.html.twig
Normal file
45
system/templates/account.resend-email-verify.html.twig
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
Please enter your account Email address.<br/><br/>
|
||||||
|
{% set title = 'Resend Email' %}
|
||||||
|
{% set background = config('darkborder') %}
|
||||||
|
{% set content %}
|
||||||
|
<table style="width:100%;">
|
||||||
|
<tr>
|
||||||
|
<td class="LabelV" >
|
||||||
|
<span><label for="email">Email Address:</label></span>
|
||||||
|
</td>
|
||||||
|
<td style="width:90%;">
|
||||||
|
<input type="email" form="form" id="email" name="email" size="30" maxlength="50" autofocus/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
{% endset %}
|
||||||
|
{% include 'tables.headline.html.twig' %}
|
||||||
|
<br/>
|
||||||
|
<table style="width:100%;">
|
||||||
|
<tr align="center">
|
||||||
|
<td>
|
||||||
|
<table border="0" cellspacing="0" cellpadding="0">
|
||||||
|
<tr>
|
||||||
|
<td style="border:0;">
|
||||||
|
<form id="form" action="{{ getLink('account/resend-email-verify') }}" method="post">
|
||||||
|
{{ csrf() }}
|
||||||
|
<input type="hidden" name="submit" value="1"/>
|
||||||
|
{{ include('buttons.submit.html.twig') }}
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
<tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<table border="0" cellspacing="0" cellpadding="0">
|
||||||
|
<tr>
|
||||||
|
<td style="border:0;">
|
||||||
|
<form action="{{ getLink('news') }}" method="post">
|
||||||
|
{{ include('buttons.back.html.twig') }}
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
@@ -0,0 +1,7 @@
|
|||||||
|
Hello {{ account }}!<br/>
|
||||||
|
<br/>
|
||||||
|
You requested to resend the verify Email on {{ config.lua.serverName }}!<br/>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
To verify your email address please click the link below:<br/>
|
||||||
|
{{ verify_url|raw }}
|
Reference in New Issue
Block a user