195 lines
5.4 KiB
PHP
195 lines
5.4 KiB
PHP
<?php
|
|
|
|
namespace App\Controllers\Beheer;
|
|
|
|
use App\Controllers\BaseController;
|
|
use CodeIgniter\HTTP\ResponseInterface;
|
|
use App\Libraries\TwoFactorAuth;
|
|
|
|
/**
|
|
* Two-Factor Authentication Settings Controller
|
|
* Allows users to manage their 2FA settings
|
|
*/
|
|
class TwoFactorController extends BaseController
|
|
{
|
|
protected TwoFactorAuth $twoFactorAuth;
|
|
|
|
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
|
|
{
|
|
parent::initController($request, $response, $logger);
|
|
|
|
// Ensure user is authenticated
|
|
if (!defined('AUTHENTICATED') || AUTHENTICATED === false) {
|
|
header('Location: ' . site_url('login'));
|
|
exit;
|
|
}
|
|
|
|
$this->twoFactorAuth = new TwoFactorAuth();
|
|
}
|
|
|
|
/**
|
|
* Show 2FA settings page
|
|
*/
|
|
public function index(): string
|
|
{
|
|
$data = [
|
|
'user' => $this->user,
|
|
'version' => $this->version
|
|
];
|
|
|
|
return view('pages/beheer/twofactor/settings_view', $data);
|
|
}
|
|
|
|
/**
|
|
* Enable 2FA for the user
|
|
* POST parameters:
|
|
* - method: 'email' or 'authenticator'
|
|
*/
|
|
public function enable(): ResponseInterface
|
|
{
|
|
$method = $this->cleanInput('method');
|
|
|
|
if (!in_array($method, ['email', 'authenticator'])) {
|
|
return $this->json(['success' => false, 'message' => 'Ongeldige methode']);
|
|
}
|
|
|
|
$secret = null;
|
|
$qrCodeUrl = null;
|
|
|
|
// If authenticator method, generate secret
|
|
if ($method === 'authenticator') {
|
|
$secret = $this->twoFactorAuth->generateSecret();
|
|
$qrCodeUrl = $this->twoFactorAuth->getQRCodeUrl(
|
|
$secret,
|
|
$this->user->username,
|
|
'DBOIS'
|
|
);
|
|
}
|
|
|
|
// Update user record
|
|
\User::whereId($this->user->id)->update([
|
|
'two_factor_enabled' => 'T',
|
|
'two_factor_method' => $method,
|
|
'two_factor_secret' => $secret
|
|
]);
|
|
|
|
$response = [
|
|
'success' => true,
|
|
'message' => 'Tweefactorauthenticatie ingeschakeld',
|
|
'method' => $method
|
|
];
|
|
|
|
if ($method === 'authenticator') {
|
|
$response['secret'] = $secret;
|
|
$response['qrCodeUrl'] = $qrCodeUrl;
|
|
}
|
|
|
|
return $this->json($response);
|
|
}
|
|
|
|
/**
|
|
* Verify authenticator setup
|
|
* POST parameters:
|
|
* - code: The 6-digit code from Google Authenticator
|
|
*/
|
|
public function verifySetup(): ResponseInterface
|
|
{
|
|
$code = $this->cleanInput('code');
|
|
|
|
if (!$this->user->two_factor_secret) {
|
|
return $this->json(['success' => false, 'message' => 'Geen geheim gevonden']);
|
|
}
|
|
|
|
$isValid = $this->twoFactorAuth->verifyCode($this->user->two_factor_secret, $code);
|
|
|
|
if ($isValid) {
|
|
return $this->json(['success' => true, 'message' => 'Code geverifieerd']);
|
|
} else {
|
|
return $this->json(['success' => false, 'message' => 'Ongeldige code']);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Disable 2FA for the user
|
|
*/
|
|
public function disable(): ResponseInterface
|
|
{
|
|
\User::whereId($this->user->id)->update([
|
|
'two_factor_enabled' => 'F',
|
|
'two_factor_method' => null,
|
|
'two_factor_secret' => null
|
|
]);
|
|
|
|
// Clean up any existing OTP codes
|
|
\UserOtp::where('user_id', $this->user->id)->delete();
|
|
|
|
return $this->json([
|
|
'success' => true,
|
|
'message' => 'Tweefactorauthenticatie uitgeschakeld'
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Change 2FA method
|
|
* POST parameters:
|
|
* - method: 'email' or 'authenticator'
|
|
*/
|
|
public function changeMethod(): ResponseInterface
|
|
{
|
|
$method = $this->cleanInput('method');
|
|
|
|
if (!in_array($method, ['email', 'authenticator'])) {
|
|
return $this->json(['success' => false, 'message' => 'Ongeldige methode']);
|
|
}
|
|
|
|
// If user is not enabled for 2FA, they should use enable endpoint
|
|
if ($this->user->two_factor_enabled !== 'T') {
|
|
return $this->json(['success' => false, 'message' => '2FA is niet ingeschakeld']);
|
|
}
|
|
|
|
$secret = null;
|
|
$qrCodeUrl = null;
|
|
|
|
// If switching to authenticator, generate new secret
|
|
if ($method === 'authenticator') {
|
|
$secret = $this->twoFactorAuth->generateSecret();
|
|
$qrCodeUrl = $this->twoFactorAuth->getQRCodeUrl(
|
|
$secret,
|
|
$this->user->username,
|
|
'DBOIS'
|
|
);
|
|
}
|
|
|
|
\User::whereId($this->user->id)->update([
|
|
'two_factor_method' => $method,
|
|
'two_factor_secret' => $secret
|
|
]);
|
|
|
|
$response = [
|
|
'success' => true,
|
|
'message' => '2FA methode gewijzigd',
|
|
'method' => $method
|
|
];
|
|
|
|
if ($method === 'authenticator') {
|
|
$response['secret'] = $secret;
|
|
$response['qrCodeUrl'] = $qrCodeUrl;
|
|
}
|
|
|
|
return $this->json($response);
|
|
}
|
|
|
|
/**
|
|
* Get current 2FA status
|
|
*/
|
|
public function status(): ResponseInterface
|
|
{
|
|
$response = [
|
|
'enabled' => $this->user->two_factor_enabled === 'T',
|
|
'method' => $this->user->two_factor_method
|
|
];
|
|
|
|
return $this->json($response);
|
|
}
|
|
}
|