diff --git a/README.md b/README.md index e578451c3..ad39c8489 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,6 @@ Repository | Reference | Recent Version [ansi-colors][ansi-colorsGHUrl] | [Documentation][ansi-colorsDOCUrl] | [![NPM version][ansi-colorsNPMVersionImage]][ansi-colorsNPMUrl] [async][asyncGHUrl] | [Documentation][asyncDOCUrl] | [![NPM version][asyncNPMVersionImage]][asyncNPMUrl] [aws-sdk][aws-sdkGHUrl] | [Documentation][aws-sdkDOCUrl] | [![NPM version][aws-sdkNPMVersionImage]][aws-sdkNPMUrl] -[base62][base62GHUrl] | [Documentation][base62DOCUrl] | [![NPM version][base62NPMVersionImage]][base62NPMUrl] [body-parser][body-parserGHUrl] | [Documentation][body-parserDOCUrl] | [![NPM version][body-parserNPMVersionImage]][body-parserNPMUrl] [bootstrap][bootstrapGHUrl] | [Documentation][bootstrapDOCUrl] | [![NPM version][bootstrapNPMVersionImage]][bootstrapNPMUrl] [bootstrap-markdown][bootstrap-markdownGHUrl] | [Documentation][bootstrap-markdownDOCUrl] | [![NPM version][bootstrap-markdownNPMVersionImage]][bootstrap-markdownNPMUrl] @@ -147,11 +146,6 @@ Outdated dependencies list can also be achieved with `$ npm outdated` [aws-sdkNPMUrl]: https://www.npmjs.com/package/aws-sdk [aws-sdkNPMVersionImage]: https://img.shields.io/npm/v/aws-sdk.svg?style=flat -[base62GHUrl]: https://github.com/base62/base62.js -[base62DOCUrl]: https://github.com/base62/base62.js/blob/master/Readme.md -[base62NPMUrl]: https://www.npmjs.com/package/base62 -[base62NPMVersionImage]: https://img.shields.io/npm/v/base62.svg?style=flat - [body-parserGHUrl]: https://github.com/expressjs/body-parser [body-parserDOCUrl]: https://github.com/expressjs/body-parser/blob/master/README.md [body-parserNPMUrl]: https://www.npmjs.com/package/body-parser diff --git a/controllers/scriptStorage.js b/controllers/scriptStorage.js index d0183811f..de74ffa39 100644 --- a/controllers/scriptStorage.js +++ b/controllers/scriptStorage.js @@ -27,7 +27,6 @@ var mediaType = require('media-type'); var mediaDB = require('mime-db'); var async = require('async'); var moment = require('moment'); -var Base62 = require('base62/lib/ascii'); var SPDX = require('spdx-license-ids'); var sizeOf = require('image-size'); var ipRangeCheck = require("ip-range-check"); @@ -570,6 +569,7 @@ exports.sendScript = function (aReq, aRes, aNext) { var lastModified = null; var eTag = null; + var hashSRI = null; var maxAge = 7 * 60 * 60 * 24; // nth day(s) in seconds var now = null; var continuation = true; @@ -628,6 +628,10 @@ exports.sendScript = function (aReq, aRes, aNext) { } } + hashSRI = aScript.hash + ? 'sha512-' + Buffer.from(aScript.hash).toString('base64') + : 'undefined'; + // HTTP/1.1 Caching aRes.set('Cache-Control', 'public, max-age=' + maxAge + ', no-cache, no-transform, must-revalidate'); @@ -639,8 +643,8 @@ exports.sendScript = function (aReq, aRes, aNext) { lastModified = moment(aScript.updated) .utc().format('ddd, DD MMM YYYY HH:mm:ss') + ' GMT'; - // Convert a based representation of the hex sha512sum - eTag = '"' + Base62.encode(parseInt('0x' + aScript.hash, 16)) + ' .user.js"'; + // Use SRI of the stored sha512sum + eTag = '"' + hashSRI + ' .user.js"'; // If already client-side... HTTP/1.1 Caching if (aReq.get('if-none-match') === eTag || aReq.get('if-modified-since') === lastModified) { @@ -796,10 +800,12 @@ exports.sendScript = function (aReq, aRes, aNext) { } else { source = result.code; - // Calculate a based representation of the hex sha512sum - eTag = '"' + Base62.encode( - parseInt('0x' + crypto.createHash('sha512').update(source).digest('hex'), 16)) + - ' .min.user.js"'; + // Calculate SRI of the source sha512sum + eTag = '"sha512-' + + Buffer.from( + crypto.createHash('sha512').update(source).digest('hex') + ).toString('base64') + ' .min.user.js"'; + } } catch (aE) { // On any failure default to unminified if (isDev) { @@ -827,8 +833,8 @@ exports.sendScript = function (aReq, aRes, aNext) { lastModified = moment(aScript.updated) .utc().format('ddd, DD MMM YYYY HH:mm:ss') + ' GMT'; - // Reset to convert a based representation of the hex sha512sum - eTag = '"' + Base62.encode(parseInt('0x' + aScript.hash, 16)) + ' .user.js"'; + // Reset SRI of the stored sha512sum + eTag = '"' + hashSRI + ' .user.js"'; } // If already client-side... partial HTTP/1.1 Caching @@ -928,8 +934,8 @@ exports.sendMeta = function (aReq, aRes, aNext) { meta = script.meta; // NOTE: Watchpoint if (/\.json$/.test(aReq.params.scriptname)) { - // Create a based representation of the hex sha512sum - eTag = '"' + Base62.encode(parseInt('0x' + aScript.hash, 16)) + ' .meta.json"'; + // Use SRI of the stored sha512sum + eTag = '"' + script.hashSRI + ' .meta.json"'; // If already client-side... HTTP/1.1 Caching if (aReq.get('if-none-match') === eTag) { @@ -955,7 +961,7 @@ exports.sendMeta = function (aReq, aRes, aNext) { // Overwrite any keys found with the following... meta.OpenUserJS.installs = [{ value: script.installs }]; meta.OpenUserJS.issues = [{ value: 'n/a' }]; - meta.OpenUserJS.hash = aScript.hash ? [{ value: aScript.hash }] : undefined; + meta.OpenUserJS.hash = script.hash ? [{ value: script.hashSRI }] : 'undefined'; // Get the number of open issues scriptOpenIssueCountQuery = Discussion.find({ category: exports @@ -966,8 +972,8 @@ exports.sendMeta = function (aReq, aRes, aNext) { async.parallel(tasks, asyncComplete); } else { - // Create a based representation of the hex sha512sum - eTag = '"' + Base62.encode(parseInt('0x' + aScript.hash, 16)) + ' .meta.js"'; + // Use SRI of the stored sha512sum + eTag = '"' + script.hashSRI + ' .meta.js"'; // If already client-side... HTTP/1.1 Caching if (aReq.get('if-none-match') === eTag) { diff --git a/libs/modelParser.js b/libs/modelParser.js index 27cf6e04a..9767751c5 100644 --- a/libs/modelParser.js +++ b/libs/modelParser.js @@ -489,7 +489,14 @@ var parseScript = function (aScript) { parseDateProperty(script, 'updated'); // Hash - script.hashShort = script.hash ? script.hash.substr(0, 7) : 'undefined'; + script.hashShort = 'undefined'; + script.hashSRI = 'undefined'; + + if (script.hash) { + // NOTE: May be absent in dev DB but should not be in pro DB + script.hashShort = script.hash.substr(0, 7); + script.hashSRI = 'sha512-' + Buffer.from(script.hash).toString('base64'); + } if (script.created && script.updated && script.created.toString() !== script.updated.toString()) { script.isUpdated = true; diff --git a/package.json b/package.json index 4def7cb12..e52d2843d 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,6 @@ "async": "3.2.0", "@octokit/auth-oauth-app": "4.3.0", "aws-sdk": "2.944.0", - "base62": "2.0.1", "body-parser": "1.19.0", "bootstrap": "3.4.1", "bootstrap-markdown": "2.10.0", diff --git a/views/pages/scriptPage.html b/views/pages/scriptPage.html index cce6bc0a6..2938a9ea5 100644 --- a/views/pages/scriptPage.html +++ b/views/pages/scriptPage.html @@ -27,7 +27,7 @@