diff --git a/README.md b/README.md index fd6bcbb0..2256dca5 100644 --- a/README.md +++ b/README.md @@ -145,3 +145,27 @@ If present, `ALL_PROXY` is used as fallback if there is no other match. You can use `npm run check` to run the tests and check whether your code adheres to the aem-cli coding style. +# Troubleshooting + +## `aem up` fails with `unable to get local issuer certificate` + +This error occurs when the server certificate is not trusted by Node.js. The typical +cause is that connections to the server `*.aem.page` and `*.hlx.page` are intercepted +by an enterprise proxy or firewall which is trying to inspect the traffic. + +These proxies use a private certificate authority (CA) to sign the certificates of the +servers they intercept. To make Node.js trust the server certificate, you need to add +the CA certificate to the list of trusted CAs. + +The CA certificate is typically provided by your IT department. You can ask them for +the CA certificate and save it to a file, e.g. `my-ca.crt`. + +Then you can use the [`NODE_EXTRA_CA_CERTS`](https://nodejs.org/docs/latest/api/cli.html) environment variable to make Node.js trust +the CA certificate: + +```bash +export NODE_EXTRA_CA_CERTS=my-ca.crt +aem up +``` + +This will make Node.js trust the server certificate and `aem up` should work. \ No newline at end of file diff --git a/src/up.cmd.js b/src/up.cmd.js index abcba57a..e1225a5f 100644 --- a/src/up.cmd.js +++ b/src/up.cmd.js @@ -119,17 +119,30 @@ export default class UpCommand extends AbstractServerCommand { // "project": "Helix Website (AEM Live)", // "testProperty": "header"; // } - const configUrl = `https://admin.hlx.page/sidekick/${gitUrl.owner}/${gitUrl.repo}/main/config.json`; - const configResp = await getFetch(this._allowInsecure)(configUrl); let previewHostBase = 'hlx.page'; - if (configResp.ok) { + const configUrl = `https://admin.hlx.page/sidekick/${gitUrl.owner}/${gitUrl.repo}/main/config.json`; + try { + const configResp = await getFetch(this._allowInsecure)(configUrl); + if (configResp.ok) { // this is best effort for now - const config = await configResp.json(); - const { previewHost } = config; - if (previewHost && previewHost.endsWith('.aem.page')) { - previewHostBase = 'aem.page'; + const config = await configResp.json(); + const { previewHost } = config; + if (previewHost && previewHost.endsWith('.aem.page')) { + previewHostBase = 'aem.page'; + } + } + /* c8 ignore start */ + // this is notoriously hard to test, so we ignore it for now + // but if you want to give it a try, set up a local server with a self-signed cert + // change, /etc/hosts to point admin.hlx.page to localhost and run the test + } catch (e) { + if (e.code === 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY' || e.code === 'DEPTH_ZERO_SELF_SIGNED_CERT') { + await this.stop(); + this.log.error(chalk`{yellow ${configUrl}} is using an invalid certificate, please check https://github.com/adobe/helix-cli#troubleshooting for help.`); + throw Error(e.message); } } + /* c8 ignore stop */ const dnsName = `${ref.replace(/\//g, '-')}--${gitUrl.repo}--${gitUrl.owner}`; // check length limit