/** * Respond with JavaScript to inform the Flarum app about the user's * authentication status. * * An array of identification attributes must be passed as the first * argument. These are checked against existing user accounts; if a match is * found, then the user is authenticated and logged into that account via * cookie. The Flarum app will then simply refresh the page. * * If no matching account is found, then an AuthToken will be generated to * store the identification attributes. This token, along with an optional * array of suggestions, will be passed into the Flarum app's sign up modal. * This results in the user not having to choose a password. When they * complete their registration, the identification attributes will be * set on their new user account. * * @param array $identification * @param array $suggestions * @return HtmlResponse */ protected function authenticate(array $identification, array $suggestions = []) { $user = User::where($identification)->first(); // If a user with these attributes already exists, then we will log them // in by generating an access token. Otherwise, we will generate a // unique token for these attributes and add it to the response, along // with the suggested account information. if ($user) { $payload = ['authenticated' => true]; } else { $token = AuthToken::generate($identification); $token->save(); $payload = array_merge($identification, $suggestions, ['token' => $token->id]); } $content = sprintf('<script>window.opener.app.authenticationComplete(%s); window.close();</script>', json_encode($payload)); $response = new HtmlResponse($content); if ($user) { // Extend the token's expiry to 2 weeks so that we can set a // remember cookie $accessToken = $this->bus->dispatch(new GenerateAccessToken($user->id)); $accessToken::unguard(); $accessToken->update(['expires_at' => new DateTime('+2 weeks')]); $response = $this->withRememberCookie($response, $accessToken->id); } return $response; }
private function collectGarbage() { if ($this->hitsLottery()) { AccessToken::whereRaw('last_activity <= ? - lifetime', [time()])->delete(); $earliestToKeep = date('Y-m-d H:i:s', time() - 24 * 60 * 60); EmailToken::where('created_at', '<=', $earliestToKeep)->delete(); PasswordToken::where('created_at', '<=', $earliestToKeep)->delete(); AuthToken::where('created_at', '<=', $earliestToKeep)->delete(); } }
/** * @param array $identification * @param array $suggestions * @param User|null $user * @return array */ private function getPayload(array $identification, array $suggestions, User $user = null) { // If a user with these attributes already exists, then we will log them // in by generating an access token. Otherwise, we will generate a // unique token for these attributes and add it to the response, along // with the suggested account information. if ($user) { $payload = ['authenticated' => true]; } else { $token = AuthToken::generate($identification); $token->save(); $payload = array_merge($identification, $suggestions, ['token' => $token->id]); } return $payload; }
/** * @param RegisterUser $command * @throws PermissionDeniedException if signup is closed and the actor is * not an administrator. * @throws \Flarum\Core\Exception\InvalidConfirmationTokenException if an * email confirmation token is provided but is invalid. * @return User */ public function handle(RegisterUser $command) { $actor = $command->actor; $data = $command->data; if (!$this->settings->get('allow_sign_up')) { $this->assertAdmin($actor); } $username = array_get($data, 'attributes.username'); $email = array_get($data, 'attributes.email'); $password = array_get($data, 'attributes.password'); // If a valid authentication token was provided as an attribute, // then we won't require the user to choose a password. if (isset($data['attributes']['token'])) { $token = AuthToken::validOrFail($data['attributes']['token']); $password = $password ?: str_random(20); } $user = User::register($username, $email, $password); // If a valid authentication token was provided, then we will assign // the attributes associated with it to the user's account. If this // includes an email address, then we will activate the user's account // from the get-go. if (isset($token)) { foreach ($token->payload as $k => $v) { $user->{$k} = $v; } if (isset($token->payload['email'])) { $user->activate(); } } $this->events->fire(new UserWillBeSaved($user, $actor, $data)); $this->validator->assertValid(array_merge($user->getAttributes(), compact('password'))); $user->save(); if (isset($token)) { $token->delete(); } $this->dispatchEventsFor($user, $actor); return $user; }