From d38766e5dbd812786a887ef6d34dae948c8284ce Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 4 Aug 2019 07:21:11 +0200 Subject: [PATCH] Firefly III can generate new backup codes. --- app/Http/Controllers/ProfileController.php | 28 ++++++++++-- resources/lang/en_US/firefly.php | 43 ++++++++++--------- resources/views/v1/profile/index.twig | 6 +++ .../views/v1/profile/new-backup-codes.twig | 29 +++++++++++++ routes/breadcrumbs.php | 8 ++++ routes/web.php | 1 + 6 files changed, 91 insertions(+), 24 deletions(-) create mode 100644 resources/views/v1/profile/new-backup-codes.twig diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php index fcb89adbc0..a10521fdf2 100644 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/ProfileController.php @@ -287,9 +287,10 @@ class ProfileController extends Controller $repository = app(ClientRepository::class); $repository->createPersonalAccessClient(null, config('app.name') . ' Personal Access Client', 'http://localhost'); } - $subTitle = $user->email; - $userId = $user->id; - $enabled2FA = null !== $user->mfa_secret; + $subTitle = $user->email; + $userId = $user->id; + $enabled2FA = null !== $user->mfa_secret; + $mfaBackupCount = count(Preferences::get('mfa_recovery', [])->data); // get access token or create one. $accessToken = app('preferences')->get('access_token', null); @@ -298,7 +299,26 @@ class ProfileController extends Controller $accessToken = app('preferences')->set('access_token', $token); } - return view('profile.index', compact('subTitle', 'userId', 'accessToken', 'enabled2FA', 'loginProvider')); + return view('profile.index', compact('subTitle', 'mfaBackupCount', 'userId', 'accessToken', 'enabled2FA', 'loginProvider')); + } + + /** + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + */ + public function newBackupCodes() + { + // generate recovery codes: + $recovery = app(Recovery::class); + $recoveryCodes = $recovery->lowercase() + ->setCount(8) // Generate 8 codes + ->setBlocks(2) // Every code must have 7 blocks + ->setChars(6) // Each block must have 16 chars + ->toArray(); + $codes = implode("\r\n", $recoveryCodes); + + Preferences::set('mfa_recovery', $recoveryCodes); + + return view('profile.new-backup-codes', compact('codes')); } /** diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index 309023aa61..2d07396e32 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -86,26 +86,29 @@ return [ 'two_factor_welcome' => 'Hello!', 'two_factor_enter_code' => 'To continue, please enter your two factor authentication code. Your application can generate it for you.', 'two_factor_code_here' => 'Enter code here', - 'two_factor_title' => 'Two factor authentication', - 'authenticate' => 'Authenticate', - 'two_factor_forgot_title' => 'Lost two factor authentication', - 'two_factor_forgot' => 'I forgot my two-factor thing.', - 'two_factor_lost_header' => 'Lost your two factor authentication?', - 'two_factor_lost_intro' => 'If you lost your backup codes as well, you have bad luck. This is not something you can fix from the web interface. You have two choices.', - 'two_factor_lost_fix_self' => 'If you run your own instance of Firefly III, check the logs in storage/logs for instructions, or run docker logs <container_id> to see the instructions (refresh this page).', - 'two_factor_lost_fix_owner' => 'Otherwise, email the site owner, :site_owner and ask them to reset your two factor authentication.', - 'mfa_backup_code' => 'You have used a backup code to login to Firefly III. It can\'t be used again, so cross it from your list.', - 'warning_much_data' => ':days days of data may take a while to load.', - 'registered' => 'You have registered successfully!', - 'Default asset account' => 'Default asset account', - 'no_budget_pointer' => 'You seem to have no budgets yet. You should create some on the budgets-page. Budgets can help you keep track of expenses.', - 'Savings account' => 'Savings account', - 'Credit card' => 'Credit card', - 'source_accounts' => 'Source account(s)', - 'destination_accounts' => 'Destination account(s)', - 'user_id_is' => 'Your user id is :user', - 'field_supports_markdown' => 'This field supports Markdown.', - 'need_more_help' => 'If you need more help using Firefly III, please open a ticket on Github.', + 'two_factor_title' => 'Two factor authentication', + 'authenticate' => 'Authenticate', + 'two_factor_forgot_title' => 'Lost two factor authentication', + 'two_factor_forgot' => 'I forgot my two-factor thing.', + 'two_factor_lost_header' => 'Lost your two factor authentication?', + 'two_factor_lost_intro' => 'If you lost your backup codes as well, you have bad luck. This is not something you can fix from the web interface. You have two choices.', + 'two_factor_lost_fix_self' => 'If you run your own instance of Firefly III, check the logs in storage/logs for instructions, or run docker logs <container_id> to see the instructions (refresh this page).', + 'two_factor_lost_fix_owner' => 'Otherwise, email the site owner, :site_owner and ask them to reset your two factor authentication.', + 'mfa_backup_code' => 'You have used a backup code to login to Firefly III. It can\'t be used again, so cross it from your list.', + 'pref_two_factor_new_backup_codes' => 'Get new backup codes', + 'pref_two_factor_backup_code_count' => 'You have :count valid backup code(s).', + '2fa_i_have_them' => 'I stored them!', + 'warning_much_data' => ':days days of data may take a while to load.', + 'registered' => 'You have registered successfully!', + 'Default asset account' => 'Default asset account', + 'no_budget_pointer' => 'You seem to have no budgets yet. You should create some on the budgets-page. Budgets can help you keep track of expenses.', + 'Savings account' => 'Savings account', + 'Credit card' => 'Credit card', + 'source_accounts' => 'Source account(s)', + 'destination_accounts' => 'Destination account(s)', + 'user_id_is' => 'Your user id is :user', + 'field_supports_markdown' => 'This field supports Markdown.', + 'need_more_help' => 'If you need more help using Firefly III, please open a ticket on Github.', 'reenable_intro_text' => 'You can also reenable the introduction guidance.', 'intro_boxes_after_refresh' => 'The introduction boxes will reappear when you refresh the page.', 'show_all_no_filter' => 'Show all transactions without grouping them by date.', diff --git a/resources/views/v1/profile/index.twig b/resources/views/v1/profile/index.twig index 4816c5b301..ba14b59710 100644 --- a/resources/views/v1/profile/index.twig +++ b/resources/views/v1/profile/index.twig @@ -85,11 +85,17 @@

