Skip to content

Commit

Permalink
Allow to upload custom image for embedding on the QR Code (#9)
Browse files Browse the repository at this point in the history
* Allow to upload custom image for embedding on the QR Code

* update code

* remove console log

Co-authored-by: IanM <[email protected]>

* format

* only serialize attribute in admin

* fix coding style

* fix review

---------

Co-authored-by: IanM <[email protected]>
  • Loading branch information
datlechin and imorland authored Sep 13, 2023
1 parent f027aab commit 7dce5cd
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 6 deletions.
8 changes: 7 additions & 1 deletion extend.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Flarum\Api\Controller\ShowUserController;
use Flarum\Api\Serializer\BasicUserSerializer;
use Flarum\Api\Serializer\CurrentUserSerializer;
use Flarum\Api\Serializer\ForumSerializer;
use Flarum\Api\Serializer\GroupSerializer;
use Flarum\Extend;
use Flarum\Group\Event\Saving as GroupSaving;
Expand All @@ -38,7 +39,9 @@
->post('/users/twofactor/verify', 'user.twofactor.verify', Api\Controller\VerifyTwoFactorController::class)
->delete('/users/{id}/twofactor/disable', 'user.twofactor.disable', Api\Controller\DisableTwoFactorController::class)
->remove('token')
->post('/token', 'token', Api\Controller\CreateTwoFactorTokenController::class),
->post('/token', 'token', Api\Controller\CreateTwoFactorTokenController::class)
->post('/ianm_twofactor_logo', 'ianm_twofactor.logo', Api\Controller\UploadLogoController::class)
->delete('/ianm_twofactor_logo', 'ianm_twofactor.logo.delete', Api\Controller\DeleteLogoController::class),

(new Extend\Routes('forum'))
->remove('login')
Expand Down Expand Up @@ -66,6 +69,9 @@
(new Extend\ApiSerializer(GroupSerializer::class))
->attributes(Api\AddGroupAttributes::class),

(new Extend\ApiSerializer(ForumSerializer::class))
->attributes(Api\AddForumAttributes::class),

(new Extend\ApiController(ShowUserController::class))
->addInclude('twoFactor'),

Expand Down
6 changes: 6 additions & 0 deletions js/src/admin/components/SettingsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import app from 'flarum/admin/app';
import ExtensionPage from 'flarum/admin/components/ExtensionPage';
import UploadImageButton from 'flarum/admin/components/UploadImageButton';
import ExtractedGroupBar from './ExtractedGroupBar';

export default class SettingsPage extends ExtensionPage {
Expand All @@ -19,6 +20,11 @@ export default class SettingsPage extends ExtensionPage {
label: app.translator.trans('ianm-twofactor.admin.settings.forum_logo_qr'),
help: app.translator.trans('ianm-twofactor.admin.settings.forum_logo_qr_help'),
})}
<div className="Form-group">
<label>{app.translator.trans('ianm-twofactor.admin.settings.logo_qr')}</label>
<div className="helpText">{app.translator.trans('ianm-twofactor.admin.settings.logo_qr_help')}</div>
<UploadImageButton name="ianm_twofactor_logo" />
</div>
{this.buildSettingComponent({
setting: 'ianm-twofactor.admin.settings.forum_logo_qr_width',
type: 'number',
Expand Down
4 changes: 3 additions & 1 deletion locale/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ ianm-twofactor:
forum_logo_qr_help: Embed the forum logo on the QR code displayed when enabling 2FA. This may help users identify the correct QR code to scan.
forum_logo_qr_width: Forum Logo QR Code Width
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.

forum:
user_2fa.alert_message: You must enable 2FA to continue accessing your account.
Expand Down Expand Up @@ -56,7 +58,7 @@ ianm-twofactor:
status_changed: |
Hello {recipient_display_name},
Two-Factor Authentication has been {type} for your account on {forum_url}.
Two-Factor Authentication has been {type} for your account on {forum_url}.
If you initiated this action, no further steps are necessary. If you did not authorize this change, please contact the forum administrators immediately.
views:
Expand Down
55 changes: 55 additions & 0 deletions src/Api/AddForumAttributes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

/*
* This file is part of ianm/twofactor.
*
* Copyright (c) 2023 IanM.
*
* For the full copyright and license information, please view the LICENSE.md
* file that was distributed with this source code.
*/

namespace IanM\TwoFactor\Api;

use Flarum\Api\Serializer\ForumSerializer;
use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Contracts\Filesystem\Factory;

class AddForumAttributes
{
/**
* @var SettingsRepositoryInterface
*/
protected $settings;

protected $assetsFilesystem;

public function __construct(Factory $filesystemFactory, SettingsRepositoryInterface $settings)
{
$this->assetsFilesystem = $filesystemFactory->disk('flarum-assets');
$this->settings = $settings;
}

public function __invoke(ForumSerializer $serializer, $object, array $attributes): array
{
$actor = $serializer->getActor();

if ($actor->isAdmin()) {
$attributes['ianm_twofactor_logoUrl'] = $this->getLogoUrl();
}

return $attributes;
}

protected function getLogoUrl(): ?string
{
$logoPath = $this->settings->get('ianm_twofactor_logo_path');

return $logoPath ? $this->getAssetUrl($logoPath) : null;
}

public function getAssetUrl(string $assetPath): string
{
return $this->assetsFilesystem->url($assetPath);
}
}
2 changes: 1 addition & 1 deletion src/Api/Controller/CreateTwoFactorTokenController.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface
$user = $this->users->findByIdentification($identification);

if (! $user || ! $user->checkPassword($password)) {
throw new NotAuthenticatedException;
throw new NotAuthenticatedException();
}

if ($this->twoFactorActive($user)) {
Expand Down
44 changes: 44 additions & 0 deletions src/Api/Controller/DeleteLogoController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

/*
* This file is part of ianm/twofactor.
*
* Copyright (c) 2023 IanM.
*
* For the full copyright and license information, please view the LICENSE.md
* file that was distributed with this source code.
*/

namespace IanM\TwoFactor\Api\Controller;

use Flarum\Api\Controller\AbstractDeleteController;
use Flarum\Http\RequestUtil;
use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Contracts\Filesystem\Factory;
use Illuminate\Contracts\Filesystem\Filesystem;
use Psr\Http\Message\ServerRequestInterface;

class DeleteLogoController extends AbstractDeleteController
{
protected Filesystem $uploadDir;

public function __construct(
protected SettingsRepositoryInterface $settings,
Factory $filesystemFactory
) {
$this->uploadDir = $filesystemFactory->disk('flarum-assets');
}

protected function delete(ServerRequestInterface $request): void
{
RequestUtil::getActor($request)->assertAdmin();

$path = $this->settings->get('ianm_twofactor_logo_path');

$this->settings->set('ianm_twofactor_logo_path', null);

if ($this->uploadDir->exists($path)) {
$this->uploadDir->delete($path);
}
}
}
2 changes: 1 addition & 1 deletion src/Api/Controller/TwoFactorResetPasswordController.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public function render(Request $request)
$token = PasswordToken::findOrFail($token);

if ($token->created_at < new DateTime('-1 day')) {
throw new InvalidConfirmationTokenException;
throw new InvalidConfirmationTokenException();
}

$hasTwoFactorEnabled = $this->twoFactorActive($token->user);
Expand Down
44 changes: 44 additions & 0 deletions src/Api/Controller/UploadLogoController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

/*
* This file is part of ianm/twofactor.
*
* Copyright (c) 2023 IanM.
*
* For the full copyright and license information, please view the LICENSE.md
* file that was distributed with this source code.
*/

namespace IanM\TwoFactor\Api\Controller;

use Flarum\Api\Controller\UploadImageController;
use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Contracts\Filesystem\Factory;
use Intervention\Image\Constraint;
use Intervention\Image\Image;
use Intervention\Image\ImageManager;
use Psr\Http\Message\UploadedFileInterface;

class UploadLogoController extends UploadImageController
{
protected $filePathSettingKey = 'ianm_twofactor_logo_path';

protected $filenamePrefix = 'ianm_twofactor_logo';

public function __construct(
SettingsRepositoryInterface $settings,
Factory $filesystemFactory,
protected ImageManager $imageManager
) {
parent::__construct($settings, $filesystemFactory);
}

protected function makeImage(UploadedFileInterface $file): Image
{
$encodedImage = $this->imageManager
->make($file->getStream()->getMetadata('uri'))
->heighten(60, fn (Constraint $constraint) => $constraint->upsize())->encode('png');

return $encodedImage;
}
}
4 changes: 2 additions & 2 deletions src/Services/QrCodeGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public function generate(string $text, bool $asDataUri = false): string
->validateResult(false)
->backgroundColor(new Color(255, 255, 255, 1));

if ($this->settings->get('ianm-twofactor.admin.settings.forum_logo_qr')) {
if ($this->settings->get('ianm-twofactor.admin.settings.forum_logo_qr') && $this->getLogoUrl()) {
$builder
->logoPath($this->getLogoUrl())
->logoResizeToWidth($this->settings->get('ianm-twofactor.admin.settings.forum_logo_qr_width') ?? 100)
Expand All @@ -62,7 +62,7 @@ public function generate(string $text, bool $asDataUri = false): string

protected function getLogoUrl(): ?string
{
$logoPath = $this->settings->get('logo_path');
$logoPath = $this->settings->get('ianm_twofactor_logo_path') ?? $this->settings->get('logo_path');

return $logoPath ? $this->getAssetUrl($logoPath) : null;
}
Expand Down

0 comments on commit 7dce5cd

Please sign in to comment.