Clean up authentication views.

This commit is contained in:
James Cole 2024-03-09 08:13:53 +01:00
parent 591c9e3b39
commit 46a60af966
No known key found for this signature in database
GPG Key ID: B49A324B7EAD6D80
54 changed files with 23996 additions and 108 deletions

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Auth;
use Cookie;
use FireflyIII\Events\ActuallyLoggedIn;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Http\Controllers\Controller;
@ -75,12 +74,21 @@ class LoginController extends Controller
*
* @throws ValidationException
*/
public function login(Request $request): JsonResponse|RedirectResponse
public function login(Request $request): JsonResponse | RedirectResponse
{
Log::channel('audit')->info(sprintf('User is trying to login using "%s"', $request->get($this->username())));
app('log')->debug('User is trying to login.');
$this->validateLogin($request);
try {
$this->validateLogin($request);
} catch (ValidationException $e) {
return redirect(route('login'))
->withErrors(
[
$this->username => trans('auth.failed')
]
)
->onlyInput($this->username);
}
app('log')->debug('Login data is present.');
// Copied directly from AuthenticatesUsers, but with logging added:
@ -91,7 +99,6 @@ class LoginController extends Controller
Log::channel('audit')->warning(sprintf('Login for user "%s" was locked out.', $request->get($this->username())));
app('log')->error(sprintf('Login for user "%s" was locked out.', $request->get($this->username())));
$this->fireLockoutEvent($request);
$this->sendLockoutResponse($request);
}
// Copied directly from AuthenticatesUsers, but with logging added:
@ -118,6 +125,7 @@ class LoginController extends Controller
$this->sendFailedLoginResponse($request);
// @noinspection PhpUnreachableStatementInspection
return response()->json([]);
}
@ -158,8 +166,8 @@ class LoginController extends Controller
*/
public function logout(Request $request)
{
$authGuard = config('firefly.authentication_guard');
$logoutUrl = config('firefly.custom_logout_url');
$authGuard = config('firefly.authentication_guard');
$logoutUrl = config('firefly.custom_logout_url');
if ('remote_user_guard' === $authGuard && '' !== $logoutUrl) {
return redirect($logoutUrl);
}
@ -195,9 +203,9 @@ class LoginController extends Controller
{
Log::channel('audit')->info('Show login form (1.1).');
$count = \DB::table('users')->count();
$guard = config('auth.defaults.guard');
$title = (string)trans('firefly.login_page_title');
$count = \DB::table('users')->count();
$guard = config('auth.defaults.guard');
$title = (string)trans('firefly.login_page_title');
if (0 === $count && 'web' === $guard) {
return redirect(route('register'));
@ -217,15 +225,16 @@ class LoginController extends Controller
$allowReset = false;
}
$email = $request->old('email');
$remember = $request->old('remember');
$email = $request->old('email');
$remember = $request->old('remember');
$storeInCookie = config('google2fa.store_in_cookie', false);
$storeInCookie = config('google2fa.store_in_cookie', false);
if (false !== $storeInCookie) {
$cookieName = config('google2fa.cookie_name', 'google2fa_token');
request()->cookies->set($cookieName, 'invalid');
}
$usernameField = $this->username();
$usernameField = $this->username();
return view('auth.login', compact('allowRegistration', 'email', 'remember', 'allowReset', 'title', 'usernameField'));
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4494
public/v2-local/bs/js/bootstrap.js vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

9
public/v2-local/fa/css/all.min.css vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

6
public/v2-local/fa/css/brands.min.css vendored Normal file

File diff suppressed because one or more lines are too long

6369
public/v2-local/fa/css/fontawesome.css vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,19 @@
/*!
* Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2023 Fonticons, Inc.
*/
:root, :host {
--fa-style-family-classic: 'Font Awesome 6 Free';
--fa-font-regular: normal 400 1em/1 'Font Awesome 6 Free'; }
@font-face {
font-family: 'Font Awesome 6 Free';
font-style: normal;
font-weight: 400;
font-display: block;
src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); }
.far,
.fa-regular {
font-weight: 400; }

View File

@ -0,0 +1,6 @@
/*!
* Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2023 Fonticons, Inc.
*/
:host,:root{--fa-style-family-classic:"Font Awesome 6 Free";--fa-font-regular:normal 400 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")}.fa-regular,.far{font-weight:400}

View File

@ -0,0 +1,19 @@
/*!
* Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2023 Fonticons, Inc.
*/
:root, :host {
--fa-style-family-classic: 'Font Awesome 6 Free';
--fa-font-solid: normal 900 1em/1 'Font Awesome 6 Free'; }
@font-face {
font-family: 'Font Awesome 6 Free';
font-style: normal;
font-weight: 900;
font-display: block;
src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); }
.fas,
.fa-solid {
font-weight: 900; }

6
public/v2-local/fa/css/solid.min.css vendored Normal file
View File

@ -0,0 +1,6 @@
/*!
* Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2023 Fonticons, Inc.
*/
:host,:root{--fa-style-family-classic:"Font Awesome 6 Free";--fa-font-solid:normal 900 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}.fa-solid,.fas{font-weight:900}

View File

@ -0,0 +1,640 @@
/*!
* Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2023 Fonticons, Inc.
*/
:root, :host {
--fa-font-solid: normal 900 1em/1 'Font Awesome 6 Solid';
--fa-font-regular: normal 400 1em/1 'Font Awesome 6 Regular';
--fa-font-light: normal 300 1em/1 'Font Awesome 6 Light';
--fa-font-thin: normal 100 1em/1 'Font Awesome 6 Thin';
--fa-font-duotone: normal 900 1em/1 'Font Awesome 6 Duotone';
--fa-font-sharp-solid: normal 900 1em/1 'Font Awesome 6 Sharp';
--fa-font-sharp-regular: normal 400 1em/1 'Font Awesome 6 Sharp';
--fa-font-sharp-light: normal 300 1em/1 'Font Awesome 6 Sharp';
--fa-font-sharp-thin: normal 100 1em/1 'Font Awesome 6 Sharp';
--fa-font-brands: normal 400 1em/1 'Font Awesome 6 Brands'; }
svg:not(:root).svg-inline--fa, svg:not(:host).svg-inline--fa {
overflow: visible;
box-sizing: content-box; }
.svg-inline--fa {
display: var(--fa-display, inline-block);
height: 1em;
overflow: visible;
vertical-align: -.125em; }
.svg-inline--fa.fa-2xs {
vertical-align: 0.1em; }
.svg-inline--fa.fa-xs {
vertical-align: 0em; }
.svg-inline--fa.fa-sm {
vertical-align: -0.07143em; }
.svg-inline--fa.fa-lg {
vertical-align: -0.2em; }
.svg-inline--fa.fa-xl {
vertical-align: -0.25em; }
.svg-inline--fa.fa-2xl {
vertical-align: -0.3125em; }
.svg-inline--fa.fa-pull-left {
margin-right: var(--fa-pull-margin, 0.3em);
width: auto; }
.svg-inline--fa.fa-pull-right {
margin-left: var(--fa-pull-margin, 0.3em);
width: auto; }
.svg-inline--fa.fa-li {
width: var(--fa-li-width, 2em);
top: 0.25em; }
.svg-inline--fa.fa-fw {
width: var(--fa-fw-width, 1.25em); }
.fa-layers svg.svg-inline--fa {
bottom: 0;
left: 0;
margin: auto;
position: absolute;
right: 0;
top: 0; }
.fa-layers-text, .fa-layers-counter {
display: inline-block;
position: absolute;
text-align: center; }
.fa-layers {
display: inline-block;
height: 1em;
position: relative;
text-align: center;
vertical-align: -.125em;
width: 1em; }
.fa-layers svg.svg-inline--fa {
-webkit-transform-origin: center center;
transform-origin: center center; }
.fa-layers-text {
left: 50%;
top: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
-webkit-transform-origin: center center;
transform-origin: center center; }
.fa-layers-counter {
background-color: var(--fa-counter-background-color, #ff253a);
border-radius: var(--fa-counter-border-radius, 1em);
box-sizing: border-box;
color: var(--fa-inverse, #fff);
line-height: var(--fa-counter-line-height, 1);
max-width: var(--fa-counter-max-width, 5em);
min-width: var(--fa-counter-min-width, 1.5em);
overflow: hidden;
padding: var(--fa-counter-padding, 0.25em 0.5em);
right: var(--fa-right, 0);
text-overflow: ellipsis;
top: var(--fa-top, 0);
-webkit-transform: scale(var(--fa-counter-scale, 0.25));
transform: scale(var(--fa-counter-scale, 0.25));
-webkit-transform-origin: top right;
transform-origin: top right; }
.fa-layers-bottom-right {
bottom: var(--fa-bottom, 0);
right: var(--fa-right, 0);
top: auto;
-webkit-transform: scale(var(--fa-layers-scale, 0.25));
transform: scale(var(--fa-layers-scale, 0.25));
-webkit-transform-origin: bottom right;
transform-origin: bottom right; }
.fa-layers-bottom-left {
bottom: var(--fa-bottom, 0);
left: var(--fa-left, 0);
right: auto;
top: auto;
-webkit-transform: scale(var(--fa-layers-scale, 0.25));
transform: scale(var(--fa-layers-scale, 0.25));
-webkit-transform-origin: bottom left;
transform-origin: bottom left; }
.fa-layers-top-right {
top: var(--fa-top, 0);
right: var(--fa-right, 0);
-webkit-transform: scale(var(--fa-layers-scale, 0.25));
transform: scale(var(--fa-layers-scale, 0.25));
-webkit-transform-origin: top right;
transform-origin: top right; }
.fa-layers-top-left {
left: var(--fa-left, 0);
right: auto;
top: var(--fa-top, 0);
-webkit-transform: scale(var(--fa-layers-scale, 0.25));
transform: scale(var(--fa-layers-scale, 0.25));
-webkit-transform-origin: top left;
transform-origin: top left; }
.fa-1x {
font-size: 1em; }
.fa-2x {
font-size: 2em; }
.fa-3x {
font-size: 3em; }
.fa-4x {
font-size: 4em; }
.fa-5x {
font-size: 5em; }
.fa-6x {
font-size: 6em; }
.fa-7x {
font-size: 7em; }
.fa-8x {
font-size: 8em; }
.fa-9x {
font-size: 9em; }
.fa-10x {
font-size: 10em; }
.fa-2xs {
font-size: 0.625em;
line-height: 0.1em;
vertical-align: 0.225em; }
.fa-xs {
font-size: 0.75em;
line-height: 0.08333em;
vertical-align: 0.125em; }
.fa-sm {
font-size: 0.875em;
line-height: 0.07143em;
vertical-align: 0.05357em; }
.fa-lg {
font-size: 1.25em;
line-height: 0.05em;
vertical-align: -0.075em; }
.fa-xl {
font-size: 1.5em;
line-height: 0.04167em;
vertical-align: -0.125em; }
.fa-2xl {
font-size: 2em;
line-height: 0.03125em;
vertical-align: -0.1875em; }
.fa-fw {
text-align: center;
width: 1.25em; }
.fa-ul {
list-style-type: none;
margin-left: var(--fa-li-margin, 2.5em);
padding-left: 0; }
.fa-ul > li {
position: relative; }
.fa-li {
left: calc(var(--fa-li-width, 2em) * -1);
position: absolute;
text-align: center;
width: var(--fa-li-width, 2em);
line-height: inherit; }
.fa-border {
border-color: var(--fa-border-color, #eee);
border-radius: var(--fa-border-radius, 0.1em);
border-style: var(--fa-border-style, solid);
border-width: var(--fa-border-width, 0.08em);
padding: var(--fa-border-padding, 0.2em 0.25em 0.15em); }
.fa-pull-left {
float: left;
margin-right: var(--fa-pull-margin, 0.3em); }
.fa-pull-right {
float: right;
margin-left: var(--fa-pull-margin, 0.3em); }
.fa-beat {
-webkit-animation-name: fa-beat;
animation-name: fa-beat;
-webkit-animation-delay: var(--fa-animation-delay, 0s);
animation-delay: var(--fa-animation-delay, 0s);
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 1s);
animation-duration: var(--fa-animation-duration, 1s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, ease-in-out);
animation-timing-function: var(--fa-animation-timing, ease-in-out); }
.fa-bounce {
-webkit-animation-name: fa-bounce;
animation-name: fa-bounce;
-webkit-animation-delay: var(--fa-animation-delay, 0s);
animation-delay: var(--fa-animation-delay, 0s);
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 1s);
animation-duration: var(--fa-animation-duration, 1s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.28, 0.84, 0.42, 1));
animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.28, 0.84, 0.42, 1)); }
.fa-fade {
-webkit-animation-name: fa-fade;
animation-name: fa-fade;
-webkit-animation-delay: var(--fa-animation-delay, 0s);
animation-delay: var(--fa-animation-delay, 0s);
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 1s);
animation-duration: var(--fa-animation-duration, 1s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));
animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1)); }
.fa-beat-fade {
-webkit-animation-name: fa-beat-fade;
animation-name: fa-beat-fade;
-webkit-animation-delay: var(--fa-animation-delay, 0s);
animation-delay: var(--fa-animation-delay, 0s);
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 1s);
animation-duration: var(--fa-animation-duration, 1s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));
animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1)); }
.fa-flip {
-webkit-animation-name: fa-flip;
animation-name: fa-flip;
-webkit-animation-delay: var(--fa-animation-delay, 0s);
animation-delay: var(--fa-animation-delay, 0s);
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 1s);
animation-duration: var(--fa-animation-duration, 1s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, ease-in-out);
animation-timing-function: var(--fa-animation-timing, ease-in-out); }
.fa-shake {
-webkit-animation-name: fa-shake;
animation-name: fa-shake;
-webkit-animation-delay: var(--fa-animation-delay, 0s);
animation-delay: var(--fa-animation-delay, 0s);
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 1s);
animation-duration: var(--fa-animation-duration, 1s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, linear);
animation-timing-function: var(--fa-animation-timing, linear); }
.fa-spin {
-webkit-animation-name: fa-spin;
animation-name: fa-spin;
-webkit-animation-delay: var(--fa-animation-delay, 0s);
animation-delay: var(--fa-animation-delay, 0s);
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 2s);
animation-duration: var(--fa-animation-duration, 2s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, linear);
animation-timing-function: var(--fa-animation-timing, linear); }
.fa-spin-reverse {
--fa-animation-direction: reverse; }
.fa-pulse,
.fa-spin-pulse {
-webkit-animation-name: fa-spin;
animation-name: fa-spin;
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 1s);
animation-duration: var(--fa-animation-duration, 1s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, steps(8));
animation-timing-function: var(--fa-animation-timing, steps(8)); }
@media (prefers-reduced-motion: reduce) {
.fa-beat,
.fa-bounce,
.fa-fade,
.fa-beat-fade,
.fa-flip,
.fa-pulse,
.fa-shake,
.fa-spin,
.fa-spin-pulse {
-webkit-animation-delay: -1ms;
animation-delay: -1ms;
-webkit-animation-duration: 1ms;
animation-duration: 1ms;
-webkit-animation-iteration-count: 1;
animation-iteration-count: 1;
-webkit-transition-delay: 0s;
transition-delay: 0s;
-webkit-transition-duration: 0s;
transition-duration: 0s; } }
@-webkit-keyframes fa-beat {
0%, 90% {
-webkit-transform: scale(1);
transform: scale(1); }
45% {
-webkit-transform: scale(var(--fa-beat-scale, 1.25));
transform: scale(var(--fa-beat-scale, 1.25)); } }
@keyframes fa-beat {
0%, 90% {
-webkit-transform: scale(1);
transform: scale(1); }
45% {
-webkit-transform: scale(var(--fa-beat-scale, 1.25));
transform: scale(var(--fa-beat-scale, 1.25)); } }
@-webkit-keyframes fa-bounce {
0% {
-webkit-transform: scale(1, 1) translateY(0);
transform: scale(1, 1) translateY(0); }
10% {
-webkit-transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);
transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0); }
30% {
-webkit-transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));
transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em)); }
50% {
-webkit-transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);
transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0); }
57% {
-webkit-transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));
transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em)); }
64% {
-webkit-transform: scale(1, 1) translateY(0);
transform: scale(1, 1) translateY(0); }
100% {
-webkit-transform: scale(1, 1) translateY(0);
transform: scale(1, 1) translateY(0); } }
@keyframes fa-bounce {
0% {
-webkit-transform: scale(1, 1) translateY(0);
transform: scale(1, 1) translateY(0); }
10% {
-webkit-transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);
transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0); }
30% {
-webkit-transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));
transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em)); }
50% {
-webkit-transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);
transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0); }
57% {
-webkit-transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));
transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em)); }
64% {
-webkit-transform: scale(1, 1) translateY(0);
transform: scale(1, 1) translateY(0); }
100% {
-webkit-transform: scale(1, 1) translateY(0);
transform: scale(1, 1) translateY(0); } }
@-webkit-keyframes fa-fade {
50% {
opacity: var(--fa-fade-opacity, 0.4); } }
@keyframes fa-fade {
50% {
opacity: var(--fa-fade-opacity, 0.4); } }
@-webkit-keyframes fa-beat-fade {
0%, 100% {
opacity: var(--fa-beat-fade-opacity, 0.4);
-webkit-transform: scale(1);
transform: scale(1); }
50% {
opacity: 1;
-webkit-transform: scale(var(--fa-beat-fade-scale, 1.125));
transform: scale(var(--fa-beat-fade-scale, 1.125)); } }
@keyframes fa-beat-fade {
0%, 100% {
opacity: var(--fa-beat-fade-opacity, 0.4);
-webkit-transform: scale(1);
transform: scale(1); }
50% {
opacity: 1;
-webkit-transform: scale(var(--fa-beat-fade-scale, 1.125));
transform: scale(var(--fa-beat-fade-scale, 1.125)); } }
@-webkit-keyframes fa-flip {
50% {
-webkit-transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));
transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg)); } }
@keyframes fa-flip {
50% {
-webkit-transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));
transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg)); } }
@-webkit-keyframes fa-shake {
0% {
-webkit-transform: rotate(-15deg);
transform: rotate(-15deg); }
4% {
-webkit-transform: rotate(15deg);
transform: rotate(15deg); }
8%, 24% {
-webkit-transform: rotate(-18deg);
transform: rotate(-18deg); }
12%, 28% {
-webkit-transform: rotate(18deg);
transform: rotate(18deg); }
16% {
-webkit-transform: rotate(-22deg);
transform: rotate(-22deg); }
20% {
-webkit-transform: rotate(22deg);
transform: rotate(22deg); }
32% {
-webkit-transform: rotate(-12deg);
transform: rotate(-12deg); }
36% {
-webkit-transform: rotate(12deg);
transform: rotate(12deg); }
40%, 100% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); } }
@keyframes fa-shake {
0% {
-webkit-transform: rotate(-15deg);
transform: rotate(-15deg); }
4% {
-webkit-transform: rotate(15deg);
transform: rotate(15deg); }
8%, 24% {
-webkit-transform: rotate(-18deg);
transform: rotate(-18deg); }
12%, 28% {
-webkit-transform: rotate(18deg);
transform: rotate(18deg); }
16% {
-webkit-transform: rotate(-22deg);
transform: rotate(-22deg); }
20% {
-webkit-transform: rotate(22deg);
transform: rotate(22deg); }
32% {
-webkit-transform: rotate(-12deg);
transform: rotate(-12deg); }
36% {
-webkit-transform: rotate(12deg);
transform: rotate(12deg); }
40%, 100% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); } }
@-webkit-keyframes fa-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); }
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg); } }
@keyframes fa-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); }
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg); } }
.fa-rotate-90 {
-webkit-transform: rotate(90deg);
transform: rotate(90deg); }
.fa-rotate-180 {
-webkit-transform: rotate(180deg);
transform: rotate(180deg); }
.fa-rotate-270 {
-webkit-transform: rotate(270deg);
transform: rotate(270deg); }
.fa-flip-horizontal {
-webkit-transform: scale(-1, 1);
transform: scale(-1, 1); }
.fa-flip-vertical {
-webkit-transform: scale(1, -1);
transform: scale(1, -1); }
.fa-flip-both,
.fa-flip-horizontal.fa-flip-vertical {
-webkit-transform: scale(-1, -1);
transform: scale(-1, -1); }
.fa-rotate-by {
-webkit-transform: rotate(var(--fa-rotate-angle, none));
transform: rotate(var(--fa-rotate-angle, none)); }
.fa-stack {
display: inline-block;
vertical-align: middle;
height: 2em;
position: relative;
width: 2.5em; }
.fa-stack-1x,
.fa-stack-2x {
bottom: 0;
left: 0;
margin: auto;
position: absolute;
right: 0;
top: 0;
z-index: var(--fa-stack-z-index, auto); }
.svg-inline--fa.fa-stack-1x {
height: 1em;
width: 1.25em; }
.svg-inline--fa.fa-stack-2x {
height: 2em;
width: 2.5em; }
.fa-inverse {
color: var(--fa-inverse, #fff); }
.sr-only,
.fa-sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0; }
.sr-only-focusable:not(:focus),
.fa-sr-only-focusable:not(:focus) {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0; }
.svg-inline--fa .fa-primary {
fill: var(--fa-primary-color, currentColor);
opacity: var(--fa-primary-opacity, 1); }
.svg-inline--fa .fa-secondary {
fill: var(--fa-secondary-color, currentColor);
opacity: var(--fa-secondary-opacity, 0.4); }
.svg-inline--fa.fa-swap-opacity .fa-primary {
opacity: var(--fa-secondary-opacity, 0.4); }
.svg-inline--fa.fa-swap-opacity .fa-secondary {
opacity: var(--fa-primary-opacity, 1); }
.svg-inline--fa mask .fa-primary,
.svg-inline--fa mask .fa-secondary {
fill: black; }
.fad.fa-inverse,
.fa-duotone.fa-inverse {
color: var(--fa-inverse, #fff); }

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,26 @@
/*!
* Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2023 Fonticons, Inc.
*/
@font-face {
font-family: 'FontAwesome';
font-display: block;
src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); }
@font-face {
font-family: 'FontAwesome';
font-display: block;
src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); }
@font-face {
font-family: 'FontAwesome';
font-display: block;
src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype");
unicode-range: U+F003,U+F006,U+F014,U+F016-F017,U+F01A-F01B,U+F01D,U+F022,U+F03E,U+F044,U+F046,U+F05C-F05D,U+F06E,U+F070,U+F087-F088,U+F08A,U+F094,U+F096-F097,U+F09D,U+F0A0,U+F0A2,U+F0A4-F0A7,U+F0C5,U+F0C7,U+F0E5-F0E6,U+F0EB,U+F0F6-F0F8,U+F10C,U+F114-F115,U+F118-F11A,U+F11C-F11D,U+F133,U+F147,U+F14E,U+F150-F152,U+F185-F186,U+F18E,U+F190-F192,U+F196,U+F1C1-F1C9,U+F1D9,U+F1DB,U+F1E3,U+F1EA,U+F1F7,U+F1F9,U+F20A,U+F247-F248,U+F24A,U+F24D,U+F255-F25B,U+F25D,U+F271-F274,U+F278,U+F27B,U+F28C,U+F28E,U+F29C,U+F2B5,U+F2B7,U+F2BA,U+F2BC,U+F2BE,U+F2C0-F2C1,U+F2C3,U+F2D0,U+F2D2,U+F2D4,U+F2DC; }
@font-face {
font-family: 'FontAwesome';
font-display: block;
src: url("../webfonts/fa-v4compatibility.woff2") format("woff2"), url("../webfonts/fa-v4compatibility.ttf") format("truetype");
unicode-range: U+F041,U+F047,U+F065-F066,U+F07D-F07E,U+F080,U+F08B,U+F08E,U+F090,U+F09A,U+F0AC,U+F0AE,U+F0B2,U+F0D0,U+F0D6,U+F0E4,U+F0EC,U+F10A-F10B,U+F123,U+F13E,U+F148-F149,U+F14C,U+F156,U+F15E,U+F160-F161,U+F163,U+F175-F178,U+F195,U+F1F8,U+F219,U+F27A; }

View File

@ -0,0 +1,6 @@
/*!
* Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2023 Fonticons, Inc.
*/
@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype");unicode-range:u+f003,u+f006,u+f014,u+f016-f017,u+f01a-f01b,u+f01d,u+f022,u+f03e,u+f044,u+f046,u+f05c-f05d,u+f06e,u+f070,u+f087-f088,u+f08a,u+f094,u+f096-f097,u+f09d,u+f0a0,u+f0a2,u+f0a4-f0a7,u+f0c5,u+f0c7,u+f0e5-f0e6,u+f0eb,u+f0f6-f0f8,u+f10c,u+f114-f115,u+f118-f11a,u+f11c-f11d,u+f133,u+f147,u+f14e,u+f150-f152,u+f185-f186,u+f18e,u+f190-f192,u+f196,u+f1c1-f1c9,u+f1d9,u+f1db,u+f1e3,u+f1ea,u+f1f7,u+f1f9,u+f20a,u+f247-f248,u+f24a,u+f24d,u+f255-f25b,u+f25d,u+f271-f274,u+f278,u+f27b,u+f28c,u+f28e,u+f29c,u+f2b5,u+f2b7,u+f2ba,u+f2bc,u+f2be,u+f2c0-f2c1,u+f2c3,u+f2d0,u+f2d2,u+f2d4,u+f2dc}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-v4compatibility.woff2) format("woff2"),url(../webfonts/fa-v4compatibility.ttf) format("truetype");unicode-range:u+f041,u+f047,u+f065-f066,u+f07d-f07e,u+f080,u+f08b,u+f08e,u+f090,u+f09a,u+f0ac,u+f0ae,u+f0b2,u+f0d0,u+f0d6,u+f0e4,u+f0ec,u+f10a-f10b,u+f123,u+f13e,u+f148-f149,u+f14c,u+f156,u+f15e,u+f160-f161,u+f163,u+f175-f178,u+f195,u+f1f8,u+f219,u+f27a}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,22 @@
/*!
* Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2023 Fonticons, Inc.
*/
@font-face {
font-family: 'Font Awesome 5 Brands';
font-display: block;
font-weight: 400;
src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); }
@font-face {
font-family: 'Font Awesome 5 Free';
font-display: block;
font-weight: 900;
src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); }
@font-face {
font-family: 'Font Awesome 5 Free';
font-display: block;
font-weight: 400;
src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); }

