mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-20 11:19:16 +00:00
Move 2FA to profile #1153
This commit is contained in:
@@ -22,11 +22,9 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Http\Controllers;
|
namespace FireflyIII\Http\Controllers;
|
||||||
|
|
||||||
use FireflyIII\Http\Requests\TokenFormRequest;
|
|
||||||
use FireflyIII\Models\AccountType;
|
use FireflyIII\Models\AccountType;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||||
use Google2FA;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Preferences;
|
use Preferences;
|
||||||
use Session;
|
use Session;
|
||||||
@@ -54,35 +52,6 @@ class PreferencesController extends Controller
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return View
|
|
||||||
*/
|
|
||||||
public function code()
|
|
||||||
{
|
|
||||||
$domain = $this->getDomain();
|
|
||||||
$secret = Google2FA::generateSecretKey();
|
|
||||||
Session::flash('two-factor-secret', $secret);
|
|
||||||
$image = Google2FA::getQRCodeInline($domain, auth()->user()->email, $secret, 200);
|
|
||||||
|
|
||||||
return view('preferences.code', compact('image'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
|
||||||
*
|
|
||||||
* @throws \Exception
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public function deleteCode()
|
|
||||||
{
|
|
||||||
Preferences::delete('twoFactorAuthEnabled');
|
|
||||||
Preferences::delete('twoFactorAuthSecret');
|
|
||||||
Session::flash('success', strval(trans('firefly.pref_two_factor_auth_disabled')));
|
|
||||||
Session::flash('info', strval(trans('firefly.pref_two_factor_auth_remove_it')));
|
|
||||||
|
|
||||||
return redirect(route('preferences.index'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param AccountRepositoryInterface $repository
|
* @param AccountRepositoryInterface $repository
|
||||||
*
|
*
|
||||||
@@ -97,12 +66,9 @@ class PreferencesController extends Controller
|
|||||||
$language = Preferences::get('language', config('firefly.default_language', 'en_US'))->data;
|
$language = Preferences::get('language', config('firefly.default_language', 'en_US'))->data;
|
||||||
$listPageSize = Preferences::get('listPageSize', 50)->data;
|
$listPageSize = Preferences::get('listPageSize', 50)->data;
|
||||||
$customFiscalYear = Preferences::get('customFiscalYear', 0)->data;
|
$customFiscalYear = Preferences::get('customFiscalYear', 0)->data;
|
||||||
$showDeps = Preferences::get('showDepositsFrontpage', false)->data;
|
|
||||||
$fiscalYearStartStr = Preferences::get('fiscalYearStart', '01-01')->data;
|
$fiscalYearStartStr = Preferences::get('fiscalYearStart', '01-01')->data;
|
||||||
$fiscalYearStart = date('Y') . '-' . $fiscalYearStartStr;
|
$fiscalYearStart = date('Y') . '-' . $fiscalYearStartStr;
|
||||||
$tjOptionalFields = Preferences::get('transaction_journal_optional_fields', [])->data;
|
$tjOptionalFields = Preferences::get('transaction_journal_optional_fields', [])->data;
|
||||||
$is2faEnabled = Preferences::get('twoFactorAuthEnabled', 0)->data; // twoFactorAuthEnabled
|
|
||||||
$has2faSecret = null !== Preferences::get('twoFactorAuthSecret'); // hasTwoFactorAuthSecret
|
|
||||||
|
|
||||||
return view(
|
return view(
|
||||||
'preferences.index',
|
'preferences.index',
|
||||||
@@ -114,31 +80,11 @@ class PreferencesController extends Controller
|
|||||||
'viewRange',
|
'viewRange',
|
||||||
'customFiscalYear',
|
'customFiscalYear',
|
||||||
'listPageSize',
|
'listPageSize',
|
||||||
'fiscalYearStart',
|
'fiscalYearStart'
|
||||||
'is2faEnabled',
|
|
||||||
'has2faSecret',
|
|
||||||
'showDeps'
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param TokenFormRequest $request
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
|
||||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter) // it's unused but the class does some validation.
|
|
||||||
*/
|
|
||||||
public function postCode(/** @scrutinizer ignore-unused */ TokenFormRequest $request)
|
|
||||||
{
|
|
||||||
Preferences::set('twoFactorAuthEnabled', 1);
|
|
||||||
Preferences::set('twoFactorAuthSecret', Session::get('two-factor-secret'));
|
|
||||||
|
|
||||||
Session::flash('success', strval(trans('firefly.saved_preferences')));
|
|
||||||
Preferences::mark();
|
|
||||||
|
|
||||||
return redirect(route('preferences.index'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @param UserRepositoryInterface $repository
|
* @param UserRepositoryInterface $repository
|
||||||
@@ -169,10 +115,6 @@ class PreferencesController extends Controller
|
|||||||
Preferences::set('customFiscalYear', $customFiscalYear);
|
Preferences::set('customFiscalYear', $customFiscalYear);
|
||||||
Preferences::set('fiscalYearStart', $fiscalYearStart);
|
Preferences::set('fiscalYearStart', $fiscalYearStart);
|
||||||
|
|
||||||
// show deposits frontpage:
|
|
||||||
$showDepositsFrontpage = 1 === intval($request->get('showDepositsFrontpage'));
|
|
||||||
Preferences::set('showDepositsFrontpage', $showDepositsFrontpage);
|
|
||||||
|
|
||||||
// save page size:
|
// save page size:
|
||||||
Preferences::set('listPageSize', 50);
|
Preferences::set('listPageSize', 50);
|
||||||
$listPageSize = intval($request->get('listPageSize'));
|
$listPageSize = intval($request->get('listPageSize'));
|
||||||
@@ -180,19 +122,6 @@ class PreferencesController extends Controller
|
|||||||
Preferences::set('listPageSize', $listPageSize);
|
Preferences::set('listPageSize', $listPageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
$twoFactorAuthEnabled = false;
|
|
||||||
$hasTwoFactorAuthSecret = false;
|
|
||||||
if (!$repository->hasRole(auth()->user(), 'demo')) {
|
|
||||||
// two factor auth
|
|
||||||
$twoFactorAuthEnabled = intval($request->get('twoFactorAuthEnabled'));
|
|
||||||
$hasTwoFactorAuthSecret = null !== Preferences::get('twoFactorAuthSecret');
|
|
||||||
|
|
||||||
// If we already have a secret, just set the two factor auth enabled to 1, and let the user continue with the existing secret.
|
|
||||||
if ($hasTwoFactorAuthSecret) {
|
|
||||||
Preferences::set('twoFactorAuthEnabled', $twoFactorAuthEnabled);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// language:
|
// language:
|
||||||
$lang = $request->get('language');
|
$lang = $request->get('language');
|
||||||
if (in_array($lang, array_keys(config('firefly.languages')))) {
|
if (in_array($lang, array_keys(config('firefly.languages')))) {
|
||||||
@@ -217,23 +146,6 @@ class PreferencesController extends Controller
|
|||||||
Session::flash('success', strval(trans('firefly.saved_preferences')));
|
Session::flash('success', strval(trans('firefly.saved_preferences')));
|
||||||
Preferences::mark();
|
Preferences::mark();
|
||||||
|
|
||||||
// if we don't have a valid secret yet, redirect to the code page.
|
|
||||||
// AND USER HAS ACTUALLY ENABLED 2FA
|
|
||||||
if (!$hasTwoFactorAuthSecret && 1 === $twoFactorAuthEnabled) {
|
|
||||||
return redirect(route('preferences.code'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect(route('preferences.index'));
|
return redirect(route('preferences.index'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function getDomain(): string
|
|
||||||
{
|
|
||||||
$url = url()->to('/');
|
|
||||||
$parts = parse_url($url);
|
|
||||||
|
|
||||||
return $parts['host'];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -31,9 +31,11 @@ use FireflyIII\Http\Middleware\IsSandStormUser;
|
|||||||
use FireflyIII\Http\Requests\DeleteAccountFormRequest;
|
use FireflyIII\Http\Requests\DeleteAccountFormRequest;
|
||||||
use FireflyIII\Http\Requests\EmailFormRequest;
|
use FireflyIII\Http\Requests\EmailFormRequest;
|
||||||
use FireflyIII\Http\Requests\ProfileFormRequest;
|
use FireflyIII\Http\Requests\ProfileFormRequest;
|
||||||
|
use FireflyIII\Http\Requests\TokenFormRequest;
|
||||||
use FireflyIII\Models\Preference;
|
use FireflyIII\Models\Preference;
|
||||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
|
use Google2FA;
|
||||||
use Hash;
|
use Hash;
|
||||||
use Illuminate\Contracts\Auth\Guard;
|
use Illuminate\Contracts\Auth\Guard;
|
||||||
use Log;
|
use Log;
|
||||||
@@ -92,6 +94,50 @@ class ProfileController extends Controller
|
|||||||
return view('profile.change-password', compact('title', 'subTitle', 'subTitleIcon'));
|
return view('profile.change-password', compact('title', 'subTitle', 'subTitleIcon'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||||
|
*/
|
||||||
|
public function deleteCode()
|
||||||
|
{
|
||||||
|
Preferences::delete('twoFactorAuthEnabled');
|
||||||
|
Preferences::delete('twoFactorAuthSecret');
|
||||||
|
Session::flash('success', strval(trans('firefly.pref_two_factor_auth_disabled')));
|
||||||
|
Session::flash('info', strval(trans('firefly.pref_two_factor_auth_remove_it')));
|
||||||
|
|
||||||
|
return redirect(route('profile.index'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* View that generates a 2FA code for the user.
|
||||||
|
* @return View
|
||||||
|
*/
|
||||||
|
public function code()
|
||||||
|
{
|
||||||
|
$domain = $this->getDomain();
|
||||||
|
$secret = Google2FA::generateSecretKey();
|
||||||
|
Session::flash('two-factor-secret', $secret);
|
||||||
|
$image = Google2FA::getQRCodeInline($domain, auth()->user()->email, $secret, 200);
|
||||||
|
|
||||||
|
return view('profile.code', compact('image'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param TokenFormRequest $request
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||||
|
* @SuppressWarnings(PHPMD.UnusedFormalParameter) // it's unused but the class does some validation.
|
||||||
|
*/
|
||||||
|
public function postCode(TokenFormRequest $request)
|
||||||
|
{
|
||||||
|
Preferences::set('twoFactorAuthEnabled', 1);
|
||||||
|
Preferences::set('twoFactorAuthSecret', Session::get('two-factor-secret'));
|
||||||
|
|
||||||
|
Session::flash('success', strval(trans('firefly.saved_preferences')));
|
||||||
|
Preferences::mark();
|
||||||
|
|
||||||
|
return redirect(route('profile.index'));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param UserRepositoryInterface $repository
|
* @param UserRepositoryInterface $repository
|
||||||
* @param string $token
|
* @param string $token
|
||||||
@@ -139,13 +185,37 @@ class ProfileController extends Controller
|
|||||||
return view('profile.delete-account', compact('title', 'subTitle', 'subTitleIcon'));
|
return view('profile.delete-account', compact('title', 'subTitle', 'subTitleIcon'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||||
|
*/
|
||||||
|
public function enable2FA(UserRepositoryInterface $repository)
|
||||||
|
{
|
||||||
|
if ($repository->hasRole(auth()->user(), 'demo')) {
|
||||||
|
return redirect(route('profile.index'));
|
||||||
|
}
|
||||||
|
$hasTwoFactorAuthSecret = (null !== Preferences::get('twoFactorAuthSecret'));
|
||||||
|
|
||||||
|
// if we don't have a valid secret yet, redirect to the code page to get one.
|
||||||
|
if (!$hasTwoFactorAuthSecret) {
|
||||||
|
return redirect(route('profile.code'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If FF3 already has a secret, just set the two factor auth enabled to 1,
|
||||||
|
// and let the user continue with the existing secret.
|
||||||
|
|
||||||
|
Preferences::set('twoFactorAuthEnabled', 1);
|
||||||
|
|
||||||
|
return redirect(route('profile.index'));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return View
|
* @return View
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$subTitle = auth()->user()->email;
|
$subTitle = auth()->user()->email;
|
||||||
$userId = auth()->user()->id;
|
$userId = auth()->user()->id;
|
||||||
|
$enabled2FA = intval(Preferences::get('twoFactorAuthEnabled', 0)->data) === 1;
|
||||||
|
|
||||||
// get access token or create one.
|
// get access token or create one.
|
||||||
$accessToken = Preferences::get('access_token', null);
|
$accessToken = Preferences::get('access_token', null);
|
||||||
@@ -154,7 +224,7 @@ class ProfileController extends Controller
|
|||||||
$accessToken = Preferences::set('access_token', $token);
|
$accessToken = Preferences::set('access_token', $token);
|
||||||
}
|
}
|
||||||
|
|
||||||
return view('profile.index', compact('subTitle', 'userId', 'accessToken'));
|
return view('profile.index', compact('subTitle', 'userId', 'accessToken', 'enabled2FA'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -332,4 +402,15 @@ class ProfileController extends Controller
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function getDomain(): string
|
||||||
|
{
|
||||||
|
$url = url()->to('/');
|
||||||
|
$parts = parse_url($url);
|
||||||
|
|
||||||
|
return $parts['host'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Support;
|
namespace FireflyIII\Support;
|
||||||
|
|
||||||
use Cache;
|
use Cache;
|
||||||
|
use Exception;
|
||||||
use FireflyIII\Models\Preference;
|
use FireflyIII\Models\Preference;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
@@ -50,8 +51,6 @@ class Preferences
|
|||||||
* @param $name
|
* @param $name
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
*/
|
||||||
public function delete(string $name): bool
|
public function delete(string $name): bool
|
||||||
{
|
{
|
||||||
@@ -59,7 +58,11 @@ class Preferences
|
|||||||
if (Cache::has($fullName)) {
|
if (Cache::has($fullName)) {
|
||||||
Cache::forget($fullName);
|
Cache::forget($fullName);
|
||||||
}
|
}
|
||||||
Preference::where('user_id', auth()->user()->id)->where('name', $name)->delete();
|
try {
|
||||||
|
Preference::where('user_id', auth()->user()->id)->where('name', $name)->delete();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// don't care.
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -446,8 +446,7 @@ return [
|
|||||||
'pref_two_factor_auth_code' => 'Verify code',
|
'pref_two_factor_auth_code' => 'Verify code',
|
||||||
'pref_two_factor_auth_code_help' => 'Scan the QR code with an application on your phone such as Authy or Google Authenticator and enter the generated code.',
|
'pref_two_factor_auth_code_help' => 'Scan the QR code with an application on your phone such as Authy or Google Authenticator and enter the generated code.',
|
||||||
'pref_two_factor_auth_reset_code' => 'Reset verification code',
|
'pref_two_factor_auth_reset_code' => 'Reset verification code',
|
||||||
'pref_two_factor_auth_remove_code' => 'Remove verification code',
|
'pref_two_factor_auth_disable_2fa' => 'Disable 2FA',
|
||||||
'pref_two_factor_auth_remove_will_disable' => '(this will also disable two-factor authentication)',
|
|
||||||
'pref_save_settings' => 'Save settings',
|
'pref_save_settings' => 'Save settings',
|
||||||
'saved_preferences' => 'Preferences saved!',
|
'saved_preferences' => 'Preferences saved!',
|
||||||
'preferences_general' => 'General',
|
'preferences_general' => 'General',
|
||||||
|
@@ -15,7 +15,6 @@
|
|||||||
<ul class="nav nav-tabs">
|
<ul class="nav nav-tabs">
|
||||||
<li class="active"><a href="#general" data-toggle="tab" aria-expanded="true">{{ 'preferences_general'|_ }}</a></li>
|
<li class="active"><a href="#general" data-toggle="tab" aria-expanded="true">{{ 'preferences_general'|_ }}</a></li>
|
||||||
<li class=""><a href="#frontpage" data-toggle="tab" aria-expanded="false">{{ 'preferences_frontpage'|_ }}</a></li>
|
<li class=""><a href="#frontpage" data-toggle="tab" aria-expanded="false">{{ 'preferences_frontpage'|_ }}</a></li>
|
||||||
<li class=""><a href="#security" data-toggle="tab" aria-expanded="false">{{ 'preferences_security'|_ }}</a></li>
|
|
||||||
<li class=""><a href="#layout" data-toggle="tab" aria-expanded="false">{{ 'preferences_layout'|_ }}</a></li>
|
<li class=""><a href="#layout" data-toggle="tab" aria-expanded="false">{{ 'preferences_layout'|_ }}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
@@ -116,70 +115,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{# frontpage settings column b #}
|
{# frontpage settings column b #}
|
||||||
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
|
|
||||||
{# show deposit chart #}
|
|
||||||
<div class="preferences-box">
|
|
||||||
<h3>{{ 'pref_home_show_deposits'|_ }}</h3>
|
|
||||||
<p class="text-info">{{ 'pref_home_show_deposits_info'|_ }}</p>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<div class="checkbox">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox" name="showDepositsFrontpage[]" value="{{ showDeps }}"
|
|
||||||
{% if showDeps %}
|
|
||||||
checked
|
|
||||||
{% endif %}
|
|
||||||
> {{ 'pref_home_do_show_deposits'|_ }}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="tab-pane" id="security">
|
|
||||||
{# security settings here #}
|
|
||||||
<div class="row">
|
|
||||||
{# security settings column A #}
|
|
||||||
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
|
|
||||||
|
|
||||||
{# 2fa #}
|
|
||||||
<div class="preferences-box">
|
|
||||||
<h3>{{ 'pref_two_factor_auth'|_ }}</h3>
|
|
||||||
<p class="text-info">{{ 'pref_two_factor_auth_help'|_ }}</p>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<div class="checkbox">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox" name="twoFactorAuthEnabled" value="1"
|
|
||||||
{% if is2faEnabled == '1' %} checked {% endif %}> {{ 'pref_enable_two_factor_auth'|_ }}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% if is2faEnabled == 1 and has2faSecret == true %}
|
|
||||||
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<div class="checkbox">
|
|
||||||
<label>
|
|
||||||
<a href="{{ route('preferences.code') }}">{{ 'pref_two_factor_auth_reset_code'|_ }}</a>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="checkbox">
|
|
||||||
<label>
|
|
||||||
<a href="{{ route('preferences.delete-code') }}">{{ 'pref_two_factor_auth_remove_code'|_ }}</a>
|
|
||||||
{{ 'pref_two_factor_auth_remove_will_disable'|_ }}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{# security settings column B #}
|
|
||||||
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
|
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -5,10 +5,10 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form method="POST" action="{{ route('preferences.code.store') }}" accept-charset="UTF-8" class="form-horizontal" id="preferences_code">
|
<form method="POST" action="{{ route('profile.code.store') }}" accept-charset="UTF-8" class="form-horizontal" id="preferences_code">
|
||||||
<input name="_token" type="hidden" value="{{ csrf_token() }}">
|
<input name="_token" type="hidden" value="{{ csrf_token() }}">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-6 col-md-6 col-sm-6">
|
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12 col-xs-12">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="box-header with-border">
|
<div class="box-header with-border">
|
||||||
<h3 class="box-title">{{ 'pref_two_factor_auth_code'|_ }}</h3>
|
<h3 class="box-title">{{ 'pref_two_factor_auth_code'|_ }}</h3>
|
||||||
@@ -19,22 +19,21 @@
|
|||||||
</p>
|
</p>
|
||||||
<div class="form group">
|
<div class="form group">
|
||||||
<div class="col-sm-8 col-md-offset-4">
|
<div class="col-sm-8 col-md-offset-4">
|
||||||
<img src="{{ image }}" alt="" title=""/>
|
<img src="{{ image }}" alt="" title=""
|
||||||
<br/><br/>
|
style="border:1px #ddd solid;"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{ ExpandedForm.text('code', code) }}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12 col-xs-12">
|
||||||
<div class="form-group">
|
<div class="box">
|
||||||
<div class="col-sm-12">
|
<div class="box-body">
|
||||||
|
{{ ExpandedForm.text('code', code) }}
|
||||||
|
</div>
|
||||||
|
<div class="box-footer">
|
||||||
<button type="submit" class="btn btn-success btn-lg">{{ 'pref_save_settings'|_ }}</button>
|
<button type="submit" class="btn btn-success btn-lg">{{ 'pref_save_settings'|_ }}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -43,12 +42,12 @@
|
|||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(function () {
|
$(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// Focus first visible form element.
|
// Focus first visible form element.
|
||||||
$("form#preferences_code input:enabled:visible:first").first().select();
|
$("form#preferences_code input:enabled:visible:first").first().select();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-6 col-lg-offset-3 col-md-6 col-sm-12">
|
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
|
||||||
<div class="box box-primary">
|
<div class="box box-primary">
|
||||||
<div class="box-header with-border">
|
<div class="box-header with-border">
|
||||||
<h3 class="box-title">{{ 'options'|_ }}</h3>
|
<h3 class="box-title">{{ 'options'|_ }}</h3>
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-6 col-lg-offset-3 col-md-6 col-sm-12">
|
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
|
||||||
<div class="box box-primary">
|
<div class="box box-primary">
|
||||||
<div class="box-header with-border">
|
<div class="box-header with-border">
|
||||||
<h3 class="box-title">{{ 'command_line_token'|_ }}</h3>
|
<h3 class="box-title">{{ 'command_line_token'|_ }}</h3>
|
||||||
@@ -53,18 +53,49 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-6 col-lg-offset-3 col-md-6 col-sm-12">
|
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
|
||||||
|
<div class="box box-primary">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title">{{ 'pref_two_factor_auth'|_ }}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="box-body">
|
||||||
|
<p class="text-info">{{ 'pref_two_factor_auth_help'|_ }}</p>
|
||||||
|
{% if enabled2FA == true %}
|
||||||
|
|
||||||
|
<div class="btn-group">
|
||||||
|
<a class="btn btn-info" href="{{ route('profile.code') }}">
|
||||||
|
<i class="fa fa-recycle"></i>
|
||||||
|
{{ 'pref_two_factor_auth_reset_code'|_ }}</a>
|
||||||
|
<a class="btn btn-danger" href="{{ route('profile.delete-code') }}">
|
||||||
|
<i class="fa fa-trash"></i>
|
||||||
|
{{ 'pref_two_factor_auth_disable_2fa'|_ }}</a>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<p>
|
||||||
|
<form action="{{ route('profile.enable2FA') }}" method="post">
|
||||||
|
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
|
||||||
|
<button type="submit" class="btn btn-info"><i class="fa fa-lock"></i> {{ 'pref_enable_two_factor_auth'|_ }}</button>
|
||||||
|
</form>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
|
||||||
<passport-clients></passport-clients>
|
<passport-clients></passport-clients>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-6 col-lg-offset-3 col-md-6 col-sm-12">
|
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
|
||||||
<passport-authorized-clients></passport-authorized-clients>
|
<passport-authorized-clients></passport-authorized-clients>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-6 col-lg-offset-3 col-md-6 col-sm-12">
|
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
|
||||||
<passport-personal-access-tokens></passport-personal-access-tokens>
|
<passport-personal-access-tokens></passport-personal-access-tokens>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -602,10 +602,10 @@ Breadcrumbs::register(
|
|||||||
);
|
);
|
||||||
|
|
||||||
Breadcrumbs::register(
|
Breadcrumbs::register(
|
||||||
'preferences.code',
|
'profile.code',
|
||||||
function (BreadCrumbsGenerator $breadcrumbs) {
|
function (BreadCrumbsGenerator $breadcrumbs) {
|
||||||
$breadcrumbs->parent('home');
|
$breadcrumbs->parent('home');
|
||||||
$breadcrumbs->push(trans('breadcrumbs.preferences'), route('preferences.index'));
|
$breadcrumbs->push(trans('breadcrumbs.profile'), route('profile.index'));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -566,10 +566,8 @@ Route::group(
|
|||||||
Route::group(
|
Route::group(
|
||||||
['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers', 'prefix' => 'preferences', 'as' => 'preferences.'], function () {
|
['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers', 'prefix' => 'preferences', 'as' => 'preferences.'], function () {
|
||||||
Route::get('', ['uses' => 'PreferencesController@index', 'as' => 'index']);
|
Route::get('', ['uses' => 'PreferencesController@index', 'as' => 'index']);
|
||||||
Route::get('/code', ['uses' => 'PreferencesController@code', 'as' => 'code']);
|
|
||||||
Route::get('/delete-code', ['uses' => 'PreferencesController@deleteCode', 'as' => 'delete-code']);
|
|
||||||
Route::post('', ['uses' => 'PreferencesController@postIndex', 'as' => 'update']);
|
Route::post('', ['uses' => 'PreferencesController@postIndex', 'as' => 'update']);
|
||||||
Route::post('/code', ['uses' => 'PreferencesController@postCode', 'as' => 'code.store']);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -589,6 +587,13 @@ Route::group(
|
|||||||
Route::post('change-password', ['uses' => 'ProfileController@postChangePassword', 'as' => 'change-password.post']);
|
Route::post('change-password', ['uses' => 'ProfileController@postChangePassword', 'as' => 'change-password.post']);
|
||||||
Route::post('change-email', ['uses' => 'ProfileController@postChangeEmail', 'as' => 'change-email.post']);
|
Route::post('change-email', ['uses' => 'ProfileController@postChangeEmail', 'as' => 'change-email.post']);
|
||||||
Route::post('regenerate', ['uses' => 'ProfileController@regenerate', 'as' => 'regenerate']);
|
Route::post('regenerate', ['uses' => 'ProfileController@regenerate', 'as' => 'regenerate']);
|
||||||
|
|
||||||
|
// new 2FA routes
|
||||||
|
Route::post('enable2FA', ['uses' => 'ProfileController@enable2FA', 'as' => 'enable2FA']);
|
||||||
|
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']);
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user