diff --git a/Dockerfile b/Dockerfile index 8235b5659115..6ebd4a9adf3a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -42,7 +42,7 @@ COPY --chown=node:node --from=install /usr/src/docs/dist /usr/src/docs/dist ENV NODE_ENV production # Use Lunr instead of Algolia -ENV USE_LUNR true +ENV AIRGAP true # Copy only what's needed to run the server COPY --chown=node:node assets ./assets diff --git a/includes/explorer.html b/includes/explorer.html index 5f92811dd05a..f471ef3054c8 100644 --- a/includes/explorer.html +++ b/includes/explorer.html @@ -1,7 +1,11 @@ {% include breadcrumbs %}
- + {% if process.env.AIRGAP %} +

GraphQL explorer is not available on this environment.

+ {% else %} + + {% endif %}
diff --git a/includes/scripts.html b/includes/scripts.html index 77555622b2b9..6f328a0cc308 100644 --- a/includes/scripts.html +++ b/includes/scripts.html @@ -1,2 +1,2 @@ - + diff --git a/javascripts/airgap-links.js b/javascripts/airgap-links.js new file mode 100644 index 000000000000..b881bde1bd35 --- /dev/null +++ b/javascripts/airgap-links.js @@ -0,0 +1,14 @@ +export default function airgapLinks () { + // When in an airgapped environment, + // show a tooltip on external links + const { airgap } = JSON.parse(document.getElementById('expose').text) + if (!airgap) return + + const externaLinks = Array.from( + document.querySelectorAll('a[href^="http"], a[href^="//"]') + ) + externaLinks.forEach(link => { + link.classList.add('tooltipped') + link.setAttribute('aria-label', 'This link may not work in this environment.') + }) +} diff --git a/javascripts/index.js b/javascripts/index.js index ea96ef7d1d84..7cc42b0042b2 100644 --- a/javascripts/index.js +++ b/javascripts/index.js @@ -18,6 +18,7 @@ import allArticles from './all-articles' import devToc from './dev-toc' import releaseNotes from './release-notes' import showMore from './show-more' +import airgapLinks from './airgap-links' document.addEventListener('DOMContentLoaded', async () => { displayPlatformSpecificContent() @@ -34,6 +35,7 @@ document.addEventListener('DOMContentLoaded', async () => { allArticles() devToc() showMore() + airgapLinks() releaseNotes() initializeEvents() experiment() diff --git a/javascripts/search.js b/javascripts/search.js index cabee3a9fbfe..760bce874bbb 100644 --- a/javascripts/search.js +++ b/javascripts/search.js @@ -26,7 +26,7 @@ export default function search () { languages, versions, nonEnterpriseDefaultVersion - } = JSON.parse(document.getElementById('search-options').text) + } = JSON.parse(document.getElementById('expose').text).searchOptions version = deriveVersionFromPath(versions, nonEnterpriseDefaultVersion) language = deriveLanguageCodeFromPath(languages) diff --git a/layouts/graphql-explorer.html b/layouts/graphql-explorer.html index 7f61637049ba..4b27a9c47c9d 100644 --- a/layouts/graphql-explorer.html +++ b/layouts/graphql-explorer.html @@ -20,9 +20,13 @@

{{ page.title }}

- + {% if process.env.AIRGAP %} +

GraphQL explorer is not available on this environment.

+ {% else %} + + {% endif %}
diff --git a/layouts/product-landing.html b/layouts/product-landing.html index d9d3e00ee9e2..fbda1d83343c 100644 --- a/layouts/product-landing.html +++ b/layouts/product-landing.html @@ -41,13 +41,15 @@

{% if page.product_video %}
- + {% unless process.env.AIRGAP %} + + {% endunless %}
{% endif %} diff --git a/lib/search/sync.js b/lib/search/sync.js index 58168b686cdd..827d47ed7953 100644 --- a/lib/search/sync.js +++ b/lib/search/sync.js @@ -71,7 +71,7 @@ module.exports = async function syncSearchIndexes (opts = {}) { // The page version will be the new version, e.g., free-pro-team@latest, enterprise-server@2.22 const records = await buildRecords(indexName, indexablePages, pageVersion, languageCode) - const index = process.env.USE_LUNR + const index = process.env.AIRGAP ? new LunrIndex(indexName, records) : new AlgoliaIndex(indexName, records) @@ -80,7 +80,7 @@ module.exports = async function syncSearchIndexes (opts = {}) { fs.writeFileSync(cacheFile, JSON.stringify(index, null, 2)) console.log('wrote dry-run index to disk: ', cacheFile) } else { - if (process.env.USE_LUNR) { + if (process.env.AIRGAP) { await index.write() console.log('wrote index to file: ', indexName) } else { @@ -93,7 +93,7 @@ module.exports = async function syncSearchIndexes (opts = {}) { // Fetch a list of index names and cache it for tests // to ensure that an index exists for every language and GHE version - const remoteIndexNames = process.env.USE_LUNR + const remoteIndexNames = process.env.AIRGAP ? await getLunrIndexNames() : await getRemoteIndexNames() const cachedIndexNamesFile = path.join(__dirname, './cached-index-names.json') diff --git a/middleware/context.js b/middleware/context.js index 30480c012d35..a2508138aacd 100644 --- a/middleware/context.js +++ b/middleware/context.js @@ -24,6 +24,7 @@ module.exports = async function contextualize (req, res, next) { featureFlags.forEach(featureFlagName => { req.context.process.env[featureFlagName] = process.env[featureFlagName] }) + if (process.env.AIRGAP) req.context.process.env.AIRGAP = true // define each context property explicitly for code-search friendliness // e.g. searches for "req.context.page" will include results from this file @@ -48,11 +49,16 @@ module.exports = async function contextualize (req, res, next) { // JS + CSS asset paths req.context.builtAssets = builtAssets - // Languages and versions for search - req.context.searchOptions = JSON.stringify({ - languages: Object.keys(languages), - versions: searchVersions, - nonEnterpriseDefaultVersion + // Object exposing selected variables to client + req.context.expose = JSON.stringify({ + // Languages and versions for search + searchOptions: { + languages: Object.keys(languages), + versions: searchVersions, + nonEnterpriseDefaultVersion + }, + // `|| undefined` won't show at all for production + airgap: Boolean(process.env.AIRGAP) || undefined }) return next() diff --git a/middleware/search.js b/middleware/search.js index a532386dd367..58025beef6fe 100644 --- a/middleware/search.js +++ b/middleware/search.js @@ -22,7 +22,7 @@ router.get('/', async (req, res) => { } try { - const results = process.env.USE_LUNR + const results = process.env.AIRGAP ? await loadLunrResults({ version, language, query, limit }) : await loadAlgoliaResults({ version, language, query, limit }) return res.status(200).json(results)