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.'); } /** * 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 */ if (!($customer = Customer::select('hashcode')->where('email_verify_token', $verifyToken)->first())) { return view('front.basic.confirm-email', compact('result')); } try { /** @var \LDC\LDCCRM\Models\Customer $crmCustomer */ $crmCustomer = $customer->apiData; if ($crmCustomer->activate()) { $result = true; } } catch (ApiErrorException $e) { if ($e->getApiError()->equals(ApiError::customerAlreadyActive())) { return view('front.auth.activate') ->with( 'message', 'Votre compte est déjà activé, vous pouvez dès à présent vous connecter avec celui-ci.' ); } // ! Une erreur critique est survenue avec la CRM. report($e); } catch (CrmException $e) { // ! Une erreur critique est survenue avec la CRM. report($e); } //end try return view('front.basic.confirm-email', compact('result')); } /** * Forgot Password form * * @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory */ public function forgotPassword() { return view('front.basic.forgot-password'); } /** * forgotPassword submit * * @param ForgotPasswordRequest $request * @return \Illuminate\Http\RedirectResponse */ public function forgotPasswordSubmit(ForgotPasswordRequest $request) { if (!($crmCustomer = $this->getCustomerFromCrm($request->email))) { return back()->withInput($request->only('email')) ->withErrors('Le mail que vous avez entré n\'est pas enregistré dans nos services.'); } /** @var \App\Models\Customer $customer */ $customer = $this->createLocalCustomer($crmCustomer); $customer->password_token = Str::uuid(); $customer->saveOrFail(); /** @var \App\Models\Settings $settings */ $settings = app(Settings::class); Mail::to($request->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. '); } if (!Customer::where('password_token', $token)->exists()) { return redirect()->route('forgot-password', ['tokenValid' => false]) ->withErrors('Le lien de changement du mot de passe est incorrect.'); } return view('front.basic.forgot-password', [ 'tokenValid' => true, 'token' => $token ]); } /** * Change password form submit * * @param UpdatePasswordRequest $request * @param mixed $token * @return \Illuminate\Http\RedirectResponse */ public function forgotPasswordResetSubmit(UpdatePasswordRequest $request, $token) { /** @var \App\Models\Customer $customer */ if (!$request->hasValidSignature(false) or !($customer = Customer::where('password_token', $token)->first())) { return redirect()->route('forgot-password', ['tokenValid' => false]) ->withErrors('Le lien de changement du mot de passe est incorrect.'); } /** @var \LDC\LDCCRM\CrmApiV2 */ $crm = app('crmAPI'); try { // Ne devrait pas survenir, $crm->login throws ApiError::authFailed() . if ($crm->login($customer->email, $request->password)) { // Mauvais identifiants. return back()->withErrors('Vous ne pouvez pas utiliser un de vos anciens mot de passe.'); } // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch } catch (ApiErrorException $e) { // * Continue } catch (\TypeError | CrmException | ApiErrorException $e) { report($e); // ! Une erreur critique est survenue avec la CRM. return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.'); } try { if (!($crmCustomer = $crm->getCustomer($customer->hashcode))) { return back()->withErrors('Changement impossible, compte inexistant.'); } $crmCustomer->password = $request->password; $crmCustomer->save(); $customer->password_token = null; $customer->saveOrFail(); return redirect()->route('login') ->with('success', 'Vous pouvez désormais vous connecter avec votre nouveau mot de passe.'); } catch (\TypeError | CrmException | ApiErrorException $e) { report($e); // ! Une erreur critique est survenue avec la CRM return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.'); } catch (ValidationException $e) { return back()->withErrors(sprintf('Nouveau mot de passe : %s', $e->getMessage())); } } /** * 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. * @phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.Missing */ private function authenticateCustomer(AuthenticateRequest $request) { /** @var \App\Models\Customer|null $customerLocal */ $customer = Customer::where('email', $request->email)->first(); /** @var \LDC\LDCCRM\CrmApiV2 */ $crm = app('crmAPI'); try { $crm->login($request->email, $request->password); if (!($crmCustomer = $this->getCustomerFromCrm($request->email))) { abort(back()->withInput($request->except('password')) ->withErrors('Une erreur est survenue veuillez réssayer plus tard.')); } // ? Test is user data valid ? try { /** * On va tester de mettre a jour uniquement les champs * requis pour mes br afin de detecter si ils doivent etre mis à jour * la validation va se faire par la crm (ou le client). */ $crmCustomer->fill([ 'birth_date' => $crmCustomer->birth_date, 'address' => $crmCustomer->address, 'postcode' => $crmCustomer->postcode, 'country' => $crmCustomer->country, 'city' => $crmCustomer->city ]); // * On valide les données selon les critères de registerController $rules = collect((new RegisterRequest())->rules()); $validator = Validator::make( [ 'birth_date' => $crmCustomer->birth_date, 'address' => $crmCustomer->address, 'postcode' => $crmCustomer->postcode, 'country' => $crmCustomer->country->value, 'city' => $crmCustomer->city ], [ 'birth_date' => $rules->get('birth_date'), 'address' => $rules->get('address'), 'postcode' => $rules->get('postcode'), 'country' => $rules->get('country'), 'city' => $rules->get('city') ] ); if ($validator->fails()) { throw new ValidationException(); } else { Session::remove('needCrmInfoUpdate', true); } } catch (ValidationException $e) { Session::push('needCrmInfoUpdate', true); } catch (ApiErrorException $e) { if (!$e->getApiError()->equals(ApiError::validationFailed())) { throw $e; } Session::push('needCrmInfoUpdate', true); } //end try // * Si pas de compte local mais existe en CRM. if (!$customer) { $customer = $this->createLocalCustomer($crmCustomer); } abort($this->processLogin($customer, $request->remember)); } catch (ApiErrorException $e) { abort($this->handleLoginApiErrorException($e, $request)); } catch (CrmException $e) { \report($e); abort(back()->withInput($request->except('password')) ->withErrors('La connexion est impossible pour le moment, veuillez réessayer plus tard.')); } //end try } /** * Handle Api error exception * * @param ApiErrorException $e * @param AuthenticateRequest $request * @return \Illuminate\Http\RedirectResponse */ private function handleLoginApiErrorException(ApiErrorException $e, AuthenticateRequest $request) { /** @var Customers|null */ $customer = Customer::where('email', $request->email)->first(); /** @var \LDC\LDCCRM\CrmApiV2 */ $crm = app('crmAPI'); switch ($e->getApiError()) { case ApiError::authFailed(): // * Mauvais identifiants return back()->withInput($request->except('password')) ->withErrors('Email ou mot de passe incorrect.'); case ApiError::customerNotActivated(): // * Le compte n'est pas activé try { if (!($crmCustomer = $crm->getCustomer($request->email))) { Log::critical(sprintf('Customer %s could not be retrieved from crm', $request->email)); return back()->withErrors( __('Une erreur est survenue, merci de réessayer ultérieurement.') ); } if (!$customer) { $customer = $this->createLocalCustomer($crmCustomer); } $tokenMail = Str::uuid(); Mail::to($request->email)->send(new VerifyEmail($crmCustomer, $tokenMail)); $customer->email_verify_token = $tokenMail; $customer->saveOrFail(); return back() ->withErrors( __('Votre compte n\'est pas activé, vérifiez dans vos emails pour y trouver le mail de confirmation. Un lien d\'activation vous a été renvoyé.') ); } catch (CrmException | ApiErrorException $e) { report($e); // ! Une erreur critique est survenue avec la CRM return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.'); } //end try default: report($e); // ! Une erreur non gérée return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.'); } //end switch } /** * Get Local customer using email and update info from crm. * * @param string $email * @return CrmCustomer|null */ private function getCustomerFromCrm(string $email): ?CrmCustomer { try { return CrmCustomer::findWithEmail($email); } catch (ApiErrorException $e) { if ($e->getApiError()->equals(ApiError::modelNotFound())) { return null; } abort(back()->withErrors($e->getMessage())); } catch (CrmException $e) { report($e); abort(back()->withErrors('Une erreur est survenue')); } } /** * Create a local customer * * @param CrmCustomer $crmCustomer * @return Customer */ private function createLocalCustomer(CrmCustomer $crmCustomer): Customer { /** @var \App\Models\Customer $customer */ $customer = Customer::firstOrNew([ 'email' => $crmCustomer->email ]); $customer->hashcode = $crmCustomer->hashcode; $customer->saveOrFail(); return $customer; } /** * Login a customer * * @param Customer $customer * @param boolean $remember * @return \Illuminate\Routing\Redirector|\Illuminate\Http\RedirectResponse */ private function processLogin(Customer $customer, bool $remember) { /** @var \Illuminate\Auth\SessionGuard */ $guard = auth('customer'); $guard->login($customer, $remember); $url = Session::pull('url.intended'); Session::forget('url.intended'); Session::save(); return $url ? redirect()->to($url) : response()->redirectToRoute('saisir-code'); } }