diff --git a/app/Http/Controllers/UserEmailChangeController.php b/app/Http/Controllers/UserEmailChangeController.php
index 89976ccc0..c7710c2ca 100644
--- a/app/Http/Controllers/UserEmailChangeController.php
+++ b/app/Http/Controllers/UserEmailChangeController.php
@@ -77,4 +77,24 @@ public function resend(Request $request): RedirectResponse
'We sent another confirmation link to '.$user->fresh()->pending_email.'. Check that inbox (and spam folder).',
);
}
+
+ public function confirmHere(Request $request): RedirectResponse
+ {
+ $user = $request->user();
+
+ $validated = $request->validate([
+ 'confirm_password' => $this->emailChangeService->requiresPassword($user)
+ ? 'required|string|max:72'
+ : 'nullable|string|max:72',
+ ]);
+
+ $updatedUser = $this->emailChangeService->confirmPendingForAuthenticatedUser(
+ $user,
+ $validated['confirm_password'] ?? null,
+ );
+
+ return redirect()
+ ->route('profile')
+ ->with('flash', 'Your login email has been updated to '.$updatedUser->email.'.');
+ }
}
diff --git a/app/Services/UserEmailChangeService.php b/app/Services/UserEmailChangeService.php
index b7b2f9a62..9a277c792 100644
--- a/app/Services/UserEmailChangeService.php
+++ b/app/Services/UserEmailChangeService.php
@@ -89,6 +89,44 @@ public function resendConfirmation(User $user): array
return ['status' => 'confirmation_resent'];
}
+ /**
+ * Confirm a pending change while logged in (fallback when the new inbox does not receive mail).
+ *
+ * @throws ValidationException
+ */
+ public function confirmPendingForAuthenticatedUser(User $user, ?string $password): User
+ {
+ $pendingEmail = SupportEmailAddress::normalize((string) ($user->pending_email ?? ''));
+ if ($pendingEmail === null || $user->pending_email_token === null) {
+ throw ValidationException::withMessages([
+ 'pending_email' => 'There is no pending email change to confirm.',
+ ]);
+ }
+
+ if ($this->requiresPassword($user)) {
+ if ($password === null || $password === '' || ! Hash::check($password, (string) $user->password)) {
+ throw ValidationException::withMessages([
+ 'confirm_password' => 'Your current password is incorrect.',
+ ]);
+ }
+ }
+
+ if ($this->emailInUseByAnotherUser($pendingEmail, (int) $user->id)) {
+ $this->cancelPending($user);
+
+ throw ValidationException::withMessages([
+ 'new_email' => 'That email address is already in use on another CodeWeek account.',
+ ]);
+ }
+
+ return DB::transaction(function () use ($user, $pendingEmail) {
+ $oldEmail = SupportEmailAddress::normalize((string) ($user->email ?? ''));
+ $this->applyEmailChange($user, $oldEmail, $pendingEmail);
+
+ return $user->fresh();
+ });
+ }
+
private function issuePendingToken(User $user): string
{
$token = Str::random(64);
diff --git a/resources/views/emails/en/pending-email-change-confirmation.blade.php b/resources/views/emails/en/pending-email-change-confirmation.blade.php
index df05a77ff..15632875e 100644
--- a/resources/views/emails/en/pending-email-change-confirmation.blade.php
+++ b/resources/views/emails/en/pending-email-change-confirmation.blade.php
@@ -9,6 +9,10 @@
Confirm new login email
@endcomponent
+If the button does not work, copy and paste this link into your browser:
+
+{{ $confirmUrl }}
+
If you did not request this change, you can ignore this email.
Thanks,
diff --git a/resources/views/profile.blade.php b/resources/views/profile.blade.php
index 8101d5d0c..15f59c0aa 100755
--- a/resources/views/profile.blade.php
+++ b/resources/views/profile.blade.php
@@ -74,7 +74,7 @@ class="border-2 border-solid border-dark-blue-200 w-full rounded-full h-12 px-4
A separate notice was sent to {{ $profileUser->email }} — that email does not contain the confirmation link.
-Can't find the email at {{ $profileUser->pending_email }}?
++ If you can access that inbox elsewhere (for example a shared team mailbox), check there first. + Otherwise, while you are signed in here, you can confirm the change on this page. +
+ +