diff --git a/app/Http/Controllers/IconController.php b/app/Http/Controllers/IconController.php index bde6a8aa..498ac6b0 100644 --- a/app/Http/Controllers/IconController.php +++ b/app/Http/Controllers/IconController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers; +use Validator; use Illuminate\Http\Request; use Illuminate\Http\File; use Illuminate\Support\Facades\Storage; @@ -18,17 +19,29 @@ class IconController extends Controller */ public function upload(Request $request) { + $messages = [ + 'icon.image' => 'Supported format are jpeg, png, bmp, gif, svg, or webp' + ]; - if($request->hasFile('icon')){ + $validator = Validator::make($request->all(), [ + 'icon' => 'required|image', + ], $messages); + + if ($validator->fails()) { + return response()->json(['error' => $validator->errors()], 400); + } + + + // if($request->hasFile('icon')){ $path = $request->file('icon')->storePublicly('public/icons'); return response()->json(pathinfo($path)['basename'], 201); - } - else - { - return response()->json('no file in $request', 204); - } + // } + // else + // { + // return response()->json('no file in $request', 204); + // } } diff --git a/app/Http/Controllers/QrCodeController.php b/app/Http/Controllers/QrCodeController.php index 85a78c37..94c3af92 100644 --- a/app/Http/Controllers/QrCodeController.php +++ b/app/Http/Controllers/QrCodeController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers; +use Validator; use Illuminate\Http\Request; use Illuminate\Http\File; use Illuminate\Support\Facades\Storage; @@ -19,53 +20,74 @@ class QrCodecontroller extends Controller public function decode(Request $request) { - if($request->hasFile('qrcode')){ + // input validation + $messages = [ + 'qrcode.image' => 'Supported format are jpeg, png, bmp, gif, svg, or webp' + ]; - $path = $request->file('qrcode')->store('qrcodes'); + $validator = Validator::make($request->all(), [ + 'qrcode' => 'required|image', + ], $messages); - $qrcode = new QrReader(storage_path('app/' . $path)); - $uri = urldecode($qrcode->text()); - - $uriChunks = explode('?', $uri); - - foreach(explode('&', $uriChunks[1]) as $option) { - $option = explode('=', $option); - $options[$option[0]] = $option[1]; - } - - $account = $service = ''; - - $serviceChunks = explode(':', str_replace('otpauth://totp/', '', $uriChunks[0])); - - if( count($serviceChunks) > 1 ) { - $account = $serviceChunks[1]; - } - - $service = $serviceChunks[0]; - - if( strstr( $service, '@') ) { - $account = $service; - $service = ''; - } - - if( empty($service) & !empty($options['issuer']) ) { - $service = $options['issuer']; - } - - $twofaccount = (object) array( - 'service' => $service, - 'account' => $account, - 'uri' => $uri, - 'icon' => '', - 'options' => $options - ); - - Storage::delete($path); - - return response()->json($twofaccount, 201); + if ($validator->fails()) { + return response()->json(['error' => $validator->errors()], 400); } - else { - return response()->json('no file in $request', 204); + + + // qrcode analysis + $path = $request->file('qrcode')->store('qrcodes'); + $qrcode = new QrReader(storage_path('app/' . $path)); + $uri = urldecode($qrcode->text()); + + Storage::delete($path); + + if( empty($uri) ) { + + return response()->json([ + 'error' => [ + 'qrcode' => 'Nothing readable in this QR code 😕' + ] + ], 400); + } + + $uriChunks = explode('?', $uri); + + foreach(explode('&', $uriChunks[1]) as $option) { + $option = explode('=', $option); + $options[$option[0]] = $option[1]; + } + + $account = $service = ''; + + $serviceChunks = explode(':', str_replace('otpauth://totp/', '', $uriChunks[0])); + + if( count($serviceChunks) > 1 ) { + $account = $serviceChunks[1]; + } + + $service = $serviceChunks[0]; + + if( strstr( $service, '@') ) { + $account = $service; + $service = ''; + } + + if( empty($service) & !empty($options['issuer']) ) { + $service = $options['issuer']; + } + + + // returned object + $twofaccount = (object) array( + 'service' => $service, + 'account' => $account, + 'uri' => $uri, + 'icon' => '', + 'options' => $options + ); + + return response()->json($twofaccount, 201); } + } diff --git a/app/Http/Controllers/TwoFAccountController.php b/app/Http/Controllers/TwoFAccountController.php index 1e6890a4..518a395a 100644 --- a/app/Http/Controllers/TwoFAccountController.php +++ b/app/Http/Controllers/TwoFAccountController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers; +use Validator; use App\TwoFAccount; use OTPHP\TOTP; use OTPHP\Factory; @@ -30,6 +31,22 @@ public function index() */ public function store(Request $request) { + + // see https://github.com/google/google-authenticator/wiki/Key-Uri-Format + // for otpauth uri format validation + $messages = [ + 'uri.starts_with' => 'Only valid TOTP uri are supported', + ]; + + $validator = Validator::make($request->all(), [ + 'service' => 'required', + 'uri' => 'required|starts_with:otpauth://totp/', + ], $messages); + + if ($validator->fails()) { + return response()->json(['error' => $validator->errors()], 400); + } + $twofaccount = TwoFAccount::create([ 'service' => $request->service, 'account' => $request->account, diff --git a/resources/js/views/Create.vue b/resources/js/views/Create.vue index bdb6e6ac..b885e199 100644 --- a/resources/js/views/Create.vue +++ b/resources/js/views/Create.vue @@ -17,17 +17,20 @@ +
{{ errors.qrcode.toString() }}
{{ errors.service.toString() }}
{{ errors.account.toString() }}
{{ errors.uri.toString() }}
{{ errors.icon.toString() }}