middleware( function ($request, $next) { View::share('title', trans('firefly.preferences')); View::share('mainTitleIcon', 'fa-gear'); return $next($request); } ); } /** * @param Google2FA $google2fa * * @return View */ public function code(Google2FA $google2fa) { $domain = $this->getDomain(); $secret = $google2fa->generateSecretKey(16); Session::flash('two-factor-secret', $secret); $image = $google2fa->getQRCodeInline('Firefly III at ' . $domain, auth()->user()->email, $secret, 150); return view('preferences.code', compact('image')); } /** * @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('preferences.index')); } /** * @param AccountRepositoryInterface $repository * * @return View */ public function index(AccountRepositoryInterface $repository) { $accounts = $repository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]); $viewRangePref = Preferences::get('viewRange', '1M'); $viewRange = $viewRangePref->data; $frontPageAccounts = Preferences::get('frontPageAccounts', []); $language = Preferences::get('language', config('firefly.default_language', 'en_US'))->data; $transactionPageSize = Preferences::get('transactionPageSize', 50)->data; $customFiscalYear = Preferences::get('customFiscalYear', 0)->data; $showDepositsFrontpage = 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 = !is_null(Preferences::get('twoFactorAuthSecret')); // hasTwoFactorAuthSecret $showIncomplete = env('SHOW_INCOMPLETE_TRANSLATIONS', false) === true; return view( 'preferences.index', compact( 'language', 'accounts', 'frontPageAccounts', 'tjOptionalFields', 'viewRange', 'customFiscalYear', 'transactionPageSize', 'fiscalYearStart', 'is2faEnabled', 'has2faSecret', 'showIncomplete', 'showDepositsFrontpage' ) ); } /** * @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('preferences.index')); } /** * @param Request $request * * @param UserRepositoryInterface $repository * * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ public function postIndex(Request $request, UserRepositoryInterface $repository) { // front page accounts $frontPageAccounts = []; if (is_array($request->get('frontPageAccounts'))) { foreach ($request->get('frontPageAccounts') as $id) { $frontPageAccounts[] = intval($id); } Preferences::set('frontPageAccounts', $frontPageAccounts); } // view range: Preferences::set('viewRange', $request->get('viewRange')); // forget session values: Session::forget('start'); Session::forget('end'); Session::forget('range'); // custom fiscal year $customFiscalYear = intval($request->get('customFiscalYear')) === 1; $fiscalYearStart = date('m-d', strtotime(strval($request->get('fiscalYearStart')))); Preferences::set('customFiscalYear', $customFiscalYear); Preferences::set('fiscalYearStart', $fiscalYearStart); // show deposits frontpage: $showDepositsFrontpage = intval($request->get('showDepositsFrontpage')) === 1; Preferences::set('showDepositsFrontpage', $showDepositsFrontpage); // save page size: Preferences::set('transactionPageSize', 50); $transactionPageSize = intval($request->get('transactionPageSize')); if ($transactionPageSize > 0 && $transactionPageSize < 1337) { Preferences::set('transactionPageSize', $transactionPageSize); } $twoFactorAuthEnabled = false; $hasTwoFactorAuthSecret = false; if (!$repository->hasRole(auth()->user(), 'demo')) { // two factor auth $twoFactorAuthEnabled = intval($request->get('twoFactorAuthEnabled')); $hasTwoFactorAuthSecret = !is_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')))) { Preferences::set('language', $lang); } // optional fields for transactions: $setOptions = $request->get('tj'); $optionalTj = [ 'interest_date' => isset($setOptions['interest_date']), 'book_date' => isset($setOptions['book_date']), 'process_date' => isset($setOptions['process_date']), 'due_date' => isset($setOptions['due_date']), 'payment_date' => isset($setOptions['payment_date']), 'invoice_date' => isset($setOptions['invoice_date']), 'internal_reference' => isset($setOptions['internal_reference']), 'notes' => isset($setOptions['notes']), 'attachments' => isset($setOptions['attachments']), ]; Preferences::set('transaction_journal_optional_fields', $optionalTj); 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 && $twoFactorAuthEnabled === 1) { 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']; } }