diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 015626828..0addda46a 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -36,5 +36,3 @@ jobs: - run: npm ci - run: npm run coverage - env: - W3C_API_KEY: ${{ secrets.W3C_API_KEY }} diff --git a/README.md b/README.md index 778257cac..5b4d8601e 100644 --- a/README.md +++ b/README.md @@ -36,11 +36,9 @@ on the same core library. ### Syntax and command-line parameters ```bash -$ W3C_API_KEY="" npm start [PORT] +$ npm start [PORT] ``` -Specberus relies on the [W3C API](https://w3c.github.io/w3c-api/) to run a few checks. You will need to provide [your key](https://w3c.github.io/w3c-api/#apikeys) in an environment variable `W3C_API_KEY` - Meaning of positional parameters: 1. `PORT`: where Specberus will be listening for HTTP connections. @@ -49,8 +47,8 @@ Meaning of positional parameters: Examples: ```bash -$ W3C_API_KEY="" npm start -$ W3C_API_KEY="" npm start 3001 +$ npm start +$ npm start 3001 ``` ![running specberus](doc/running.jpg) @@ -58,7 +56,7 @@ $ W3C_API_KEY="" npm start 3001 Set the environment variable `DEBUG` to run in _debug mode_ instead: ```bash -$ DEBUG=true W3C_API_KEY="" npm run start +$ DEBUG=true npm run start ``` This modifies the behaviour of certain parts of the application to facilitate debugging. @@ -69,8 +67,8 @@ If Specberus is _not_ going to be served from the root directory of a domain, or set also `BASE_URI` pointing to the public root URI of Specberus; eg ```bash -$ BASE_URI=https://spec-store.com/check/ W3C_API_KEY=deadbeef npm start -$ BASE_URI=/hostname/can/be/omitted/ W3C_API_KEY=deadbeef npm start 88 +$ BASE_URI=https://spec-store.com/check/ npm start +$ BASE_URI=/hostname/can/be/omitted/ npm start 88 ``` 2. Auto reload when developing @@ -78,9 +76,9 @@ $ BASE_URI=/hostname/can/be/omitted/ W3C_API_KEY=deadbeef npm start 88 Run `npm run live` when developing. The app will automatically reload when changes happen. ```bash -$ W3C_API_KEY="xxx" npm run live +$ npm run live -$ W3C_API_KEY="xxx" npm run live 3001 +$ npm run live 3001 ``` ## 3. Testing @@ -90,7 +88,7 @@ $ W3C_API_KEY="xxx" npm run live 3001 Testing is done using mocha. Simply run: ```bash -$ W3C_API_KEY="" mocha +$ mocha ``` from the root and you will be running the test suite. Mocha can be installed with: @@ -105,7 +103,7 @@ Some of the tests can on occasion take a long time, or fail outright because a r unavailable. To work around this, you can set SKIP_NETWORK: ```bash -$ SKIP_NETWORK=1 W3C_API_KEY="" mocha +$ SKIP_NETWORK=1 mocha ``` #### 3. Run testserver diff --git a/app.js b/app.js index a934b2019..4f91ef51e 100644 --- a/app.js +++ b/app.js @@ -21,12 +21,6 @@ const { version } = importJSON('./package.json', import.meta.url); // Settings: const DEFAULT_PORT = 80; -if (!process.env.W3C_API_KEY || process.env.W3C_API_KEY.length < 1) { - throw new Error( - 'Pubrules is missing a valid key for the W3C API; define environment variable “W3C_API_KEY”' - ); -} - if (!process.env.BASE_URI || process.env.BASE_URI.length < 1) { console.warn( `Environment variable “BASE_URI” not defined; assuming that Pubrules lives at “/”` @@ -42,7 +36,7 @@ app.use(compression()); app.use('/badterms.json', cors()); app.use(express.static('public')); -api.setUp(app, process.env.W3C_API_KEY); +api.setUp(app); views.setUp(app); // @TODO Localize this properly when messages are translated; hard-coded British English for now. @@ -55,7 +49,7 @@ io.on('connection', socket => { socket.on('extractMetadata', data => { if (!data.url) return socket.emit('exception', { message: 'URL not provided.' }); - const specberus = new Specberus(process.env.W3C_API_KEY); + const specberus = new Specberus(); const handler = new Sink(); handler.on('err', (type, data) => { try { @@ -118,7 +112,7 @@ io.on('connection', socket => { message: `Failed to get profile ${profilePath}.`, }); } - const specberus = new Specberus(process.env.W3C_API_KEY); + const specberus = new Specberus(); const handler = new Sink(); const profileCode = profile.name; socket.emit('start', { diff --git a/lib/rules/echidna/deliverer-change.js b/lib/rules/echidna/deliverer-change.js index 3db3265ac..902e514f1 100644 --- a/lib/rules/echidna/deliverer-change.js +++ b/lib/rules/echidna/deliverer-change.js @@ -1,7 +1,5 @@ import w3cApi from 'node-w3capi'; -w3cApi.apiKey = process.env.W3C_API_KEY; - const self = { name: 'echidna.deliverer-change', section: 'metadata', diff --git a/lib/rules/metadata/profile.js b/lib/rules/metadata/profile.js index 0d04ff7bd..0ef972bc2 100644 --- a/lib/rules/metadata/profile.js +++ b/lib/rules/metadata/profile.js @@ -3,15 +3,12 @@ */ // Internal packages: -import w3cApi from 'node-w3capi'; import { allProfiles, importJSON } from '../../util.js'; import { sortedProfiles } from '../../views.js'; import { check as getTitle } from './title.js'; const rules = importJSON('../../rules.json', import.meta.url); -w3cApi.apiKey = process.env.W3C_API_KEY; - // 'self.name' would be 'metadata.profile' export const name = 'metadata.profile'; diff --git a/lib/validator.js b/lib/validator.js index a8b0cddda..2dcecbd80 100644 --- a/lib/validator.js +++ b/lib/validator.js @@ -26,13 +26,8 @@ const { rules } = profileMetadata; const { version } = importJSON('../package.json', import.meta.url); setLanguage('en_GB'); -w3cApi.apiKey = process.env.W3C_API_KEY; -const Specberus = function (apiKey = process.env.W3C_API_KEY) { - if (typeof apiKey !== 'string' || !apiKey.length) { - throw new Error('apiKey is required.'); - } - this.apiKey = apiKey; +const Specberus = function () { this.version = version; this.clearCache(); }; @@ -583,12 +578,10 @@ Specberus.prototype.getDelivererGroups = async function () { // send request to W3C API if there's id extracted from the doc. for (let i = 0; i < ids.length; i += 1) { const groupApiUrl = `https://api.w3.org/groups/${ids[i]}`; - const apikey = this.apiKey; promiseArray.push( new Promise(resolve => { get(groupApiUrl) .set('User-Agent', `W3C-Pubrules/${version}`) - .query({ apikey }) .end((err, data) => { resolve(data); }); @@ -662,12 +655,10 @@ Specberus.prototype.getDelivererIDs = async function () { const [, type, shortname] = REGEX_DELIVERER_IPR_URL.exec(href); const groupApiUrl = `https://api.w3.org/groups/${type}/${shortname}`; - const apikey = this.apiKey; promiseArray.push( new Promise(resolve => { get(groupApiUrl) .set('User-Agent', `W3C-Pubrules/${version}`) - .query({ apikey }) .end((err, data) => { resolve(data); }); diff --git a/package-lock.json b/package-lock.json index 64fc3af7a..a2c540759 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "jsdom": "22.1.0", "metaviewport-parser": "0.3.0", "morgan": "1.10.0", - "node-w3capi": "2.0.1", + "node-w3capi": "2.1.0", "promise": "8.3.0", "puppeteer": "20.9.0", "socket.io": "4.7.0", @@ -579,9 +579,9 @@ } }, "node_modules/@cspell/dict-ada": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@cspell/dict-ada/-/dict-ada-4.0.1.tgz", - "integrity": "sha512-/E9o3nHrXOhYmQE43deKbxZcR3MIJAsa+66IzP9TXGHheKEx8b9dVMVVqydDDH8oom1H0U20NRPtu6KRVbT9xw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-ada/-/dict-ada-4.0.2.tgz", + "integrity": "sha512-0kENOWQeHjUlfyId/aCM/mKXtkEgV0Zu2RhUXCBr4hHo9F9vph+Uu8Ww2b0i5a4ZixoIkudGA+eJvyxrG1jUpA==", "dev": true }, "node_modules/@cspell/dict-aws": { @@ -603,9 +603,9 @@ "dev": true }, "node_modules/@cspell/dict-cpp": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@cspell/dict-cpp/-/dict-cpp-5.0.3.tgz", - "integrity": "sha512-7sx/RFsf0hB3q8chx8OHYl9Kd+g0pqA1laphwaAQ+/jPwoAreYT3kNQWbJ3bIt/rMoORetFSQxckSbaJXwwqpw==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@cspell/dict-cpp/-/dict-cpp-5.0.4.tgz", + "integrity": "sha512-Vmz/CCb2d91ES5juaO8+CFWeTa2AFsbpR8bkCPJq+P8cRP16+37tY0zNXEBSK/1ur4MakaRf76jeQBijpZxw0Q==", "dev": true }, "node_modules/@cspell/dict-cryptocurrencies": { @@ -627,15 +627,15 @@ "dev": true }, "node_modules/@cspell/dict-dart": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@cspell/dict-dart/-/dict-dart-2.0.2.tgz", - "integrity": "sha512-jigcODm7Z4IFZ4vParwwP3IT0fIgRq/9VoxkXfrxBMsLBGGM2QltHBj7pl+joX+c4cOHxfyZktGJK1B1wFtR4Q==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-dart/-/dict-dart-2.0.3.tgz", + "integrity": "sha512-cLkwo1KT5CJY5N5RJVHks2genFkNCl/WLfj+0fFjqNR+tk3tBI1LY7ldr9piCtSFSm4x9pO1x6IV3kRUY1lLiw==", "dev": true }, "node_modules/@cspell/dict-data-science": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@cspell/dict-data-science/-/dict-data-science-1.0.7.tgz", - "integrity": "sha512-Q9VUFaarUpqM6CAmR8peP4o9alk0XQ4rgVoE2R2XalpC2cqPI8Hmg6QwMU2UPioSUcWMJCqLc/KzJti0gBMuxA==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@cspell/dict-data-science/-/dict-data-science-1.0.8.tgz", + "integrity": "sha512-uGx0rd3BftfZ5mvXtPxvLNkQ33y0ylNw4GpBAAfF3hgGtifKdvLSmphOGuNgDYUPpJ0+e025bsvtN0/ZZCzWTg==", "dev": true }, "node_modules/@cspell/dict-django": { @@ -645,9 +645,9 @@ "dev": true }, "node_modules/@cspell/dict-docker": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/@cspell/dict-docker/-/dict-docker-1.1.6.tgz", - "integrity": "sha512-zCCiRTZ6EOQpBnSOm0/3rnKW1kCcAUDUA7SxJG3SuH6iZvKi3I8FEg8+O83WQUeXg0SyPNerD9F40JLnnJjJig==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@cspell/dict-docker/-/dict-docker-1.1.7.tgz", + "integrity": "sha512-XlXHAr822euV36GGsl2J1CkBIVg3fZ6879ZOg5dxTIssuhUOCiV2BuzKZmt6aIFmcdPmR14+9i9Xq+3zuxeX0A==", "dev": true }, "node_modules/@cspell/dict-dotnet": { @@ -663,9 +663,9 @@ "dev": true }, "node_modules/@cspell/dict-en_us": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.3.4.tgz", - "integrity": "sha512-mR2yqWmFip1zTKja2SqyVMbzuqEThqkEJk9M32bMDziPJpEyOIPvLA0UPmj3cyRKJkRuVF0bhDCE33O+at38hw==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.3.6.tgz", + "integrity": "sha512-odhgsjNZI9BtEOJdvqfAuv/3yz5aB1ngfBNaph7WSnYVt//9e3fhrElZ6/pIIkoyuGgeQPwz1fXt+tMgcnLSEQ==", "dev": true }, "node_modules/@cspell/dict-en-common-misspellings": { @@ -789,15 +789,15 @@ "dev": true }, "node_modules/@cspell/dict-public-licenses": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@cspell/dict-public-licenses/-/dict-public-licenses-2.0.2.tgz", - "integrity": "sha512-baKkbs/WGEV2lCWZoL0KBPh3uiPcul5GSDwmXEBAsR5McEW52LF94/b7xWM0EmSAc/y8ODc5LnPYC7RDRLi6LQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-public-licenses/-/dict-public-licenses-2.0.3.tgz", + "integrity": "sha512-JSLEdpEYufQ1H+93UHi+axlqQm1fhgK6kpdLHp6uPHu//CsvETcqNVawjB+qOdI/g38JTMw5fBqSd0aGNxa6Dw==", "dev": true }, "node_modules/@cspell/dict-python": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@cspell/dict-python/-/dict-python-4.1.2.tgz", - "integrity": "sha512-Whcn4K8R0Ux/hcx/P9Fbx6i29GwTaXgT3LTt95AuCnV5RRLrzsqoyZkz851hcg5z4kjUQVMduDl3HECGgW/FNw==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@cspell/dict-python/-/dict-python-4.1.4.tgz", + "integrity": "sha512-4JJ6MjIyuZN4h2VkSxZxiQ55lVh6NccW/0H6rdu0aDz+E3uyFVFtlBp5kTY5jIA11PZqSZZpyowzGnwrJX6w0g==", "dev": true, "dependencies": { "@cspell/dict-data-science": "^1.0.0" @@ -834,9 +834,9 @@ "dev": true }, "node_modules/@cspell/dict-sql": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-sql/-/dict-sql-2.1.0.tgz", - "integrity": "sha512-Bb+TNWUrTNNABO0bmfcYXiTlSt0RD6sB2MIY+rNlaMyIwug43jUjeYmkLz2tPkn3+2uvySeFEOMVYhMVfcuDKg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-sql/-/dict-sql-2.1.1.tgz", + "integrity": "sha512-v1mswi9NF40+UDUMuI148YQPEQvWjac72P6ZsjlRdLjEiQEEMEsTQ+zlkIdnzC9QCNyJaqD5Liq9Mn78/8Zxtw==", "dev": true }, "node_modules/@cspell/dict-svelte": { @@ -1410,9 +1410,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.4.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.2.tgz", - "integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==" + "version": "20.4.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.4.tgz", + "integrity": "sha512-CukZhumInROvLq3+b5gLev+vgpsIqC2D0deQr/yS1WnxvmYLlJXZpaQrQiseMY+6xusl79E04UjWoqyr+t1/Ew==" }, "node_modules/@types/yauzl": { "version": "2.10.0", @@ -2035,9 +2035,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001516", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001516.tgz", - "integrity": "sha512-Wmec9pCBY8CWbmI4HsjBeQLqDTqV91nFVR83DnZpYyRnPI1wePDsTg0bGLPC5VU/3OIZV1fmxEea1b+tFKe86g==", + "version": "1.0.30001517", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001517.tgz", + "integrity": "sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA==", "dev": true, "funding": [ { @@ -2918,9 +2918,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.464", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.464.tgz", - "integrity": "sha512-guZ84yoou4+ILNdj0XEbmGs6DEWj6zpVOWYpY09GU66yEb0DSYvP/biBPzHn0GuW/3RC/pnaYNUWlQE1fJYtgA==", + "version": "1.4.468", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.468.tgz", + "integrity": "sha512-6M1qyhaJOt7rQtNti1lBA0GwclPH+oKCmsra/hkcWs5INLxfXXD/dtdnaKUYQu/pjOBP/8Osoe4mAcNvvzoFag==", "dev": true }, "node_modules/emoji-regex": { @@ -3906,9 +3906,9 @@ "integrity": "sha512-IgfweLvEpwyA4WgiQe9Nx6VV2QkML2NkvZnk1oKnIzXgXdWxuhF7zw4DvLTPZJn6PIUneiAXPF24QmoEqHTjyw==" }, "node_modules/fast-glob": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz", - "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -5497,9 +5497,9 @@ } }, "node_modules/js-sdsl": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.1.tgz", - "integrity": "sha512-6Gsx8R0RucyePbWqPssR8DyfuXmLBooYN5cZFZKjHGnQuaf7pEzhtpceagJxVu4LqhYY5EYA7nko3FmeHZ1KbA==", + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.2.tgz", + "integrity": "sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w==", "dev": true, "funding": { "type": "opencollective", @@ -6405,9 +6405,9 @@ "dev": true }, "node_modules/node-w3capi": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-w3capi/-/node-w3capi-2.0.1.tgz", - "integrity": "sha512-uPsFyr22jG3ypdfFPjBOuydEURBqV/8ttm6JquJhcpzYGwbJb75AI4/SiRJtUtWnt9ZbHmNomYLYbctgySSfrQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/node-w3capi/-/node-w3capi-2.1.0.tgz", + "integrity": "sha512-7V7lYqM0eRo3H15Tc+LfAAazQUVfRbY15/TAbOZdhyA2NtBhCbgJvnYXc4Aa1KNuiGTewKTPTAYuuG5cK5M3ZQ==", "dependencies": { "async": "3.2.4", "superagent": "8.0.9" diff --git a/package.json b/package.json index cbcd730d6..0b39a1b29 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "jsdom": "22.1.0", "metaviewport-parser": "0.3.0", "morgan": "1.10.0", - "node-w3capi": "2.0.1", + "node-w3capi": "2.1.0", "promise": "8.3.0", "puppeteer": "20.9.0", "socket.io": "4.7.0", diff --git a/test/api.js b/test/api.js index f2f5d8175..af6964313 100644 --- a/test/api.js +++ b/test/api.js @@ -31,7 +31,7 @@ let server; const launchServer = function () { const app = express(); server = http.createServer(app); - setUp(app, process.env.W3C_API_KEY); + setUp(app); server.listen(PORT).on('error', err => { throw new Error(err); }); diff --git a/test/rules.js b/test/rules.js index e3ef87218..d2a459db0 100644 --- a/test/rules.js +++ b/test/rules.js @@ -43,7 +43,7 @@ const testProfile = process.env.PROFILE; */ const compareMetadata = function (url, file, expectedObject) { - const specberus = new Specberus(process.env.W3C_API_KEY); + const specberus = new Specberus(); const handler = new Sink(data => { throw new Error(data); }); @@ -127,7 +127,7 @@ const compareMetadata = function (url, file, expectedObject) { }; describe('Basics', () => { - const specberus = new Specberus(process.env.W3C_API_KEY); + const specberus = new Specberus(); describe('Method "extractMetadata"', () => { it('Should exist and be a function', done => { @@ -191,9 +191,7 @@ function buildHandler(test, mock, done) { Object.keys(groupNames).forEach(groupName => { const groupId = groupNames[groupName]; nock('https://api.w3.org', { allowUnmocked: true }) - .get( - `/groups/wg/${groupName}?apikey=${process.env.W3C_API_KEY}` - ) + .get(`/groups/wg/${groupName}`) .reply(200, { id: groupId, type: 'working group', @@ -321,9 +319,7 @@ describe('Making sure good documents pass Specberus...', () => { }; // for (const o in test.options) options[o] = test.options[o]; - new Specberus(process.env.W3C_API_KEY).validate( - options - ); + new Specberus().validate(options); } ); }); @@ -367,9 +363,7 @@ function checkRule(tests, options) { events: buildHandler(test, true, done), ...test.options, }; - new Specberus(process.env.W3C_API_KEY).validate( - options - ); + new Specberus().validate(options); } ); }