Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
- Fixed a bug where typing an option’s exact label or value into a combobox that accepts free text could make two options look selected. Exact matches are now listed first.
- Fixed a bug where rich selects’ menus could extend off-screen when an option had a long label or hint, and a long option could stretch the select itself past its container.
- Fixed a bug where permission trees, such as user group permissions and the public MCP settings, used the browser’s native checkboxes instead of the control panel’s checkbox styling.
- Fixed a bug where logging in from the control panel’s login page could redirect to the front end instead of the control panel, when a front-end login path was also configured.
- Fixed a bug where element edit pages could have a few pixels of vertical scroll after the window was resized, even though their content fit within it. ([#20028](https://github.com/craftcms/cms/pull/20028))
- Fixed a bug where control panel pages and details panes shifted sideways when a scrollbar appeared. ([#20030](https://github.com/craftcms/cms/pull/20030))

Expand Down
2 changes: 1 addition & 1 deletion routes/cp.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@

Route::allowDuringMaintenance()->middleware(RunQueue::class)->group(function () {
Route::get(CpAuthPath::Login->value, [LoginController::class, 'showLogin']);
Route::post(CpAuthPath::Login->value, [LoginController::class, 'attemptLogin'])->middleware('throttle:'.LoginRateLimiter::NAME);
Route::post(CpAuthPath::Login->value, [LoginController::class, 'attemptLogin'])->middleware('throttle:'.LoginRateLimiter::NAME)->name('login.attempt');
Route::match(['get', 'post'], CpAuthPath::Logout->value, [LoginController::class, 'logout'])->name('logout');
Route::get(CpAuthPath::TwoFactorChallenge->value, [TwoFactorAuthenticationController::class, 'showForm'])->middleware(EnsureTwoFactorChallengeIsRecent::class);
Route::get(CpAuthPath::SetPassword->value, [SetPasswordController::class, 'show']);
Expand Down
6 changes: 3 additions & 3 deletions src/Http/Controllers/Auth/LoginController.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ public function showLogin(Request $request, GeneralConfig $generalConfig, AuthMe
inertiaProps: [
'username' => $generalConfig->rememberUsernameDuration ? $authMethods->getRememberedUsername() : '',
'oauthLoginButtons' => $oauthLoginButtons,
'action' => $request->isCpRequest() ? action([self::class, 'attemptLogin']) : action_url('users/login'),
'action' => $request->isCpRequest() ? route('craft.cp.login.attempt') : action_url('users/login'),
],
data: [
'action' => action([self::class, 'attemptLogin']),
'action' => $request->isCpRequest() ? route('craft.cp.login.attempt') : action([self::class, 'attemptLogin']),
'oauthLoginButtons' => $oauthLoginButtons,
],
);
Expand Down Expand Up @@ -103,7 +103,7 @@ public function showLoginModal(Request $request, Impersonation $impersonation, H
}

$html = template('_special/login-modal', [
'action' => action([LoginController::class, 'attemptLogin']),
'action' => route('craft.cp.login.attempt'),
'staticEmail' => $staticEmail,
'forElevatedSession' => $forElevatedSession,
], templateMode: TemplateMode::Cp);
Expand Down
2 changes: 1 addition & 1 deletion src/Http/Controllers/Auth/SessionInfoController.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public function confirmPassword(
$loginName = (string) ($user->email ?? $user->username);
$context = [
...$templateGlobals->resolve(),
'action' => action([LoginController::class, 'attemptLogin']),
'action' => route('craft.cp.login.attempt'),
'forElevatedSession' => true,
'generalConfig' => $generalConfig,
'staticEmail' => $loginName,
Expand Down
15 changes: 15 additions & 0 deletions tests/Feature/Http/Controllers/Auth/LoginControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,21 @@
expect(Auth::id())->toBe($user->id);
});

test('control panel logins post to the control panel and redirect to the post-CP-login redirect', function () {
// A front-end login path is another route to the same action, so URLs generated from the action could point there.
Route::post('logmein', [LoginController::class, 'attemptLogin']);
Route::getRoutes()->refreshActionLookups();
Cms::config()->postCpLoginRedirect = 'entries';

get(cp_url(CpAuthPath::Login->value))
->assertInertia(fn (AssertableInertia $page) => $page->where('action', cp_url(CpAuthPath::Login->value)));

post(cp_url(CpAuthPath::Login->value), [
'loginName' => User::findOne()->email,
'password' => 'craftcms2018!!',
])->assertRedirect(cp_url('entries'));
});

test('modal login requires refreshing the token before resubmitting a form', function (bool $authenticated) {
// Laravel skips CSRF verification in the testing environment.
$this->app->instance('env', 'local');
Expand Down