1 | <?php declare(strict_types=1); |
||||
2 | |||||
3 | namespace Bone\User\Controller; |
||||
4 | |||||
5 | use Bone\Http\Response\HtmlResponse; |
||||
6 | use Bone\Http\Response\LayoutResponse; |
||||
7 | use Bone\I18n\Form; |
||||
8 | use Bone\Controller\Controller; |
||||
9 | use Bone\Paseto\PasetoService; |
||||
10 | use Bone\Server\SiteConfigAwareInterface; |
||||
11 | use Bone\Server\Traits\HasSiteConfigTrait; |
||||
12 | use Bone\View\ViewEngine; |
||||
13 | use Bone\Server\SessionAwareInterface; |
||||
14 | use Bone\Server\Traits\HasSessionTrait; |
||||
15 | use Bone\Mail\EmailMessage; |
||||
16 | use Bone\Mail\Service\MailService; |
||||
17 | use Bone\User\Form\LoginForm; |
||||
18 | use Bone\User\Form\PersonForm; |
||||
19 | use Bone\User\Form\RegistrationForm; |
||||
20 | use Bone\User\Form\ResetPasswordForm; |
||||
21 | use DateTime; |
||||
22 | use Del\Entity\User; |
||||
23 | use Del\Exception\EmailLinkException; |
||||
24 | use Del\Exception\UserException; |
||||
25 | use Del\Factory\CountryFactory; |
||||
26 | use Del\Form\Field\Text\EmailAddress; |
||||
27 | use Del\Icon; |
||||
28 | use Del\Service\UserService; |
||||
29 | use Del\SessionManager; |
||||
30 | use Del\Value\User\State; |
||||
31 | use Exception; |
||||
32 | use Laminas\Diactoros\Response\RedirectResponse; |
||||
33 | use Laminas\Diactoros\Uri; |
||||
34 | use Psr\Http\Message\ResponseInterface; |
||||
35 | use Psr\Http\Message\ServerRequestInterface; |
||||
36 | |||||
37 | class BoneUserController extends Controller implements SessionAwareInterface |
||||
38 | { |
||||
39 | use HasSessionTrait; |
||||
40 | use HasSiteConfigTrait; |
||||
41 | |||||
42 | private string $logo = ''; |
||||
43 | |||||
44 | 41 | public function __construct( |
|||
45 | private UserService $userService, |
||||
46 | private MailService $mailService, |
||||
47 | private string $loginRedirectRoute, |
||||
48 | private string $adminLayout, |
||||
49 | private PasetoService $pasetoService, |
||||
50 | private bool $registrationEnabled = true, |
||||
51 | private $profileRequired = false, |
||||
52 | private bool $rememberMeCookie = true |
||||
53 | ) { |
||||
54 | 41 | } |
|||
55 | |||||
56 | /** |
||||
57 | * @return string |
||||
58 | */ |
||||
59 | 29 | public function getLogo(): string |
|||
60 | { |
||||
61 | 29 | if ($this->logo === '') { |
|||
62 | 29 | $this->logo = $this->getSiteConfig()->getLogo(); |
|||
63 | } |
||||
64 | |||||
65 | 29 | return $this->logo; |
|||
66 | } |
||||
67 | |||||
68 | /** |
||||
69 | * @param ServerRequestInterface $request |
||||
70 | * @return ResponseInterface $response |
||||
71 | * @throws \Exception |
||||
72 | */ |
||||
73 | 1 | public function indexAction(ServerRequestInterface $request): ResponseInterface |
|||
0 ignored issues
–
show
|
|||||
74 | { |
||||
75 | 1 | if ($this->getSession()->get('user')) { |
|||
76 | 1 | return new RedirectResponse('/user/home'); |
|||
77 | } |
||||
78 | |||||
79 | 1 | $body = $this->getView()->render('boneuser::index', [ |
|||
80 | 1 | 'logo' => $this->getLogo(), |
|||
81 | 1 | 'canRegister' => $this->registrationEnabled |
|||
82 | 1 | ] |
|||
83 | 1 | ); |
|||
84 | |||||
85 | 1 | return new HtmlResponse($body); |
|||
86 | } |
||||
87 | |||||
88 | /** |
||||
89 | * @param ServerRequestInterface $request |
||||
90 | * @return ResponseInterface |
||||
91 | * @throws UserException |
||||
92 | */ |
||||
93 | 4 | public function registerAction(ServerRequestInterface $request): ResponseInterface |
|||
94 | { |
||||
95 | 4 | $form = new RegistrationForm('register', $this->getTranslator()); |
|||
96 | 4 | $message = null; |
|||
97 | |||||
98 | 4 | if ($request->getMethod() === 'POST') { |
|||
99 | |||||
100 | 3 | $formData = $request->getParsedBody(); |
|||
101 | 3 | $form->populate($formData); |
|||
0 ignored issues
–
show
It seems like
$formData can also be of type null and object ; however, parameter $data of Del\Form\AbstractForm::populate() does only seem to accept array , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
102 | |||||
103 | 3 | if ($form->isValid()) { |
|||
104 | 2 | $data = $form->getValues(); |
|||
105 | |||||
106 | try { |
||||
107 | 2 | $user = $this->userService->registerUser($data); |
|||
108 | 1 | $link = $this->userService->generateEmailLink($user); |
|||
109 | 1 | $mail = $this->mailService; |
|||
110 | |||||
111 | 1 | $env = $mail->getSiteConfig()->getEnvironment(); |
|||
112 | 1 | $email = $user->getEmail(); |
|||
113 | 1 | $token = $link->getToken(); |
|||
114 | |||||
115 | 1 | $mail = new EmailMessage(); |
|||
116 | 1 | $mail->setTo($user->getEmail()); |
|||
117 | 1 | $mail->setSubject($this->getTranslator()->translate('email.user.register.thankswith', 'user') . ' ' . $this->mailService->getSiteConfig()->getTitle()); |
|||
118 | 1 | $mail->setTemplate('email.user::user_registration/user_registration'); |
|||
119 | 1 | $mail->setViewData([ |
|||
120 | 1 | 'siteUrl' => $env->getSiteURL(), |
|||
121 | 1 | 'logo' => $this->getSiteConfig()->getEmailLogo(), |
|||
122 | 1 | 'address' => $this->getSiteConfig()->getAddress(), |
|||
123 | 1 | 'activationLink' => '/user/activate/' . $email . '/' . $token, |
|||
124 | 1 | ]); |
|||
125 | 1 | $this->mailService->sendEmail($mail); |
|||
126 | 1 | $body = $this->getView()->render('boneuser::thanks-for-registering', ['logo' => $this->getLogo()]); |
|||
127 | |||||
128 | 1 | return new HtmlResponse($body); |
|||
129 | |||||
130 | 1 | } catch (UserException $e) { |
|||
131 | 1 | $message = [$e->getMessage(), 'danger']; |
|||
132 | } |
||||
133 | } else { |
||||
134 | 1 | $message = [Icon::WARNING . ' There was a problem with your form.', 'danger']; |
|||
135 | } |
||||
136 | } |
||||
137 | |||||
138 | 3 | $body = $this->getView()->render('boneuser::register', ['form' => $form, 'message' => $message, 'logo' => $this->getLogo()]); |
|||
139 | |||||
140 | 3 | return new HtmlResponse($body); |
|||
141 | } |
||||
142 | |||||
143 | /** |
||||
144 | * @param ServerRequestInterface $request |
||||
145 | * @return ResponseInterface |
||||
146 | * @throws \Doctrine\ORM\ORMException |
||||
147 | * @throws \Doctrine\ORM\OptimisticLockException |
||||
148 | */ |
||||
149 | 3 | public function activateAction(ServerRequestInterface $request): ResponseInterface |
|||
150 | { |
||||
151 | 3 | $email = $request->getAttribute('email'); |
|||
152 | 3 | $token = $request->getAttribute('token'); |
|||
153 | 3 | $translator = $this->getTranslator(); |
|||
154 | 3 | $userService = $this->userService; |
|||
155 | 3 | $loginRedirect = $this->loginRedirectRoute; |
|||
156 | 3 | $message = null; |
|||
157 | |||||
158 | try { |
||||
159 | 3 | $link = $userService->findEmailLink($email, $token); |
|||
160 | 1 | $user = $link->getUser(); |
|||
161 | 1 | $user->setState(new State(State::STATE_ACTIVATED)); |
|||
162 | 1 | $user->setLastLogin(new DateTime()); |
|||
163 | 1 | $userService->saveUser($user); |
|||
164 | 1 | $userService->deleteEmailLink($link); |
|||
165 | 1 | $this->getSession()->set('user', $user->getId()); |
|||
166 | |||||
167 | 1 | if ($this->profileRequired && !$this->userService->hasProfile($user)) { |
|||
168 | 1 | $this->loginRedirectRoute = '/user/edit-profile'; |
|||
169 | |||||
170 | 1 | return new RedirectResponse($this->loginRedirectRoute); |
|||
171 | } |
||||
172 | 2 | } catch (EmailLinkException $e) { |
|||
173 | 2 | switch ($e->getMessage()) { |
|||
174 | 2 | case EmailLinkException::LINK_EXPIRED: |
|||
175 | 1 | $message = [$translator->translate('login.activation.expired', 'user') |
|||
176 | 1 | . ' <a href="/user/resend-activation-mail/' . $email . '">' |
|||
177 | 1 | . $translator->translate('login.activation.expired2', 'user') . '</a>', 'danger']; |
|||
178 | 1 | break; |
|||
179 | default: |
||||
180 | 1 | $message = [$e->getMessage(), 'danger']; |
|||
181 | 1 | break; |
|||
182 | } |
||||
183 | } |
||||
184 | |||||
185 | 2 | $body = $this->getView()->render('boneuser::activate-user-account', [ |
|||
186 | 2 | 'loginRedirect' => $loginRedirect, |
|||
187 | 2 | 'message' => $message, |
|||
188 | 2 | 'logo' => $this->getLogo(), |
|||
189 | 2 | ]); |
|||
190 | |||||
191 | 2 | return new HtmlResponse($body); |
|||
192 | } |
||||
193 | |||||
194 | 6 | private function initForm(LoginForm $form) |
|||
195 | { |
||||
196 | 6 | $this->rememberMeCookie === false ? $form->getFields()->removeByName('remember') : null; |
|||
197 | } |
||||
198 | |||||
199 | |||||
200 | /** |
||||
201 | * @param ServerRequestInterface $request |
||||
202 | * @return ResponseInterface |
||||
203 | */ |
||||
204 | 1 | public function loginAction(ServerRequestInterface $request): ResponseInterface |
|||
0 ignored issues
–
show
The parameter
$request is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||
205 | { |
||||
206 | 1 | $form = new LoginForm('userlogin', $this->getTranslator()); |
|||
207 | 1 | $this->initForm($form); |
|||
208 | 1 | $body = $this->getView()->render('boneuser::login', ['form' => $form, 'logo' => $this->getLogo()]); |
|||
209 | |||||
210 | 1 | return new HtmlResponse($body); |
|||
211 | } |
||||
212 | |||||
213 | |||||
214 | /** |
||||
215 | * @param ServerRequestInterface $request |
||||
216 | * @return ResponseInterface |
||||
217 | */ |
||||
218 | 5 | public function loginFormAction(ServerRequestInterface $request): ResponseInterface |
|||
219 | { |
||||
220 | 5 | $translator = $this->getTranslator(); |
|||
221 | 5 | $form = new LoginForm('userlogin', $translator); |
|||
222 | 5 | $this->initForm($form); |
|||
223 | 5 | $post = $request->getParsedBody(); |
|||
224 | 5 | $form->populate($post); |
|||
0 ignored issues
–
show
It seems like
$post can also be of type null and object ; however, parameter $data of Del\Form\AbstractForm::populate() does only seem to accept array , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
225 | 5 | $params = ['form' => $form]; |
|||
226 | |||||
227 | try { |
||||
228 | 5 | if ($form->isValid()) { |
|||
229 | 5 | $data = $form->getValues(); |
|||
230 | 5 | $email = $data['email']; |
|||
231 | 5 | $pass = $data['password']; |
|||
232 | 5 | $userId = $this->userService->authenticate($email, $pass); |
|||
233 | 5 | $locale = $translator->getLocale(); |
|||
234 | 5 | $session = $this->getSession(); |
|||
235 | 5 | $session->set('user', $userId); |
|||
236 | 5 | $session->set('locale', $locale); |
|||
237 | 5 | $this->rememberMeCookie && isset($data['remember']) ? $this->setCookie((int)$data['remember'], $userId) : null; |
|||
238 | |||||
239 | 5 | if ($route = $session->get('loginRedirectRoute')) { |
|||
240 | 5 | $this->loginRedirectRoute = $route; |
|||
241 | 5 | $session->unset('loginRedirectRoute'); |
|||
242 | } |
||||
243 | |||||
244 | 5 | $user = $this->userService->findUserById($userId); |
|||
245 | 1 | $user->setLastLogin(new DateTime()); |
|||
246 | 1 | $this->userService->saveUser($user); |
|||
0 ignored issues
–
show
It seems like
$user can also be of type null ; however, parameter $user of Del\Service\UserService::saveUser() does only seem to accept Del\Entity\UserInterface , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
247 | |||||
248 | 1 | if ($this->profileRequired && !$this->userService->hasProfile($user)) { |
|||
0 ignored issues
–
show
It seems like
$user can also be of type null ; however, parameter $user of Del\Service\UserService::hasProfile() does only seem to accept Del\Entity\UserInterface , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
249 | 1 | $this->loginRedirectRoute = '/user/edit-profile'; |
|||
250 | } |
||||
251 | |||||
252 | 1 | return new RedirectResponse('/' . $locale . $this->loginRedirectRoute); |
|||
253 | } |
||||
254 | 4 | } catch (UserException $e) { |
|||
255 | 4 | switch ($e->getMessage()) { |
|||
256 | 4 | case UserException::USER_NOT_FOUND: |
|||
257 | 4 | case UserException::WRONG_PASSWORD: |
|||
258 | 1 | $message = [Icon::WARNING . ' ' . $translator->translate('login.error.password', 'user') . '<a href="/user/lost-password/' . $email . '">' . $translator->translate('login.error.password2', 'user') . '</a>', 'danger']; |
|||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
259 | 1 | break; |
|||
260 | 3 | case UserException::USER_UNACTIVATED: |
|||
261 | 1 | $message = [Icon::WARNING . ' ' . $translator->translate('login.unactivated', 'user') . '<a href="/user/resend-activation-mail/' . $email . '">' . $translator->translate('login.unactivated2', 'user') . '</a>', 'danger']; |
|||
262 | 1 | break; |
|||
263 | 2 | case UserException::USER_DISABLED: |
|||
264 | 2 | case UserException::USER_BANNED: |
|||
265 | 1 | $message = [Icon::REMOVE . ' ' . $translator->translate('login.activation.banned', 'user'), 'danger']; |
|||
266 | 1 | break; |
|||
267 | default: |
||||
268 | 1 | $message = $e->getMessage(); |
|||
269 | 1 | break; |
|||
270 | } |
||||
271 | |||||
272 | 4 | $params['message'] = $message; |
|||
273 | } |
||||
274 | |||||
275 | 4 | $params['logo'] = $this->getLogo(); |
|||
276 | 4 | $body = $this->getView()->render('boneuser::login', $params); |
|||
277 | |||||
278 | 4 | return new HtmlResponse($body); |
|||
279 | |||||
280 | } |
||||
281 | |||||
282 | /** |
||||
283 | * @param int $length |
||||
284 | * @param int $userId |
||||
285 | * @throws \ParagonIE\Paseto\Exception\InvalidKeyException |
||||
286 | * @throws \ParagonIE\Paseto\Exception\InvalidPurposeException |
||||
287 | * @throws \ParagonIE\Paseto\Exception\PasetoException |
||||
288 | */ |
||||
289 | 1 | private function setCookie(int $length, int $userId): void |
|||
290 | { |
||||
291 | 1 | $times = [ |
|||
292 | 1 | 1 => 60 * 60 * 24 * 7, |
|||
293 | 1 | 2 => 60 * 60 * 24 * 30, |
|||
294 | 1 | 3 => 60 * 60 * 24 * 365, |
|||
295 | 1 | ]; |
|||
296 | |||||
297 | 1 | $intervals = [ |
|||
298 | 1 | 1 => 'P07D', |
|||
299 | 1 | 2 => 'P30D', |
|||
300 | 1 | 3 => 'P365D', |
|||
301 | 1 | ]; |
|||
302 | |||||
303 | 1 | $time = array_key_exists($length, $times) ? $times[$length] : 0; |
|||
304 | 1 | $time += \time(); |
|||
305 | 1 | $expiry = \time() + $time; |
|||
306 | 1 | $interval = array_key_exists($length, $intervals) ? $intervals[$length] : 'P0D'; |
|||
307 | 1 | $token = $this->pasetoService->encryptToken([ |
|||
308 | 1 | 'user' => $userId, |
|||
309 | 1 | ], $interval); |
|||
310 | 1 | \setcookie('resu', $token, $expiry, '/'); |
|||
311 | } |
||||
312 | |||||
313 | /** |
||||
314 | * @param ServerRequestInterface $request |
||||
315 | * @return ResponseInterface |
||||
316 | */ |
||||
317 | 2 | public function homePageAction(ServerRequestInterface $request): ResponseInterface |
|||
318 | { |
||||
319 | 2 | if ($this->loginRedirectRoute !== '/user/home') { |
|||
320 | 1 | return new RedirectResponse($this->loginRedirectRoute); |
|||
321 | } |
||||
322 | |||||
323 | 1 | $user = $request->getAttribute('user'); |
|||
324 | |||||
325 | 1 | if ($this->profileRequired && !$this->userService->hasProfile($user)) { |
|||
326 | 1 | $this->loginRedirectRoute = '/user/edit-profile'; |
|||
327 | |||||
328 | 1 | return new RedirectResponse($this->loginRedirectRoute); |
|||
329 | } |
||||
330 | |||||
331 | $body = $this->getView()->render('boneuser::home', [ |
||||
332 | 'message' => [$this->getTranslator()->translate('home.loggedin', 'user'), 'success'], |
||||
333 | 'user' => $user, |
||||
334 | 'logo' => $this->getSiteConfig()->getLogo(), |
||||
335 | ]); |
||||
336 | |||||
337 | return new LayoutResponse($body, $this->adminLayout); |
||||
338 | } |
||||
339 | |||||
340 | /** |
||||
341 | * @param ServerRequestInterface $request |
||||
342 | * @return ResponseInterface |
||||
343 | */ |
||||
344 | 1 | public function logoutAction(ServerRequestInterface $request): ResponseInterface |
|||
0 ignored issues
–
show
The parameter
$request is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||
345 | { |
||||
346 | 1 | SessionManager::destroySession(); |
|||
347 | 1 | \setcookie('resu', '', 1, '/'); |
|||
348 | |||||
349 | 1 | return new RedirectResponse(new Uri('/')); |
|||
350 | } |
||||
351 | |||||
352 | /** |
||||
353 | * @param ServerRequestInterface $request |
||||
354 | * @return ResponseInterface |
||||
355 | */ |
||||
356 | 4 | public function resendActivationEmailAction(ServerRequestInterface $request): ResponseInterface |
|||
357 | { |
||||
358 | 4 | $email = $request->getAttribute('email'); |
|||
359 | 4 | $user = $this->userService->findUserByEmail($email); |
|||
360 | 4 | $message = null; |
|||
361 | 4 | $translator = $this->getTranslator(); |
|||
362 | |||||
363 | 4 | if (!$user) { |
|||
364 | 1 | throw new Exception(UserException::USER_NOT_FOUND, 404); |
|||
365 | } |
||||
366 | |||||
367 | 3 | if ($user->getState()->getValue() == State::STATE_ACTIVATED) { |
|||
368 | 1 | $message = [UserException::USER_ACTIVATED, 'danger']; |
|||
369 | } else { |
||||
370 | try { |
||||
371 | 2 | $link = $this->userService->generateEmailLink($user); |
|||
372 | 1 | $mail = $this->mailService; |
|||
373 | |||||
374 | 1 | $env = $mail->getSiteConfig()->getEnvironment(); |
|||
375 | 1 | $email = $user->getEmail(); |
|||
376 | 1 | $token = $link->getToken(); |
|||
377 | |||||
378 | 1 | $mail = new EmailMessage(); |
|||
379 | 1 | $mail->setTo($user->getEmail()); |
|||
380 | 1 | $mail->setSubject($translator->translate('email.user.register.thankswith', 'user') . ' ' . $this->mailService->getSiteConfig()->getTitle()); |
|||
381 | 1 | $mail->setTemplate('email.user::user_registration/user_registration'); |
|||
382 | 1 | $mail->setViewData([ |
|||
383 | 1 | 'siteUrl' => $env->getSiteURL(), |
|||
384 | 1 | 'logo' => $this->getSiteConfig()->getEmailLogo(), |
|||
385 | 1 | 'address' => $this->getSiteConfig()->getAddress(), |
|||
386 | 1 | 'activationLink' => '/user/activate/' . $email . '/' . $token, |
|||
387 | 1 | ]); |
|||
388 | 1 | $this->mailService->sendEmail($mail); |
|||
389 | |||||
390 | 1 | } catch (Exception $e) { |
|||
391 | 1 | $message = [$translator->translate('login.resendactivation.error', 'user') |
|||
392 | 1 | . $this->getSiteConfig()->getContactEmail() . '', 'danger']; |
|||
393 | } |
||||
394 | } |
||||
395 | |||||
396 | 3 | $body = $this->getView()->render('boneuser::resend-activation', [ |
|||
397 | 3 | 'message' => $message, |
|||
398 | 3 | 'logo' => $this->getLogo(), |
|||
399 | 3 | ]); |
|||
400 | |||||
401 | 3 | return new HtmlResponse($body); |
|||
402 | } |
||||
403 | |||||
404 | |||||
405 | /** |
||||
406 | * @param ServerRequestInterface $request |
||||
407 | * @return ResponseInterface |
||||
408 | */ |
||||
409 | 4 | public function forgotPasswordAction(ServerRequestInterface $request): ResponseInterface |
|||
410 | { |
||||
411 | 4 | $email = $request->getAttribute('email'); |
|||
412 | 4 | $user = $this->userService->findUserByEmail($email); |
|||
413 | |||||
414 | 4 | if (!$user) { |
|||
415 | 1 | throw new Exception(UserException::USER_NOT_FOUND, 404); |
|||
416 | } |
||||
417 | |||||
418 | 3 | if ($user->getState()->getValue() == State::STATE_UNACTIVATED) { |
|||
419 | 1 | return new RedirectResponse('/user/resend-activation-mail/' . $email); |
|||
420 | } |
||||
421 | |||||
422 | try { |
||||
423 | 2 | $link = $this->userService->generateEmailLink($user); |
|||
424 | 1 | $email = $user->getEmail(); |
|||
425 | 1 | $token = $link->getToken(); |
|||
426 | 1 | $env = $this->getSiteConfig()->getEnvironment(); |
|||
427 | 1 | $mail = new EmailMessage(); |
|||
428 | 1 | $mail->setTo($email); |
|||
429 | 1 | $mail->setSubject($this->getTranslator()->translate('email.forgotpass.subject', 'user') . $this->mailService->getSiteConfig()->getTitle() . '.'); |
|||
430 | 1 | $mail->setTemplate('email.user::user_registration/reset_password'); |
|||
431 | 1 | $mail->setViewData([ |
|||
432 | 1 | 'siteUrl' => $env->getSiteURL(), |
|||
433 | 1 | 'logo' => $this->getSiteConfig()->getEmailLogo(), |
|||
434 | 1 | 'address' => $this->getSiteConfig()->getAddress(), |
|||
435 | 1 | 'resetLink' => '/user/reset-password/' . $email . '/' . $token, |
|||
436 | 1 | ]); |
|||
437 | 1 | $this->mailService->sendEmail($mail); |
|||
438 | 1 | } catch (Exception $e) { |
|||
439 | 1 | $this->view->message = [$e->getMessage(), 'danger']; |
|||
0 ignored issues
–
show
|
|||||
440 | } |
||||
441 | |||||
442 | 2 | $body = $this->getView()->render('boneuser::forgot-password', ['logo' => $this->getLogo()]); |
|||
443 | |||||
444 | 2 | return new HtmlResponse($body); |
|||
445 | } |
||||
446 | |||||
447 | |||||
448 | /** |
||||
449 | * @param ServerRequestInterface $request |
||||
450 | * @return ResponseInterface |
||||
451 | */ |
||||
452 | 5 | public function resetPasswordAction(ServerRequestInterface $request): ResponseInterface |
|||
453 | { |
||||
454 | 5 | $email = $request->getAttribute('email'); |
|||
455 | 5 | $token = $request->getAttribute('token'); |
|||
456 | 5 | $form = new ResetPasswordForm('resetpass'); |
|||
457 | 5 | $translator = $this->getTranslator(); |
|||
458 | 5 | $params = []; |
|||
459 | 5 | $success = false; |
|||
460 | 5 | $user = $this->userService->findUserByEmail($email); |
|||
461 | |||||
462 | 5 | if (!$user) { |
|||
463 | 1 | throw new Exception(UserException::USER_NOT_FOUND, 404); |
|||
464 | } |
||||
465 | |||||
466 | try { |
||||
467 | 4 | $link = $this->userService->findEmailLink($email, $token); |
|||
468 | |||||
469 | 2 | if ($request->getMethod() === 'POST') { |
|||
470 | 2 | $data = $request->getParsedBody(); |
|||
471 | 2 | $form->populate($data); |
|||
0 ignored issues
–
show
It seems like
$data can also be of type null and object ; however, parameter $data of Del\Form\AbstractForm::populate() does only seem to accept array , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
472 | |||||
473 | 2 | if ($form->isValid()) { |
|||
474 | 2 | $data = $form->getValues(); |
|||
475 | |||||
476 | 2 | if ($data['password'] === $data['confirm']) { |
|||
477 | 1 | $this->userService->changePassword($user, $data['password']); |
|||
478 | 1 | $this->userService->deleteEmailLink($link); |
|||
479 | 1 | $message = [$translator->translate('email.resetpass.success', 'user'), 'success']; |
|||
480 | 1 | $success = true; |
|||
481 | 1 | $this->getSession()->set('user', $user->getId()); |
|||
482 | } else { |
||||
483 | 1 | $message = [$translator->translate('email.resetpass.nomatch', 'user'), 'danger']; |
|||
484 | 2 | $form = new ResetPasswordForm('resetpass'); |
|||
485 | } |
||||
486 | } |
||||
487 | } |
||||
488 | 2 | } catch (EmailLinkException $e) { |
|||
489 | 1 | $message = [$e->getMessage(), 'danger']; |
|||
490 | 1 | } catch (Exception $e) { |
|||
491 | 1 | throw $e; |
|||
492 | } |
||||
493 | |||||
494 | 3 | if (isset($message)) { |
|||
495 | 3 | $params['message'] = $message; |
|||
496 | } |
||||
497 | |||||
498 | 3 | $params['success'] = $success; |
|||
499 | 3 | $params['form'] = $form; |
|||
500 | 3 | $params['logo'] = $this->getLogo(); |
|||
501 | 3 | $body = $this->getView()->render('boneuser::reset-pass', $params); |
|||
502 | |||||
503 | 3 | return new HtmlResponse($body); |
|||
504 | } |
||||
505 | |||||
506 | /** |
||||
507 | * @param ServerRequestInterface $request |
||||
508 | * @return ResponseInterface |
||||
509 | */ |
||||
510 | 3 | public function changePasswordAction(ServerRequestInterface $request): ResponseInterface |
|||
511 | { |
||||
512 | 3 | $user = $request->getAttribute('user'); |
|||
513 | 3 | $form = new ResetPasswordForm('resetpass'); |
|||
514 | 3 | $translator = $this->getTranslator(); |
|||
515 | 3 | $message = null; |
|||
516 | 3 | $success = false; |
|||
517 | |||||
518 | 3 | if ($request->getMethod() === 'POST') { |
|||
519 | 3 | $data = $request->getParsedBody(); |
|||
520 | 3 | $form->populate($data); |
|||
521 | |||||
522 | 3 | if ($form->isValid()) { |
|||
523 | 2 | $data = $form->getValues(); |
|||
524 | |||||
525 | 2 | if ($data['password'] === $data['confirm']) { |
|||
526 | 1 | $this->userService->changePassword($user, $data['password']); |
|||
527 | 1 | $message = [Icon::CHECK_CIRCLE . ' ' . $translator->translate('email.resetpass.success', 'user'), 'success']; |
|||
528 | 1 | $success = true; |
|||
529 | } else { |
||||
530 | 1 | $message = [Icon::WARNING . ' ' . $translator->translate('email.resetpass.nomatch', 'user'), 'danger']; |
|||
531 | 1 | $form = new ResetPasswordForm('resetpass'); |
|||
532 | } |
||||
533 | } else { |
||||
534 | 1 | $message = [Icon::WARNING . ' There was a problem with your form.', 'danger']; |
|||
535 | } |
||||
536 | } |
||||
537 | |||||
538 | 3 | $params['success'] = $success; |
|||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
539 | 3 | $params['form'] = $form; |
|||
540 | 3 | $params['logo'] = $this->getLogo(); |
|||
541 | |||||
542 | 3 | $body = $this->getView()->render('boneuser::change-pass', [ |
|||
543 | 3 | 'success' => $success, |
|||
544 | 3 | 'form' => $form, |
|||
545 | 3 | 'logo' => $this->getLogo(), |
|||
546 | 3 | 'message' => $message |
|||
547 | 3 | ]); |
|||
548 | |||||
549 | 3 | return new HtmlResponse($body); |
|||
550 | } |
||||
551 | |||||
552 | /** |
||||
553 | * @param ServerRequestInterface $request |
||||
554 | * @return ResponseInterface |
||||
555 | */ |
||||
556 | 4 | public function changeEmailAction(ServerRequestInterface $request): ResponseInterface |
|||
557 | { |
||||
558 | 4 | $user = $request->getAttribute('user'); |
|||
559 | 4 | $form = new LoginForm('changeemail', $this->getTranslator()); |
|||
560 | 4 | $form->getFields()->removeByName('remember'); |
|||
561 | 4 | $form->getField('email')->setLabel('New email'); |
|||
562 | 4 | $form->getField('submit')->setValue('Submit'); |
|||
563 | 4 | $translator = $this->getTranslator(); |
|||
564 | 4 | $params = [ |
|||
565 | 4 | 'form' => $form |
|||
566 | 4 | ]; |
|||
567 | |||||
568 | 4 | if ($request->getMethod() === 'POST') { |
|||
569 | 4 | $data = $request->getParsedBody(); |
|||
570 | 4 | $form->populate($data); |
|||
571 | 4 | $message = null; |
|||
572 | |||||
573 | 4 | if ($form->isValid()) { |
|||
574 | |||||
575 | 4 | $newEmail = $form->getField('email')->getValue(); |
|||
576 | 4 | $password = $form->getField('password')->getValue(); |
|||
577 | 4 | $existing = $this->userService->findUserByEmail($newEmail); |
|||
578 | |||||
579 | 4 | if ($existing) { |
|||
580 | 1 | $message = [$translator->translate('email.changeemail.registered', 'user') . $this->getSiteConfig()->getTitle() . '.', 'danger']; |
|||
581 | } else { |
||||
582 | 3 | if ($this->userService->checkPassword($user, $password)) { |
|||
583 | |||||
584 | try { |
||||
585 | |||||
586 | 2 | $link = $this->userService->generateEmailLink($user); |
|||
587 | 1 | $email = $user->getEmail(); |
|||
588 | 1 | $token = $link->getToken(); |
|||
589 | 1 | $env = $this->getSiteConfig()->getEnvironment(); |
|||
590 | 1 | $mail = new EmailMessage(); |
|||
591 | 1 | $mail->setTo($email); |
|||
592 | 1 | $mail->setSubject($translator->translate('email.changeemail.subject', 'user') . $this->mailService->getSiteConfig()->getTitle() . '.'); |
|||
593 | 1 | $mail->setTemplate('email.user::user_registration/change_email'); |
|||
594 | 1 | $mail->setViewData([ |
|||
595 | 1 | 'siteUrl' => $env->getSiteURL(), |
|||
596 | 1 | 'logo' => $this->getSiteConfig()->getEmailLogo(), |
|||
597 | 1 | 'address' => $this->getSiteConfig()->getAddress(), |
|||
598 | 1 | 'resetLink' => '/user/reset-email/' . $email . '/' . $newEmail . '/' . $token, |
|||
599 | 1 | ]); |
|||
600 | 1 | $this->mailService->sendEmail($mail); |
|||
601 | 1 | $message = [$translator->translate('email.changeemail.sent', 'user'), 'info']; |
|||
602 | 1 | unset ($params['form']); |
|||
603 | |||||
604 | 1 | } catch (Exception $e) { |
|||
605 | 1 | $message = [$translator->translate('email.changeemail.notsent', 'user') . $this->getSiteConfig()->getContactEmail() . '.', 'danger']; |
|||
606 | } |
||||
607 | |||||
608 | } else { |
||||
609 | 1 | $message = [$translator->translate('email.changeemail.wrongpass', 'user'), 'danger']; |
|||
610 | } |
||||
611 | } |
||||
612 | } |
||||
613 | |||||
614 | 4 | $params['message'] = $message; |
|||
615 | } |
||||
616 | |||||
617 | 4 | $params['logo'] = $this->getLogo(); |
|||
618 | 4 | $body = $this->getView()->render('boneuser::change-email', $params); |
|||
619 | |||||
620 | 4 | return new LayoutResponse($body, 'layouts::admin'); |
|||
621 | } |
||||
622 | |||||
623 | /** |
||||
624 | * @param ServerRequestInterface $request |
||||
625 | * @return ResponseInterface |
||||
626 | */ |
||||
627 | 1 | public function editProfileAction(ServerRequestInterface $request): ResponseInterface |
|||
628 | { |
||||
629 | 1 | $user = $request->getAttribute('user'); |
|||
630 | 1 | $person = $user->getPerson(); |
|||
631 | 1 | $image = $person->getImage(); |
|||
632 | 1 | $form = new PersonForm('profile', $this->getTranslator()); |
|||
633 | 1 | $array = $this->userService->getPersonSvc()->toArray($person); |
|||
0 ignored issues
–
show
The function
Del\Service\UserService::getPersonSvc() has been deprecated: use getPersonService() instead
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead. ![]() |
|||||
634 | 1 | $form->populate($array); |
|||
635 | |||||
636 | 1 | if ($request->getMethod() === 'POST') { |
|||
637 | 1 | $post = $request->getParsedBody(); |
|||
638 | 1 | $form->populate($post); |
|||
0 ignored issues
–
show
It seems like
$post can also be of type null and object ; however, parameter $data of Del\Form\AbstractForm::populate() does only seem to accept array , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
639 | |||||
640 | 1 | if ($form->isValid()) { |
|||
641 | 1 | $data = $form->getValues(); |
|||
642 | 1 | $data['image'] = $image; |
|||
643 | 1 | $dateFormat = $this->getSiteConfig()->getAttribute('i18n')['date_format']; |
|||
644 | 1 | $data['dob'] = DateTime::createFromFormat($dateFormat, $data['dob']); |
|||
645 | 1 | $data['country'] = CountryFactory::generate($data['country']); |
|||
646 | 1 | $this->userService->getPersonSvc()->populateFromArray($person, $data); |
|||
0 ignored issues
–
show
The function
Del\Service\UserService::getPersonSvc() has been deprecated: use getPersonService() instead
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead. ![]() |
|||||
647 | 1 | $this->userService->saveUser($user); |
|||
648 | } |
||||
649 | } |
||||
650 | |||||
651 | 1 | $body = $this->getView()->render('boneuser::edit-profile', [ |
|||
652 | 1 | 'person' => $person, |
|||
653 | 1 | 'form' => $form->render(), |
|||
654 | 1 | ]); |
|||
655 | |||||
656 | 1 | return new LayoutResponse($body, $this->adminLayout); |
|||
657 | } |
||||
658 | |||||
659 | /** |
||||
660 | * @param ServerRequestInterface $requestApiController |
||||
661 | * @return ResponseInterface |
||||
662 | */ |
||||
663 | 2 | public function resetEmailAction(ServerRequestInterface $request): ResponseInterface |
|||
664 | { |
||||
665 | 2 | $email = $request->getAttribute('email'); |
|||
666 | 2 | $newEmail = $request->getAttribute('new-email'); |
|||
667 | 2 | $token = $request->getAttribute('token'); |
|||
668 | 2 | $translator = $this->getTranslator(); |
|||
669 | |||||
670 | try { |
||||
671 | 2 | $link = $this->userService->findEmailLink($email, $token); |
|||
672 | 1 | $user = $link->getUser(); |
|||
673 | 1 | $user->setEmail($newEmail); |
|||
674 | 1 | $this->userService->saveUser($user); |
|||
675 | 1 | $this->userService->deleteEmailLink($link); |
|||
676 | 1 | $message = [$translator->translate('email.changeemail.success', 'user') . $newEmail . $translator->translate('email.changeemail.success2', 'user'), 'success']; |
|||
677 | 1 | SessionManager::getInstance()->set('user', $user->getId()); |
|||
678 | 1 | } catch (EmailLinkException $e) { |
|||
679 | 1 | $message = [$e->getMessage(), 'danger']; |
|||
680 | } |
||||
681 | |||||
682 | 2 | $body = $this->getView()->render('boneuser::reset-email', ['message' => $message, 'logo' => $this->getLogo()]); |
|||
683 | |||||
684 | 2 | return new HtmlResponse($body); |
|||
685 | } |
||||
686 | } |
||||
687 |
This check looks for parameters that have been defined for a function or method, but which are not used in the method body.