View File

@ -0,0 +1,6 @@
/*!
* Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2023 Fonticons, Inc.
*/
@font-face{font-family:"Font Awesome 5 Brands";font-display:block;font-weight:400;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:900;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:400;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -168,7 +168,7 @@ return [
// Ignore this comment
'secure_password' => 'This is not a secure password. Please try again. For more information, visit https://bit.ly/FF3-password-security',
'secure_password' => 'This is not a secure password. Please try again. For more information, visit https://bit.ly/FF3-password',
'valid_recurrence_rep_type' => 'Invalid repetition type for recurring transactions.',
'valid_recurrence_rep_moment' => 'Invalid repetition moment for this type of repetition.',
'invalid_account_info' => 'Invalid account information.',

View File

@ -0,0 +1,89 @@
@extends('layout.v2.session')
@section('content')
@if(true===$IS_DEMO_SITE)
<div class="card">
<div class="card-body">
<p class="">
Welcome to the Firefly III demo!<br/>
<br/>
To log in, please use email address <strong>{{ $DEMO_USERNAME }}</strong> with password
<strong>{{ $DEMO_PASSWORD }}</strong>.
</p>
</div>
</div>
@endif
{{-- SUCCESS MESSAGE (ALWAYS SINGULAR) --}}
@if(session()->has('success'))
<div class="alert alert-success" role="alert">
<strong>{{ trans('firefly.flash_success') }}</strong> {{ session('success') }}
</div>
@endif
@if($errors->any())
<div class="alert alert-danger" role="alert">
<ul>
@foreach($errors->getBags() as $bag)
@foreach($bag->all() as $error)
<li>{{ $error }}</li>
@endforeach
@endforeach
</ul>
</div>
@endif
@if(session('logoutMessage'))
<div class="alert alert-primary" role="alert">
{{ session('logoutMessage') }}
</div>
@endif
<div class="card">
<div class="card-body login-card-body">
<p class="login-box-msg">{{ __('firefly.sign_in_to_start') }}
</p>
<form action="{{ route('login.post') }}" method="post">
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
@if(config('firefly.authentication_guard') === 'web')
<div class="input-group mb-3"> <input type="email" name="email" " class="form-control" placeholder="{{ trans('form.email') }}" value="@if(true===$IS_DEMO_SITE){{ $DEMO_USERNAME }}@else{{ $email }}@endif">
<div class="input-group-text"> <em class="fa-solid fa-envelope"></em> </div>
</div>
@else
<div class="input-group mb-3"> <input type="text" autocomplete="username" " name="{{ $usernameField }}" class="form-control" placeholder="{{ trans('form.login_name') }}" value="{{ $email }}">
<div class="input-group-text"> <em class="fa-solid fa-user"></em> </div>
</div>
@endif
<div class="input-group mb-3"> <input type="password" name="password" class="form-control" placeholder="{{ trans('form.password') }}" @if(true===$IS_DEMO_SITE)value="{{ $DEMO_PASSWORD }}"@endif autocomplete="current-password">
<div class="input-group-text"> <em class="fa-solid fa-lock"></em> </div>
</div> <!--begin::Row-->
<div class="row">
<div class="col-8">
<div class="form-check"> <input class="form-check-input" name="remember" id="remember" type="checkbox" value="1"> <label class="form-check-label" for="remember">
{{ trans('form.remember_me') }}
</label> </div>
</div> <!-- /.col -->
<div class="col-4">
<div class="d-grid gap-2"> <button type="submit" class="btn btn-primary">{{ trans('firefly.sign_in') }}</button> </div>
</div> <!-- /.col -->
</div> <!--end::Row-->
</form>
@if($allowReset)
<p class="mb-1 mt-3"> <a href="{{ route('password.reset.request') }}">{{ trans('firefly.forgot_my_password') }}</a> </p>
@endif
@if($allowRegistration)
<p class="mb-0"> <a class='text-center' href='{{ route('register') }}'>{{ trans('firefly.register_new_account') }}</a> </p>
@endif
</div> <!-- /.login-card-body -->
</div>
@endsection
@section('scripts')
<script nonce="{{ $JS_NONCE }}">
addEventListener("DOMContentLoaded", () => {
document.querySelector('#focus').focus();
});
</script>
@endsection

View File

@ -0,0 +1,48 @@
@extends('layout.v2.session')
@section('content')
@if($errors->any())
<div class="alert alert-danger" role="alert">
<ul>
@foreach($errors->getBags() as $bag)
@foreach($bag->all() as $error)
<li>{{ $error }}</li>
@endforeach
@endforeach
</ul>
</div>
@endif
@if(session()->has('error'))
<div class="alert alert-danger" role="alert">
{{ session('error') }}
</div>
@endif
<div class="card">
<div class="card-body login-card-body">
<p class="login-box-msg">{{ trans('firefly.two_factor_welcome', ['user' => auth()->user()->email]) }}</p>
<p class="login-box-msg">{{ __('firefly.two_factor_enter_code') }}</p>
<form action="{{ route('two-factor.submit') }}" method="post">
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
<div class="input-group mb-3">
<input type="text" name="one_time_password" inputmode="numeric" autocomplete="one-time-code" class="form-control" placeholder="{{ __('firefly.two_factor_code_here') }}" autofocus />
<div class="input-group-text"> <em class="fa-solid fa-calculator"></em> </div>
</div>
<div class="row">
<!-- /.col -->
<div class="col">
<button type="submit" class="btn btn-primary btn-block">{{ __('firefly.authenticate') }}</button>
</div>
<!-- /.col -->
</div>
</form>
<p class="mb-1 mt-3">
<a href="{{ route('two-factor.lost') }}">{{ __('firefly.two_factor_forgot') }}</a>
</p>
</div>
</div>
@endsection

View File

@ -67,11 +67,11 @@
<div class="input-group mb-3">
{% if config('firefly.authentication_guard') == 'web' %}
<input type="email" id="focus" class="form-control" name="email"
<input type="email" " class="form-control" name="email"
placeholder="{{ trans('form.email') }}"
value="{% if not IS_DEMO_SITE %}{{ email }}{% else %}{{ DEMO_USERNAME }}{% endif %}">
{% else %}
<input type="text" id="focus" autocomplete="username" name="{{ usernameField }}" value="{{ email }}"
<input type="text" " autocomplete="username" name="{{ usernameField }}" value="{{ email }}"
class="form-control" placeholder="{{ trans('form.login_name') }}"/>
{% endif %}
<div class="input-group-append">

View File

@ -0,0 +1,67 @@
@extends('layout.v2.session')
@section('content')
{{-- SUCCESS MESSAGE (ALWAYS SINGULAR) --}}
@if(session()->has('success'))
<div class="alert alert-success" role="alert">
<strong>{{ trans('firefly.flash_success') }}</strong> {{ session('success') }}
</div>
@endif
@if($errors->any())
<div class="alert alert-danger" role="alert">
<ul>
@foreach($errors->getBags() as $bag)
@foreach($bag->all() as $error)
<li>{{ $error }}</li>
@endforeach
@endforeach
</ul>
</div>
@endif
<div class="card">
<div class="card-body login-card-body">
@if(session('status'))
<p class="login-box-msg text-success">
{{ session('status') }}
</p>
@else
<p class="login-box-msg">{{ trans('firefly.reset_password') }}</p>
<form action="{{ route('password.email') }}" method="post">
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
<div class="input-group mb-3">
<input type="email" " class="form-control" name="email"
placeholder="{{ trans('form.email') }}"/>
<div class="input-group-text"> <em class="fa-solid fa-envelope"></em> </div>
</div>
<div class="row">
<div class="col-12">
<button type="submit" class="btn btn-primary btn-block">{{ trans('firefly.reset_button') }}</button>
</div>
<!-- /.col -->
</div>
</form>
<p class="mt-3 mb-1">
<a href="{{ route('login') }}">{{ trans('firefly.want_to_login') }}</a>
</p>
@if($allowRegistration)
<p class="mb-0">
<a href="{{ route('register') }}" class="text-center">{{ trans('firefly.register_new_account') }}</a>
</p>
@endif
@endif
</div>
</div>
@endsection
@section('scripts')
<script nonce="{{ $JS_NONCE }}">
addEventListener("DOMContentLoaded", () => {
document.querySelector('#focus').focus();
});
</script>
@endsection

View File

@ -0,0 +1,28 @@
{% extends "./layout/v3/session" %}
{% block content %}
<div class="login-box">
<div class="login-logo">
<img src="v3-local/logo/logo-session.png" width="68" height="100" alt="Firefly III Logo"
title="Firefly III"/>
</div>
{% if errors|length > 0 %}
<div class="alert alert-danger">
<strong>{{ 'flash_error'|_ }}</strong> {{ 'problems_with_input'|_ }}<br><br>
<ul>
{% for error in errors.all %}
<li>{{ error }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<div class="card">
<!-- /.login-card-body -->
</div>
</div>
<!-- /.login-box -->
{% include 'partials.password-modal' %}
{% endblock %}

View File

@ -0,0 +1,87 @@
@extends('layout.v2.session')
@section('content')
@if($errors->any())
<div class="alert alert-danger" role="alert">
<ul>
@foreach($errors->getBags() as $bag)
@foreach($bag->all() as $error)
<li>{{ $error }}</li>
@endforeach
@endforeach
</ul>
</div>
@endif
@if(session('logoutMessage'))
<div class="alert alert-primary" role="alert">
{{ session('logoutMessage') }}
</div>
@endif
<div class="card">
<div class="card-body login-card-body">
<p class="login-box-msg">{{ trans('firefly.reset_password') }}</p>
<form action="{{ url('/password/reset') }}" method="post">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="hidden" name="token" value="{{ $token }}">
<div class="input-group mb-3">
<input type="email" name="email" " class="form-control" value="{{ old('email') }}"
placeholder="{{ trans('form.email') }}"/>
<div class="input-group-text"> <em class="fa-solid fa-envelope"></em> </div>
</div>
<div class="input-group mb-3">
<input type="password" class="form-control" placeholder="{{ trans('form.password') }}"
name="password"/>
<div class="input-group-text"> <em class="fa-solid fa-lock"></em> </div>
</div>
<div class="input-group mb-3">
<input type="password" class="form-control" placeholder="{{ trans('form.password_confirmation') }}"
name="password_confirmation"/>
<div class="input-group-text"> <em class="fa-solid fa-lock"></em> </div>
</div>
<div class="row">
<div class="col-12">
<input type="checkbox" id="verify_password" checked name="verify_password" value="1">
<label for="verify_password">
{{ trans('form.verify_password') }}
<a href="#"
data-bs-toggle="modal" data-bs-target="#passwordModal"
><span
class="fa fa-fw fa-question-circle"></span></a>
</label>
</div>
</div>
<div class="row mt-3">
<div class="col">
<button type="submit" class="btn btn-primary btn-block">{{ trans('firefly.button_reset_password') }}</button>
</div>
<!-- /.col -->
</div>
</form>
<p class="mt-3 mb-1">
<a href="{{ route('login') }}">{{ trans('firefly.want_to_login') }}</a>
</p>
@if($allowRegistration)
<p class="mb-0">
<a href="{{ route('register') }}" class="text-center">{{ trans('firefly.register_new_account') }}</a>
</p>
@endif
</div>
</div>
@include('partials.password-modal')
@endsection
@section('scripts')
<script nonce="{{ $JS_NONCE }}" src="v2-local/bs/js/bootstrap.min.js"></script>
<script nonce="{{ $JS_NONCE }}">
addEventListener("DOMContentLoaded", () => {
document.querySelector('#focus').focus();
});
</script>
@endsection

View File

@ -1,89 +0,0 @@
{% extends "./layout/v3/session" %}
{% block content %}
<div class="login-box">
<div class="login-logo">
<img src="v3-local/logo/logo-session.png" width="68" height="100" alt="Firefly III Logo"
title="Firefly III"/>
</div>
{% if errors|length > 0 %}
<div class="alert alert-danger">
<strong>{{ 'flash_error'|_ }}</strong> {{ 'problems_with_input'|_ }}<br><br>
<ul>
{% for error in errors.all %}
<li>{{ error }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<div class="card">
<div class="card-body login-card-body">
<p class="login-box-msg">{{ 'reset_password'|_ }}</p>
<form action="{{ url('/password/reset') }}" method="post">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="hidden" name="token" value="{{ token }}">
<div class="input-group mb-3">
<input type="email" name="email" class="form-control" value="{{ old('email') }}" placeholder="{{ trans('form.email') }}"/>
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-envelope"></span>
</div>
</div>
</div>
<div class="input-group mb-3">
<input type="password" class="form-control" placeholder="{{ trans('form.password') }}" name="password"/>
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-lock"></span>
</div>
</div>
</div>
<div class="input-group mb-3">
<input type="password" class="form-control" placeholder="{{ trans('form.password_confirmation') }}" name="password_confirmation"/>
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-lock"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="icheck-primary">
<input type="checkbox" id="verify_password" checked name="verify_password" value="1">
<label for="verify_password">
{{ trans('form.verify_password') }}
<a data-toggle="modal" data-target="#passwordModal" href="#passwordModal"><span
class="fa fa-fw fa-question-circle"></span></a>
</label>
</div>
</div>
</div>
<div class="row">
<div class="col-6 offset-6">
<button type="submit" class="btn btn-primary btn-block">{{ 'button_reset_password'|_ }}</button>
</div>
<!-- /.col -->
</div>
</form>
<p class="mt-3 mb-1">
<a href="{{ route('login') }}">{{ 'want_to_login'|_ }}</a>
</p>
{% if allowRegistration %}
<p class="mb-0">
<a href="{{ route('register') }}" class="text-center">{{ 'register_new_account'|_ }}</a>
</p>
{% endif %}
</div>
<!-- /.login-card-body -->
</div>
</div>
<!-- /.login-box -->
{% include 'partials.password-modal' %}
{% endblock %}

View File

@ -0,0 +1,85 @@
@extends('layout.v2.session')
@section('content')
{{-- SUCCESS MESSAGE (ALWAYS SINGULAR) --}}
@if(session()->has('success'))
<div class="alert alert-success" role="alert">
<strong>{{ trans('firefly.flash_success') }}</strong> {{ session('success') }}
</div>
@endif
@if($errors->any())
<div class="alert alert-danger" role="alert">
<ul>
@foreach($errors->getBags() as $bag)
@foreach($bag->all() as $error)
<li>{{ $error }}</li>
@endforeach
@endforeach
</ul>
</div>
@endif
<div class="card">
<div class="card-body register-card-body">
<p class="login-box-msg">{{ trans('firefly.register_new_account') }}</p>
<form action="{{ route('register') }}" method="post">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="hidden" name="invite_code" value="{{ $inviteCode ?? '' }}">
<div class="input-group mb-3">
<input type="email" name="email" value="{{ $email }}" class="form-control" "
placeholder="{{ trans('form.email') }}"/>
<div class="input-group-text"> <em class="fa-solid fa-envelope"></em> </div>
</div>
<div class="input-group mb-3">
<input type="password" autocomplete="new-password" class="form-control"
placeholder="{{ trans('form.password') }}" name="password"/>
<div class="input-group-text"> <em class="fa-solid fa-lock"></em> </div>
</div>
<div class="input-group mb-3">
<input type="password" autocomplete="new-password" class="form-control"
placeholder="{{ trans('form.password_confirmation') }}" name="password_confirmation"/>
<div class="input-group-text"> <em class="fa-solid fa-lock"></em> </div>
</div>
<div class="row">
<div class="col-12">
<input type="checkbox" id="verify_password" checked name="verify_password" value="1">
<label for="verify_password">
{{ trans('form.verify_password') }}
<a href="#"
data-bs-toggle="modal" data-bs-target="#passwordModal"
><span
class="fa fa-fw fa-question-circle"></span></a>
</label>
</div>
</div>
<div class="row mt-3">
<div class="col-4 offset-8">
<button type="submit" class="btn btn-primary btn-block">Register</button>
</div>
</div>
</form>
<p class="mb-1 mt-3">
<a href="{{ route('login') }}">{{ trans('firefly.want_to_login') }}</a>
</p>
<p class="mb-0">
<a href="{{ route('password.reset.request') }}">{{ trans('firefly.forgot_my_password') }}</a>
</p>
</div>
<!-- /.form-box -->
</div><!-- /.card -->
@include('partials.password-modal')
@endsection
@section('scripts')
<script nonce="{{ $JS_NONCE }}" src="v2-local/bs/js/bootstrap.min.js"></script>
<script nonce="{{ $JS_NONCE }}">
addEventListener("DOMContentLoaded", () => {
document.querySelector('#focus').focus();
});
</script>
@endsection

View File

@ -0,0 +1,85 @@
<!DOCTYPE html>
<html lang="en">
<head>
<base href="{{ route('index') }}/" />
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>{{ __('firefly.login_page_title') }}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="{{ __('firefly.login_page_title') }}">
<!-- copy of head.blade.php -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="csrf-token" content="{{ csrf_token() }}">
<meta name="robots" content="noindex, nofollow, noarchive, noodp, NoImageIndex, noydir">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="color-scheme" content="light dark">
<script type="text/javascript" nonce="{{ $JS_NONCE }}">
/*!
* Color mode toggler for Bootstrap's docs (https://getbootstrap.com/)
* Copyright 2011-2023 The Bootstrap Authors
* Licensed under the Creative Commons Attribution 3.0 Unported License.
*/
(() => {
'use strict'
// todo store just happens to store in localStorage but if not, this would break.
const getStoredTheme = () => JSON.parse(localStorage.getItem('darkMode'))
const getPreferredTheme = () => {
const storedTheme = getStoredTheme()
if (storedTheme) {
return storedTheme
}
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
}
const setTheme = theme => {
if (theme === 'browser' && window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.documentElement.setAttribute('data-bs-theme', 'dark')
window.theme = 'dark';
return;
}
if (theme === 'browser' && window.matchMedia('(prefers-color-scheme: light)').matches) {
window.theme = 'light';
document.documentElement.setAttribute('data-bs-theme', 'light')
return;
}
document.documentElement.setAttribute('data-bs-theme', theme)
window.theme = theme;
}
setTheme(getPreferredTheme())
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
const storedTheme = getStoredTheme()
if (storedTheme !== 'light' && storedTheme !== 'dark') {
setTheme(getPreferredTheme())
}
})
})()
</script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="v2/css/fonts.css" rel="stylesheet">
<link rel="stylesheet" href="v2/css/adminlte.css">
<!-- session layout includes custom set of icons -->
<link href="v2-local/fa/css/fontawesome.min.css" rel="stylesheet" />
<link href="v2-local/fa/css/solid.min.css" rel="stylesheet" />
</head> <!--end::Head--> <!--begin::Body-->
<body class="login-page bg-body-secondary">
<div class="login-box">
<div class="login-logo">
<img src="images/logo-session.png" width="68" height="100" alt="Firefly III Logo" title="Firefly III" /><br>
<a href='{{ route('index') }}'><b>Firefly</b> III</a> </div>
@yield('content')
</div> <!-- /.login-box --> <!--begin::Third Party Plugin(OverlayScrollbars)-->
<script src="v2/js/adminlte.js" nonce="{{ $JS_NONCE }}"></script>
@yield('scripts')
</body><!--end::Body-->
</html>

View File

@ -0,0 +1,35 @@
<div class="modal fade" id="passwordModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
{{ __('firefly.secure_pw_title') }}
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{{ __('firefly.close') }}"></button>
</div>
<div class="modal-body">
<p>
{{ __('firefly.secure_pw_history') }}
</p>
<p>
{{ __('firefly.secure_pw_ff') }}
</p>
<p>
{{ __('firefly.secure_pw_check_box') }}
</p>
<h4>{{ __('firefly.secure_pw_working_title') }}</h4>
<p>
{!! __('firefly.secure_pw_working') !!}
</p>
<h4>{{ __('firefly.secure_pw_should') }}</h4>
<p>
{{ __('firefly.secure_pw_long_password') }}
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ __('firefly.close') }}</button>
</div>
</div>
</div>
</div>

View File

@ -1,3 +1 @@
<!--begin::Required Plugin(AdminLTE)-->
<script src="v2/js/adminlte.js" nonce="{{ $JS_NONCE }}"></script>
<!--end::Required Plugin(AdminLTE)-->