diff --git a/app/Filament/Resources/UserResource/Pages/EditProfile.php b/app/Filament/Resources/UserResource/Pages/EditProfile.php index 08aedbbaf..ed4a09604 100644 --- a/app/Filament/Resources/UserResource/Pages/EditProfile.php +++ b/app/Filament/Resources/UserResource/Pages/EditProfile.php @@ -4,6 +4,11 @@ namespace App\Filament\Resources\UserResource\Pages; use App\Models\ActivityLog; use App\Models\User; +use App\Services\Users\TwoFactorSetupService; +use chillerlan\QRCode\Common\EccLevel; +use chillerlan\QRCode\Common\Version; +use chillerlan\QRCode\QRCode; +use chillerlan\QRCode\QROptions; use Filament\Forms\Components\Placeholder; use Filament\Forms\Components\Repeater; use Filament\Forms\Components\Select; @@ -77,9 +82,63 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile Tab::make('2FA') ->icon('tabler-shield-lock') - ->schema([ - Placeholder::make('Coming soon!'), - ]), + ->schema(function () { + + if ($this->getUser()->use_totp) { + return [ + Placeholder::make('2FA already enabled!'), + ]; + } + $setupService = app(TwoFactorSetupService::class); + + ['image_url_data' => $url] = $setupService->handle($this->getUser()); + + $options = new QROptions([ + 'svgLogo' => public_path('pelican.svg'), + 'addLogoSpace' => true, + 'logoSpaceWidth' => 13, + 'logoSpaceHeight' => 13, + ]); + + // https://github.com/chillerlan/php-qrcode/blob/main/examples/svgWithLogo.php + + // SVG logo options (see extended class) + $options->svgLogo = public_path('pelican.svg'); // logo from: https://github.com/simple-icons/simple-icons + $options->svgLogoScale = 0.05; + // $options->svgLogoCssClass = 'dark'; + + // QROptions + $options->version = Version::AUTO; + // $options->outputInterface = QRSvgWithLogo::class; + $options->outputBase64 = false; + $options->eccLevel = EccLevel::H; // ECC level H is necessary when using logos + $options->addQuietzone = true; + // $options->drawLightModules = true; + $options->connectPaths = true; + $options->drawCircularModules = true; + // $options->circleRadius = 0.45; + + $options->svgDefs = ' + + + + + '; + + $image = (new QRCode($options))->render($url); + + return [ + Placeholder::make('qr') + ->label('Scan QR Code') + ->content(fn () => new HtmlString(" +
$image
+ ")) + ->default('asdfasdf'), + ]; + }), Tab::make('API Keys') ->icon('tabler-key') diff --git a/composer.json b/composer.json index e5cf3f9e0..d4c3d4966 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,7 @@ "ext-posix": "*", "ext-zip": "*", "aws/aws-sdk-php": "~3.288.1", + "chillerlan/php-qrcode": "^5.0", "doctrine/dbal": "~3.6.0", "filament/filament": "^3.2", "guzzlehttp/guzzle": "^7.5", diff --git a/composer.lock b/composer.lock index d3ade3465..9923d10c1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "bf147fbbb2f57777d6c6b137bc61bcda", + "content-hash": "d2c8db4966266b50f8f28b31708f73a6", "packages": [ { "name": "anourvalar/eloquent-serialize", @@ -495,6 +495,165 @@ ], "time": "2023-10-01T12:35:29+00:00" }, + { + "name": "chillerlan/php-qrcode", + "version": "5.0.2", + "source": { + "type": "git", + "url": "https://github.com/chillerlan/php-qrcode.git", + "reference": "da5bdb82c8755f54de112b271b402aaa8df53269" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/chillerlan/php-qrcode/zipball/da5bdb82c8755f54de112b271b402aaa8df53269", + "reference": "da5bdb82c8755f54de112b271b402aaa8df53269", + "shasum": "" + }, + "require": { + "chillerlan/php-settings-container": "^2.1.4 || ^3.1", + "ext-mbstring": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "chillerlan/php-authenticator": "^4.1 || ^5.1", + "phan/phan": "^5.4", + "phpmd/phpmd": "^2.15", + "phpunit/phpunit": "^9.6", + "setasign/fpdf": "^1.8.2", + "squizlabs/php_codesniffer": "^3.8" + }, + "suggest": { + "chillerlan/php-authenticator": "Yet another Google authenticator! Also creates URIs for mobile apps.", + "setasign/fpdf": "Required to use the QR FPDF output.", + "simple-icons/simple-icons": "SVG icons that you can use to embed as logos in the QR Code" + }, + "type": "library", + "autoload": { + "psr-4": { + "chillerlan\\QRCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT", + "Apache-2.0" + ], + "authors": [ + { + "name": "Kazuhiko Arase", + "homepage": "https://github.com/kazuhikoarase/qrcode-generator" + }, + { + "name": "ZXing Authors", + "homepage": "https://github.com/zxing/zxing" + }, + { + "name": "Ashot Khanamiryan", + "homepage": "https://github.com/khanamiryan/php-qrcode-detector-decoder" + }, + { + "name": "Smiley", + "email": "smiley@chillerlan.net", + "homepage": "https://github.com/codemasher" + }, + { + "name": "Contributors", + "homepage": "https://github.com/chillerlan/php-qrcode/graphs/contributors" + } + ], + "description": "A QR code generator and reader with a user friendly API. PHP 7.4+", + "homepage": "https://github.com/chillerlan/php-qrcode", + "keywords": [ + "phpqrcode", + "qr", + "qr code", + "qr-reader", + "qrcode", + "qrcode-generator", + "qrcode-reader" + ], + "support": { + "docs": "https://php-qrcode.readthedocs.io", + "issues": "https://github.com/chillerlan/php-qrcode/issues", + "source": "https://github.com/chillerlan/php-qrcode" + }, + "funding": [ + { + "url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4", + "type": "custom" + }, + { + "url": "https://ko-fi.com/codemasher", + "type": "ko_fi" + } + ], + "time": "2024-02-27T14:37:26+00:00" + }, + { + "name": "chillerlan/php-settings-container", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/chillerlan/php-settings-container.git", + "reference": "8f93648fac8e6bacac8e00a8d325eba4950295e6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/8f93648fac8e6bacac8e00a8d325eba4950295e6", + "reference": "8f93648fac8e6bacac8e00a8d325eba4950295e6", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^8.1" + }, + "require-dev": { + "phan/phan": "^5.4", + "phpmd/phpmd": "^2.15", + "phpunit/phpunit": "^10.5", + "squizlabs/php_codesniffer": "^3.9" + }, + "type": "library", + "autoload": { + "psr-4": { + "chillerlan\\Settings\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Smiley", + "email": "smiley@chillerlan.net", + "homepage": "https://github.com/codemasher" + } + ], + "description": "A container class for immutable settings objects. Not a DI container.", + "homepage": "https://github.com/chillerlan/php-settings-container", + "keywords": [ + "Settings", + "configuration", + "container", + "helper" + ], + "support": { + "issues": "https://github.com/chillerlan/php-settings-container/issues", + "source": "https://github.com/chillerlan/php-settings-container" + }, + "funding": [ + { + "url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4", + "type": "custom" + }, + { + "url": "https://ko-fi.com/codemasher", + "type": "ko_fi" + } + ], + "time": "2024-03-02T20:07:15+00:00" + }, { "name": "danharrin/date-format-converter", "version": "v0.3.0",