Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling ajax CORS preflight options requests while system status is not "live" #4008

Closed
Anubarak opened this issue Mar 19, 2019 · 1 comment
Labels
enhancement improvements to existing features extensibility 🔌 features related to plugin/module dev

Comments

@Anubarak
Copy link
Contributor

Description

When you set isSystemLive to false or if the Settings -> System -> live property is set to false, Craft will throw an ServiceUnavailableHttpException Exception and render the offline template. This is all good for normal page requests but as soon as you use Craft/Yii2 as a REST API which requirer to send a CORS preflight options requests it will become a little bit problematic since those requests are blocked as well.

Unfortunately browsers can't/won't reveal the real error nor the 503 status code in this case. The response for such requests are just undefined which makes it really difficult to handle the maintenance mode in Craft in a frontend properly.

The Exception in craft\web\Application::_enforceSystemStatusPermissions will take place before you can define your custom header via CORS Filter properly so always setting them for every request in config/app.php seems to be the only way currently and even if you are able to set the correct response headers, the request will still fail.

/**
 * Checks if the system is off, and if it is, enforces the "Access the site/CP when the system is off" permissions.
 *
 * @param Request $request
 * @throws ServiceUnavailableHttpException
 */
private function _enforceSystemStatusPermissions(Request $request)
{
    if (!$this->_checkSystemStatusPermissions($request)) {
        $error = null;

        if (!$this->getUser()->getIsGuest()) {
            if ($request->getIsCpRequest()) {
                $error = Craft::t('app', 'Your account doesn’t have permission to access the Control Panel when the system is offline.');
            } else {
                $error = Craft::t('app', 'Your account doesn’t have permission to access the site when the system is offline.');
            }
        } else {
            // If this is a CP request, redirect to the Login page
            if ($this->getRequest()->getIsCpRequest()) {
                $this->getUser()->loginRequired();
                $this->end();
            }
        }

        $this->_unregisterDebugModule();
        throw new ServiceUnavailableHttpException($error);
    }
}

So the only way to determinate such issues is by using some kind of "wildcard" for example via Axios

axios.interceptors.response.use((response) => response, (error) => {
  if (typeof error.response === 'undefined') {
    alert('A network error occurred. '
        + 'This could be a CORS issue or a dropped internet connection. '
        + 'Or Craft is in offline mode '
        + 'It is not possible for us to know. We can just display >> please try again later <<')
  }
  return Promise.reject(error)
})

It would be nice if there was a way to handle it a little bit better even though I don't really know how.

Steps to reproduce

  1. Create a CORS request to a \yii\base\Controller
  2. set isSystemLive to false and see there won't be any response available for requests anymore

Additional info

  • Craft version: 3.1.18
  • PHP version: 7.2
@brandonkelly
Copy link
Member

I’ve solved this by moving anonymous/offline/Control Panel access validation over to craft\web\Controller::beforeAction() (where CSRF validation already takes place).

That ended up being a significant change, which introduced a slight change in behavior for custom Login controllers, so decided to do it on the 3.2 branch rather than develop.

To get the change right away, change craftcms/cms requirement in composer.json to:

"require": {
  "craftcms/cms": "3.2.x-dev as 3.2.0-alpha.1",
  "...": "..."
}

Then run composer update.

@brandonkelly brandonkelly added this to the 3.2 milestone Mar 19, 2019
@brandonkelly brandonkelly added enhancement improvements to existing features extensibility 🔌 features related to plugin/module dev labels Mar 28, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement improvements to existing features extensibility 🔌 features related to plugin/module dev
Projects
None yet
Development

No branches or pull requests

2 participants