mirror of
https://github.com/getnamingo/registry.git
synced 2025-07-21 18:16:03 +02:00
Added ability to logout from all other sessions in CP
This commit is contained in:
parent
37b9d0ad9e
commit
276cbb1c0d
5 changed files with 63 additions and 3 deletions
|
@ -13,6 +13,7 @@ use Pinga\Auth\ResetDisabledException;
|
||||||
use Pinga\Auth\TokenExpiredException;
|
use Pinga\Auth\TokenExpiredException;
|
||||||
use Pinga\Auth\TooManyRequestsException;
|
use Pinga\Auth\TooManyRequestsException;
|
||||||
use Pinga\Auth\UserAlreadyExistsException;
|
use Pinga\Auth\UserAlreadyExistsException;
|
||||||
|
use Pinga\Auth\UnknownIdException;
|
||||||
use RobThree\Auth\TwoFactorAuth;
|
use RobThree\Auth\TwoFactorAuth;
|
||||||
use RobThree\Auth\Providers\Qr\BaconQrCodeProvider;
|
use RobThree\Auth\Providers\Qr\BaconQrCodeProvider;
|
||||||
|
|
||||||
|
@ -373,6 +374,21 @@ class Auth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log out user from all other sessions except the current one
|
||||||
|
* @throws \Pinga\Auth\AuthError
|
||||||
|
*/
|
||||||
|
public static function logoutEverywhereElse() {
|
||||||
|
$auth = self::$auth;
|
||||||
|
try {
|
||||||
|
$auth->logOutEverywhereElse();
|
||||||
|
redirect()->route('profile')->with('success', 'Logged out from all other devices');
|
||||||
|
}
|
||||||
|
catch (NotLoggedInException $e) {
|
||||||
|
redirect()->route('login')->with('error', 'You are not logged in');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws \Pinga\Auth\AuthError
|
* @throws \Pinga\Auth\AuthError
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -7,6 +7,7 @@ use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
use Psr\Container\ContainerInterface;
|
use Psr\Container\ContainerInterface;
|
||||||
use RobThree\Auth\TwoFactorAuth;
|
use RobThree\Auth\TwoFactorAuth;
|
||||||
use RobThree\Auth\Providers\Qr\BaconQrCodeProvider;
|
use RobThree\Auth\Providers\Qr\BaconQrCodeProvider;
|
||||||
|
use App\Auth\Auth;
|
||||||
|
|
||||||
class ProfileController extends Controller
|
class ProfileController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -235,4 +236,34 @@ class ProfileController extends Controller
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function logoutEverywhereElse(Request $request, Response $response)
|
||||||
|
{
|
||||||
|
global $container;
|
||||||
|
$db = $container->get('db');
|
||||||
|
|
||||||
|
$currentDateTime = new \DateTime();
|
||||||
|
$currentDate = $currentDateTime->format('Y-m-d H:i:s.v'); // Current timestamp
|
||||||
|
$db->insert(
|
||||||
|
'users_audit',
|
||||||
|
[
|
||||||
|
'user_id' => $_SESSION['auth_user_id'],
|
||||||
|
'user_event' => 'user.logout.everywhere',
|
||||||
|
'user_resource' => 'control.panel',
|
||||||
|
'user_agent' => $_SERVER['HTTP_USER_AGENT'],
|
||||||
|
'user_ip' => get_client_ip(),
|
||||||
|
'user_location' => get_client_location(),
|
||||||
|
'event_time' => $currentDate,
|
||||||
|
'user_data' => json_encode([
|
||||||
|
'remaining_session_id' => session_id(),
|
||||||
|
'logged_out_sessions' => 'All other sessions terminated',
|
||||||
|
'previous_ip' => $_SESSION['previous_ip'] ?? null,
|
||||||
|
'previous_user_agent' => $_SESSION['previous_user_agent'] ?? null,
|
||||||
|
'timestamp' => $currentDate,
|
||||||
|
])
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
Auth::logoutEverywhereElse();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -41,8 +41,8 @@
|
||||||
<!-- Page body -->
|
<!-- Page body -->
|
||||||
<div class="page-body">
|
<div class="page-body">
|
||||||
<div class="container-xl">
|
<div class="container-xl">
|
||||||
<div class="row row-deck row-cards">
|
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
|
{% include 'partials/flash.twig' %}
|
||||||
<div class="row row-cards">
|
<div class="row row-cards">
|
||||||
{% if registrars %}
|
{% if registrars %}
|
||||||
<div class="{% if minimum_data == 'false' %}col-sm-6 col-lg-3{% else %}col-sm-4 col-lg-4{% endif %}">
|
<div class="{% if minimum_data == 'false' %}col-sm-6 col-lg-3{% else %}col-sm-4 col-lg-4{% endif %}">
|
||||||
|
@ -254,7 +254,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{% include 'partials/footer.twig' %}
|
{% include 'partials/footer.twig' %}
|
||||||
</div>
|
</div>
|
||||||
{% if registrars %}
|
{% if registrars %}
|
||||||
|
|
|
@ -38,6 +38,9 @@
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a href="#tabs-webauthn" class="nav-link" data-bs-toggle="tab">WebAuthn</a>
|
<a href="#tabs-webauthn" class="nav-link" data-bs-toggle="tab">WebAuthn</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="#tabs-security" class="nav-link" data-bs-toggle="tab">{{ __('Security') }}</a>
|
||||||
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a href="#tabs-log" class="nav-link" data-bs-toggle="tab">{{ __('Log') }}</a>
|
<a href="#tabs-log" class="nav-link" data-bs-toggle="tab">{{ __('Log') }}</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -203,6 +206,16 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="tab-pane" id="tabs-security">
|
||||||
|
<h3 class="card-title">{{ __('Security') }}</h3>
|
||||||
|
<p>{{ __('If you’ve logged in on multiple devices or browsers and want to ensure your account remains secure, you can log out from all other sessions except this one. This will end access from any other logged-in devices.') }}</p>
|
||||||
|
<form action="{{route('profile.logout.everywhere')}}" name="logoutEverywhere" method="post">
|
||||||
|
{{ csrf.field | raw }}
|
||||||
|
<button type="submit" class="btn btn-danger">
|
||||||
|
{{ __('Log Out from All Devices') }}
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
<div class="tab-pane" id="tabs-log">
|
<div class="tab-pane" id="tabs-log">
|
||||||
<h3 class="card-title">{{ __('User Audit Log') }}</h3>
|
<h3 class="card-title">{{ __('User Audit Log') }}</h3>
|
||||||
<p>{{ __('Track and review all user activities in your account below. Monitor logins, profile changes, and other key actions to ensure security and transparency.') }}</p>
|
<p>{{ __('Track and review all user activities in your account below. Monitor logins, profile changes, and other key actions to ensure security and transparency.') }}</p>
|
||||||
|
|
|
@ -149,6 +149,7 @@ $app->group('', function ($route) {
|
||||||
|
|
||||||
$route->get('/profile', ProfileController::class .':profile')->setName('profile');
|
$route->get('/profile', ProfileController::class .':profile')->setName('profile');
|
||||||
$route->post('/profile/2fa', ProfileController::class .':activate2fa')->setName('activate2fa');
|
$route->post('/profile/2fa', ProfileController::class .':activate2fa')->setName('activate2fa');
|
||||||
|
$route->post('/profile/logout-everywhere', ProfileController::class . ':logoutEverywhereElse')->setName('profile.logout.everywhere');
|
||||||
$route->get('/webauthn/register/challenge', ProfileController::class . ':getRegistrationChallenge')->setName('webauthn.register.challenge');
|
$route->get('/webauthn/register/challenge', ProfileController::class . ':getRegistrationChallenge')->setName('webauthn.register.challenge');
|
||||||
$route->post('/webauthn/register/verify', ProfileController::class . ':verifyRegistration')->setName('webauthn.register.verify');
|
$route->post('/webauthn/register/verify', ProfileController::class . ':verifyRegistration')->setName('webauthn.register.verify');
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue