ldc-gen-game-web/app/Http/Controllers/Fo/LoginController.php
2022-03-16 10:47:17 +01:00

383 lines
14 KiB
PHP

<?php
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
use App\Http\Requests\Fo\AuthenticateRequest;
use App\Http\Requests\Fo\UpdatePasswordRequest;
use App\Lib\ToolboxHelper;
use App\Mail\PasswordReset;
use App\Mail\VerifyEmail;
use App\Models\Customer;
use App\Models\Settings;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
class LoginController extends Controller
{
/**
* apiCRM
*
* @var \LDCCRM\ApiV1
*/
private $apiCrm;
/**
* LoginController
*/
public function __construct()
{
$this->apiCrm = new \LDCCRM\ApiV1(config('crm.endpoint'), config('crm.token'));
}
/**
* Show login form
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function loginForm()
{
if (!ToolboxHelper::isLoginAccessAllowed()) {
abort(\response()->redirectToRoute('home'));
}
return view('front.basic.login');
}
/**
* Authenticate user
*
* @param AuthenticateRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
public function loginFormSubmit(AuthenticateRequest $request)
{
$this->authenticateUser($request);
$this->authenticateCustomer($request);
return back()->withInput($request->except('password'))
->withErrors('Les identifiants entrés sont incorrects.');
}
/**
* Try Login User if exists (email)
*
* Does nothing if email does not exists in users table.
*
* @param AuthenticateRequest $request
* @return void
* @throws \Symfony\Component\HttpKernel\Exception\HttpException If user is logged in.
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException If redirect route is not found.
*/
private function authenticateUser(AuthenticateRequest $request)
{
if (
User::whereEmail($request->email)->exists() and
\auth('web')->attempt([
'email' => $request->email,
'password' => $request->password
], $request->remember)
) {
abort(redirect()->route('bo.dashboard'));
}
}
/**
* Try Login Customer if exists (email)
*
* Does nothing if email does not exists in customers table.
*
* @param AuthenticateRequest $request
* @return void
* @throws \Symfony\Component\HttpKernel\Exception\HttpException If user is logged in.
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException If redirect route is not found.
*/
private function authenticateCustomer(AuthenticateRequest $request)
{
/** @var \App\Models\Customer|null $customerLocal */
$customerLocal = Customer::where('email', $request->email)->first();
$connect = $this->apiCrm->loginCustomer($request->email, $request->password);
if (\optional($connect)->code === 500) {
abort(back()->withInput($request->except("password"))
->withErrors("La connexion est impossible pour le moment, veuillez réessayer plus tard."));
}
// * Compte existant mais non activé.
if (\optional($connect)->code === 116) {
/** @var \App\Models\Customer $customerLocal */
$customerLocal = Customer::create([
'crm_id' => $connect->user->crm_id,
'firstname' => $connect->user->firstname,
'lastname' => $connect->user->lastname,
'birth_date' => $connect->user->birth_date,
'email' => $request->email,
// TODO : MOTDEPASSE ???.
'password' => Hash::make("MOTDEPASSE"),
'address' => $connect->user->address,
'address2' => $connect->user->address2,
'town' => $connect->user->city,
'postal_code' => $connect->user->postcode,
'country' => $connect->user->country
]);
$customerLocal->email_verify_token = Str::uuid();
$customerLocal->saveOrFail();
Mail::to($request->email)->send(new VerifyEmail($customerLocal));
abort(back()->withInput($request->except("password"))
// phpcs:ignore Generic.Files.LineLength.TooLong
->withErrors("Votre compte existe mais votre email n'est pas confirmé, merci de vérifier vos emails."));
} //end if
// * Connexion OK
if (!$customerLocal and $connect->status === 'OK') {
/** @var \App\Models\Customer $customerLocal */
$customerLocal = Customer::create([
'crm_id' => $connect->user->crm_id,
'firstname' => $connect->user->firstname,
'lastname' => $connect->user->lastname,
'birth_date' => $connect->user->birth_date,
'email' => $request->email,
// TODO : MOTDEPASSE ???.
'password' => Hash::make("MOTDEPASSE"),
'address' => $connect->user->address,
'address2' => $connect->user->address2,
'town' => $connect->user->city,
'postal_code' => $connect->user->postcode,
'country' => $connect->user->country,
'email_verified' => true
]);
} //end if
// * Pas de customer (non trouvé ou mot de pass invalide)
if (!$customerLocal or \optional($connect)->code === 117) {
abort(back()->withInput($request->except("password"))
->withErrors("Email ou mot de passe incorrect."));
}
if ($connect->status !== 'OK') {
abort(back()->withInput($request->except("password"))
->withErrors('Une erreur est survenue'));
}
// * Enregistrer Customer is besoin
$customerLocal->saveOrFail();
// * Email non vérifié
if (!$customerLocal->email_verified) {
$customerLocal->email_verify_token = Str::uuid();
$customerLocal->saveOrFail();
Mail::to($request->email)->send(new VerifyEmail($customerLocal));
abort(back()->withInput($request->except("password"))
->withErrors(
'Votre compte existe mais votre email n\'est pas confirmé, merci de vérifier vos emails.'
));
} //end if
// ??? Pas sûr.
$tmpPwd = "MOTDEPASSE";
if ($customerLocal and $customerLocal->isLocal()) {
$tmpPwd = $request->password;
}
// * Authentification locale
if (auth('customer')->attempt(["email" => $request->email, "password" => $tmpPwd], $request->remember)) {
abort(redirect()->route('saisir-code'));
}
}
/**
* Log out
*
* @return \Illuminate\Routing\Redirector|\Illuminate\Http\RedirectResponse
*/
public function logout()
{
auth('web')->logout();
auth('customer')->logout();
return redirect()->route('home');
}
/**
* Confirm Email
*
* @param mixed $verifyToken
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function confirmEmail($verifyToken)
{
$result = false;
/** @var \App\Models\Customer $customer */
$customer = Customer::where('email_verify_token', $verifyToken)->first();
if (!$customer) {
return view('front.basic.confirm-email', compact('result'));
}
$activation = $this->apiCrm->activateCustomer($customer->crm_id);
if ($activation->status === 'OK') {
$customer->email_verified = true;
$customer->email_verify_token = null;
$customer->saveOrFail();
$result = true;
} else {
// User already active.
if ($activation->code === 110) {
$customer->email_verified = true;
$customer->email_verify_token = null;
$customer->saveOrFail();
$result = true;
}
}
return view('front.basic.confirm-email', compact('result'));
}
/**
* Forgot Password form
*
* @param Request $request
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function forgotPassword(Request $request)
{
if ($request->tokenValid && $request->token) {
$tokenValid = $request->tokenValid;
$token = $request->token;
return view('front.basic.forgot-password', compact('tokenValid', 'token'));
}
return view('front.basic.forgot-password');
}
/**
* Send password reset mail
*
* @param Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function mailPassword(Request $request)
{
$email = filter_var($request->email, FILTER_SANITIZE_STRING);
/** @var \App\Models\Customer $customer */
$customer = Customer::where('email', $email)->first();
if (!$customer) {
$userCrm = $this->apiCrm->getCustomerByEmail($email);
if ($userCrm->status === 'OK') {
/** @var \App\Models\Customer $customer */
$customer = Customer::create([
'crm_id' => $userCrm->user->crm_id,
'firstname' => $userCrm->user->firstname,
'lastname' => $userCrm->user->lastname,
'birth_date' => $userCrm->user->birth_date,
'email' => $email,
// TODO : MOTDEPASSE ???
'password' => Hash::make("MOTDEPASSE"),
'address' => $userCrm->user->address,
'address2' => $userCrm->user->address2,
'town' => $userCrm->user->city,
'postal_code' => $userCrm->user->postcode,
'country' => $userCrm->user->country,
'email_verified' => true
]);
if ($userCrm->user->status === 0) {
$customer->email_verified = false;
$customer->email_verify_token = Str::uuid();
$customer->saveOrFail();
Mail::to($email)->send(new VerifyEmail($customer));
return back()->withInput($request->except("password"))
// phpcs:ignore Generic.Files.LineLength.TooLong
->withErrors("Votre compte existe mais votre email n'est pas confirmé, merci de vérifier vos emails.");
}
} else {
if ($userCrm->code === 101) {
return back()->withInput($request->only('email'))
->withErrors("Le mail que vous avez entré n'est pas enregistré dans nos services.");
} else {
return back()->withErrors("Une erreur est survenue, veuillez réessayer plus tard.");
}
} //end if
} //end if
$customer->password_token = Str::uuid();
$customer->saveOrFail();
/** @var \App\Models\Settings $settings */
$settings = app(Settings::class);
Mail::to($email)->send(new PasswordReset($customer, $settings));
return redirect()->route('login')
->with('success', 'Un mail de réinitialisation de votre mot de passe vous a été envoyé(e).');
}
/**
* Forgot password form show
*
* @param Request $request
* @param mixed $token
* @return \Illuminate\Http\RedirectResponse
*/
public function forgotPasswordReset(Request $request, $token)
{
if (!$request->hasValidSignature(false)) {
return redirect()->route('login')
->withErrors("Le lien de changement de votre mot de passe n'est plus valide, veuillez réessayer.");
}
$tokenValid = false;
if (!Customer::where('password_token', $token)->exists()) {
return redirect()->route('forgot-password', compact('tokenValid'))
->withErrors('Le lien de changement du mot de passe est incorrect.');
}
$tokenValid = true;
return redirect()->route('forgot-password', compact('tokenValid', 'token'));
}
/**
* Change password form submit
*
* @param UpdatePasswordRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
public function changePassword(UpdatePasswordRequest $request)
{
/** @var \App\Models\Customer $customer */
$customer = Customer::where(
'password_token',
filter_var($request->token, FILTER_SANITIZE_STRING)
)->first();
if (!$customer) {
return back()->withErrors('Le lien de changement de votre mot de passe est incorrect, veuillez réessayer.');
}
// TODO : Ajouter controle du contenu du mot de passe.
$newPassword = $request->password;
$update = $this->apiCrm->changePwdCustomer($customer->crm_id, $newPassword);
if ($update->status === 'OK') {
$customer->password_token = null;
$customer->saveOrFail();
return redirect()->route('login')
->with('success', 'Vous pouvez désormais vous connecter avec votre nouveau mot de passe.');
} else {
if ($update->code === 123) {
return back()
// phpcs:ignore Generic.Files.LineLength.TooLong
->withErrors("Il semblerait que vous ayez déjà utilisé ce mot de passe pour votre compte. Veuillez réessayer en changeant de mot de passe.");
} else {
return back()->withErrors("Une erreur est survenue, veuillez réessayer plus tard.");
}
}
}
}