{{ 'pref_two_factor_auth_help'|_ }}

{% if enabled2FA == true %} +

+ {{ trans('firefly.pref_two_factor_backup_code_count', {count: mfaBackupCount}) }} +

{{ 'pref_two_factor_auth_reset_code'|_ }} + + + {{ 'pref_two_factor_new_backup_codes'|_ }} {{ 'pref_two_factor_auth_disable_2fa'|_ }} diff --git a/resources/views/v1/profile/new-backup-codes.twig b/resources/views/v1/profile/new-backup-codes.twig new file mode 100644 index 0000000000..79056c54bb --- /dev/null +++ b/resources/views/v1/profile/new-backup-codes.twig @@ -0,0 +1,29 @@ +{% extends "./layout/default" %} + +{% block breadcrumbs %} + {{ Breadcrumbs.render(Route.getCurrentRoute.getName) }} +{% endblock %} + +{% block content %} +
+
+
+
+

{{ 'pref_two_factor_auth_code'|_ }}

+
+
+
+

+ {{ '2fa_backup_codes'|_ }} +

+
{{ codes }}
+
+
+ +
+
+
+ +{% endblock %} diff --git a/routes/breadcrumbs.php b/routes/breadcrumbs.php index 55e0dd4b5d..ae4fffd9f4 100644 --- a/routes/breadcrumbs.php +++ b/routes/breadcrumbs.php @@ -669,6 +669,14 @@ try { } ); + Breadcrumbs::register( + 'profile.new-backup-codes', + function (BreadcrumbsGenerator $breadcrumbs) { + $breadcrumbs->parent('home'); + $breadcrumbs->push(trans('breadcrumbs.profile'), route('profile.index')); + } + ); + // PROFILE Breadcrumbs::register( 'profile.index', diff --git a/routes/web.php b/routes/web.php index a24e4fdb31..f1be50bc4e 100644 --- a/routes/web.php +++ b/routes/web.php @@ -644,6 +644,7 @@ Route::group( Route::get('2fa/code', ['uses' => 'ProfileController@code', 'as' => 'code']); Route::post('2fa/code', ['uses' => 'ProfileController@postCode', 'as' => 'code.store']); Route::get('/delete-code', ['uses' => 'ProfileController@deleteCode', 'as' => 'delete-code']); + Route::get('2fa/new-codes', ['uses' => 'ProfileController@newBackupCodes', 'as' => 'new-backup-codes']); } );