Skip to content

Commit

Permalink
feat: kill inactive access tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
imorland committed Jun 15, 2024
1 parent a695c9d commit c5c001a
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 1 deletion.
11 changes: 10 additions & 1 deletion extend.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@
use Flarum\Api\Serializer\CurrentUserSerializer;
use Flarum\Api\Serializer\ForumSerializer;
use Flarum\Api\Serializer\GroupSerializer;
use Flarum\Console\Schedule;
use Flarum\Extend;
use Flarum\Group\Event\Saving as GroupSaving;
use Flarum\Group\Group;
use Flarum\User\User;
use IanM\TwoFactor\Api\Serializer\TwoFactorSerializer;
use IanM\TwoFactor\Model\TwoFactor;
use IanM\TwoFactor\OAuth\TwoFactorOAuthCheck;
use Illuminate\Console\Scheduling\Event;

return [
(new Extend\Frontend('forum'))
Expand Down Expand Up @@ -92,7 +94,14 @@

(new Extend\Settings())
->default('ianm-twofactor.admin.settings.forum_logo_qr', true)
->default('ianm-twofactor.admin.settings.forum_logo_qr_width', 100),
->default('ianm-twofactor.admin.settings.forum_logo_qr_width', 100)
->default('ianm-twofactor.kill_inactive_tokens', true)
->default('ianm-twofactor.kill_inactive_tokens_age_days', 30)
->default('ianm-twofactor.also_kill_developer_tokens', false),

(new Extend\Console())
->command(Console\KillInactiveTokensCommand::class)
->schedule(Console\KillInactiveTokensCommand::class, Console\InactiveTokensSchedule::class),

(new Extend\Conditional())
->whenExtensionEnabled('fof-oauth', fn () => [
Expand Down
21 changes: 21 additions & 0 deletions js/src/admin/components/SettingsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,27 @@ export default class SettingsPage extends ExtensionPage {
help: app.translator.trans('ianm-twofactor.admin.settings.forum_logo_qr_width_help'),
max: 200,
})}
<h3>{app.translator.trans('ianm-twofactor.admin.settings.tokens.heading')}</h3>
<p className="helpText">{app.translator.trans('ianm-twofactor.admin.settings.tokens.help')}</p>
{this.buildSettingComponent({
setting: 'ianm-twofactor.kill_inactive_tokens',
type: 'boolean',
label: app.translator.trans('ianm-twofactor.admin.settings.tokens.kill_inactive_tokens'),
help: app.translator.trans('ianm-twofactor.admin.settings.tokens.kill_inactive_tokens_help'),
})}
{this.buildSettingComponent({
setting: 'ianm-twofactor.kill_inactive_tokens_age_days',
type: 'number',
min: 1,
label: app.translator.trans('ianm-twofactor.admin.settings.tokens.kill_inactive_tokens_age_days'),
help: app.translator.trans('ianm-twofactor.admin.settings.tokens.kill_inactive_tokens_age_days_help'),
})}
{this.buildSettingComponent({
setting: 'ianm-twofactor.also_kill_developer_tokens',
type: 'boolean',
label: app.translator.trans('ianm-twofactor.admin.settings.tokens.also_kill_developer_tokens'),
help: app.translator.trans('ianm-twofactor.admin.settings.tokens.also_kill_developer_tokens_help'),
})}
{this.submitButton()}
</div>
</div>
Expand Down
10 changes: 10 additions & 0 deletions locale/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ ianm-twofactor:
forum_logo_qr_width_help: The width of the forum logo embedded on the QR code displayed when enabling 2FA. Max 200.
logo_qr: Logo on QR Code
logo_qr_help: If logo has been uploaded, this logo will be embedded on the QR code. Leave blank to use the forum logo.
tokens:
heading: Access Tokens
help: For extended security, you can manage additional behaviour here related to access tokens.
kill_inactive_tokens: Kill Inactive Tokens
kill_inactive_tokens_help: Automatically kill access tokens that have been inactive for a specified period of time.
kill_inactive_tokens_age_days: Kill Inactive Tokens After (Days)
kill_inactive_tokens_age_days_help: The number of days of inactivity after which access tokens will be deleted.
also_kill_developer_tokens: Also Kill Developer Tokens
also_kill_developer_tokens_help: Also kill developer access tokens that have been inactive for the specified period of time.


forum:
user_2fa.alert_message: You must enable 2FA to continue accessing your account.
Expand Down
22 changes: 22 additions & 0 deletions src/Console/InactiveTokensSchedule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace IanM\TwoFactor\Console;

use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Console\Scheduling\Event;

class InactiveTokensSchedule
{
public function __construct(
protected SettingsRepositoryInterface $settings
) { }

public function __invoke(Event $event)
{
if (! (bool) $this->settings->get('ianm-twofactor.kill_inactive_tokens')) {
return;
}

$event->twiceDaily();
}
}
49 changes: 49 additions & 0 deletions src/Console/KillInactiveTokensCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

namespace IanM\TwoFactor\Console;

use Carbon\Carbon;
use Flarum\Http\AccessToken;
use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Console\Command;

class KillInactiveTokensCommand extends Command
{
protected $signature = 'twofactor:kill-inactive-tokens';
protected $description = 'Kill all inactive tokens';

public function __construct(
protected SettingsRepositoryInterface $settings
) {
parent::__construct();
}

public function handle(): void
{
$age = (int) $this->settings->get('ianm-twofactor.kill_inactive_tokens_age_days');
$maxAge = Carbon::now()->subdays($age);

Check failure on line 24 in src/Console/KillInactiveTokensCommand.php

View workflow job for this annotation

GitHub Actions / run / PHPStan PHP 8.1

Call to an undefined method Carbon\Carbon::subdays().

Check failure on line 24 in src/Console/KillInactiveTokensCommand.php

View workflow job for this annotation

GitHub Actions / run / PHPStan PHP 8.2

Call to an undefined method Carbon\Carbon::subdays().

Check failure on line 24 in src/Console/KillInactiveTokensCommand.php

View workflow job for this annotation

GitHub Actions / run / PHPStan PHP 8.3

Call to an undefined method Carbon\Carbon::subdays().

$query = AccessToken::query()
->where('last_activity_at', '<', $maxAge);

if (! (bool) $this->settings->get('ianm-twofactor.also_kill_developer_tokens')) {
$this->info('Not deleting any developer tokens.');
$query->where('type', '!=', 'developer');
}

$count = $query->count();

if ($count === 0) {
$this->info("No tokens found which have not been used in $age+ days.");
return;
}

$this->info("Found $count tokens which have not been used in $age+ days. Deleting...");

$this->output->progressStart($count);

$query->delete();

$this->output->progressFinish();
}
}

0 comments on commit c5c001a

Please sign in to comment.