updated tokens and emails
This commit is contained in:
@@ -4,11 +4,9 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers;
|
||||
use App\Jobs\SendEmail;
|
||||
use App\Mail\EmailUpdateLink;
|
||||
use App\Mail\RegisterLink;
|
||||
use App\Mail\UserEmailUpdateRequest;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rule;
|
||||
@@ -49,7 +47,7 @@ class AccountController extends Controller
|
||||
$validator = Validator::make($request->all(), [
|
||||
'firstname' => 'required',
|
||||
'surname' => 'required',
|
||||
'email' => ['required', 'email', Rule::unique('users')->ignore($user->id)],
|
||||
'email' => ['required', 'email', 'unique:users,email,' . $user->id],
|
||||
'phone' => 'required',
|
||||
|
||||
'home_address' => 'required_with:home_city,home_postcode,home_country,home_state',
|
||||
@@ -92,20 +90,18 @@ class AccountController extends Controller
|
||||
$newEmail = $userData['email'];
|
||||
unset($userData['email']);
|
||||
|
||||
if ($user->email !== $newEmail) {
|
||||
if(User::where('email', $request->get('email'))->exists()) {
|
||||
$validator->errors()->add('email', __('validation.custom_messages.email_exists'));
|
||||
return redirect()->back()->withErrors($validator)->withInput();
|
||||
}
|
||||
if (strtolower($user->email) !== strtolower($newEmail)) {
|
||||
$user->tokens()->where('type', 'email-update')->delete();
|
||||
|
||||
$token = Str::random(60);
|
||||
$user->emailUpdate()->delete();
|
||||
$emailUpdate = $user->emailUpdate()->create([
|
||||
'email' => $newEmail,
|
||||
'token' => $token
|
||||
$token = $user->tokens()->create([
|
||||
'type' => 'email-update',
|
||||
'data' => [
|
||||
'email' => $newEmail,
|
||||
],
|
||||
'expires_at' => now()->addMinutes(30),
|
||||
]);
|
||||
|
||||
dispatch(new SendEmail($user->email, new EmailUpdateLink($token, $user->getName(), $user->email, $newEmail)))->onQueue('mail');
|
||||
dispatch(new SendEmail($user->email, new UserEmailUpdateRequest($token->id, $user->email, $newEmail)))->onQueue('mail');
|
||||
}
|
||||
|
||||
$userData['subscribed'] = ($request->get('subscribed', false) === 'on');
|
||||
|
||||
@@ -3,57 +3,89 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Jobs\SendEmail;
|
||||
use App\Mail\LoginLink;
|
||||
use App\Mail\RegisterLink;
|
||||
use App\Models\EmailSubscriptions;
|
||||
use App\Models\EmailUpdate;
|
||||
use App\Mail\UserEmailUpdateConfirm;
|
||||
use App\Mail\UserLogin;
|
||||
use App\Mail\UserRegister;
|
||||
use App\Mail\UserWelcome;
|
||||
use App\Models\Token;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class AuthController extends Controller
|
||||
{
|
||||
public function showLogin(Request $request) {
|
||||
/**
|
||||
* Show the login form or if token present, process the login
|
||||
*
|
||||
* @param Request $request
|
||||
* @return View|RedirectResponse
|
||||
*/
|
||||
public function showLogin(Request $request): View|RedirectResponse
|
||||
{
|
||||
if (auth()->check()) {
|
||||
// return redirect()->route('dashboard');
|
||||
return redirect()->action([HomeController::class, 'index']);
|
||||
}
|
||||
|
||||
$token = $request->query('token');
|
||||
if ($token) {
|
||||
return $this->tokenLogin($token);
|
||||
return $this->LoginByToken($token);
|
||||
}
|
||||
|
||||
return view('auth.login');
|
||||
}
|
||||
|
||||
public function tokenLogin($token)
|
||||
/**
|
||||
* Process the login form
|
||||
*
|
||||
* @param Request $request
|
||||
* @return View|RedirectResponse
|
||||
*/
|
||||
public function postLogin(Request $request): View|RedirectResponse
|
||||
{
|
||||
$loginToken = DB::table('login_tokens')->where('token', $token)->first();
|
||||
$request->validate([
|
||||
'email' => 'required|email',
|
||||
], [
|
||||
'email.required' => __('validation.custom_messages.email_required'),
|
||||
'email.email' => __('validation.custom_messages.email_invalid'),
|
||||
]);
|
||||
|
||||
if ($loginToken) {
|
||||
$user = User::where('email', $loginToken->email)->first();
|
||||
$intended_url = $loginToken->intended_url;
|
||||
$user = User::where('email', $request->email)->whereNotNull('email_verified_at')->first();
|
||||
if($user) {
|
||||
$token = $user->tokens()->create([
|
||||
'type' => 'login',
|
||||
'data' => ['url' => session()->pull('url.intended', null)],
|
||||
]);
|
||||
|
||||
DB::table('login_tokens')->where('token', $token)->delete();
|
||||
dispatch(new SendEmail($user->email, new UserLogin($token->id, $user->getName(), $user->email)))->onQueue('mail');
|
||||
return view('auth.login-link');
|
||||
}
|
||||
|
||||
if ($user) {
|
||||
Auth::login($user);
|
||||
session()->flash('status', 'not-found');
|
||||
return view('auth.login');
|
||||
}
|
||||
|
||||
$user->markEmailAsVerified();
|
||||
DB::table('login_tokens')->where('token', $token)->delete();
|
||||
|
||||
session()->flash('message', 'You have been logged in');
|
||||
session()->flash('message-title', 'Logged in');
|
||||
session()->flash('message-type', 'success');
|
||||
/**
|
||||
* Process the login by token
|
||||
*
|
||||
* @param string $tokenStr
|
||||
* @return View|RedirectResponse
|
||||
*/
|
||||
public function loginByToken(string $tokenStr): View|RedirectResponse
|
||||
{
|
||||
$token = Token::where('id', $tokenStr)
|
||||
->where('type', 'login')
|
||||
->where('expires_at', '>', now())
|
||||
->first();
|
||||
|
||||
if($intended_url) {
|
||||
return redirect($intended_url);
|
||||
}
|
||||
|
||||
return redirect()->action([HomeController::class, 'index']);
|
||||
if ($token) {
|
||||
$user = $token->user;
|
||||
if($user) {
|
||||
$token->delete();
|
||||
return $this->loginByUser($user, $token->data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,27 +95,40 @@ class AuthController extends Controller
|
||||
return view('auth.login');
|
||||
}
|
||||
|
||||
public function postLogin(Request $request) {
|
||||
$request->validate([
|
||||
'email' => 'required|email',
|
||||
], [
|
||||
'email.required' => __('validation.custom_messages.email_required'),
|
||||
'email.email' => __('validation.custom_messages.email_invalid'),
|
||||
]);
|
||||
|
||||
$user = User::where('email', $request->email)->first();
|
||||
if($user) {
|
||||
$token = $user->createLoginToken(session()->pull('url.intended', null));
|
||||
dispatch(new SendEmail($user->email, new LoginLink($token, $user->getName(), $user->email)))->onQueue('mail');
|
||||
|
||||
return view('auth.login-link');
|
||||
/**
|
||||
* Process the login by user
|
||||
*
|
||||
* @param User $user
|
||||
* @param array $data
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function loginByUser(User $user, array $data = [])
|
||||
{
|
||||
$url = null;
|
||||
if($data && isset($data->url) && $data->url) {
|
||||
$url = $data->url;
|
||||
}
|
||||
|
||||
session()->flash('status', 'not-found');
|
||||
return view('auth.login');
|
||||
Auth::login($user);
|
||||
|
||||
session()->flash('message', 'You have been logged in');
|
||||
session()->flash('message-title', 'Logged in');
|
||||
session()->flash('message-type', 'success');
|
||||
|
||||
if($url) {
|
||||
return redirect($url);
|
||||
}
|
||||
|
||||
return redirect()->action([HomeController::class, 'index']);
|
||||
}
|
||||
|
||||
public function logout() {
|
||||
/**
|
||||
* Process the user logout
|
||||
*
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function logout(): RedirectResponse
|
||||
{
|
||||
auth()->logout();
|
||||
|
||||
session()->flash('message', 'You have been logged out');
|
||||
@@ -92,15 +137,57 @@ class AuthController extends Controller
|
||||
return redirect()->route('index');
|
||||
}
|
||||
|
||||
public function showRegister(Request $request) {
|
||||
/**
|
||||
* Show the registration form or if token present, process the registration
|
||||
*
|
||||
* @param Request $request
|
||||
* @return View|RedirectResponse
|
||||
*/
|
||||
public function showRegister(Request $request): View|RedirectResponse
|
||||
{
|
||||
if (auth()->check()) {
|
||||
return redirect()->route('index');
|
||||
}
|
||||
|
||||
$tokenStr = $request->query('token');
|
||||
if ($tokenStr) {
|
||||
$token = Token::where('id', $tokenStr)
|
||||
->where('type', 'register')
|
||||
->where('expires_at', '>', now())
|
||||
->first();
|
||||
|
||||
if ($token) {
|
||||
$user = $token->user;
|
||||
if ($user) {
|
||||
$user->email_verified_at = now();
|
||||
$user->save();
|
||||
|
||||
$user->tokens()->where('type', 'register')->delete();
|
||||
|
||||
dispatch(new SendEmail($user->email, new UserWelcome($user->email)))->onQueue('mail');
|
||||
|
||||
$this->loginByUser($user);
|
||||
return redirect()->route('index');
|
||||
}
|
||||
}
|
||||
|
||||
session()->flash('message', 'That token has expired or is invalid');
|
||||
session()->flash('message-title', 'Registration failed');
|
||||
session()->flash('message-type', 'danger');
|
||||
}
|
||||
|
||||
|
||||
return view('auth.register');
|
||||
}
|
||||
|
||||
public function postRegister(Request $request) {
|
||||
/**
|
||||
* Process the registration form
|
||||
*
|
||||
* @param Request $request
|
||||
* @return View|RedirectResponse
|
||||
*/
|
||||
public function postRegister(Request $request): View|RedirectResponse
|
||||
{
|
||||
$request->validate([
|
||||
'email' => 'required|email',
|
||||
], [
|
||||
@@ -119,46 +206,65 @@ class AuthController extends Controller
|
||||
]);
|
||||
}
|
||||
} else if($passHoneypot) {
|
||||
$firstname = explode('@', $request->email)[0];
|
||||
|
||||
$user = User::create([
|
||||
'firstname' => $firstname,
|
||||
'email' => $request->email,
|
||||
]);
|
||||
|
||||
EmailUpdate::where('email', $request->email)->delete();
|
||||
}
|
||||
|
||||
if($passHoneypot) {
|
||||
Log::channel('honeypot')->info('Valid key used for registration using email: ' . $request->email . ', ip address: ' . $request->ip() . ', user agent: ' . $request->userAgent());
|
||||
$token = $user->createLoginToken(session()->pull('url.intended', null));
|
||||
dispatch(new SendEmail($user->email, new RegisterLink($token, $user->getName(), $user->email)))->onQueue('mail');
|
||||
$user->tokens()->where('type', 'register')->delete();
|
||||
$token = $user->tokens()->create([
|
||||
'type' => 'register',
|
||||
'data' => ['url' => session()->pull('url.intended', null)],
|
||||
]);
|
||||
|
||||
dispatch(new SendEmail($user->email, new UserRegister($token->id, $user->email)))->onQueue('mail');
|
||||
} else {
|
||||
Log::channel('honeypot')->info('Invalid key used for registration using email: ' . $request->email . ', ip address: ' . $request->ip() . ', user agent: ' . $request->userAgent() . ', key: ' . $key);
|
||||
}
|
||||
|
||||
return view('auth.login-link');
|
||||
return view('auth.register-link');
|
||||
}
|
||||
|
||||
public function updateEmail(Request $request)
|
||||
/**
|
||||
* Confirm the user email update.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function updateEmail(Request $request): RedirectResponse
|
||||
{
|
||||
$token = $request->query('token');
|
||||
$emailUpdate = EmailUpdate::where('token', $token)->first();
|
||||
if($emailUpdate && $emailUpdate->user) {
|
||||
$emailUpdate->user->email = $emailUpdate->email;
|
||||
$emailUpdate->user->email_verified_at = now();
|
||||
$emailUpdate->user->save();
|
||||
$emailUpdate->delete();
|
||||
$tokenStr = $request->query('token');
|
||||
|
||||
session()->flash('message', 'Your email has been updated');
|
||||
session()->flash('message-title', 'Email updated');
|
||||
session()->flash('message-type', 'success');
|
||||
return redirect()->route('index');
|
||||
$token = Token::where('id', $tokenStr)
|
||||
->where('type', 'email-update')
|
||||
->where('expires_at', '>', now())
|
||||
->first();
|
||||
|
||||
if($token && $token->user) {
|
||||
if($token->data && isset($token->data['email'])) {
|
||||
$user = $token->user;
|
||||
$user->email = $token->data['email'];
|
||||
$user->email_verified_at = now();
|
||||
$user->save();
|
||||
|
||||
$user->tokens()->where('type', 'email-update')->delete();
|
||||
|
||||
session()->flash('message', 'Your email has been updated');
|
||||
session()->flash('message-title', 'Email updated');
|
||||
session()->flash('message-type', 'success');
|
||||
|
||||
dispatch(new SendEmail($user->email, new UserEmailUpdateConfirm($user->email)))->onQueue('mail');
|
||||
|
||||
return redirect()->route('index');
|
||||
}
|
||||
}
|
||||
|
||||
session()->flash('message', 'That token has expired or is invalid');
|
||||
session()->flash('message-title', 'Email update failed');
|
||||
session()->flash('message-type', 'danger');
|
||||
|
||||
return redirect()->route('index');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user