[MediaWiki-commits] [Gerrit] mediawiki...eventstreams[master]: Merge from upstream template/master at a354b0e8bbf88123a6c2f...
Ottomata has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/339706 ) Change subject: Merge from upstream template/master at a354b0e8bbf88123a6c2fe17693435fb1107b794 .. Merge from upstream template/master at a354b0e8bbf88123a6c2fe17693435fb1107b794 Conflicts: lib/api-util.js package.json routes/ex.js routes/root.js routes/v1.js Change-Id: Ia0cc779e5292bde0ffe287b8bc9c901462c5852a --- A lib/swagger-ui.js M package.json M routes/root.js M spec.template.yaml 4 files changed, 101 insertions(+), 5 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/services/eventstreams refs/changes/06/339706/1 diff --git a/lib/swagger-ui.js b/lib/swagger-ui.js new file mode 100644 index 000..a4e41c2 --- /dev/null +++ b/lib/swagger-ui.js @@ -0,0 +1,79 @@ +'use strict'; + + +const BBPromise = require('bluebird'); +const fs = BBPromise.promisifyAll(require('fs')); +const path = require('path'); +const HTTPError = require('../lib/util.js').HTTPError; + + +// Swagger-ui helpfully exporting the absolute path of its dist directory +const docRoot = `${require('swagger-ui').dist}/`; + +function processRequest(app, req, res) { + +const reqPath = req.query.path || '/index.html'; +const filePath = path.join(docRoot, reqPath); + +// Disallow relative paths. +// Test relies on docRoot ending on a slash. +if (filePath.substring(0, docRoot.length) !== docRoot) { +throw new HTTPError({ +status: 404, +type: 'not_found', +title: 'File not found', +detail: `${reqPath} could not be found.` +}); +} + +return fs.readFileAsync(filePath) +.then((body) => { +if (reqPath === '/index.html') { +body = body.toString() +.replace(/((?:src|href)=['"])/g, '$1?doc=') +// Some self-promotion +.replace(//, +`${app.info.name}`) +.replace(/[^<]*<\/title>/, `${app.info.name}`) +// Replace the default url with ours, switch off validation & +// limit the size of documents to apply syntax highlighting to +.replace(/Sorter: "alpha"/, 'Sorter: "alpha", validatorUrl: null, ' + +'highlightSizeThreshold: 1') +.replace(/docExpansion: "none"/, 'docExpansion: "list"') +.replace(/ url: url,/, 'url: "/?spec",'); +} + +let contentType = 'text/html'; +if (/\.js$/.test(reqPath)) { +contentType = 'text/javascript'; +body = body.toString() +.replace(/underscore-min\.map/, '?doc=lib/underscore-min.map'); +} else if (/\.png$/.test(reqPath)) { +contentType = 'image/png'; +} else if (/\.map$/.test(reqPath)) { +contentType = 'application/json'; +} else if (/\.ttf$/.test(reqPath)) { +contentType = 'application/x-font-ttf'; +} else if (/\.css$/.test(reqPath)) { +contentType = 'text/css'; +body = body.toString().replace(/\.\.\/(images|fonts)\//g, '?doc=$1/'); +} + +res.setHeader('Content-Type', contentType); +res.setHeader('content-security-policy', "default-src 'none'; " + +"script-src 'self' 'unsafe-inline'; connect-src *; " + +"style-src 'self' 'unsafe-inline'; img-src 'self'; font-src 'self';"); +res.send(body.toString()); +}) +.catch({ code: 'ENOENT' }, () => { +res.status(404) +.type('not_found') +.send('not found'); +}); + +} + +module.exports = { +processRequest +}; + diff --git a/package.json b/package.json index 4e1bd94..bf74eab 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,20 @@ { +<<< HEAD "name": "eventstreams", "version": "0.0.2", "description": "Streaming Wikimedia Events via HTTP SSE", +=== + "name": "service-template-node", + "version": "0.5.0", + "description": "A blueprint for MediaWiki REST API services", +>>> tmpl/master "main": "./app.js", "scripts": { "start": "service-runner", -"test": "mocha && nsp check", +"test": "PREQ_CONNECT_TIMEOUT=15 mocha && nsp check", "docker-start": "service-runner docker-start", "docker-test": "service-runner docker-test", +"test-build": "service-runner docker-test && service-runner build --deploy-repo --force", "coverage": "istanbul cover _mocha -- -R spec" }, "repository": { @@ -42,6 +49,7 @@ "js-yaml": "^3.7.0", "service-runner": "^2.1.11", "swagger-router": "^0.5.5", +"swagger-ui": "git+https://github.com/wikimedia/swagger-ui#master;, "node-rdkafka-statsd": "^0.1.0", "kafka-sse": "git+https://phabricator.wikimedia.org/diffusion/WKSE/kafkasse.git#v0.0.6; }, diff --git a/routes/root.js
[MediaWiki-commits] [Gerrit] mediawiki...eventstreams[master]: Merge from upstream template/master at a354b0e8bbf88123a6c2f...
Ottomata has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/339706 ) Change subject: Merge from upstream template/master at a354b0e8bbf88123a6c2fe17693435fb1107b794 .. Merge from upstream template/master at a354b0e8bbf88123a6c2fe17693435fb1107b794 Conflicts: lib/api-util.js package.json routes/ex.js routes/root.js routes/v1.js Change-Id: Ia0cc779e5292bde0ffe287b8bc9c901462c5852a --- A lib/swagger-ui.js M package.json M routes/root.js M spec.template.yaml 4 files changed, 95 insertions(+), 5 deletions(-) Approvals: Ottomata: Verified; Looks good to me, approved diff --git a/lib/swagger-ui.js b/lib/swagger-ui.js new file mode 100644 index 000..a4e41c2 --- /dev/null +++ b/lib/swagger-ui.js @@ -0,0 +1,79 @@ +'use strict'; + + +const BBPromise = require('bluebird'); +const fs = BBPromise.promisifyAll(require('fs')); +const path = require('path'); +const HTTPError = require('../lib/util.js').HTTPError; + + +// Swagger-ui helpfully exporting the absolute path of its dist directory +const docRoot = `${require('swagger-ui').dist}/`; + +function processRequest(app, req, res) { + +const reqPath = req.query.path || '/index.html'; +const filePath = path.join(docRoot, reqPath); + +// Disallow relative paths. +// Test relies on docRoot ending on a slash. +if (filePath.substring(0, docRoot.length) !== docRoot) { +throw new HTTPError({ +status: 404, +type: 'not_found', +title: 'File not found', +detail: `${reqPath} could not be found.` +}); +} + +return fs.readFileAsync(filePath) +.then((body) => { +if (reqPath === '/index.html') { +body = body.toString() +.replace(/((?:src|href)=['"])/g, '$1?doc=') +// Some self-promotion +.replace(//, +`${app.info.name}`) +.replace(/[^<]*<\/title>/, `${app.info.name}`) +// Replace the default url with ours, switch off validation & +// limit the size of documents to apply syntax highlighting to +.replace(/Sorter: "alpha"/, 'Sorter: "alpha", validatorUrl: null, ' + +'highlightSizeThreshold: 1') +.replace(/docExpansion: "none"/, 'docExpansion: "list"') +.replace(/ url: url,/, 'url: "/?spec",'); +} + +let contentType = 'text/html'; +if (/\.js$/.test(reqPath)) { +contentType = 'text/javascript'; +body = body.toString() +.replace(/underscore-min\.map/, '?doc=lib/underscore-min.map'); +} else if (/\.png$/.test(reqPath)) { +contentType = 'image/png'; +} else if (/\.map$/.test(reqPath)) { +contentType = 'application/json'; +} else if (/\.ttf$/.test(reqPath)) { +contentType = 'application/x-font-ttf'; +} else if (/\.css$/.test(reqPath)) { +contentType = 'text/css'; +body = body.toString().replace(/\.\.\/(images|fonts)\//g, '?doc=$1/'); +} + +res.setHeader('Content-Type', contentType); +res.setHeader('content-security-policy', "default-src 'none'; " + +"script-src 'self' 'unsafe-inline'; connect-src *; " + +"style-src 'self' 'unsafe-inline'; img-src 'self'; font-src 'self';"); +res.send(body.toString()); +}) +.catch({ code: 'ENOENT' }, () => { +res.status(404) +.type('not_found') +.send('not found'); +}); + +} + +module.exports = { +processRequest +}; + diff --git a/package.json b/package.json index 4e1bd94..ff9e48f 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,10 @@ "main": "./app.js", "scripts": { "start": "service-runner", -"test": "mocha && nsp check", +"test": "PREQ_CONNECT_TIMEOUT=15 mocha && nsp check", "docker-start": "service-runner docker-start", "docker-test": "service-runner docker-test", +"test-build": "service-runner docker-test && service-runner build --deploy-repo --force", "coverage": "istanbul cover _mocha -- -R spec" }, "repository": { @@ -42,6 +43,7 @@ "js-yaml": "^3.7.0", "service-runner": "^2.1.11", "swagger-router": "^0.5.5", +"swagger-ui": "git+https://github.com/wikimedia/swagger-ui#master;, "node-rdkafka-statsd": "^0.1.0", "kafka-sse": "git+https://phabricator.wikimedia.org/diffusion/WKSE/kafkasse.git#v0.0.6; }, diff --git a/routes/root.js b/routes/root.js index 28930cb..42686eb 100644 --- a/routes/root.js +++ b/routes/root.js @@ -2,6 +2,7 @@ const sUtil = require('../lib/util'); +const swaggerUi = require('../lib/swagger-ui'); /** @@ -31,15 +32,17 @@ /** * GET / - * Main entry point. Currently it only responds if the spec query + *