Enhance QR code reading & return more relevant error msg - Fixes #244

This commit is contained in:
Bubka 2024-03-22 18:04:44 +01:00
parent 9c8d349e1c
commit 2db5adfe3b
3 changed files with 39 additions and 5 deletions

View File

@ -45,7 +45,8 @@ public function register()
$this->renderable(function (InvalidQrCodeException $exception, $request) {
return response()->json([
'message' => 'not a valid QR code', ], 400);
'message' => $exception->getMessage(),
], 400);
});
$this->renderable(function (InvalidSecretException $exception, $request) {

View File

@ -5,6 +5,9 @@
use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;
use Illuminate\Support\Facades\Log;
use Zxing\ChecksumException;
use Zxing\FormatException;
use Zxing\NotFoundException;
use Zxing\QrReader;
class QrCodeService
@ -37,12 +40,39 @@ public static function encode(string $data)
public static function decode(\Illuminate\Http\UploadedFile $file)
{
$qrcode = new QrReader($file->get(), QrReader::SOURCE_TYPE_BLOB);
$data = urldecode($qrcode->text());
$text = $qrcode->text();
if (! $data) {
throw new \App\Exceptions\InvalidQrCodeException;
if (! $text) {
$text = $qrcode->text([
'TRY_HARDER' => true,
'NR_ALLOW_SKIP_ROWS' => 0,
]);
}
// At this point, if we do not have a text, QR code cannot be detected or decoded
// so we check the error to provide the user a relevant error message
if (! $text) {
switch (get_class($qrcode->getError())) {
case NotFoundException::class:
throw new \App\Exceptions\InvalidQrCodeException(__('errors.cannot_detect_qrcode_in_image'));
break;
case FormatException::class:
throw new \App\Exceptions\InvalidQrCodeException(__('errors.cannot_decode_detected_qrcode'));
break;
case ChecksumException::class:
throw new \App\Exceptions\InvalidQrCodeException(__('errors.qrcode_has_invalid_checksum'));
break;
default:
throw new \App\Exceptions\InvalidQrCodeException(__('errors.no_readable_qrcode'));
break;
}
}
$data = urldecode($qrcode->text());
Log::info('QR code decoded');
return $data;

View File

@ -67,5 +67,8 @@
'account_managed_by_external_provider' => 'Account managed by an external provider',
'data_cannot_be_refreshed_from_server' => 'Data cannot be refreshed from server',
'no_pwd_reset_for_this_user_type' => 'Password reset unavailable for this user',
'app_key_is_not_set' => 'The APP_KEY environment variable is not set',
'cannot_detect_qrcode_in_image' => 'Cannot detect a QR code in the image, try to crop the image',
'cannot_decode_detected_qrcode' => 'Cannot decode detected QR code, try to crop or sharpen the image',
'qrcode_has_invalid_checksum' => 'QR code has invalid checksum',
'no_readable_qrcode' => 'No readable QR code',
];