Completed
Push — master ( 38961a...52c0e0 )
by Morris
108:20 queued 94:02
created
core/Controller/LoginController.php 1 patch
Indentation   +295 added lines, -295 removed lines patch added patch discarded remove patch
@@ -58,299 +58,299 @@
 block discarded – undo
58 58
 use OCP\Util;
59 59
 
60 60
 class LoginController extends Controller {
61
-	/** @var IUserManager */
62
-	private $userManager;
63
-	/** @var IConfig */
64
-	private $config;
65
-	/** @var ISession */
66
-	private $session;
67
-	/** @var IUserSession|Session */
68
-	private $userSession;
69
-	/** @var IURLGenerator */
70
-	private $urlGenerator;
71
-	/** @var ILogger */
72
-	private $logger;
73
-	/** @var Manager */
74
-	private $twoFactorManager;
75
-	/** @var Defaults */
76
-	private $defaults;
77
-	/** @var Throttler */
78
-	private $throttler;
79
-
80
-	/**
81
-	 * @param string $appName
82
-	 * @param IRequest $request
83
-	 * @param IUserManager $userManager
84
-	 * @param IConfig $config
85
-	 * @param ISession $session
86
-	 * @param IUserSession $userSession
87
-	 * @param IURLGenerator $urlGenerator
88
-	 * @param ILogger $logger
89
-	 * @param Manager $twoFactorManager
90
-	 * @param Defaults $defaults
91
-	 * @param Throttler $throttler
92
-	 */
93
-	public function __construct($appName,
94
-								IRequest $request,
95
-								IUserManager $userManager,
96
-								IConfig $config,
97
-								ISession $session,
98
-								IUserSession $userSession,
99
-								IURLGenerator $urlGenerator,
100
-								ILogger $logger,
101
-								Manager $twoFactorManager,
102
-								Defaults $defaults,
103
-								Throttler $throttler) {
104
-		parent::__construct($appName, $request);
105
-		$this->userManager = $userManager;
106
-		$this->config = $config;
107
-		$this->session = $session;
108
-		$this->userSession = $userSession;
109
-		$this->urlGenerator = $urlGenerator;
110
-		$this->logger = $logger;
111
-		$this->twoFactorManager = $twoFactorManager;
112
-		$this->defaults = $defaults;
113
-		$this->throttler = $throttler;
114
-	}
115
-
116
-	/**
117
-	 * @NoAdminRequired
118
-	 * @UseSession
119
-	 *
120
-	 * @return RedirectResponse
121
-	 */
122
-	public function logout() {
123
-		$loginToken = $this->request->getCookie('nc_token');
124
-		if (!is_null($loginToken)) {
125
-			$this->config->deleteUserValue($this->userSession->getUser()->getUID(), 'login_token', $loginToken);
126
-		}
127
-		$this->userSession->logout();
128
-
129
-		$response = new RedirectResponse($this->urlGenerator->linkToRouteAbsolute('core.login.showLoginForm'));
130
-		$response->addHeader('Clear-Site-Data', '"cache", "cookies", "storage", "executionContexts"');
131
-		return $response;
132
-	}
133
-
134
-	/**
135
-	 * @PublicPage
136
-	 * @NoCSRFRequired
137
-	 * @UseSession
138
-	 *
139
-	 * @param string $user
140
-	 * @param string $redirect_url
141
-	 *
142
-	 * @return TemplateResponse|RedirectResponse
143
-	 */
144
-	public function showLoginForm(string $user = null, string $redirect_url = null): Http\Response {
145
-
146
-		if ($this->userSession->isLoggedIn()) {
147
-			return new RedirectResponse(OC_Util::getDefaultPageUrl());
148
-		}
149
-
150
-		$parameters = array();
151
-		$loginMessages = $this->session->get('loginMessages');
152
-		$errors = [];
153
-		$messages = [];
154
-		if (is_array($loginMessages)) {
155
-			list($errors, $messages) = $loginMessages;
156
-		}
157
-		$this->session->remove('loginMessages');
158
-		foreach ($errors as $value) {
159
-			$parameters[$value] = true;
160
-		}
161
-
162
-		$parameters['messages'] = $messages;
163
-		if ($user !== null && $user !== '') {
164
-			$parameters['loginName'] = $user;
165
-			$parameters['user_autofocus'] = false;
166
-		} else {
167
-			$parameters['loginName'] = '';
168
-			$parameters['user_autofocus'] = true;
169
-		}
170
-		if (!empty($redirect_url)) {
171
-			$parameters['redirect_url'] = $redirect_url;
172
-		}
173
-
174
-		$parameters['canResetPassword'] = true;
175
-		$parameters['resetPasswordLink'] = $this->config->getSystemValue('lost_password_link', '');
176
-		if (!$parameters['resetPasswordLink']) {
177
-			if ($user !== null && $user !== '') {
178
-				$userObj = $this->userManager->get($user);
179
-				if ($userObj instanceof IUser) {
180
-					$parameters['canResetPassword'] = $userObj->canChangePassword();
181
-				}
182
-			}
183
-		} elseif ($parameters['resetPasswordLink'] === 'disabled') {
184
-			$parameters['canResetPassword'] = false;
185
-		}
186
-
187
-		$parameters['alt_login'] = OC_App::getAlternativeLogIns();
188
-
189
-		if ($user !== null && $user !== '') {
190
-			$parameters['loginName'] = $user;
191
-			$parameters['user_autofocus'] = false;
192
-		} else {
193
-			$parameters['loginName'] = '';
194
-			$parameters['user_autofocus'] = true;
195
-		}
196
-
197
-		$parameters['throttle_delay'] = $this->throttler->getDelay($this->request->getRemoteAddress());
198
-
199
-		// OpenGraph Support: http://ogp.me/
200
-		Util::addHeader('meta', ['property' => 'og:title', 'content' => Util::sanitizeHTML($this->defaults->getName())]);
201
-		Util::addHeader('meta', ['property' => 'og:description', 'content' => Util::sanitizeHTML($this->defaults->getSlogan())]);
202
-		Util::addHeader('meta', ['property' => 'og:site_name', 'content' => Util::sanitizeHTML($this->defaults->getName())]);
203
-		Util::addHeader('meta', ['property' => 'og:url', 'content' => $this->urlGenerator->getAbsoluteURL('/')]);
204
-		Util::addHeader('meta', ['property' => 'og:type', 'content' => 'website']);
205
-		Util::addHeader('meta', ['property' => 'og:image', 'content' => $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core','favicon-touch.png'))]);
206
-
207
-		return new TemplateResponse(
208
-			$this->appName, 'login', $parameters, 'guest'
209
-		);
210
-	}
211
-
212
-	/**
213
-	 * @param string $redirectUrl
214
-	 * @return RedirectResponse
215
-	 */
216
-	private function generateRedirect($redirectUrl) {
217
-		if (!is_null($redirectUrl) && $this->userSession->isLoggedIn()) {
218
-			$location = $this->urlGenerator->getAbsoluteURL(urldecode($redirectUrl));
219
-			// Deny the redirect if the URL contains a @
220
-			// This prevents unvalidated redirects like ?redirect_url=:[email protected]
221
-			if (strpos($location, '@') === false) {
222
-				return new RedirectResponse($location);
223
-			}
224
-		}
225
-		return new RedirectResponse(OC_Util::getDefaultPageUrl());
226
-	}
227
-
228
-	/**
229
-	 * @PublicPage
230
-	 * @UseSession
231
-	 * @NoCSRFRequired
232
-	 * @BruteForceProtection(action=login)
233
-	 *
234
-	 * @param string $user
235
-	 * @param string $password
236
-	 * @param string $redirect_url
237
-	 * @param boolean $remember_login
238
-	 * @param string $timezone
239
-	 * @param string $timezone_offset
240
-	 * @return RedirectResponse
241
-	 */
242
-	public function tryLogin($user, $password, $redirect_url, $remember_login = true, $timezone = '', $timezone_offset = '') {
243
-		if(!is_string($user)) {
244
-			throw new \InvalidArgumentException('Username must be string');
245
-		}
246
-
247
-		// If the user is already logged in and the CSRF check does not pass then
248
-		// simply redirect the user to the correct page as required. This is the
249
-		// case when an user has already logged-in, in another tab.
250
-		if(!$this->request->passesCSRFCheck()) {
251
-			return $this->generateRedirect($redirect_url);
252
-		}
253
-
254
-		if ($this->userManager instanceof PublicEmitter) {
255
-			$this->userManager->emit('\OC\User', 'preLogin', array($user, $password));
256
-		}
257
-
258
-		$originalUser = $user;
259
-		// TODO: Add all the insane error handling
260
-		/* @var $loginResult IUser */
261
-		$loginResult = $this->userManager->checkPasswordNoLogging($user, $password);
262
-		if ($loginResult === false) {
263
-			$users = $this->userManager->getByEmail($user);
264
-			// we only allow login by email if unique
265
-			if (count($users) === 1) {
266
-				$previousUser = $user;
267
-				$user = $users[0]->getUID();
268
-				if($user !== $previousUser) {
269
-					$loginResult = $this->userManager->checkPassword($user, $password);
270
-				}
271
-			}
272
-		}
273
-		if ($loginResult === false) {
274
-			$this->logger->warning('Login failed: \''. $user .'\' (Remote IP: \''. $this->request->getRemoteAddress(). '\')', ['app' => 'core']);
275
-			// Read current user and append if possible - we need to return the unmodified user otherwise we will leak the login name
276
-			$args = !is_null($user) ? ['user' => $originalUser] : [];
277
-			if (!is_null($redirect_url)) {
278
-				$args['redirect_url'] = $redirect_url;
279
-			}
280
-			$response = new RedirectResponse($this->urlGenerator->linkToRoute('core.login.showLoginForm', $args));
281
-			$response->throttle(['user' => $user]);
282
-			$this->session->set('loginMessages', [
283
-				['invalidpassword'], []
284
-			]);
285
-			return $response;
286
-		}
287
-		// TODO: remove password checks from above and let the user session handle failures
288
-		// requires https://github.com/owncloud/core/pull/24616
289
-		$this->userSession->completeLogin($loginResult, ['loginName' => $user, 'password' => $password]);
290
-		$this->userSession->createSessionToken($this->request, $loginResult->getUID(), $user, $password, IToken::REMEMBER);
291
-
292
-		// User has successfully logged in, now remove the password reset link, when it is available
293
-		$this->config->deleteUserValue($loginResult->getUID(), 'core', 'lostpassword');
294
-
295
-		$this->session->set('last-password-confirm', $loginResult->getLastLogin());
296
-
297
-		if ($timezone_offset !== '') {
298
-			$this->config->setUserValue($loginResult->getUID(), 'core', 'timezone', $timezone);
299
-			$this->session->set('timezone', $timezone_offset);
300
-		}
301
-
302
-		if ($this->twoFactorManager->isTwoFactorAuthenticated($loginResult)) {
303
-			$this->twoFactorManager->prepareTwoFactorLogin($loginResult, $remember_login);
304
-
305
-			$providers = $this->twoFactorManager->getProviders($loginResult);
306
-			if (count($providers) === 1) {
307
-				// Single provider, hence we can redirect to that provider's challenge page directly
308
-				/* @var $provider IProvider */
309
-				$provider = array_pop($providers);
310
-				$url = 'core.TwoFactorChallenge.showChallenge';
311
-				$urlParams = [
312
-					'challengeProviderId' => $provider->getId(),
313
-				];
314
-			} else {
315
-				$url = 'core.TwoFactorChallenge.selectChallenge';
316
-				$urlParams = [];
317
-			}
318
-
319
-			if (!is_null($redirect_url)) {
320
-				$urlParams['redirect_url'] = $redirect_url;
321
-			}
322
-
323
-			return new RedirectResponse($this->urlGenerator->linkToRoute($url, $urlParams));
324
-		}
325
-
326
-		if ($remember_login) {
327
-			$this->userSession->createRememberMeToken($loginResult);
328
-		}
329
-
330
-		return $this->generateRedirect($redirect_url);
331
-	}
332
-
333
-	/**
334
-	 * @NoAdminRequired
335
-	 * @UseSession
336
-	 * @BruteForceProtection(action=sudo)
337
-	 *
338
-	 * @license GNU AGPL version 3 or any later version
339
-	 *
340
-	 * @param string $password
341
-	 * @return DataResponse
342
-	 */
343
-	public function confirmPassword($password) {
344
-		$loginName = $this->userSession->getLoginName();
345
-		$loginResult = $this->userManager->checkPassword($loginName, $password);
346
-		if ($loginResult === false) {
347
-			$response = new DataResponse([], Http::STATUS_FORBIDDEN);
348
-			$response->throttle();
349
-			return $response;
350
-		}
351
-
352
-		$confirmTimestamp = time();
353
-		$this->session->set('last-password-confirm', $confirmTimestamp);
354
-		return new DataResponse(['lastLogin' => $confirmTimestamp], Http::STATUS_OK);
355
-	}
61
+    /** @var IUserManager */
62
+    private $userManager;
63
+    /** @var IConfig */
64
+    private $config;
65
+    /** @var ISession */
66
+    private $session;
67
+    /** @var IUserSession|Session */
68
+    private $userSession;
69
+    /** @var IURLGenerator */
70
+    private $urlGenerator;
71
+    /** @var ILogger */
72
+    private $logger;
73
+    /** @var Manager */
74
+    private $twoFactorManager;
75
+    /** @var Defaults */
76
+    private $defaults;
77
+    /** @var Throttler */
78
+    private $throttler;
79
+
80
+    /**
81
+     * @param string $appName
82
+     * @param IRequest $request
83
+     * @param IUserManager $userManager
84
+     * @param IConfig $config
85
+     * @param ISession $session
86
+     * @param IUserSession $userSession
87
+     * @param IURLGenerator $urlGenerator
88
+     * @param ILogger $logger
89
+     * @param Manager $twoFactorManager
90
+     * @param Defaults $defaults
91
+     * @param Throttler $throttler
92
+     */
93
+    public function __construct($appName,
94
+                                IRequest $request,
95
+                                IUserManager $userManager,
96
+                                IConfig $config,
97
+                                ISession $session,
98
+                                IUserSession $userSession,
99
+                                IURLGenerator $urlGenerator,
100
+                                ILogger $logger,
101
+                                Manager $twoFactorManager,
102
+                                Defaults $defaults,
103
+                                Throttler $throttler) {
104
+        parent::__construct($appName, $request);
105
+        $this->userManager = $userManager;
106
+        $this->config = $config;
107
+        $this->session = $session;
108
+        $this->userSession = $userSession;
109
+        $this->urlGenerator = $urlGenerator;
110
+        $this->logger = $logger;
111
+        $this->twoFactorManager = $twoFactorManager;
112
+        $this->defaults = $defaults;
113
+        $this->throttler = $throttler;
114
+    }
115
+
116
+    /**
117
+     * @NoAdminRequired
118
+     * @UseSession
119
+     *
120
+     * @return RedirectResponse
121
+     */
122
+    public function logout() {
123
+        $loginToken = $this->request->getCookie('nc_token');
124
+        if (!is_null($loginToken)) {
125
+            $this->config->deleteUserValue($this->userSession->getUser()->getUID(), 'login_token', $loginToken);
126
+        }
127
+        $this->userSession->logout();
128
+
129
+        $response = new RedirectResponse($this->urlGenerator->linkToRouteAbsolute('core.login.showLoginForm'));
130
+        $response->addHeader('Clear-Site-Data', '"cache", "cookies", "storage", "executionContexts"');
131
+        return $response;
132
+    }
133
+
134
+    /**
135
+     * @PublicPage
136
+     * @NoCSRFRequired
137
+     * @UseSession
138
+     *
139
+     * @param string $user
140
+     * @param string $redirect_url
141
+     *
142
+     * @return TemplateResponse|RedirectResponse
143
+     */
144
+    public function showLoginForm(string $user = null, string $redirect_url = null): Http\Response {
145
+
146
+        if ($this->userSession->isLoggedIn()) {
147
+            return new RedirectResponse(OC_Util::getDefaultPageUrl());
148
+        }
149
+
150
+        $parameters = array();
151
+        $loginMessages = $this->session->get('loginMessages');
152
+        $errors = [];
153
+        $messages = [];
154
+        if (is_array($loginMessages)) {
155
+            list($errors, $messages) = $loginMessages;
156
+        }
157
+        $this->session->remove('loginMessages');
158
+        foreach ($errors as $value) {
159
+            $parameters[$value] = true;
160
+        }
161
+
162
+        $parameters['messages'] = $messages;
163
+        if ($user !== null && $user !== '') {
164
+            $parameters['loginName'] = $user;
165
+            $parameters['user_autofocus'] = false;
166
+        } else {
167
+            $parameters['loginName'] = '';
168
+            $parameters['user_autofocus'] = true;
169
+        }
170
+        if (!empty($redirect_url)) {
171
+            $parameters['redirect_url'] = $redirect_url;
172
+        }
173
+
174
+        $parameters['canResetPassword'] = true;
175
+        $parameters['resetPasswordLink'] = $this->config->getSystemValue('lost_password_link', '');
176
+        if (!$parameters['resetPasswordLink']) {
177
+            if ($user !== null && $user !== '') {
178
+                $userObj = $this->userManager->get($user);
179
+                if ($userObj instanceof IUser) {
180
+                    $parameters['canResetPassword'] = $userObj->canChangePassword();
181
+                }
182
+            }
183
+        } elseif ($parameters['resetPasswordLink'] === 'disabled') {
184
+            $parameters['canResetPassword'] = false;
185
+        }
186
+
187
+        $parameters['alt_login'] = OC_App::getAlternativeLogIns();
188
+
189
+        if ($user !== null && $user !== '') {
190
+            $parameters['loginName'] = $user;
191
+            $parameters['user_autofocus'] = false;
192
+        } else {
193
+            $parameters['loginName'] = '';
194
+            $parameters['user_autofocus'] = true;
195
+        }
196
+
197
+        $parameters['throttle_delay'] = $this->throttler->getDelay($this->request->getRemoteAddress());
198
+
199
+        // OpenGraph Support: http://ogp.me/
200
+        Util::addHeader('meta', ['property' => 'og:title', 'content' => Util::sanitizeHTML($this->defaults->getName())]);
201
+        Util::addHeader('meta', ['property' => 'og:description', 'content' => Util::sanitizeHTML($this->defaults->getSlogan())]);
202
+        Util::addHeader('meta', ['property' => 'og:site_name', 'content' => Util::sanitizeHTML($this->defaults->getName())]);
203
+        Util::addHeader('meta', ['property' => 'og:url', 'content' => $this->urlGenerator->getAbsoluteURL('/')]);
204
+        Util::addHeader('meta', ['property' => 'og:type', 'content' => 'website']);
205
+        Util::addHeader('meta', ['property' => 'og:image', 'content' => $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core','favicon-touch.png'))]);
206
+
207
+        return new TemplateResponse(
208
+            $this->appName, 'login', $parameters, 'guest'
209
+        );
210
+    }
211
+
212
+    /**
213
+     * @param string $redirectUrl
214
+     * @return RedirectResponse
215
+     */
216
+    private function generateRedirect($redirectUrl) {
217
+        if (!is_null($redirectUrl) && $this->userSession->isLoggedIn()) {
218
+            $location = $this->urlGenerator->getAbsoluteURL(urldecode($redirectUrl));
219
+            // Deny the redirect if the URL contains a @
220
+            // This prevents unvalidated redirects like ?redirect_url=:[email protected]
221
+            if (strpos($location, '@') === false) {
222
+                return new RedirectResponse($location);
223
+            }
224
+        }
225
+        return new RedirectResponse(OC_Util::getDefaultPageUrl());
226
+    }
227
+
228
+    /**
229
+     * @PublicPage
230
+     * @UseSession
231
+     * @NoCSRFRequired
232
+     * @BruteForceProtection(action=login)
233
+     *
234
+     * @param string $user
235
+     * @param string $password
236
+     * @param string $redirect_url
237
+     * @param boolean $remember_login
238
+     * @param string $timezone
239
+     * @param string $timezone_offset
240
+     * @return RedirectResponse
241
+     */
242
+    public function tryLogin($user, $password, $redirect_url, $remember_login = true, $timezone = '', $timezone_offset = '') {
243
+        if(!is_string($user)) {
244
+            throw new \InvalidArgumentException('Username must be string');
245
+        }
246
+
247
+        // If the user is already logged in and the CSRF check does not pass then
248
+        // simply redirect the user to the correct page as required. This is the
249
+        // case when an user has already logged-in, in another tab.
250
+        if(!$this->request->passesCSRFCheck()) {
251
+            return $this->generateRedirect($redirect_url);
252
+        }
253
+
254
+        if ($this->userManager instanceof PublicEmitter) {
255
+            $this->userManager->emit('\OC\User', 'preLogin', array($user, $password));
256
+        }
257
+
258
+        $originalUser = $user;
259
+        // TODO: Add all the insane error handling
260
+        /* @var $loginResult IUser */
261
+        $loginResult = $this->userManager->checkPasswordNoLogging($user, $password);
262
+        if ($loginResult === false) {
263
+            $users = $this->userManager->getByEmail($user);
264
+            // we only allow login by email if unique
265
+            if (count($users) === 1) {
266
+                $previousUser = $user;
267
+                $user = $users[0]->getUID();
268
+                if($user !== $previousUser) {
269
+                    $loginResult = $this->userManager->checkPassword($user, $password);
270
+                }
271
+            }
272
+        }
273
+        if ($loginResult === false) {
274
+            $this->logger->warning('Login failed: \''. $user .'\' (Remote IP: \''. $this->request->getRemoteAddress(). '\')', ['app' => 'core']);
275
+            // Read current user and append if possible - we need to return the unmodified user otherwise we will leak the login name
276
+            $args = !is_null($user) ? ['user' => $originalUser] : [];
277
+            if (!is_null($redirect_url)) {
278
+                $args['redirect_url'] = $redirect_url;
279
+            }
280
+            $response = new RedirectResponse($this->urlGenerator->linkToRoute('core.login.showLoginForm', $args));
281
+            $response->throttle(['user' => $user]);
282
+            $this->session->set('loginMessages', [
283
+                ['invalidpassword'], []
284
+            ]);
285
+            return $response;
286
+        }
287
+        // TODO: remove password checks from above and let the user session handle failures
288
+        // requires https://github.com/owncloud/core/pull/24616
289
+        $this->userSession->completeLogin($loginResult, ['loginName' => $user, 'password' => $password]);
290
+        $this->userSession->createSessionToken($this->request, $loginResult->getUID(), $user, $password, IToken::REMEMBER);
291
+
292
+        // User has successfully logged in, now remove the password reset link, when it is available
293
+        $this->config->deleteUserValue($loginResult->getUID(), 'core', 'lostpassword');
294
+
295
+        $this->session->set('last-password-confirm', $loginResult->getLastLogin());
296
+
297
+        if ($timezone_offset !== '') {
298
+            $this->config->setUserValue($loginResult->getUID(), 'core', 'timezone', $timezone);
299
+            $this->session->set('timezone', $timezone_offset);
300
+        }
301
+
302
+        if ($this->twoFactorManager->isTwoFactorAuthenticated($loginResult)) {
303
+            $this->twoFactorManager->prepareTwoFactorLogin($loginResult, $remember_login);
304
+
305
+            $providers = $this->twoFactorManager->getProviders($loginResult);
306
+            if (count($providers) === 1) {
307
+                // Single provider, hence we can redirect to that provider's challenge page directly
308
+                /* @var $provider IProvider */
309
+                $provider = array_pop($providers);
310
+                $url = 'core.TwoFactorChallenge.showChallenge';
311
+                $urlParams = [
312
+                    'challengeProviderId' => $provider->getId(),
313
+                ];
314
+            } else {
315
+                $url = 'core.TwoFactorChallenge.selectChallenge';
316
+                $urlParams = [];
317
+            }
318
+
319
+            if (!is_null($redirect_url)) {
320
+                $urlParams['redirect_url'] = $redirect_url;
321
+            }
322
+
323
+            return new RedirectResponse($this->urlGenerator->linkToRoute($url, $urlParams));
324
+        }
325
+
326
+        if ($remember_login) {
327
+            $this->userSession->createRememberMeToken($loginResult);
328
+        }
329
+
330
+        return $this->generateRedirect($redirect_url);
331
+    }
332
+
333
+    /**
334
+     * @NoAdminRequired
335
+     * @UseSession
336
+     * @BruteForceProtection(action=sudo)
337
+     *
338
+     * @license GNU AGPL version 3 or any later version
339
+     *
340
+     * @param string $password
341
+     * @return DataResponse
342
+     */
343
+    public function confirmPassword($password) {
344
+        $loginName = $this->userSession->getLoginName();
345
+        $loginResult = $this->userManager->checkPassword($loginName, $password);
346
+        if ($loginResult === false) {
347
+            $response = new DataResponse([], Http::STATUS_FORBIDDEN);
348
+            $response->throttle();
349
+            return $response;
350
+        }
351
+
352
+        $confirmTimestamp = time();
353
+        $this->session->set('last-password-confirm', $confirmTimestamp);
354
+        return new DataResponse(['lastLogin' => $confirmTimestamp], Http::STATUS_OK);
355
+    }
356 356
 }
Please login to merge, or discard this patch.