소스 검색

Add back-end route|controller|request for import feature

Bubka 3 년 전
부모
커밋
0cccdf32ed
3개의 변경된 파일88개의 추가작업 그리고 0개의 파일을 삭제
  1. 56 0
      app/Api/v1/Controllers/TwoFAccountController.php
  2. 31 0
      app/Api/v1/Requests/TwoFAccountImportRequest.php
  3. 1 0
      routes/api/v1.php

+ 56 - 0
app/Api/v1/Controllers/TwoFAccountController.php

@@ -7,6 +7,7 @@ use App\Exceptions\UndecipherableException;
 use App\Api\v1\Requests\TwoFAccountReorderRequest;
 use App\Api\v1\Requests\TwoFAccountReorderRequest;
 use App\Api\v1\Requests\TwoFAccountStoreRequest;
 use App\Api\v1\Requests\TwoFAccountStoreRequest;
 use App\Api\v1\Requests\TwoFAccountUpdateRequest;
 use App\Api\v1\Requests\TwoFAccountUpdateRequest;
+use App\Api\v1\Requests\TwoFAccountImportRequest;
 use App\Api\v1\Requests\TwoFAccountBatchRequest;
 use App\Api\v1\Requests\TwoFAccountBatchRequest;
 use App\Api\v1\Requests\TwoFAccountUriRequest;
 use App\Api\v1\Requests\TwoFAccountUriRequest;
 use App\Api\v1\Requests\TwoFAccountDynamicRequest;
 use App\Api\v1\Requests\TwoFAccountDynamicRequest;
@@ -16,6 +17,7 @@ use App\Api\v1\Resources\TwoFAccountStoreResource;
 use App\Services\GroupService;
 use App\Services\GroupService;
 use App\Services\TwoFAccountService;
 use App\Services\TwoFAccountService;
 use Illuminate\Support\Arr;
 use Illuminate\Support\Arr;
+use Illuminate\Support\Str;
 use Illuminate\Http\Request;
 use Illuminate\Http\Request;
 use App\Http\Controllers\Controller;
 use App\Http\Controllers\Controller;
 
 
@@ -120,6 +122,60 @@ class TwoFAccountController extends Controller
     }
     }
 
 
 
 
+    /**
+     * Dry-import Google authenticator data
+     *
+     * @param  \App\Api\v1\Requests\TwoFAccountImportRequest  $request
+     * @return \App\Api\v1\Resources\TwoFAccountCollection
+     */
+    public function import(TwoFAccountImportRequest $request)
+    {
+        $ALGORITHM = [
+            '',
+            'sha1',
+            'sha256',
+            'sha512',
+            'md5'
+        ];
+
+        $DIGIT_COUNT = [
+            '',
+            6,
+            8
+        ];
+
+        $OTP_TYPE = [
+            '',
+            'hotp',
+            'totp'
+        ];
+
+        // require_once base_path('protobuf/SearchRequest.php');
+        // $uri = 'otpauth-migration://offline?data=CjUKCi8gSXtDdoRpZEkSEWVkb3VhcmRAZ2FuZWF1Lm1lGg5iYW5rLmdhbmVhdS5tZSABKAEwAhABGAEgAA==';
+        // $uri = base64_decode(urldecode('CjUKCi8gSXtDdoRpZEkSEWVkb3VhcmRAZ2FuZWF1Lm1lGg5iYW5rLmdhbmVhdS5tZSABKAEwAhABGAEgAA=='));
+        // $uri = 'otpauth-migration://offline?data=CiQKCj1PS8k1EUgVI0ESB0BidWJrYV8aB1R3aXR0ZXIgASgBMAIKIQoK6/l62ezmsWvMNRIFQnVia2EaBkdpdEh1YiABKAEwAhABGAEgAA==';
+        // $uri = base64_decode(urldecode('CiQKCj1PS8k1EUgVI0ESB0BidWJrYV8aB1R3aXR0ZXIgASgBMAIKIQoK6/l62ezmsWvMNRIFQnVia2EaBkdpdEh1YiABKAEwAhABGAEgAA=='));
+
+        $data = base64_decode(urldecode(Str::replace('otpauth-migration://offline?data=', '', $request->uri)));
+
+        $proto = new \App\Protobuf\GoogleAuth\Payload();
+        $proto->mergeFromString($data);
+        $otpParameters = $proto->getOtpParameters();
+
+        foreach ($otpParameters->getIterator() as $key => $otp_parameters) {
+            $out[$key]['secret'] = \ParagonIE\ConstantTime\Base32::encodeUpper($otp_parameters->getSecret());
+            $out[$key]['account'] = $otp_parameters->getName();
+            $out[$key]['service'] = $otp_parameters->getIssuer();
+            $out[$key]['algorithm'] = $ALGORITHM[$otp_parameters->getalgorithm()];
+            $out[$key]['digits'] = $DIGIT_COUNT[$otp_parameters->getDigits()];
+            $out[$key]['otp_type'] = $OTP_TYPE[$otp_parameters->getType()];
+            $out[$key]['counter'] = $otp_parameters->getCounter();
+        }
+
+        return response()->json($out, 200);
+    }
+
+
     /**
     /**
      * Save 2FA accounts order
      * Save 2FA accounts order
      *
      *

+ 31 - 0
app/Api/v1/Requests/TwoFAccountImportRequest.php

@@ -0,0 +1,31 @@
+<?php
+
+namespace App\Api\v1\Requests;
+
+use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Auth;
+
+class TwoFAccountImportRequest extends FormRequest
+{
+    /**
+     * Determine if the user is authorized to make this request.
+     *
+     * @return bool
+     */
+    public function authorize()
+    {
+        return Auth::check();
+    }
+
+    /**
+     * Get the validation rules that apply to the request.
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        return [
+            'uri' => 'required|string|regex:/^otpauth-migration:\/\/offline\?data=/i',
+        ];
+    }
+}

+ 1 - 0
routes/api/v1.php

@@ -27,6 +27,7 @@ Route::group(['middleware' => 'auth:api-guard'], function () {
     Route::delete('settings/{settingName}', 'SettingController@destroy')->name('settings.destroy');
     Route::delete('settings/{settingName}', 'SettingController@destroy')->name('settings.destroy');
 
 
     Route::delete('twofaccounts', 'TwoFAccountController@batchDestroy')->name('twofaccounts.batchDestroy');
     Route::delete('twofaccounts', 'TwoFAccountController@batchDestroy')->name('twofaccounts.batchDestroy');
+    Route::post('twofaccounts/import', 'TwoFAccountController@import')->name('twofaccounts.import');
     Route::patch('twofaccounts/withdraw', 'TwoFAccountController@withdraw')->name('twofaccounts.withdraw');
     Route::patch('twofaccounts/withdraw', 'TwoFAccountController@withdraw')->name('twofaccounts.withdraw');
     Route::post('twofaccounts/reorder', 'TwoFAccountController@reorder')->name('twofaccounts.reorder');
     Route::post('twofaccounts/reorder', 'TwoFAccountController@reorder')->name('twofaccounts.reorder');
     Route::post('twofaccounts/preview', 'TwoFAccountController@preview')->name('twofaccounts.preview');
     Route::post('twofaccounts/preview', 'TwoFAccountController@preview')->name('twofaccounts.preview');