/**
  * {@inheritdoc}
  */
 public function __invoke(Request $request, Response $response, callable $out = null)
 {
     do {
         // Check if a guest.
         $actor = $request->getAttribute('actor');
         if (!$actor->isGuest()) {
             break;
         }
         // Check for the global cookie setting.
         $authSettings = SingleSO::settingsAuth($this->settings, false);
         if (!$authSettings) {
             break;
         }
         // Check if the cookie is configured.
         $globalCookie = $authSettings['global_cookie'];
         if (!$globalCookie) {
             break;
         }
         // Check if that cookie is set.
         $cookies = $request->getCookieParams();
         if (!isset($cookies[$globalCookie])) {
             break;
         }
         // Get current request path.
         // And URL hash is unfortunately unavailable.
         // Such data will be discarded on auto-login.
         $requestUri = $request->getUri();
         $requestPath = $requestUri->getPath();
         // Ignore if the controller path, avoid infinite redirect.
         if (strpos($requestPath, SingleSO::CONTROLLER_PATH) === 0) {
             break;
         }
         // Get any query parameters.
         $query = $requestUri->getQuery();
         // Create the redirect path, preserve ? even if no query.
         $params = $request->getQueryParams();
         $redirect = $requestPath . ($query ? '?' . $query : (isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '?') !== false ? '?' : ''));
         // Create the login path.
         $loginPath = rtrim($this->app->url(), '/') . SingleSO::CONTROLLER_PATH . '/login';
         // Create the redirect target, include return redirect parameters.
         $target = SingleSO::addParams($loginPath, ['redirect' => $redirect]);
         // Take over the response, redirect to login URL.
         return new RedirectResponse($target);
     } while (false);
     return $out ? $out($request, $response) : $response;
 }
 /**
  * @param Request $request
  * @param boolean $register
  * @throws SingleSOException
  * @return \Psr\Http\Message\ResponseInterface|RedirectResponse
  */
 public function createLoginResponse(Request $request, $register = false)
 {
     // If current user is already logged in, just redirect now.
     $actor = $request->getAttribute('actor');
     if (!$actor->isGuest()) {
         return new RedirectResponse($this->expandRedirect(array_get($params, 'redirect')));
     }
     // Load settings or fail.
     $authSettings = SingleSO::settingsAuth($this->settings, true);
     // Get parameters.
     $params = $request->getQueryParams();
     $redirect = array_get($params, 'redirect');
     // If the register action, show registration page, else show login.
     $target = $authSettings[$register ? 'register_url' : 'login_url'];
     // Store state in session.
     $session = $request->getAttribute('session');
     $state = $this->sessionStateCreate($session, $redirect);
     // Setup parameters.
     $ssoParams = ['redirect_uri' => $this->getRedirectURI(), 'client_id' => $authSettings['client_id'], 'scope' => 'user email profile', 'state' => $state];
     // Construct URL and redirect.
     return new RedirectResponse(SingleSO::addParams($target, $ssoParams));
 }