diff --git a/app/Console/Commands/VerifyDatabase.php b/app/Console/Commands/VerifyDatabase.php index 4f66dddd94..f69a630f1a 100644 --- a/app/Console/Commands/VerifyDatabase.php +++ b/app/Console/Commands/VerifyDatabase.php @@ -27,6 +27,7 @@ use FireflyIII\User; use Illuminate\Console\Command; use Illuminate\Contracts\Encryption\DecryptException; use Illuminate\Database\Eloquent\Builder; +use Preferences; use Schema; use stdClass; @@ -102,6 +103,22 @@ class VerifyDatabase extends Command // create default link types if necessary $this->createLinkTypes(); + // create user access tokens, if not present already. + $this->createAccessTokens(); + + } + + private function createAccessTokens() + { + $users = User::get(); + /** @var User $user */ + foreach ($users as $user) { + $pref = Preferences::getForUser($user, 'access_token', null); + if (is_null($pref)) { + $token = $user->generateAccessToken(); + Preferences::setForUser($user, 'access_token', $token); + } + } } /** diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php index 780c3038f4..a85086a060 100644 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/ProfileController.php @@ -21,6 +21,7 @@ use FireflyIII\Repositories\User\UserRepositoryInterface; use FireflyIII\User; use Hash; use Log; +use Preferences; use Session; use View; @@ -84,7 +85,14 @@ class ProfileController extends Controller $subTitle = auth()->user()->email; $userId = auth()->user()->id; - return view('profile.index', compact('subTitle', 'userId')); + // get access token or create one. + $accessToken = Preferences::get('access_token', null); + if (is_null($accessToken)) { + $token = auth()->user()->generateAccessToken(); + $accessToken = Preferences::set('access_token', $token); + } + + return view('profile.index', compact('subTitle', 'userId', 'accessToken')); } /** @@ -140,6 +148,17 @@ class ProfileController extends Controller return redirect(route('index')); } + /** + * + */ + function regenerate() + { + $token = auth()->user()->generateAccessToken(); + Preferences::set('access_token', $token); + Session::flash('success', strval(trans('firefly.token_regenerated'))); + + return redirect(route('profile.index')); + } /** * @param User $user diff --git a/app/User.php b/app/User.php index da5e565d38..562a7b2b6d 100644 --- a/app/User.php +++ b/app/User.php @@ -136,6 +136,16 @@ class User extends Authenticatable return $this->hasMany('FireflyIII\Models\ExportJob'); } + /** + * @return string + */ + public function generateAccessToken(): string + { + $bytes = random_bytes(16); + + return strval(bin2hex($bytes)); + } + /** * Checks if the user has a role by its name. * diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index bdb8e8657c..52abc3bff6 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -416,7 +416,10 @@ return [ 'secure_pw_should' => 'Should I check the box?', 'secure_pw_long_password' => 'If you just generated a long, single-use password for Firefly III using some kind of password generator: no.', 'secure_pw_short' => 'If you just entered the password you always use: Please yes.', - + 'personal_access_token' => 'Personal access token', + 'explain_access_token' => 'You need this token to perform command line options, such as importing or exporting data. Without it, such sensitive commands will not work. Do not share your access token. Nobody will ask you for this token, not even me. If you fear you lost this, or when you\'re paranoid, regenerate this token using the button.', + 'regenerate_access_token' => 'Regenerate access token', + 'token_regenerated' => 'A new token was generated', // attachments 'nr_of_attachments' => 'One attachment|:count attachments', diff --git a/resources/views/profile/index.twig b/resources/views/profile/index.twig index f86a713205..75c08792fa 100644 --- a/resources/views/profile/index.twig +++ b/resources/views/profile/index.twig @@ -9,7 +9,7 @@
@@ -23,4 +23,28 @@
+ {{ 'explain_access_token'|_ }} +
++ + +
++
+ +