mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2024-12-25 08:21:08 -06:00
Move 2FA to profile #1153
This commit is contained in:
parent
ad18b9b81b
commit
dff2d716a1
@ -22,11 +22,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use FireflyIII\Http\Requests\TokenFormRequest;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use Google2FA;
|
||||
use Illuminate\Http\Request;
|
||||
use Preferences;
|
||||
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
|
||||
*
|
||||
@ -97,12 +66,9 @@ class PreferencesController extends Controller
|
||||
$language = Preferences::get('language', config('firefly.default_language', 'en_US'))->data;
|
||||
$listPageSize = Preferences::get('listPageSize', 50)->data;
|
||||
$customFiscalYear = Preferences::get('customFiscalYear', 0)->data;
|
||||
$showDeps = Preferences::get('showDepositsFrontpage', false)->data;
|
||||
$fiscalYearStartStr = Preferences::get('fiscalYearStart', '01-01')->data;
|
||||
$fiscalYearStart = date('Y') . '-' . $fiscalYearStartStr;
|
||||
$tjOptionalFields = Preferences::get('transaction_journal_optional_fields', [])->data;
|
||||
$is2faEnabled = Preferences::get('twoFactorAuthEnabled', 0)->data; // twoFactorAuthEnabled
|
||||
$has2faSecret = null !== Preferences::get('twoFactorAuthSecret'); // hasTwoFactorAuthSecret
|
||||
|
||||
return view(
|
||||
'preferences.index',
|
||||
@ -114,31 +80,11 @@ class PreferencesController extends Controller
|
||||
'viewRange',
|
||||
'customFiscalYear',
|
||||
'listPageSize',
|
||||
'fiscalYearStart',
|
||||
'is2faEnabled',
|
||||
'has2faSecret',
|
||||
'showDeps'
|
||||
'fiscalYearStart'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 UserRepositoryInterface $repository
|
||||
@ -169,10 +115,6 @@ class PreferencesController extends Controller
|
||||
Preferences::set('customFiscalYear', $customFiscalYear);
|
||||
Preferences::set('fiscalYearStart', $fiscalYearStart);
|
||||
|
||||
// show deposits frontpage:
|
||||
$showDepositsFrontpage = 1 === intval($request->get('showDepositsFrontpage'));
|
||||
Preferences::set('showDepositsFrontpage', $showDepositsFrontpage);
|
||||
|
||||
// save page size:
|
||||
Preferences::set('listPageSize', 50);
|
||||
$listPageSize = intval($request->get('listPageSize'));
|
||||
@ -180,19 +122,6 @@ class PreferencesController extends Controller
|
||||
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:
|
||||
$lang = $request->get('language');
|
||||
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')));
|
||||
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 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\EmailFormRequest;
|
||||
use FireflyIII\Http\Requests\ProfileFormRequest;
|
||||
use FireflyIII\Http\Requests\TokenFormRequest;
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Google2FA;
|
||||
use Hash;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Log;
|
||||
@ -92,6 +94,50 @@ class ProfileController extends Controller
|
||||
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 string $token
|
||||
@ -139,13 +185,37 @@ class ProfileController extends Controller
|
||||
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
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$subTitle = auth()->user()->email;
|
||||
$userId = auth()->user()->id;
|
||||
$subTitle = auth()->user()->email;
|
||||
$userId = auth()->user()->id;
|
||||
$enabled2FA = intval(Preferences::get('twoFactorAuthEnabled', 0)->data) === 1;
|
||||
|
||||
// get access token or create one.
|
||||
$accessToken = Preferences::get('access_token', null);
|
||||
@ -154,7 +224,7 @@ class ProfileController extends Controller
|
||||
$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 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;
|
||||
|
||||
use Cache;
|
||||
use Exception;
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\Collection;
|
||||
@ -50,8 +51,6 @@ class Preferences
|
||||
* @param $name
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function delete(string $name): bool
|
||||
{
|
||||
@ -59,7 +58,11 @@ class Preferences
|
||||
if (Cache::has($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;
|
||||
}
|
||||
|
@ -446,8 +446,7 @@ return [
|
||||
'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_reset_code' => 'Reset verification code',
|
||||
'pref_two_factor_auth_remove_code' => 'Remove verification code',
|
||||
'pref_two_factor_auth_remove_will_disable' => '(this will also disable two-factor authentication)',
|
||||
'pref_two_factor_auth_disable_2fa' => 'Disable 2FA',
|
||||
'pref_save_settings' => 'Save settings',
|
||||
'saved_preferences' => 'Preferences saved!',
|
||||
'preferences_general' => 'General',
|
||||
|
@ -15,7 +15,6 @@
|
||||
<ul class="nav nav-tabs">
|
||||
<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="#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>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
@ -116,70 +115,6 @@
|
||||
</div>
|
||||
</div>
|
||||
{# 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>
|
||||
</div>
|
||||
|
@ -5,10 +5,10 @@
|
||||
{% endblock %}
|
||||
|
||||
{% 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() }}">
|
||||
<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-header with-border">
|
||||
<h3 class="box-title">{{ 'pref_two_factor_auth_code'|_ }}</h3>
|
||||
@ -19,22 +19,21 @@
|
||||
</p>
|
||||
<div class="form group">
|
||||
<div class="col-sm-8 col-md-offset-4">
|
||||
<img src="{{ image }}" alt="" title=""/>
|
||||
<br/><br/>
|
||||
<img src="{{ image }}" alt="" title=""
|
||||
style="border:1px #ddd solid;"/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{{ ExpandedForm.text('code', code) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12 col-xs-12">
|
||||
<div class="box">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
@ -43,12 +42,12 @@
|
||||
</form>
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
"use strict";
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
"use strict";
|
||||
|
||||
// Focus first visible form element.
|
||||
$("form#preferences_code input:enabled:visible:first").first().select();
|
||||
});
|
||||
</script>
|
||||
// Focus first visible form element.
|
||||
$("form#preferences_code input:enabled:visible:first").first().select();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
|
||||
<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">{{ 'options'|_ }}</h3>
|
||||
@ -30,7 +30,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<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">{{ 'command_line_token'|_ }}</h3>
|
||||
@ -53,18 +53,49 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -602,10 +602,10 @@ Breadcrumbs::register(
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'preferences.code',
|
||||
'profile.code',
|
||||
function (BreadCrumbsGenerator $breadcrumbs) {
|
||||
$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(
|
||||
['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers', 'prefix' => 'preferences', 'as' => 'preferences.'], function () {
|
||||
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('/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-email', ['uses' => 'ProfileController@postChangeEmail', 'as' => 'change-email.post']);
|
||||
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']);
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user