mirror of
https://github.com/slawkens/myaac.git
synced 2026-01-23 14:36:22 +01:00
2fa: first draft
This commit is contained in:
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;
|
||||
}
|
||||
}
|
||||
44
system/src/TwoFactorAuth/Gateway/EmailAuthGateway.php
Normal file
44
system/src/TwoFactorAuth/Gateway/EmailAuthGateway.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?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;
|
||||
}
|
||||
|
||||
public function hasRecentEmailCode(): bool {
|
||||
return AccountEMailCode::where('account_id', '=', $this->account->getId())->where('created_at', '>', time() - TwoFactorAuth::EMAIL_CODE_VALID_UNTIL)->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');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace MyAAC\TwoFactorAuth\Interface;
|
||||
|
||||
interface AuthGatewayInterface
|
||||
{
|
||||
public function __construct(\OTS_Account $account);
|
||||
public function verifyCode(string $code): bool;
|
||||
}
|
||||
63
system/src/TwoFactorAuth/TwoFactorAuth.php
Normal file
63
system/src/TwoFactorAuth/TwoFactorAuth.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace MyAAC\TwoFactorAuth;
|
||||
|
||||
use MyAAC\Models\AccountEMailCode;
|
||||
use MyAAC\TwoFactorAuth\Gateway\AppAuthGateway;
|
||||
use MyAAC\TwoFactorAuth\Gateway\EmailAuthGateway;
|
||||
use MyAAC\TwoFactorAuth\Interface\AuthGatewayInterface;
|
||||
|
||||
class TwoFactorAuth
|
||||
{
|
||||
const TYPE_NONE = 0;
|
||||
const TYPE_EMAIL = 1;
|
||||
const TYPE_APP = 2;
|
||||
|
||||
const EMAIL_CODE_VALID_UNTIL = 24 * 60 * 60;
|
||||
|
||||
private \OTS_Account $account;
|
||||
private int $authType;
|
||||
private EmailAuthGateway|AppAuthGateway $authGateway;
|
||||
|
||||
public function __construct(\OTS_Account $account) {
|
||||
$this->account = $account;
|
||||
|
||||
$this->authType = (int)$this->account->getCustomField('2fa_type');
|
||||
if ($this->authType === self::TYPE_EMAIL) {
|
||||
$this->authGateway = new EmailAuthGateway($account);
|
||||
}
|
||||
else if ($this->authType === self::TYPE_APP) {
|
||||
$this->authGateway = new AppAuthGateway($account);
|
||||
}
|
||||
}
|
||||
|
||||
public function process()
|
||||
{
|
||||
global $twig;
|
||||
|
||||
if ($this->authType == TwoFactorAuth::TYPE_EMAIL) {
|
||||
if (!$this->authGateway->hasRecentEmailCode()) {
|
||||
$this->authGateway->resendEmailCode();
|
||||
success('Resent email.');
|
||||
}
|
||||
|
||||
define('HIDE_LOGIN_BOX', true);
|
||||
$twig->display('account.2fa.email-code.login.html.twig');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user