mirror of
https://github.com/projectsend/projectsend.git
synced 2026-09-16 16:45:07 +00:00
6e47d76ba6
Client file sharing, rebuilt from the ground up: a private area per client, resumable uploads, folders, groups and categories, sharing with expiry dates and download limits, comments, file versions, an activity log, a REST API, and sixteen languages. This repository begins here. ProjectSend 2 was developed privately, and that development history is not published — the previous generation remains available, with its own history, at projectsend/legacy. Free software under the GNU General Public License v2, or (at your option) any later version.
69 lines
2.5 KiB
PHP
69 lines
2.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Modules\Identity\TwoFactor;
|
|
|
|
use App\Models\User;
|
|
use App\Modules\Audit\Action;
|
|
use App\Modules\Audit\ActivityLogger;
|
|
use App\Modules\Identity\Notifications\TwoFactorResetNotification;
|
|
use App\Modules\Platform\Settings\Setting;
|
|
use App\Modules\Platform\Settings\Settings;
|
|
|
|
/**
|
|
* An administrator removing somebody else's second factor.
|
|
*
|
|
* This exists because of an asymmetry: enrolling in two-factor
|
|
* authentication is something only you can do, but *losing* it — a wiped
|
|
* phone, a reinstalled authenticator app, recovery codes in a drawer at
|
|
* the old office — locks you out of an account nobody else can open
|
|
* either. Without this, the only remedies are a database edit or deleting
|
|
* the account, and deleting a staff account means reassigning everything
|
|
* it owns to get somebody back in through the front door.
|
|
*
|
|
* The three things that happen here belong together and are the reason
|
|
* this is a service rather than four lines in a controller. Clearing the
|
|
* credentials is the smallest part; the audit entry and the email to the
|
|
* account holder are what make the action accountable, and a surface that
|
|
* forgot either would turn a support tool into a silent takeover route.
|
|
*
|
|
* What is deliberately *not* here is who may do it. That is an authority
|
|
* question, and it already has answers: `can:edit_users` /
|
|
* `can:edit_clients` on the route, and StaffAccounts::guardTarget() for
|
|
* "may this actor touch this particular account".
|
|
*/
|
|
class TwoFactorAdministration
|
|
{
|
|
public function __construct(
|
|
private readonly TwoFactorService $twoFactor,
|
|
private readonly ActivityLogger $activity,
|
|
private readonly Settings $settings,
|
|
) {}
|
|
|
|
/**
|
|
* Remove the target's second factor. Returns whether one was in force
|
|
* — a half-finished enrolment is still cleared, but there is nothing
|
|
* to report about it.
|
|
*
|
|
* If the installation enforces two-factor authentication for the
|
|
* target's user type, EnforceTwoFactor walks them straight back into
|
|
* enrolment on their next request. That is the intended outcome: this
|
|
* un-sticks an account, it does not exempt one.
|
|
*/
|
|
public function reset(User $target): bool
|
|
{
|
|
if (! $this->twoFactor->clear($target)) {
|
|
return false;
|
|
}
|
|
|
|
$this->activity->log(Action::TwoFactorReset, subject: $target);
|
|
|
|
if ($this->settings->get(Setting::EmailNotificationsEnabled) === true) {
|
|
$target->notify(new TwoFactorResetNotification);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|