From b0103b0d496262c438b40bc20304081dbfe41e73 Mon Sep 17 00:00:00 2001 From: Justin Wind <justin.wind+git@gmail.com> Date: Mon, 26 Dec 2022 15:17:45 -0800 Subject: [PATCH] initial commit --- .eslintrc.json | 89 + .gitignore | 7 + .nycrc.json | 6 + CHANGELOG.md | 14 + README.md | 76 + bin/addProfile.js | 38 + bin/addProfileScope.js | 32 + bin/addScope.js | 32 + bin/authUserAdd.js | 70 + bin/cli-helper.js | 38 + bin/dumpProfiles.js | 32 + ...generate-engine-entity-relation-diagram.sh | 18 + bin/resourceCreate.js | 46 + config/default.js | 99 + config/development.js | 36 + config/index.js | 24 + config/test.js | 16 + documentation/media/consent-page.png | Bin 0 -> 449120 bytes documentation/media/postgres-er.svg | 184 + documentation/media/sqlite-er.svg | 183 + documentation/media/ticket-page.png | Bin 0 -> 230324 bytes package-lock.json | 9787 +++++++++++++++++ package.json | 64 + server.js | 39 + src/chores.js | 70 + src/common.js | 167 + src/db/abstract.js | 563 + src/db/errors.js | 56 + src/db/index.js | 42 + src/db/postgres/index.js | 638 ++ src/db/postgres/sql/almanac-get-all.sql | 3 + src/db/postgres/sql/almanac-get.sql | 6 + src/db/postgres/sql/almanac-upsert.sql | 9 + src/db/postgres/sql/authentication-get.sql | 4 + .../postgres/sql/authentication-success.sql | 4 + src/db/postgres/sql/authentication-upsert.sql | 9 + src/db/postgres/sql/profile-get.sql | 3 + .../sql/profile-identifier-insert.sql | 4 + src/db/postgres/sql/profile-scope-insert.sql | 5 + src/db/postgres/sql/profile-scopes-clear.sql | 6 + .../postgres/sql/profile-scopes-set-all.sql | 5 + .../sql/profiles-scopes-by-identifier.sql | 10 + src/db/postgres/sql/redeem-code.sql | 30 + src/db/postgres/sql/refresh-code.sql | 19 + src/db/postgres/sql/resource-get.sql | 4 + src/db/postgres/sql/resource-upsert.sql | 10 + src/db/postgres/sql/schema/1.0.0/apply.sql | 147 + src/db/postgres/sql/schema/1.0.0/er.dot | 105 + src/db/postgres/sql/schema/1.0.0/revert.sql | 9 + src/db/postgres/sql/schema/init.sql | 15 + src/db/postgres/sql/scope-cleanup.sql | 8 + src/db/postgres/sql/scope-delete.sql | 3 + src/db/postgres/sql/scope-in-use.sql | 13 + src/db/postgres/sql/scope-upsert.sql | 14 + src/db/postgres/sql/scopes-insert.sql | 6 + src/db/postgres/sql/token-cleanup.sql | 26 + src/db/postgres/sql/token-get-by-code-id.sql | 24 + .../sql/token-refresh-revoke-by-code-id.sql | 5 + .../postgres/sql/token-revoke-by-code-id.sql | 5 + src/db/postgres/sql/token-scopes-remove.sql | 7 + src/db/postgres/sql/token-scopes-set.sql | 4 + .../postgres/sql/tokens-get-by-identifier.sql | 26 + src/db/schema-version-helper.js | 131 + src/db/sqlite/index.js | 739 ++ src/db/sqlite/sql/almanac-get-all.sql | 2 + src/db/sqlite/sql/almanac-get.sql | 2 + src/db/sqlite/sql/almanac-upsert.sql | 9 + src/db/sqlite/sql/authentication-get.sql | 8 + src/db/sqlite/sql/authentication-success.sql | 4 + src/db/sqlite/sql/authentication-upsert.sql | 9 + src/db/sqlite/sql/profile-get.sql | 3 + .../sqlite/sql/profile-identifier-insert.sql | 4 + src/db/sqlite/sql/profile-scope-insert.sql | 5 + src/db/sqlite/sql/profile-scopes-clear.sql | 5 + .../sql/profiles-scopes-by-identifier.sql | 10 + src/db/sqlite/sql/redeem-code.sql | 27 + src/db/sqlite/sql/refresh-code.sql | 15 + src/db/sqlite/sql/resource-get.sql | 4 + src/db/sqlite/sql/resource-upsert.sql | 9 + src/db/sqlite/sql/schema/1.0.0/apply.sql | 97 + src/db/sqlite/sql/schema/1.0.0/er.dot | 106 + src/db/sqlite/sql/schema/1.0.0/revert.sql | 7 + src/db/sqlite/sql/schema/init.sql | 11 + src/db/sqlite/sql/scope-cleanup.sql | 8 + src/db/sqlite/sql/scope-delete.sql | 3 + src/db/sqlite/sql/scope-in-use.sql | 13 + src/db/sqlite/sql/scope-insert.sql | 5 + src/db/sqlite/sql/scope-upsert.sql | 16 + src/db/sqlite/sql/token-cleanup.sql | 32 + src/db/sqlite/sql/token-get-by-code-id.sql | 20 + .../sql/token-refresh-revoke-by-code-id.sql | 5 + src/db/sqlite/sql/token-revoke-by-code-id.sql | 5 + src/db/sqlite/sql/token-scope-remove.sql | 3 + src/db/sqlite/sql/token-scope-set.sql | 3 + .../sql/token-scopes-get-by-code-id.sql | 4 + .../sqlite/sql/tokens-get-by-identifier.sql | 21 + src/enum.js | 27 + src/errors.js | 21 + src/logger/data-sanitizers.js | 116 + src/logger/index.js | 13 + src/manager.js | 2015 ++++ src/service.js | 544 + src/template/admin-html.js | 214 + src/template/admin-maintenance-html.js | 86 + src/template/admin-ticket-html.js | 98 + src/template/authorization-error-html.js | 26 + src/template/authorization-request-html.js | 376 + src/template/index.js | 10 + src/template/root-html.js | 63 + src/template/template-helper.js | 53 + static/.external-link.svg.meta | 2 + static/.favicon.ico.meta | 3 + static/.logo.svg.meta | 3 + static/Makefile | 14 + static/custom.css | 6 + static/external-link.svg | 15 + static/favicon.ico | Bin 0 -> 105637 bytes static/index.html | 16 + static/logo.svg | 1 + static/robots.txt | 2 + static/theme.css | 175 + test/config.js | 23 + test/src/chores.js | 140 + test/src/common.js | 181 + test/src/db/abstract.js | 295 + test/src/db/factory.js | 49 + test/src/db/integration.js | 503 + test/src/db/postgres.js | 953 ++ test/src/db/schema-version-helper.js | 159 + test/src/db/sqlite.js | 918 ++ test/src/errors.js | 15 + test/src/logger.js | 136 + test/src/manager.js | 2323 ++++ test/src/service.js | 278 + test/src/template/admin-html.js | 112 + test/src/template/admin-maintenance-html.js | 47 + test/src/template/admin-ticket-html.js | 87 + test/src/template/authorization-error-html.js | 38 + .../template/authorization-request-html.js | 144 + test/src/template/root-html.js | 35 + test/src/template/template-helper.js | 95 + test/stub-db.js | 35 + test/stub-logger.js | 10 + 143 files changed, 24834 insertions(+) create mode 100644 .eslintrc.json create mode 100644 .gitignore create mode 100644 .nycrc.json create mode 100644 CHANGELOG.md create mode 100644 README.md create mode 100644 bin/addProfile.js create mode 100644 bin/addProfileScope.js create mode 100644 bin/addScope.js create mode 100644 bin/authUserAdd.js create mode 100644 bin/cli-helper.js create mode 100644 bin/dumpProfiles.js create mode 100755 bin/generate-engine-entity-relation-diagram.sh create mode 100644 bin/resourceCreate.js create mode 100644 config/default.js create mode 100644 config/development.js create mode 100644 config/index.js create mode 100644 config/test.js create mode 100644 documentation/media/consent-page.png create mode 100644 documentation/media/postgres-er.svg create mode 100644 documentation/media/sqlite-er.svg create mode 100644 documentation/media/ticket-page.png create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 server.js create mode 100644 src/chores.js create mode 100644 src/common.js create mode 100644 src/db/abstract.js create mode 100644 src/db/errors.js create mode 100644 src/db/index.js create mode 100644 src/db/postgres/index.js create mode 100644 src/db/postgres/sql/almanac-get-all.sql create mode 100644 src/db/postgres/sql/almanac-get.sql create mode 100644 src/db/postgres/sql/almanac-upsert.sql create mode 100644 src/db/postgres/sql/authentication-get.sql create mode 100644 src/db/postgres/sql/authentication-success.sql create mode 100644 src/db/postgres/sql/authentication-upsert.sql create mode 100644 src/db/postgres/sql/profile-get.sql create mode 100644 src/db/postgres/sql/profile-identifier-insert.sql create mode 100644 src/db/postgres/sql/profile-scope-insert.sql create mode 100644 src/db/postgres/sql/profile-scopes-clear.sql create mode 100644 src/db/postgres/sql/profile-scopes-set-all.sql create mode 100644 src/db/postgres/sql/profiles-scopes-by-identifier.sql create mode 100644 src/db/postgres/sql/redeem-code.sql create mode 100644 src/db/postgres/sql/refresh-code.sql create mode 100644 src/db/postgres/sql/resource-get.sql create mode 100644 src/db/postgres/sql/resource-upsert.sql create mode 100644 src/db/postgres/sql/schema/1.0.0/apply.sql create mode 100644 src/db/postgres/sql/schema/1.0.0/er.dot create mode 100644 src/db/postgres/sql/schema/1.0.0/revert.sql create mode 100644 src/db/postgres/sql/schema/init.sql create mode 100644 src/db/postgres/sql/scope-cleanup.sql create mode 100644 src/db/postgres/sql/scope-delete.sql create mode 100644 src/db/postgres/sql/scope-in-use.sql create mode 100644 src/db/postgres/sql/scope-upsert.sql create mode 100644 src/db/postgres/sql/scopes-insert.sql create mode 100644 src/db/postgres/sql/token-cleanup.sql create mode 100644 src/db/postgres/sql/token-get-by-code-id.sql create mode 100644 src/db/postgres/sql/token-refresh-revoke-by-code-id.sql create mode 100644 src/db/postgres/sql/token-revoke-by-code-id.sql create mode 100644 src/db/postgres/sql/token-scopes-remove.sql create mode 100644 src/db/postgres/sql/token-scopes-set.sql create mode 100644 src/db/postgres/sql/tokens-get-by-identifier.sql create mode 100644 src/db/schema-version-helper.js create mode 100644 src/db/sqlite/index.js create mode 100644 src/db/sqlite/sql/almanac-get-all.sql create mode 100644 src/db/sqlite/sql/almanac-get.sql create mode 100644 src/db/sqlite/sql/almanac-upsert.sql create mode 100644 src/db/sqlite/sql/authentication-get.sql create mode 100644 src/db/sqlite/sql/authentication-success.sql create mode 100644 src/db/sqlite/sql/authentication-upsert.sql create mode 100644 src/db/sqlite/sql/profile-get.sql create mode 100644 src/db/sqlite/sql/profile-identifier-insert.sql create mode 100644 src/db/sqlite/sql/profile-scope-insert.sql create mode 100644 src/db/sqlite/sql/profile-scopes-clear.sql create mode 100644 src/db/sqlite/sql/profiles-scopes-by-identifier.sql create mode 100644 src/db/sqlite/sql/redeem-code.sql create mode 100644 src/db/sqlite/sql/refresh-code.sql create mode 100644 src/db/sqlite/sql/resource-get.sql create mode 100644 src/db/sqlite/sql/resource-upsert.sql create mode 100644 src/db/sqlite/sql/schema/1.0.0/apply.sql create mode 100644 src/db/sqlite/sql/schema/1.0.0/er.dot create mode 100644 src/db/sqlite/sql/schema/1.0.0/revert.sql create mode 100644 src/db/sqlite/sql/schema/init.sql create mode 100644 src/db/sqlite/sql/scope-cleanup.sql create mode 100644 src/db/sqlite/sql/scope-delete.sql create mode 100644 src/db/sqlite/sql/scope-in-use.sql create mode 100644 src/db/sqlite/sql/scope-insert.sql create mode 100644 src/db/sqlite/sql/scope-upsert.sql create mode 100644 src/db/sqlite/sql/token-cleanup.sql create mode 100644 src/db/sqlite/sql/token-get-by-code-id.sql create mode 100644 src/db/sqlite/sql/token-refresh-revoke-by-code-id.sql create mode 100644 src/db/sqlite/sql/token-revoke-by-code-id.sql create mode 100644 src/db/sqlite/sql/token-scope-remove.sql create mode 100644 src/db/sqlite/sql/token-scope-set.sql create mode 100644 src/db/sqlite/sql/token-scopes-get-by-code-id.sql create mode 100644 src/db/sqlite/sql/tokens-get-by-identifier.sql create mode 100644 src/enum.js create mode 100644 src/errors.js create mode 100644 src/logger/data-sanitizers.js create mode 100644 src/logger/index.js create mode 100644 src/manager.js create mode 100644 src/service.js create mode 100644 src/template/admin-html.js create mode 100644 src/template/admin-maintenance-html.js create mode 100644 src/template/admin-ticket-html.js create mode 100644 src/template/authorization-error-html.js create mode 100644 src/template/authorization-request-html.js create mode 100644 src/template/index.js create mode 100644 src/template/root-html.js create mode 100644 src/template/template-helper.js create mode 100644 static/.external-link.svg.meta create mode 100644 static/.favicon.ico.meta create mode 100644 static/.logo.svg.meta create mode 100644 static/Makefile create mode 100644 static/custom.css create mode 100644 static/external-link.svg create mode 100644 static/favicon.ico create mode 100644 static/index.html create mode 100644 static/logo.svg create mode 100644 static/robots.txt create mode 100644 static/theme.css create mode 100644 test/config.js create mode 100644 test/src/chores.js create mode 100644 test/src/common.js create mode 100644 test/src/db/abstract.js create mode 100644 test/src/db/factory.js create mode 100644 test/src/db/integration.js create mode 100644 test/src/db/postgres.js create mode 100644 test/src/db/schema-version-helper.js create mode 100644 test/src/db/sqlite.js create mode 100644 test/src/errors.js create mode 100644 test/src/logger.js create mode 100644 test/src/manager.js create mode 100644 test/src/service.js create mode 100644 test/src/template/admin-html.js create mode 100644 test/src/template/admin-maintenance-html.js create mode 100644 test/src/template/admin-ticket-html.js create mode 100644 test/src/template/authorization-error-html.js create mode 100644 test/src/template/authorization-request-html.js create mode 100644 test/src/template/root-html.js create mode 100644 test/src/template/template-helper.js create mode 100644 test/stub-db.js create mode 100644 test/stub-logger.js diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..b3ffbe2 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,89 @@ +{ + "env": { + "browser": false, + "es6": true, + "node": true + }, + "extends": [ + "eslint:recommended", + "plugin:node/recommended", + "plugin:security/recommended", + "plugin:sonarjs/recommended" + ], + "parserOptions": { + "ecmaVersion": "latest" + }, + "plugins": [ + "node", + "security", + "sonarjs" + ], + "rules": { + "array-element-newline": [ + "error", + "consistent" + ], + "arrow-parens": [ + "error", + "always" + ], + "arrow-spacing": [ + "error", + { + "after": true, + "before": true + } + ], + "block-scoped-var": "error", + "block-spacing": "error", + "brace-style": "error", + "callback-return": "error", + "camelcase": "error", + "class-methods-use-this": "error", + "comma-dangle": [ + "error", + "always-multiline" + ], + "comma-spacing": [ + "error", + { + "after": true, + "before": false + } + ], + "comma-style": [ + "error", + "last" + ], + "indent": [ + "warn", + 2, + { + "SwitchCase": 1 + } + ], + "sonarjs/cognitive-complexity": "warn", + "sonarjs/no-duplicate-string": "warn", + "keyword-spacing": "error", + "linebreak-style": [ + "error", + "unix" + ], + "no-unused-vars": [ + "error", { + "varsIgnorePattern": "^_" + } + ], + "object-curly-spacing": [ + "error", + "always" + ], + "prefer-const": "error", + "quotes": [ + "error", + "single" + ], + "strict": "error", + "vars-on-top": "error" + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..88f74fe --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +node_modules +.nyc_output +coverage +.vscode +*.sqlite* +static/*.gz +static/*.br diff --git a/.nycrc.json b/.nycrc.json new file mode 100644 index 0000000..497d8af --- /dev/null +++ b/.nycrc.json @@ -0,0 +1,6 @@ +{ + "reporter": [ + "lcov", + "text" + ] +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..80cf52d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog + +Releases and notable changes to this project are documented here. + +## [v1.0.0] - TBD + +### Added + +- Everything. MVP first stable release. + +--- + +[Unreleased]: https://git.squeep.com/?p=squeep-indie-auther;a=commitdiff;h=HEAD;hp=v1.0.0 +[v1.0.0]: https://git.squeep.com/?p=squeep-indie-auther;a=commitdiff;h=v1.0.0;hp=v0.0.0 diff --git a/README.md b/README.md new file mode 100644 index 0000000..e37aea1 --- /dev/null +++ b/README.md @@ -0,0 +1,76 @@ +# Welcome to my IndieAuth-er + +## What + +[IndieAuth](https://indieweb.org/IndieAuth) is a [protocol](https://indieauth.spec.indieweb.org/) which facilitates identifying users uniquely by the URLs they control to third-party applications. It is an extension of [Oauth 2](https://indieauth.spec.indieweb.org). + +This service implements the functionality required to negotiate that identity authentication and validation. + +## Let's Do Some Auth + +A ```user``` is an entity known to this service, with a credential (currently a password) used to authenticate and login to this service. +Authentication of a ```user``` is handled by either a [hashed password](https://en.wikipedia.org/wiki/Argon2) stored securely in one of the available database engines, or by optionally delegating to the host machine's [<abbr title="Pluggable Authentication Module">PAM</abbr> subsystem](https://en.wikipedia.org/wiki/Pluggable_Authentication_Modules). +PAM can be used to leverage, exempli gratia, LDAP integration for user authentication. + +A ```profile``` is a URL (under control of a ```user```) which contents includes the necessary meta-data informing an application to contact this server for identification validation. Each ```user``` may have one or more ```profile```s. + +Each ```profile``` may also be associated with a customizable list of additional [scopes](https://www.oauth.com/oauth2-servers/scope/) which may be added to any application client grant for convenience. + +An example of the user-interface when granting consent to a client application: + + +A rudimentary ticket-sending UI is also available: + + +## Resource Service Integration + +Other services (resources) may make calls to validate token grants by configuring a pre-shared secret, and authenticating to this server using [an HMAC-style bearer token scheme](https://git.squeep.com/?p=squeep-resource-authentication-module;a=blob_plain;f=README.md;hb=HEAD). + +## Ticket Auth + +This service can accept proffered [authentication tickets](https://indieweb.org/IndieAuth_Ticket_Auth). It will simply publish any proffered tickets for valid profiles to a configured AMQP/RabbitMQ queue for some other service to redeem and make use of. + +## Architecture + +A granted token is an encrypted identifier (specifically a UUID assigned to the initial authentication request) which references the user/client relationship stored in the database. Details such as granted scopes, token expiration, refreshability, and revocation status are stored there. + +Uh, more later. + + + +### Quirks + +This implementation is built atop an in-house API framework, for Reasons. Limiting the footprint of external dependencies as much as is reasonable is a design goal. + +### File Tour + +- bin/ - utility scripts +- config/ + - default.js - defines all configuration parameters' default values + - index.js - merges an environment's values over defaults + - *.js - environment specific values, edit these as needed +- server.js - launches the application server +- src/ + - chores.js - recurring maintenance tasks + - common.js - utility functions + - db/ + - abstract.js - base database class that any engine will implement + - errors.js - database Error types + - index.js - database factory + - schema-version-helper.js - schema migrations aide + - postgres/ + - index.js - PostgreSQL engine implementation + - sql/ - statements and schemas + - sqlite/ + - index.js - SQLite engine implementation + - sql - statements and schemas + - enum.js - invariants + - errors.js - local Error types + - logger/ + - data-sanitizers.js - logger helpers to scrub sensitive and verbose data + - index.js - a very simple logging class + - manager.js - process incoming requests, most of application logic resides here + - service.js - defines incoming endpoints, linking the API server framework to the manager methods + - template/ - HTML content +- static/ - static web assets, CSS, images, et cetera +- test/ - unit and coverage tests diff --git a/bin/addProfile.js b/bin/addProfile.js new file mode 100644 index 0000000..6a47b3c --- /dev/null +++ b/bin/addProfile.js @@ -0,0 +1,38 @@ +'use strict'; + +const DB = require('../src/db'); +const Logger = require('../src/logger'); +const Config = require('../config'); +const config = new Config(process.env.NODE_ENV); + +const logger = new Logger(config); +const db = new DB(logger, config); + + +const identifier = process.argv[2]; +const profile = process.argv[3]; + +if (!identifier) { + console.log('missing user'); + throw new Error('missing argument'); +} +if (!profile) { + console.log('missing profile'); + throw new Error('missing argument'); +} + +(async () => { + await db.initialize(); + await db.context(async (dbCtx) => { + const user = await db.authenticationGet(dbCtx, identifier); + if (!user) { + console.log('user does not exist'); + throw new Error('invalid identifier'); + } + const profileURL = new URL(profile); // Validate and normalize + const result = await db.profileIdentifierInsert(dbCtx, profileURL.href, identifier); + console.log(result); + }); + console.log('done'); + await db._closeConnection(); +})(); diff --git a/bin/addProfileScope.js b/bin/addProfileScope.js new file mode 100644 index 0000000..dfeaca0 --- /dev/null +++ b/bin/addProfileScope.js @@ -0,0 +1,32 @@ +'use strict'; + +const DB = require('../src/db'); +const Logger = require('../src/logger'); +const Config = require('../config'); +const config = new Config(process.env.NODE_ENV); + +const logger = new Logger(config); +const db = new DB(logger, config); + + +const profile = process.argv[2]; +const scope = process.argv[3]; + +if (!scope) { + console.log('missing scope'); + throw new Error('missing argument'); +} +if (!profile) { + console.log('missing profile'); + throw new Error('missing argument'); +} + +(async () => { + await db.initialize(); + await db.context(async (dbCtx) => { + const result = await db.profileScopeInsert(dbCtx, profile, scope); + console.log(result); + }); + console.log('done'); + await db._closeConnection(); +})(); diff --git a/bin/addScope.js b/bin/addScope.js new file mode 100644 index 0000000..809ee5f --- /dev/null +++ b/bin/addScope.js @@ -0,0 +1,32 @@ +'use strict'; + +const DB = require('../src/db'); +const Logger = require('../src/logger'); +const Config = require('../config'); +const config = new Config(process.env.NODE_ENV); + +const logger = new Logger(config); +const db = new DB(logger, config); + + +const scope = process.argv[2]; +const description = process.argv[3]; + +if (!scope) { + console.log('missing scope'); + throw new Error('missing argument'); +} +if (!description) { + console.log('missing description'); + throw new Error('missing argument'); +} + +(async () => { + await db.initialize(); + await db.context(async (dbCtx) => { + const result = await db.scopeUpsert(dbCtx, scope, description); + console.log(result); + }); + console.log('done'); + await db._closeConnection(); +})(); diff --git a/bin/authUserAdd.js b/bin/authUserAdd.js new file mode 100644 index 0000000..cc71552 --- /dev/null +++ b/bin/authUserAdd.js @@ -0,0 +1,70 @@ +'use strict'; + +const argon2 = require('argon2'); +const readline = require('readline'); +const stream = require('stream'); +const DB = require('../src/db'); +const Logger = require('../src/logger'); +const Config = require('../config'); +const config = new Config(process.env.NODE_ENV); + +const logger = new Logger(config); +const db = new DB(logger, config); + +const flags = { + isPAM: false, +}; +if (process.argv.includes('-P')) { + flags.isPAM = true; + process.argv.splice(process.argv.indexOf('-P'), 1); +} + +const identifier = process.argv[2]; + +if (!identifier) { + console.log('missing user to add'); + throw new Error('missing argument'); +} + +async function readPassword(prompt) { + const input = process.stdin; + const output = new stream.Writable({ + write: function (chunk, encoding, callback) { + if (!this.muted) { + process.stdout.write(chunk, encoding); + } + callback(); + }, + }); + const rl = readline.createInterface({ input, output, terminal: !!process.stdin.isTTY }); + rl.setPrompt(prompt); + rl.prompt(); + output.muted = true; + + return new Promise((resolve) => { + rl.question('', (answer) => { + output.muted = false; + rl.close(); + output.write('\n'); + resolve(answer); + }); + }); +} + +(async () => { + await db.initialize(); + let credential; + if (flags.isPAM) { + credential = '$PAM$'; + } else { + const password = await readPassword('password: '); + credential = await argon2.hash(password, { type: argon2.argon2id }); + } + console.log(`\t${identifier}:${credential}`); + await db.context(async (dbCtx) => { + const result = await db.authenticationUpsert(dbCtx, identifier, credential); + console.log(result); + }); + console.log('done'); + await db._closeConnection(); +})(); diff --git a/bin/cli-helper.js b/bin/cli-helper.js new file mode 100644 index 0000000..5f1a1a3 --- /dev/null +++ b/bin/cli-helper.js @@ -0,0 +1,38 @@ +'use strict'; + + +/** + * + * @param {String} option + * @returns {*} + */ +function getOption(option) { + let value; + while (process.argv.includes(option)) { + const optionIndex = process.argv.indexOf(option); + value = process.argv.splice(optionIndex, 2)[1]; + } + return value; +} + + +/** + * + * @param {String} flag + * @returns {Number} + */ +function getFlag(flag) { + let value = 0; + while (process.argv.includes(flag)) { + const flagIndex = process.argv.indexOf(flag); + process.argv.splice(flagIndex, 1); + value += 1; + } + return value; +} + + +module.exports = { + getFlag, + getOption, +}; \ No newline at end of file diff --git a/bin/dumpProfiles.js b/bin/dumpProfiles.js new file mode 100644 index 0000000..5b249fd --- /dev/null +++ b/bin/dumpProfiles.js @@ -0,0 +1,32 @@ +'use strict'; + +const DB = require('../src/db'); +const Logger = require('../src/logger'); +const Config = require('../config'); +const config = new Config(process.env.NODE_ENV); + +const logger = new Logger(config); +const db = new DB(logger, config); + + +const identifier = process.argv[2]; + +if (!identifier) { + console.log('missing user'); + throw new Error('missing argument'); +} + +(async () => { + await db.initialize(); + await db.context(async (dbCtx) => { + const user = await db.authenticationGet(dbCtx, identifier); + + const profiles = await db.profilesByIdentifier(dbCtx, identifier); + console.log(profiles); + if (!user) { + console.log('(user does not exist)'); + } + }); // dbCtx + console.log('done'); + await db._closeConnection(); +})(); diff --git a/bin/generate-engine-entity-relation-diagram.sh b/bin/generate-engine-entity-relation-diagram.sh new file mode 100755 index 0000000..cd54251 --- /dev/null +++ b/bin/generate-engine-entity-relation-diagram.sh @@ -0,0 +1,18 @@ +#!/bin/bash +if [[ $# -ne 2 ]] +then + echo "Usage: $(basename "$0") engine schema-version" + exit 64 # EX_USAGE +fi +engine="$1" +schema="$2" +base="$(dirname "$0")/.." +pwd="$(pwd)" +src=$(realpath --relative-to "${pwd}" "${base}/src/db/${engine}/sql/schema/${schema}/er.dot") +dst=$(realpath --relative-to "${pwd}" "${base}/documentation/media/${engine}-er.svg") +if [[ ! -e "${src}" ]] +then + echo "Missing: ${src}" 1>&2 + exit 65 # EX_DATAERR +fi +dot -Tsvg -o"${dst}" "${src}" diff --git a/bin/resourceCreate.js b/bin/resourceCreate.js new file mode 100644 index 0000000..ae7390a --- /dev/null +++ b/bin/resourceCreate.js @@ -0,0 +1,46 @@ +'use strict'; + +const cli = require('./cli-helper'); +const DB = require('../src/db'); +const Logger = require('../src/logger'); +const Config = require('../config'); +const { newSecret } = require('../src/common'); +const config = new Config(process.env.NODE_ENV, false); +const verbose = cli.getFlag('-v'); +if (!verbose) { + config.logger.ignoreBelowLevel = 'info'; +} +const logger = new Logger(config); +const db = new DB(logger, config); + + +const resourceId = cli.getOption('-i'); +let secret = cli.getOption('-s'); +const rest = process.argv.slice(2); +const description = rest.length ? rest.join(' ') : undefined; + +(async () => { + await db.initialize(); + try { + if (!resourceId) { + if (!description || !description.length) { + console.log('ERROR: description is required when creating a new resource.'); + throw new Error('Invalid parameters'); + } + if (!secret) { + secret = await newSecret(); + } + } + + await db.context(async (dbCtx) => { + const result = await db.resourceUpsert(dbCtx, resourceId, secret, description); + console.log(result); + }); + } catch (e) { + console.log(e); + } finally { + await db._closeConnection(); + } +})().then(() => { + console.log('done'); +}); diff --git a/config/default.js b/config/default.js new file mode 100644 index 0000000..55945fd --- /dev/null +++ b/config/default.js @@ -0,0 +1,99 @@ +'use strict'; + +// Provide default values for all configuration. + +const { name: packageName, version: packageVersion } = require('../package.json'); +const common = require('../src/common'); +const Enum = require('../src/enum'); +const roman = require('@squeep/roman'); + +const currentYear = (new Date()).getFullYear(); +const romanYearHTML = roman.toRoman(currentYear, true); + +const defaultOptions = { + // Uniquely identify this instance. + nodeId: common.requestId(), // Default to ephemeral ID: easiest for clustered deployments. + + encryptionSecret: '', // No default; set this to a long passphrase or randomness. + // This may also be set to an array, if secret needs to be rolled. This needs more documentation. + + // Dingus API Server Framework options. + dingus: { + // This needs to be the full externally accessible root URL, including any proxyPrefix component. + selfBaseUrl: '', + + // trustProxy: true, // If true, trust values of some headers regarding client IP address and protocol. + proxyPrefix: '', // Leading path parts to ignore when parsing routes, and include when constructing links, e.g. /indieauth + }, + + // The terminal portions of API route path endpoints. + route: { + authorization: 'auth', + consent: 'consent', + healthcheck: 'healthcheck', + introspection: 'introspect', + metadata: 'meta', + revocation: 'revoke', + ticket: 'ticket', + token: 'token', + userinfo: 'userinfo', + }, + + // Database options + db: { + connectionString: '', // e.g. sqlite://path/to/dbfile.sqlite + queryLogLevel: undefined, // Set to log queries + + // SQLite specific options + sqliteOptimizeAfterChanges: 0, // Number of changes before running pragma optimize, 0 for never + }, + + // Queue options, currently only for handing off ticket offers + queues: { + amqp: { + url: undefined, // AMQP endpoint, e.g. 'amqp://user:pass@rmq.host:5672' If not specified, ticket endpoint will be disabled + prefix: undefined, + }, + ticketPublishName: 'indieauth.ticket.proffered', // exchange to publish proffered tickets to + }, + + // Logging options + logger: { + ignoreBelowLevel: 'info', + }, + + manager: { + codeValidityTimeoutMs: 10 * 60 * 1000, + ticketLifespanSeconds: 300, + pageTitle: packageName, // title on html pages + logoUrl: 'static/logo.svg', // image to go with title + footerEntries: [ // common footers on all html pages + '<a href="https://git.squeep.com/?p=squeep-indie-auther;a=tree">Development Repository</a>', + `<span class="copyright">©<time datetime="${currentYear}">${romanYearHTML}</time></span>`, + ], + allowLegacyNonPKCE: false, // Whether to process auth requests lacking code challenges + }, + + chores: { + scopeCleanupMs: 0, // how often to clean up unreferenced scopes, 0 for never + tokenCleanupMs: 0, // how often to clean up no-longer-valid scopes, 0 for never + }, + + // Outgoing request UA header. Setting these here to override helper defaults. + userAgent: { + product: packageName, + version: packageVersion, + implementation: Enum.Specification, + }, + + authenticator: { + authnEnabled: ['argon2', 'pam'], // Types of authentication to attempt. + secureAuthOnly: true, // Require secure transport for authentication. + forbiddenPAMIdentifiers: [ + 'root', + ], + }, + +}; + +module.exports = defaultOptions; diff --git a/config/development.js b/config/development.js new file mode 100644 index 0000000..2f69e39 --- /dev/null +++ b/config/development.js @@ -0,0 +1,36 @@ +'use strict'; +module.exports = [ + { + authenticator: { + authnEnabled: undefined, // remove all, then set one below + }, + }, + { + encryptionSecret: 'this is not a very good secret', + db: { + connectionString: `postgresql://${encodeURIComponent('/var/lib/postgresql/14/data')}/indieauther`, // local pg socket + queryLogLevel: 'debug', + }, + dingus: { + selfBaseUrl: 'https://ia.squeep.com/', + }, + queues: { + amqp: { + url: 'amqp://guest:guest@rmq.int:5672', + }, + }, + logger: { + ignoreBelowLevel: 'debug', + }, + authenticator: { + authnEnabled: ['argon2'], + }, + chores: { + scopeCleanupMs: 86400000, + tokenCleanupMs: 86400000, + }, + manager: { + allowLegacyNonPKCE: true, + }, + }, +]; diff --git a/config/index.js b/config/index.js new file mode 100644 index 0000000..79410a6 --- /dev/null +++ b/config/index.js @@ -0,0 +1,24 @@ +'use strict'; + +const common = require('../src/common'); + +const defaultEnvironment = 'development'; +const testEnvironment = 'test'; + +function Config(environment, freeze = true) { + environment = environment || defaultEnvironment; + const defaultConfig = require('./default'); + let envConfig = require(`./${environment}`); // eslint-disable-line security/detect-non-literal-require + if (!Array.isArray(envConfig)) { + envConfig = Array(envConfig); + } + // We support arrays of config options in env to allow e.g. resetting an existing array + const combinedConfig = common.mergeDeep(defaultConfig, ...envConfig, { environment }); + if (freeze && !environment.includes(testEnvironment)) { + /* istanbul ignore next */ + common.freezeDeep(combinedConfig); + } + return combinedConfig; +} + +module.exports = Config; \ No newline at end of file diff --git a/config/test.js b/config/test.js new file mode 100644 index 0000000..b92272f --- /dev/null +++ b/config/test.js @@ -0,0 +1,16 @@ +'use strict'; +// Configuration used by test suites. +module.exports = { + encryptionSecret: 'not a great secret', + dingus: { + selfBaseUrl: 'https://example.com/indieauthie/', + }, + db: { + queryLogLevel: 'debug', + }, + queues: { + amqp: { + url: 'ampq://localhost:5432', + }, + }, +}; diff --git a/documentation/media/consent-page.png b/documentation/media/consent-page.png new file mode 100644 index 0000000000000000000000000000000000000000..fab0b424b68c9b1ed5fbf4456eac9d846f1a6249 GIT binary patch literal 449120 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%0A%xm^D9Zu~#&y=7RH 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Ðdc#uw=n_V?b`61YJ_I3W|A_ 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%0DYVy#x;{jL6^$e=2Dw;N=yjXZx*U@D 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 ZhCNq2&L;m_I*$PeJYD@<);T3K0RZCV2-*Mu literal 0 HcmV?d00001 diff --git a/documentation/media/postgres-er.svg b/documentation/media/postgres-er.svg new file mode 100644 index 0000000..670582a --- /dev/null +++ b/documentation/media/postgres-er.svg @@ -0,0 +1,184 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.50.0 (20211204.2007) + --> +<!-- Title: indieAutherERD Pages: 1 --> +<svg width="656pt" height="668pt" + viewBox="0.00 0.00 656.00 668.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 664)"> +<title>indieAutherERD</title> +<polygon fill="white" stroke="transparent" points="-4,4 -4,-664 652,-664 652,4 -4,4"/> +<text text-anchor="middle" x="324" y="-635.2" font-family="Times,serif" font-size="26.00">IndieAuther Entity-Relations</text> +<text text-anchor="middle" x="324" y="-606.2" font-family="Times,serif" font-size="26.00">Postgres</text> +<text text-anchor="middle" x="324" y="-577.2" font-family="Times,serif" font-size="26.00">Schema 1.0.0</text> +<!-- token --> +<g id="node1" class="node"> +<title>token</title> +<polygon fill="lightblue" stroke="transparent" points="362.5,-501.5 362.5,-524.5 488.5,-524.5 488.5,-501.5 362.5,-501.5"/> +<polygon fill="none" stroke="black" stroke-width="2" points="363.5,-502.5 363.5,-523.5 487.5,-523.5 487.5,-502.5 363.5,-502.5"/> +<text text-anchor="start" x="398.5" y="-509.3" font-family="Times,serif" font-size="14.00">TOKEN</text> +<polygon fill="none" stroke="black" points="362.5,-480.5 362.5,-501.5 488.5,-501.5 488.5,-480.5 362.5,-480.5"/> +<text text-anchor="start" x="398.5" y="-487.3" font-family="Times,serif" font-size="14.00">code_id</text> +<polygon fill="none" stroke="black" points="362.5,-459.5 362.5,-480.5 488.5,-480.5 488.5,-459.5 362.5,-459.5"/> +<text text-anchor="start" x="392" y="-466.3" font-family="Times,serif" font-size="14.00">profile_id</text> +<polygon fill="none" stroke="black" points="362.5,-438.5 362.5,-459.5 488.5,-459.5 488.5,-438.5 362.5,-438.5"/> +<text text-anchor="start" x="398" y="-445.3" font-family="Times,serif" font-size="14.00">created</text> +<polygon fill="none" stroke="black" points="362.5,-417.5 362.5,-438.5 488.5,-438.5 488.5,-417.5 362.5,-417.5"/> +<text text-anchor="start" x="399" y="-424.3" font-family="Times,serif" font-size="14.00">expires</text> +<polygon fill="none" stroke="black" points="362.5,-396.5 362.5,-417.5 488.5,-417.5 488.5,-396.5 362.5,-396.5"/> +<text text-anchor="start" x="369.5" y="-403.3" font-family="Times,serif" font-size="14.00">refresh_expires</text> +<polygon fill="none" stroke="black" points="362.5,-375.5 362.5,-396.5 488.5,-396.5 488.5,-375.5 362.5,-375.5"/> +<text text-anchor="start" x="390.5" y="-382.3" font-family="Times,serif" font-size="14.00">refreshed</text> +<polygon fill="none" stroke="black" points="362.5,-354.5 362.5,-375.5 488.5,-375.5 488.5,-354.5 362.5,-354.5"/> +<text text-anchor="start" x="395" y="-361.3" font-family="Times,serif" font-size="14.00">duration</text> +<polygon fill="none" stroke="black" points="362.5,-333.5 362.5,-354.5 488.5,-354.5 488.5,-333.5 362.5,-333.5"/> +<text text-anchor="start" x="365.5" y="-340.3" font-family="Times,serif" font-size="14.00">refresh_duration</text> +<polygon fill="none" stroke="black" points="362.5,-312.5 362.5,-333.5 488.5,-333.5 488.5,-312.5 362.5,-312.5"/> +<text text-anchor="start" x="376" y="-319.3" font-family="Times,serif" font-size="14.00">refresh_count</text> +<polygon fill="none" stroke="black" points="362.5,-291.5 362.5,-312.5 488.5,-312.5 488.5,-291.5 362.5,-291.5"/> +<text text-anchor="start" x="387.5" y="-298.3" font-family="Times,serif" font-size="14.00">is_revoked</text> +<polygon fill="none" stroke="black" points="362.5,-270.5 362.5,-291.5 488.5,-291.5 488.5,-270.5 362.5,-270.5"/> +<text text-anchor="start" x="396" y="-277.3" font-family="Times,serif" font-size="14.00">is_token</text> +<polygon fill="none" stroke="black" points="362.5,-249.5 362.5,-270.5 488.5,-270.5 488.5,-249.5 362.5,-249.5"/> +<text text-anchor="start" x="395" y="-256.3" font-family="Times,serif" font-size="14.00">client_id</text> +<polygon fill="none" stroke="black" points="362.5,-228.5 362.5,-249.5 488.5,-249.5 488.5,-228.5 362.5,-228.5"/> +<text text-anchor="start" x="394" y="-235.3" font-family="Times,serif" font-size="14.00">resource</text> +<polygon fill="none" stroke="black" points="362.5,-207.5 362.5,-228.5 488.5,-228.5 488.5,-207.5 362.5,-207.5"/> +<text text-anchor="start" x="383" y="-214.3" font-family="Times,serif" font-size="14.00">profile_data</text> +</g> +<!-- token_scope --> +<g id="node4" class="node"> +<title>token_scope</title> +<polygon fill="lightblue" stroke="transparent" points="528,-315.5 528,-338.5 648,-338.5 648,-315.5 528,-315.5"/> +<polygon fill="none" stroke="black" stroke-width="2" points="529,-316.5 529,-337.5 647,-337.5 647,-316.5 529,-316.5"/> +<text text-anchor="start" x="532" y="-323.3" font-family="Times,serif" font-size="14.00">TOKEN_SCOPE</text> +<polygon fill="none" stroke="black" points="528,-294.5 528,-315.5 648,-315.5 648,-294.5 528,-294.5"/> +<text text-anchor="start" x="561" y="-301.3" font-family="Times,serif" font-size="14.00">code_id</text> +<polygon fill="none" stroke="black" points="528,-273.5 528,-294.5 648,-294.5 648,-273.5 528,-273.5"/> +<text text-anchor="start" x="557.5" y="-280.3" font-family="Times,serif" font-size="14.00">scope_id</text> +</g> +<!-- token->token_scope --> +<g id="edge2" class="edge"> +<title>token:pk_code_id->token_scope:fk_code_id</title> +<path fill="none" stroke="black" d="M489.5,-491.5C570.54,-491.5 454.5,-320.92 517.83,-305.6"/> +<polygon fill="black" stroke="black" points="518.06,-305.57 528.48,-308.97 523.03,-305.04 528,-304.5 528,-304.5 528,-304.5 523.03,-305.04 527.52,-300.03 518.06,-305.57 518.06,-305.57"/> +</g> +<!-- profile --> +<g id="node2" class="node"> +<title>profile</title> +<polygon fill="lightblue" stroke="transparent" points="206.5,-355.5 206.5,-378.5 299.5,-378.5 299.5,-355.5 206.5,-355.5"/> +<polygon fill="none" stroke="black" stroke-width="2" points="207.5,-356.5 207.5,-377.5 298.5,-377.5 298.5,-356.5 207.5,-356.5"/> +<text text-anchor="start" x="219.5" y="-363.3" font-family="Times,serif" font-size="14.00">PROFILE</text> +<polygon fill="none" stroke="black" points="206.5,-334.5 206.5,-355.5 299.5,-355.5 299.5,-334.5 206.5,-334.5"/> +<text text-anchor="start" x="219.5" y="-341.3" font-family="Times,serif" font-size="14.00">profile_id</text> +<polygon fill="none" stroke="black" points="206.5,-313.5 206.5,-334.5 299.5,-334.5 299.5,-313.5 206.5,-313.5"/> +<text text-anchor="start" x="209.5" y="-320.3" font-family="Times,serif" font-size="14.00">identifier_id</text> +<polygon fill="none" stroke="black" points="206.5,-292.5 206.5,-313.5 299.5,-313.5 299.5,-292.5 206.5,-292.5"/> +<text text-anchor="start" x="229.5" y="-299.3" font-family="Times,serif" font-size="14.00">profile</text> +</g> +<!-- profile->token --> +<g id="edge1" class="edge"> +<title>profile:pk_profile_id->token:fk_profile_id</title> +<path fill="none" stroke="black" d="M300.5,-345.5C358.57,-345.5 306.81,-455.82 351.58,-469.18"/> +<polygon fill="black" stroke="black" points="351.59,-469.18 360.91,-474.96 356.54,-469.84 361.5,-470.5 361.5,-470.5 361.5,-470.5 356.54,-469.84 362.09,-466.04 351.59,-469.18 351.59,-469.18"/> +</g> +<!-- profile_scope --> +<g id="node6" class="node"> +<title>profile_scope</title> +<polygon fill="lightblue" stroke="transparent" points="359.5,-166.5 359.5,-189.5 492.5,-189.5 492.5,-166.5 359.5,-166.5"/> +<polygon fill="none" stroke="black" stroke-width="2" points="360.5,-167.5 360.5,-188.5 491.5,-188.5 491.5,-167.5 360.5,-167.5"/> +<text text-anchor="start" x="363.5" y="-174.3" font-family="Times,serif" font-size="14.00">PROFILE_SCOPE</text> +<polygon fill="none" stroke="black" points="359.5,-145.5 359.5,-166.5 492.5,-166.5 492.5,-145.5 359.5,-145.5"/> +<text text-anchor="start" x="392.5" y="-152.3" font-family="Times,serif" font-size="14.00">profile_id</text> +<polygon fill="none" stroke="black" points="359.5,-124.5 359.5,-145.5 492.5,-145.5 492.5,-124.5 359.5,-124.5"/> +<text text-anchor="start" x="395.5" y="-131.3" font-family="Times,serif" font-size="14.00">scope_id</text> +</g> +<!-- profile->profile_scope --> +<g id="edge5" class="edge"> +<title>profile:pk_profile_id->profile_scope:fk_profile_id</title> +<path fill="none" stroke="black" d="M300.5,-345.5C385.06,-345.5 280.42,-171.48 348.72,-156.52"/> +<polygon fill="black" stroke="black" points="349.05,-156.49 359.45,-159.98 354.02,-155.99 359,-155.5 359,-155.5 359,-155.5 354.02,-155.99 358.55,-151.02 349.05,-156.49 349.05,-156.49"/> +</g> +<!-- scope --> +<g id="node3" class="node"> +<title>scope</title> +<polygon fill="lightblue" stroke="transparent" points="182.5,-125.5 182.5,-148.5 323.5,-148.5 323.5,-125.5 182.5,-125.5"/> +<polygon fill="none" stroke="black" stroke-width="2" points="183.5,-126.5 183.5,-147.5 322.5,-147.5 322.5,-126.5 183.5,-126.5"/> +<text text-anchor="start" x="227" y="-133.3" font-family="Times,serif" font-size="14.00">SCOPE</text> +<polygon fill="none" stroke="black" points="182.5,-104.5 182.5,-125.5 323.5,-125.5 323.5,-104.5 182.5,-104.5"/> +<text text-anchor="start" x="222.5" y="-111.3" font-family="Times,serif" font-size="14.00">scope_id</text> +<polygon fill="none" stroke="black" points="182.5,-83.5 182.5,-104.5 323.5,-104.5 323.5,-83.5 182.5,-83.5"/> +<text text-anchor="start" x="232.5" y="-90.3" font-family="Times,serif" font-size="14.00">scope</text> +<polygon fill="none" stroke="black" points="182.5,-62.5 182.5,-83.5 323.5,-83.5 323.5,-62.5 182.5,-62.5"/> +<text text-anchor="start" x="212.5" y="-69.3" font-family="Times,serif" font-size="14.00">description</text> +<polygon fill="none" stroke="black" points="182.5,-41.5 182.5,-62.5 323.5,-62.5 323.5,-41.5 182.5,-41.5"/> +<text text-anchor="start" x="213.5" y="-48.3" font-family="Times,serif" font-size="14.00">application</text> +<polygon fill="none" stroke="black" points="182.5,-20.5 182.5,-41.5 323.5,-41.5 323.5,-20.5 182.5,-20.5"/> +<text text-anchor="start" x="204.5" y="-27.3" font-family="Times,serif" font-size="14.00">is_permanent</text> +<polygon fill="none" stroke="black" points="182.5,0.5 182.5,-20.5 323.5,-20.5 323.5,0.5 182.5,0.5"/> +<text text-anchor="start" x="185.5" y="-6.3" font-family="Times,serif" font-size="14.00">is_manually_added</text> +</g> +<!-- scope->token_scope --> +<g id="edge3" class="edge"> +<title>scope:pk_scope_id->token_scope:fk_scope_id</title> +<path fill="none" stroke="black" d="M323,-115.5C398.11,-115.5 433.59,-68.28 492,-115.5 548.48,-161.16 461,-271.95 518.03,-282.66"/> +<polygon fill="black" stroke="black" points="518.03,-282.66 527.62,-287.98 523.02,-283.08 528,-283.5 528,-283.5 528,-283.5 523.02,-283.08 528.38,-279.02 518.03,-282.66 518.03,-282.66"/> +</g> +<!-- scope->profile_scope --> +<g id="edge6" class="edge"> +<title>scope:pk_scope_id->profile_scope:fk_scope_id</title> +<path fill="none" stroke="black" d="M323,-115.5C336.99,-115.5 340.05,-126.87 349.09,-132.02"/> +<polygon fill="black" stroke="black" points="349.3,-132.07 357.91,-138.86 354.15,-133.28 359,-134.5 359,-134.5 359,-134.5 354.15,-133.28 360.09,-130.14 349.3,-132.07 349.3,-132.07"/> +</g> +<!-- authentication --> +<g id="node5" class="node"> +<title>authentication</title> +<polygon fill="lightblue" stroke="transparent" points="0,-333.5 0,-356.5 146,-356.5 146,-333.5 0,-333.5"/> +<polygon fill="none" stroke="black" stroke-width="2" points="1,-334.5 1,-355.5 145,-355.5 145,-334.5 1,-334.5"/> +<text text-anchor="start" x="4" y="-341.3" font-family="Times,serif" font-size="14.00">AUTHENTICATION</text> +<polygon fill="none" stroke="black" points="0,-312.5 0,-333.5 146,-333.5 146,-312.5 0,-312.5"/> +<text text-anchor="start" x="29.5" y="-319.3" font-family="Times,serif" font-size="14.00">identifier_id</text> +<polygon fill="none" stroke="black" points="0,-291.5 0,-312.5 146,-312.5 146,-291.5 0,-291.5"/> +<text text-anchor="start" x="45.5" y="-298.3" font-family="Times,serif" font-size="14.00">created</text> +<polygon fill="none" stroke="black" points="0,-270.5 0,-291.5 146,-291.5 146,-270.5 0,-270.5"/> +<text text-anchor="start" x="6.5" y="-277.3" font-family="Times,serif" font-size="14.00">last_authenticated</text> +<polygon fill="none" stroke="black" points="0,-249.5 0,-270.5 146,-270.5 146,-249.5 0,-249.5"/> +<text text-anchor="start" x="39.5" y="-256.3" font-family="Times,serif" font-size="14.00">identifier</text> +<polygon fill="none" stroke="black" points="0,-228.5 0,-249.5 146,-249.5 146,-228.5 0,-228.5"/> +<text text-anchor="start" x="36.5" y="-235.3" font-family="Times,serif" font-size="14.00">credential</text> +</g> +<!-- authentication->profile --> +<g id="edge4" class="edge"> +<title>authentication:pk_identifier_id->profile:fk_identifier_id</title> +<path fill="none" stroke="black" d="M146,-323.5C168.73,-323.5 176.8,-323.5 195.41,-323.5"/> +<polygon fill="black" stroke="black" points="195.5,-323.5 205.5,-328 200.5,-323.5 205.5,-323.5 205.5,-323.5 205.5,-323.5 200.5,-323.5 205.5,-319 195.5,-323.5 195.5,-323.5"/> +</g> +<!-- resource --> +<g id="node7" class="node"> +<title>resource</title> +<polygon fill="lightblue" stroke="transparent" points="26,-458.5 26,-481.5 120,-481.5 120,-458.5 26,-458.5"/> +<polygon fill="none" stroke="black" stroke-width="2" points="27,-459.5 27,-480.5 119,-480.5 119,-459.5 27,-459.5"/> +<text text-anchor="start" x="30" y="-466.3" font-family="Times,serif" font-size="14.00">RESOURCE</text> +<polygon fill="none" stroke="black" points="26,-437.5 26,-458.5 120,-458.5 120,-437.5 26,-437.5"/> +<text text-anchor="start" x="31.5" y="-444.3" font-family="Times,serif" font-size="14.00">resource_id</text> +<polygon fill="none" stroke="black" points="26,-416.5 26,-437.5 120,-437.5 120,-416.5 26,-416.5"/> +<text text-anchor="start" x="32.5" y="-423.3" font-family="Times,serif" font-size="14.00">description</text> +<polygon fill="none" stroke="black" points="26,-395.5 26,-416.5 120,-416.5 120,-395.5 26,-395.5"/> +<text text-anchor="start" x="45.5" y="-402.3" font-family="Times,serif" font-size="14.00">created</text> +<polygon fill="none" stroke="black" points="26,-374.5 26,-395.5 120,-395.5 120,-374.5 26,-374.5"/> +<text text-anchor="start" x="50.5" y="-381.3" font-family="Times,serif" font-size="14.00">secret</text> +</g> +<!-- almanac --> +<g id="node8" class="node"> +<title>almanac</title> +<polygon fill="lightblue" stroke="transparent" points="31,-541.5 31,-564.5 115,-564.5 115,-541.5 31,-541.5"/> +<polygon fill="none" stroke="black" stroke-width="2" points="32,-542.5 32,-563.5 114,-563.5 114,-542.5 32,-542.5"/> +<text text-anchor="start" x="35" y="-549.3" font-family="Times,serif" font-size="14.00">ALMANAC</text> +<polygon fill="none" stroke="black" points="31,-520.5 31,-541.5 115,-541.5 115,-520.5 31,-520.5"/> +<text text-anchor="start" x="53" y="-527.3" font-family="Times,serif" font-size="14.00">event</text> +<polygon fill="none" stroke="black" points="31,-499.5 31,-520.5 115,-520.5 115,-499.5 31,-499.5"/> +<text text-anchor="start" x="57" y="-506.3" font-family="Times,serif" font-size="14.00">date</text> +</g> +</g> +</svg> diff --git a/documentation/media/sqlite-er.svg b/documentation/media/sqlite-er.svg new file mode 100644 index 0000000..8d036ed --- /dev/null +++ b/documentation/media/sqlite-er.svg @@ -0,0 +1,183 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.50.0 (20211204.2007) + --> +<!-- Title: indieAutherERD Pages: 1 --> +<svg width="656pt" height="639pt" + viewBox="0.00 0.00 656.00 639.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 635)"> +<title>indieAutherERD</title> +<polygon fill="white" stroke="transparent" points="-4,4 -4,-635 652,-635 652,4 -4,4"/> +<text text-anchor="middle" x="324" y="-606.2" font-family="Times,serif" font-size="26.00">IndieAuther Entity-RelationsSQLite</text> +<text text-anchor="middle" x="324" y="-577.2" font-family="Times,serif" font-size="26.00">Schema 1.0.0</text> +<!-- token --> +<g id="node1" class="node"> +<title>token</title> +<polygon fill="lightblue" stroke="transparent" points="362.5,-501.5 362.5,-524.5 488.5,-524.5 488.5,-501.5 362.5,-501.5"/> +<polygon fill="none" stroke="black" stroke-width="2" points="363.5,-502.5 363.5,-523.5 487.5,-523.5 487.5,-502.5 363.5,-502.5"/> +<text text-anchor="start" x="398.5" y="-509.3" font-family="Times,serif" font-size="14.00">TOKEN</text> +<polygon fill="none" stroke="black" points="362.5,-480.5 362.5,-501.5 488.5,-501.5 488.5,-480.5 362.5,-480.5"/> +<text text-anchor="start" x="398.5" y="-487.3" font-family="Times,serif" font-size="14.00">code_id</text> +<polygon fill="none" stroke="black" points="362.5,-459.5 362.5,-480.5 488.5,-480.5 488.5,-459.5 362.5,-459.5"/> +<text text-anchor="start" x="392" y="-466.3" font-family="Times,serif" font-size="14.00">profile_id</text> +<polygon fill="none" stroke="black" points="362.5,-438.5 362.5,-459.5 488.5,-459.5 488.5,-438.5 362.5,-438.5"/> +<text text-anchor="start" x="398" y="-445.3" font-family="Times,serif" font-size="14.00">created</text> +<polygon fill="none" stroke="black" points="362.5,-417.5 362.5,-438.5 488.5,-438.5 488.5,-417.5 362.5,-417.5"/> +<text text-anchor="start" x="399" y="-424.3" font-family="Times,serif" font-size="14.00">expires</text> +<polygon fill="none" stroke="black" points="362.5,-396.5 362.5,-417.5 488.5,-417.5 488.5,-396.5 362.5,-396.5"/> +<text text-anchor="start" x="369.5" y="-403.3" font-family="Times,serif" font-size="14.00">refresh_expires</text> +<polygon fill="none" stroke="black" points="362.5,-375.5 362.5,-396.5 488.5,-396.5 488.5,-375.5 362.5,-375.5"/> +<text text-anchor="start" x="390.5" y="-382.3" font-family="Times,serif" font-size="14.00">refreshed</text> +<polygon fill="none" stroke="black" points="362.5,-354.5 362.5,-375.5 488.5,-375.5 488.5,-354.5 362.5,-354.5"/> +<text text-anchor="start" x="395" y="-361.3" font-family="Times,serif" font-size="14.00">duration</text> +<polygon fill="none" stroke="black" points="362.5,-333.5 362.5,-354.5 488.5,-354.5 488.5,-333.5 362.5,-333.5"/> +<text text-anchor="start" x="365.5" y="-340.3" font-family="Times,serif" font-size="14.00">refresh_duration</text> +<polygon fill="none" stroke="black" points="362.5,-312.5 362.5,-333.5 488.5,-333.5 488.5,-312.5 362.5,-312.5"/> +<text text-anchor="start" x="376" y="-319.3" font-family="Times,serif" font-size="14.00">refresh_count</text> +<polygon fill="none" stroke="black" points="362.5,-291.5 362.5,-312.5 488.5,-312.5 488.5,-291.5 362.5,-291.5"/> +<text text-anchor="start" x="387.5" y="-298.3" font-family="Times,serif" font-size="14.00">is_revoked</text> +<polygon fill="none" stroke="black" points="362.5,-270.5 362.5,-291.5 488.5,-291.5 488.5,-270.5 362.5,-270.5"/> +<text text-anchor="start" x="396" y="-277.3" font-family="Times,serif" font-size="14.00">is_token</text> +<polygon fill="none" stroke="black" points="362.5,-249.5 362.5,-270.5 488.5,-270.5 488.5,-249.5 362.5,-249.5"/> +<text text-anchor="start" x="395" y="-256.3" font-family="Times,serif" font-size="14.00">client_id</text> +<polygon fill="none" stroke="black" points="362.5,-228.5 362.5,-249.5 488.5,-249.5 488.5,-228.5 362.5,-228.5"/> +<text text-anchor="start" x="394" y="-235.3" font-family="Times,serif" font-size="14.00">resource</text> +<polygon fill="none" stroke="black" points="362.5,-207.5 362.5,-228.5 488.5,-228.5 488.5,-207.5 362.5,-207.5"/> +<text text-anchor="start" x="383" y="-214.3" font-family="Times,serif" font-size="14.00">profile_data</text> +</g> +<!-- token_scope --> +<g id="node4" class="node"> +<title>token_scope</title> +<polygon fill="lightblue" stroke="transparent" points="528,-315.5 528,-338.5 648,-338.5 648,-315.5 528,-315.5"/> +<polygon fill="none" stroke="black" stroke-width="2" points="529,-316.5 529,-337.5 647,-337.5 647,-316.5 529,-316.5"/> +<text text-anchor="start" x="532" y="-323.3" font-family="Times,serif" font-size="14.00">TOKEN_SCOPE</text> +<polygon fill="none" stroke="black" points="528,-294.5 528,-315.5 648,-315.5 648,-294.5 528,-294.5"/> +<text text-anchor="start" x="561" y="-301.3" font-family="Times,serif" font-size="14.00">code_id</text> +<polygon fill="none" stroke="black" points="528,-273.5 528,-294.5 648,-294.5 648,-273.5 528,-273.5"/> +<text text-anchor="start" x="557.5" y="-280.3" font-family="Times,serif" font-size="14.00">scope_id</text> +</g> +<!-- token->token_scope --> +<g id="edge2" class="edge"> +<title>token:pk_code_id->token_scope:fk_code_id</title> +<path fill="none" stroke="black" d="M489.5,-491.5C570.54,-491.5 454.5,-320.92 517.83,-305.6"/> +<polygon fill="black" stroke="black" points="518.06,-305.57 528.48,-308.97 523.03,-305.04 528,-304.5 528,-304.5 528,-304.5 523.03,-305.04 527.52,-300.03 518.06,-305.57 518.06,-305.57"/> +</g> +<!-- profile --> +<g id="node2" class="node"> +<title>profile</title> +<polygon fill="lightblue" stroke="transparent" points="206.5,-355.5 206.5,-378.5 299.5,-378.5 299.5,-355.5 206.5,-355.5"/> +<polygon fill="none" stroke="black" stroke-width="2" points="207.5,-356.5 207.5,-377.5 298.5,-377.5 298.5,-356.5 207.5,-356.5"/> +<text text-anchor="start" x="219.5" y="-363.3" font-family="Times,serif" font-size="14.00">PROFILE</text> +<polygon fill="none" stroke="black" points="206.5,-334.5 206.5,-355.5 299.5,-355.5 299.5,-334.5 206.5,-334.5"/> +<text text-anchor="start" x="219.5" y="-341.3" font-family="Times,serif" font-size="14.00">profile_id</text> +<polygon fill="none" stroke="black" points="206.5,-313.5 206.5,-334.5 299.5,-334.5 299.5,-313.5 206.5,-313.5"/> +<text text-anchor="start" x="209.5" y="-320.3" font-family="Times,serif" font-size="14.00">identifier_id</text> +<polygon fill="none" stroke="black" points="206.5,-292.5 206.5,-313.5 299.5,-313.5 299.5,-292.5 206.5,-292.5"/> +<text text-anchor="start" x="229.5" y="-299.3" font-family="Times,serif" font-size="14.00">profile</text> +</g> +<!-- profile->token --> +<g id="edge1" class="edge"> +<title>profile:pk_profile_id->token:fk_profile_id</title> +<path fill="none" stroke="black" d="M300.5,-345.5C358.57,-345.5 306.81,-455.82 351.58,-469.18"/> +<polygon fill="black" stroke="black" points="351.59,-469.18 360.91,-474.96 356.54,-469.84 361.5,-470.5 361.5,-470.5 361.5,-470.5 356.54,-469.84 362.09,-466.04 351.59,-469.18 351.59,-469.18"/> +</g> +<!-- profile_scope --> +<g id="node6" class="node"> +<title>profile_scope</title> +<polygon fill="lightblue" stroke="transparent" points="359.5,-166.5 359.5,-189.5 492.5,-189.5 492.5,-166.5 359.5,-166.5"/> +<polygon fill="none" stroke="black" stroke-width="2" points="360.5,-167.5 360.5,-188.5 491.5,-188.5 491.5,-167.5 360.5,-167.5"/> +<text text-anchor="start" x="363.5" y="-174.3" font-family="Times,serif" font-size="14.00">PROFILE_SCOPE</text> +<polygon fill="none" stroke="black" points="359.5,-145.5 359.5,-166.5 492.5,-166.5 492.5,-145.5 359.5,-145.5"/> +<text text-anchor="start" x="392.5" y="-152.3" font-family="Times,serif" font-size="14.00">profile_id</text> +<polygon fill="none" stroke="black" points="359.5,-124.5 359.5,-145.5 492.5,-145.5 492.5,-124.5 359.5,-124.5"/> +<text text-anchor="start" x="395.5" y="-131.3" font-family="Times,serif" font-size="14.00">scope_id</text> +</g> +<!-- profile->profile_scope --> +<g id="edge5" class="edge"> +<title>profile:pk_profile_id->profile_scope:fk_profile_id</title> +<path fill="none" stroke="black" d="M300.5,-345.5C385.06,-345.5 280.42,-171.48 348.72,-156.52"/> +<polygon fill="black" stroke="black" points="349.05,-156.49 359.45,-159.98 354.02,-155.99 359,-155.5 359,-155.5 359,-155.5 354.02,-155.99 358.55,-151.02 349.05,-156.49 349.05,-156.49"/> +</g> +<!-- scope --> +<g id="node3" class="node"> +<title>scope</title> +<polygon fill="lightblue" stroke="transparent" points="182.5,-125.5 182.5,-148.5 323.5,-148.5 323.5,-125.5 182.5,-125.5"/> +<polygon fill="none" stroke="black" stroke-width="2" points="183.5,-126.5 183.5,-147.5 322.5,-147.5 322.5,-126.5 183.5,-126.5"/> +<text text-anchor="start" x="227" y="-133.3" font-family="Times,serif" font-size="14.00">SCOPE</text> +<polygon fill="none" stroke="black" points="182.5,-104.5 182.5,-125.5 323.5,-125.5 323.5,-104.5 182.5,-104.5"/> +<text text-anchor="start" x="222.5" y="-111.3" font-family="Times,serif" font-size="14.00">scope_id</text> +<polygon fill="none" stroke="black" points="182.5,-83.5 182.5,-104.5 323.5,-104.5 323.5,-83.5 182.5,-83.5"/> +<text text-anchor="start" x="232.5" y="-90.3" font-family="Times,serif" font-size="14.00">scope</text> +<polygon fill="none" stroke="black" points="182.5,-62.5 182.5,-83.5 323.5,-83.5 323.5,-62.5 182.5,-62.5"/> +<text text-anchor="start" x="212.5" y="-69.3" font-family="Times,serif" font-size="14.00">description</text> +<polygon fill="none" stroke="black" points="182.5,-41.5 182.5,-62.5 323.5,-62.5 323.5,-41.5 182.5,-41.5"/> +<text text-anchor="start" x="213.5" y="-48.3" font-family="Times,serif" font-size="14.00">application</text> +<polygon fill="none" stroke="black" points="182.5,-20.5 182.5,-41.5 323.5,-41.5 323.5,-20.5 182.5,-20.5"/> +<text text-anchor="start" x="204.5" y="-27.3" font-family="Times,serif" font-size="14.00">is_permanent</text> +<polygon fill="none" stroke="black" points="182.5,0.5 182.5,-20.5 323.5,-20.5 323.5,0.5 182.5,0.5"/> +<text text-anchor="start" x="185.5" y="-6.3" font-family="Times,serif" font-size="14.00">is_manually_added</text> +</g> +<!-- scope->token_scope --> +<g id="edge3" class="edge"> +<title>scope:pk_scope_id->token_scope:fk_scope_id</title> +<path fill="none" stroke="black" d="M323,-115.5C398.11,-115.5 433.59,-68.28 492,-115.5 548.48,-161.16 461,-271.95 518.03,-282.66"/> +<polygon fill="black" stroke="black" points="518.03,-282.66 527.62,-287.98 523.02,-283.08 528,-283.5 528,-283.5 528,-283.5 523.02,-283.08 528.38,-279.02 518.03,-282.66 518.03,-282.66"/> +</g> +<!-- scope->profile_scope --> +<g id="edge6" class="edge"> +<title>scope:pk_scope_id->profile_scope:fk_scope_id</title> +<path fill="none" stroke="black" d="M323,-115.5C336.99,-115.5 340.05,-126.87 349.09,-132.02"/> +<polygon fill="black" stroke="black" points="349.3,-132.07 357.91,-138.86 354.15,-133.28 359,-134.5 359,-134.5 359,-134.5 354.15,-133.28 360.09,-130.14 349.3,-132.07 349.3,-132.07"/> +</g> +<!-- authentication --> +<g id="node5" class="node"> +<title>authentication</title> +<polygon fill="lightblue" stroke="transparent" points="0,-333.5 0,-356.5 146,-356.5 146,-333.5 0,-333.5"/> +<polygon fill="none" stroke="black" stroke-width="2" points="1,-334.5 1,-355.5 145,-355.5 145,-334.5 1,-334.5"/> +<text text-anchor="start" x="4" y="-341.3" font-family="Times,serif" font-size="14.00">AUTHENTICATION</text> +<polygon fill="none" stroke="black" points="0,-312.5 0,-333.5 146,-333.5 146,-312.5 0,-312.5"/> +<text text-anchor="start" x="29.5" y="-319.3" font-family="Times,serif" font-size="14.00">identifier_id</text> +<polygon fill="none" stroke="black" points="0,-291.5 0,-312.5 146,-312.5 146,-291.5 0,-291.5"/> +<text text-anchor="start" x="45.5" y="-298.3" font-family="Times,serif" font-size="14.00">created</text> +<polygon fill="none" stroke="black" points="0,-270.5 0,-291.5 146,-291.5 146,-270.5 0,-270.5"/> +<text text-anchor="start" x="6.5" y="-277.3" font-family="Times,serif" font-size="14.00">last_authenticated</text> +<polygon fill="none" stroke="black" points="0,-249.5 0,-270.5 146,-270.5 146,-249.5 0,-249.5"/> +<text text-anchor="start" x="39.5" y="-256.3" font-family="Times,serif" font-size="14.00">identifier</text> +<polygon fill="none" stroke="black" points="0,-228.5 0,-249.5 146,-249.5 146,-228.5 0,-228.5"/> +<text text-anchor="start" x="36.5" y="-235.3" font-family="Times,serif" font-size="14.00">credential</text> +</g> +<!-- authentication->profile --> +<g id="edge4" class="edge"> +<title>authentication:pk_identifier_id->profile:fk_identifier_id</title> +<path fill="none" stroke="black" d="M146,-323.5C168.73,-323.5 176.8,-323.5 195.41,-323.5"/> +<polygon fill="black" stroke="black" points="195.5,-323.5 205.5,-328 200.5,-323.5 205.5,-323.5 205.5,-323.5 205.5,-323.5 200.5,-323.5 205.5,-319 195.5,-323.5 195.5,-323.5"/> +</g> +<!-- resource --> +<g id="node7" class="node"> +<title>resource</title> +<polygon fill="lightblue" stroke="transparent" points="26,-458.5 26,-481.5 120,-481.5 120,-458.5 26,-458.5"/> +<polygon fill="none" stroke="black" stroke-width="2" points="27,-459.5 27,-480.5 119,-480.5 119,-459.5 27,-459.5"/> +<text text-anchor="start" x="30" y="-466.3" font-family="Times,serif" font-size="14.00">RESOURCE</text> +<polygon fill="none" stroke="black" points="26,-437.5 26,-458.5 120,-458.5 120,-437.5 26,-437.5"/> +<text text-anchor="start" x="31.5" y="-444.3" font-family="Times,serif" font-size="14.00">resource_id</text> +<polygon fill="none" stroke="black" points="26,-416.5 26,-437.5 120,-437.5 120,-416.5 26,-416.5"/> +<text text-anchor="start" x="32.5" y="-423.3" font-family="Times,serif" font-size="14.00">description</text> +<polygon fill="none" stroke="black" points="26,-395.5 26,-416.5 120,-416.5 120,-395.5 26,-395.5"/> +<text text-anchor="start" x="45.5" y="-402.3" font-family="Times,serif" font-size="14.00">created</text> +<polygon fill="none" stroke="black" points="26,-374.5 26,-395.5 120,-395.5 120,-374.5 26,-374.5"/> +<text text-anchor="start" x="50.5" y="-381.3" font-family="Times,serif" font-size="14.00">secret</text> +</g> +<!-- almanac --> +<g id="node8" class="node"> +<title>almanac</title> +<polygon fill="lightblue" stroke="transparent" points="31,-541.5 31,-564.5 115,-564.5 115,-541.5 31,-541.5"/> +<polygon fill="none" stroke="black" stroke-width="2" points="32,-542.5 32,-563.5 114,-563.5 114,-542.5 32,-542.5"/> +<text text-anchor="start" x="35" y="-549.3" font-family="Times,serif" font-size="14.00">ALMANAC</text> +<polygon fill="none" stroke="black" points="31,-520.5 31,-541.5 115,-541.5 115,-520.5 31,-520.5"/> +<text text-anchor="start" x="53" y="-527.3" font-family="Times,serif" font-size="14.00">event</text> +<polygon fill="none" stroke="black" points="31,-499.5 31,-520.5 115,-520.5 115,-499.5 31,-499.5"/> +<text text-anchor="start" x="51.5" y="-506.3" font-family="Times,serif" font-size="14.00">epoch</text> +</g> +</g> +</svg> diff --git a/documentation/media/ticket-page.png b/documentation/media/ticket-page.png new file mode 100644 index 0000000000000000000000000000000000000000..5865180edfe87233df5fba508f79236a97e51343 GIT binary patch literal 230324 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 literal 0 HcmV?d00001 diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..79c2b74 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,9787 @@ +{ + "name": "@squeep/indie-auther", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "@squeep/indie-auther", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@squeep/amqp-helper": "git+https://git.squeep.com/squeep-amqp-helper#v1.0.0", + "@squeep/api-dingus": "git+https://git.squeep.com/squeep-api-dingus/#v1.2.9", + "@squeep/authentication-module": "git+https://git.squeep.com/squeep-authentication-module/#v1.2.12", + "@squeep/chores": "git+https://git.squeep.com/squeep-chores/#v1.0.0", + "@squeep/html-template-helper": "git+https://git.squeep.com/squeep-html-template-helper#v1.4.0", + "@squeep/indieauth-helper": "git+https://git.squeep.com/squeep-indieauth-helper/#v1.2.2", + "@squeep/logger-json-console": "git+https://git.squeep.com/squeep-logger-json-console#v1.0.2", + "@squeep/mystery-box": "^1.2.0", + "@squeep/resource-authentication-module": "git+https://git.squeep.com/squeep-resource-authentication-module#v1.0.0", + "@squeep/roman": "^1.0.0", + "@squeep/web-linking": "^1.0.7", + "better-sqlite3": "^8.0.1", + "pg-promise": "^10.15.4", + "uuid": "^9.0.0" + }, + "devDependencies": { + "@squeep/test-helper": "git+https://git.squeep.com/squeep-test-helper#v1.0.0", + "eslint": "^8.30.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-security": "^1.5.0", + "eslint-plugin-sonarjs": "^0.17.0", + "html-minifier-lint": "^2.0.0", + "mocha": "^10.2.0", + "mocha-steps": "^1.3.0", + "nyc": "^15.1.0", + "pre-commit": "^1.2.2", + "sinon": "^15.0.1" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/@acuminous/bitsyntax": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@acuminous/bitsyntax/-/bitsyntax-0.1.2.tgz", + "integrity": "sha512-29lUK80d1muEQqiUsSo+3A0yP6CdspgC95EnKBMi22Xlwt79i/En4Vr67+cXhU+cZjbti3TgGGC5wy1stIywVQ==", + "dependencies": { + "buffer-more-ints": "~1.0.0", + "debug": "^4.3.4", + "safe-buffer": "~5.1.2" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.20.10", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz", + "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.7.tgz", + "integrity": "sha512-t1ZjCluspe5DW24bn2Rr1CDb2v9rn/hROtg9a2tmd0+QYf4bsloYfLQzjG4qHPNMhWtKdGC33R5AxGR2Af2cBw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.20.7", + "@babel/helpers": "^7.20.7", + "@babel/parser": "^7.20.7", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", + "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "dev": true, + "dependencies": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", + "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.10", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz", + "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz", + "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.20.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.10.tgz", + "integrity": "sha512-oSf1juCgymrSez8NI4A2sr4+uB/mFd9MXplYGPEBnfAuWmmyeVcHa6xLPiaRBcXkcb/28bgxmQLTVwFKE1yfsg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.0.tgz", + "integrity": "sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz", + "integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@phc/format": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@phc/format/-/format-1.0.0.tgz", + "integrity": "sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==", + "optional": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^2.0.0" + } + }, + "node_modules/@sinonjs/samsam": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-7.0.1.tgz", + "integrity": "sha512-zsAk2Jkiq89mhZovB2LLOdTCxJF4hqqTToGP0ASWlhp4I1hqOjcfmZGafXntCN7MDC6yySH0mFHrYtHceOeLmw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^2.0.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "node_modules/@sinonjs/text-encoding": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", + "dev": true + }, + "node_modules/@squeep/amqp-helper": { + "version": "1.0.0", + "resolved": "git+https://git.squeep.com/squeep-amqp-helper#174280d3f44ba13dac0b26d42d968189a4f4fa93", + "license": "ISC", + "dependencies": { + "amqplib": "^0.10.3" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@squeep/api-dingus": { + "version": "1.2.9", + "resolved": "git+https://git.squeep.com/squeep-api-dingus/#3b15b5ff792fc5d61be8337989058c297460cd99", + "license": "ISC", + "dependencies": { + "mime-db": "^1.52.0", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@squeep/authentication-module": { + "version": "1.2.12", + "resolved": "git+https://git.squeep.com/squeep-authentication-module/#9a7d5352698481c0857ba8827e31c7cb97625133", + "license": "ISC", + "dependencies": { + "@squeep/api-dingus": "git+https://git.squeep.com/squeep-api-dingus/#v1.2.9", + "@squeep/html-template-helper": "git+https://git.squeep.com/squeep-html-template-helper#v1.4.0", + "@squeep/indieauth-helper": "git+https://git.squeep.com/squeep-indieauth-helper/#v1.1.7", + "@squeep/mystery-box": "^1.2.0" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "argon2": "^0.30.1", + "node-linux-pam": "^0.2.1" + } + }, + "node_modules/@squeep/base64url": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@squeep/base64url/-/base64url-1.0.5.tgz", + "integrity": "sha512-J1UBXYQ4tBuHGnFfg0MdmxCP3oEti7jJWK/qBsg520d8tZd10sL6TXiMDGdBiH9GD3OtlfSYf6wWIN4QfdW21A==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@squeep/chores": { + "version": "1.0.0", + "resolved": "git+https://git.squeep.com/squeep-chores/#d98a3c114eb33bd68477c0ca750e6f82b4d02964", + "license": "ISC" + }, + "node_modules/@squeep/html-template-helper": { + "version": "1.4.0", + "resolved": "git+https://git.squeep.com/squeep-html-template-helper#100046316a87631fb8814f80b35647709e6c7319", + "license": "ISC", + "dependencies": { + "@squeep/lazy-property": "^1.1.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@squeep/indieauth-helper": { + "version": "1.2.2", + "resolved": "git+https://git.squeep.com/squeep-indieauth-helper/#9d77dc15cee59356a4a4f7935db6a450b04a083c", + "license": "ISC", + "dependencies": { + "@squeep/base64url": "^1.0.5", + "@squeep/web-linking": "^1.0.7", + "axios": "^1.2.1", + "iconv": "^3.0.1", + "ip-address": "^8.1.0", + "microformats-parser": "^1.4.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@squeep/lazy-property": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@squeep/lazy-property/-/lazy-property-1.1.2.tgz", + "integrity": "sha512-wRdR4IOqWXoDMArx0HPo5MtM2Wk5wemAULbZ6PabVw1ylSQekkzKfoAUuupxsKuzjcRPjZvbpGDv+i04hBMnQw==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@squeep/logger-json-console": { + "version": "1.0.2", + "resolved": "git+https://git.squeep.com/squeep-logger-json-console#dbff0fa5f018f7a302f73250e55f761c0ccf24b1", + "license": "ISC", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@squeep/mystery-box": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@squeep/mystery-box/-/mystery-box-1.2.0.tgz", + "integrity": "sha512-HYxsF+mv2yrOsgQO2am2i07SRgp5L4o0CySmlM3rIsVWJXlywVPGk9xZFpKtk49BXCGxopWfvtPhpM8U0roaRg==", + "dependencies": { + "@squeep/base64url": "^1.0.5" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@squeep/resource-authentication-module": { + "version": "1.0.0", + "resolved": "git+https://git.squeep.com/squeep-resource-authentication-module#69a2f5e7d73dd3f58e07b652c306daa8b253245d", + "license": "ISC", + "dependencies": { + "@squeep/api-dingus": "git+https://git.squeep.com/squeep-api-dingus/#v1.2.8", + "@squeep/base64url": "^1.0.5", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@squeep/roman": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@squeep/roman/-/roman-1.0.0.tgz", + "integrity": "sha512-D02jDw/we8tc6QiCPor7tWVviY8MLITyp/egqp3XqrrKtsFMYdguAhaFKUmIBu1ZL1uPKgoLBOy8hIptmh8cWA==" + }, + "node_modules/@squeep/test-helper": { + "version": "1.0.0", + "resolved": "git+https://git.squeep.com/squeep-test-helper#7a5a384abb99757b53c8898c508023f0ba9e94b1", + "dev": true, + "license": "ISC", + "dependencies": { + "eslint": "^8.23.1", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-security": "^1.5.0", + "eslint-plugin-sonarjs": "^0.15.0", + "mocha": "^10.0.0", + "nyc": "^15.1.0", + "pre-commit": "^1.2.2", + "sinon": "^14.0.0" + } + }, + "node_modules/@squeep/test-helper/node_modules/@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@squeep/test-helper/node_modules/@sinonjs/fake-timers/node_modules/@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@squeep/test-helper/node_modules/eslint-plugin-sonarjs": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.15.0.tgz", + "integrity": "sha512-LuxHdAe6VqSbi1phsUvNjbmXLuvlobmryQJJNyQYbdubCfz6K8tmgoqNiJPnz0pP2AbYDbtuPm0ajOMgMrC+dQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@squeep/test-helper/node_modules/sinon": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-14.0.2.tgz", + "integrity": "sha512-PDpV0ZI3ZCS3pEqx0vpNp6kzPhHrLx72wA0G+ZLaaJjLIYeE0n8INlgaohKuGy7hP0as5tbUd23QWu5U233t+w==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^2.0.0", + "@sinonjs/fake-timers": "^9.1.2", + "@sinonjs/samsam": "^7.0.1", + "diff": "^5.0.0", + "nise": "^5.1.2", + "supports-color": "^7.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, + "node_modules/@squeep/web-linking": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@squeep/web-linking/-/web-linking-1.0.7.tgz", + "integrity": "sha512-9d3QijrWc/WNE7p/K7NLUHbmPf92CURRqfzDLV0cGqYNA4QWAPfzwC8hxWpdUkUnep3KakvLKK60l0kEBMM3ag==", + "engines": { + "node": ">=14.0" + } + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "optional": true + }, + "node_modules/acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/amqplib": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.10.3.tgz", + "integrity": "sha512-UHmuSa7n8vVW/a5HGh2nFPqAEr8+cD4dEZ6u9GjP91nHfr1a54RyAKyra7Sb5NH7NBKOUlyQSMXIp0qAixKexw==", + "dependencies": { + "@acuminous/bitsyntax": "^0.1.2", + "buffer-more-ints": "~1.0.0", + "readable-stream": "1.x >=1.1.9", + "url-parse": "~1.5.10" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "devOptional": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "dependencies": { + "default-require-extensions": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "optional": true + }, + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", + "dev": true + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/are-we-there-yet/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "optional": true + }, + "node_modules/are-we-there-yet/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "optional": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/argon2": { + "version": "0.30.2", + "resolved": "https://registry.npmjs.org/argon2/-/argon2-0.30.2.tgz", + "integrity": "sha512-RBbXTUsrJUQH259/72CCJxQa0hV961pV4PyZ7R1czGkArSsQP4DToCS2axmNfHywXaBNEMPWMW6rM82EArulYA==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.10", + "@phc/format": "^1.0.0", + "node-addon-api": "^5.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/assert-options": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/assert-options/-/assert-options-0.8.0.tgz", + "integrity": "sha512-qSELrEaEz4sGwTs4Qh+swQkjiHAysC4rot21+jzXU86dJzNG+FDqBzyS3ohSoTRf4ZLA3FSwxQdiuNl5NXUtvA==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.1.tgz", + "integrity": "sha512-I88cFiGu9ryt/tfVEi4kX2SITsvDddTajXTOFmt2uK1ZVA8LytjtdeyefdQWEf5PU8w+4SSJDoYnggflB5tW4A==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "devOptional": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/better-sqlite3": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-8.0.1.tgz", + "integrity": "sha512-JhTZjpyapA1icCEjIZB4TSSgkGdFgpWZA2Wszg7Cf4JwJwKQmbvuNnJBeR+EYG/Z29OXvR4G//Rbg31BW/Z7Yg==", + "hasInstallScript": true, + "dependencies": { + "bindings": "^1.5.0", + "prebuild-install": "^7.1.0" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bl/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bl/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "devOptional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/buffer-more-ints": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", + "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==" + }, + "node_modules/buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "dependencies": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", + "dev": true, + "dependencies": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "devOptional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001441", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001441.tgz", + "integrity": "sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "optional": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/clean-css": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", + "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", + "dev": true, + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "devOptional": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "devOptional": true + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "optional": true, + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "dev": true + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "devOptional": true + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "optional": true + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/default-require-extensions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", + "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", + "dev": true, + "dependencies": { + "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "optional": true + }, + "node_modules/detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "devOptional": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.30.0.tgz", + "integrity": "sha512-MGADB39QqYuzEGov+F/qb18r4i7DohCDOfatHaxI2iGlPuC65bwG2gxgO+7DkyL38dRFaRH7RaRAgU6JKL9rMQ==", + "dev": true, + "dependencies": { + "@eslint/eslintrc": "^1.4.0", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "node_modules/eslint-plugin-es/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-plugin-es/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "dependencies": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" + } + }, + "node_modules/eslint-plugin-node/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-plugin-node/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-node/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-promise": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", + "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-security": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-security/-/eslint-plugin-security-1.5.0.tgz", + "integrity": "sha512-hAFVwLZ/UeXrlyVD2TDarv/x00CoFVpaY0IUZhKjPjiFxqkuQVixsK4f2rxngeQOqSxi6OUjzJM/jMwKEVjJ8g==", + "dev": true, + "dependencies": { + "safe-regex": "^2.1.1" + } + }, + "node_modules/eslint-plugin-sonarjs": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.17.0.tgz", + "integrity": "sha512-jtGtxI49UbJJeJj7CVRLI3+LLH+y+hkR3GOOwM7vBbci9DEFIRGCWvEd2BJScrzltZ6D6iubukTAfc9cyG7sdw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/espree": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "dev": true, + "dependencies": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz", + "integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "optional": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs-minipass/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "devOptional": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "optional": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "devOptional": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "devOptional": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "optional": true + }, + "node_modules/hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasha/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/html-minifier": { + "version": "3.5.21", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", + "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", + "dev": true, + "dependencies": { + "camel-case": "3.0.x", + "clean-css": "4.2.x", + "commander": "2.17.x", + "he": "1.2.x", + "param-case": "2.1.x", + "relateurl": "0.2.x", + "uglify-js": "3.4.x" + }, + "bin": { + "html-minifier": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/html-minifier-lint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/html-minifier-lint/-/html-minifier-lint-2.0.0.tgz", + "integrity": "sha512-halWZUg/us7Y16irVM90DTdyAUP3ksFthWfFPJTG1jpBaYYyGHt9azTW9H++hZ8LWRArzQm9oIcrfM/o/CO+4A==", + "dev": true, + "dependencies": { + "html-minifier": "3.x" + }, + "bin": { + "html-minifier-lint": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "optional": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/iconv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/iconv/-/iconv-3.0.1.tgz", + "integrity": "sha512-lJnFLxVc0d82R7GfU7a9RujKVUQ3Eee19tPKWZWBJtAEGRHVEyFzCtbNl3GPKuDnHBBRT4/nDS4Ru9AIDT72qA==", + "hasInstallScript": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "devOptional": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/ip-address": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-8.1.0.tgz", + "integrity": "sha512-Wz91gZKpNKoXtqvY8ScarKYwhXoK4r/b5QuT+uywe/azv0/nUCo7Bh0IRRI7F9DHR06kJNWtzMGLIbXavngbKA==", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "1.1.2" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "dependencies": { + "append-transform": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-processinfo": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", + "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", + "dev": true, + "dependencies": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.3", + "istanbul-lib-coverage": "^3.2.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/js-sdsl": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", + "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==" + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", + "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", + "dev": true + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "devOptional": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "devOptional": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/microformats-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/microformats-parser/-/microformats-parser-1.4.1.tgz", + "integrity": "sha512-BSg9Y/Aik8hvvme/fkxnXMRvTKuVwOeTapeZdaPQ+92DEubyM31iMtwbgFZ1383om643UvfYY5G23E9s1FY2KQ==", + "dependencies": { + "parse5": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "devOptional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.0.0.tgz", + "integrity": "sha512-g2Uuh2jEKoht+zvO6vJqXmYpflPqzRBT+Th2h01DKh5z7wbY/AZ2gCQ78cP70YoHPyFdY30YBV5WxgLOEwOykw==", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "optional": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "optional": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, + "node_modules/mocha": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", + "dev": true, + "dependencies": { + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha-steps": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/mocha-steps/-/mocha-steps-1.3.0.tgz", + "integrity": "sha512-KZvpMJTqzLZw3mOb+EEuYi4YZS41C9iTnb7skVFRxHjUd1OYbl64tCMSmpdIRM9LnwIrSOaRfPtNpF5msgv6Eg==", + "dev": true + }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/nanoid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/nise": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", + "integrity": "sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^2.0.0", + "@sinonjs/fake-timers": "^10.0.2", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + } + }, + "node_modules/no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "dev": true, + "dependencies": { + "lower-case": "^1.1.1" + } + }, + "node_modules/node-abi": { + "version": "3.30.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.30.0.tgz", + "integrity": "sha512-qWO5l3SCqbwQavymOmtTVuCWZE23++S+rxyoHjXqUmPyzRcaoI4lA2gO55/drddGnedAyjA7sk76SfQ5lfUMnw==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.0.0.tgz", + "integrity": "sha512-CvkDw2OEnme7ybCykJpVcKH+uAOLV2qLqiyla128dN9TkEWfrYmxG6C2boDe5KcNQqZF3orkqzGgOMvZ/JNekA==", + "optional": true + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "optional": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-linux-pam": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-linux-pam/-/node-linux-pam-0.2.1.tgz", + "integrity": "sha512-OeMZW0Bs1bffsvXI/bJQbU0rkiWTOo0ceT6+mrbU84TJ33vAKykIZrLI+ApfRqkBQW5jzW5rJ7x+NSyToafqig==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "@mapbox/node-pre-gyp": "1.0.5", + "bindings": "1.5.0", + "node-addon-api": "3.1.0", + "string-template": "1.0.0", + "yargs": "15.4.1" + }, + "bin": { + "nlp": "cli.js" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/node-linux-pam/node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz", + "integrity": "sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA==", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.1", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "rimraf": "^3.0.2", + "semver": "^7.3.4", + "tar": "^6.1.0" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/node-linux-pam/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-linux-pam/node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "optional": true + }, + "node_modules/node-linux-pam/node_modules/are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/node-linux-pam/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "optional": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/node-linux-pam/node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-linux-pam/node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "optional": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-linux-pam/node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/node-linux-pam/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "optional": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-linux-pam/node_modules/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", + "optional": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/node-linux-pam/node_modules/gauge/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "optional": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-linux-pam/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "optional": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-linux-pam/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "optional": true + }, + "node_modules/node-linux-pam/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "optional": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-linux-pam/node_modules/node-addon-api": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.1.0.tgz", + "integrity": "sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw==", + "optional": true + }, + "node_modules/node-linux-pam/node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "optional": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/node-linux-pam/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "optional": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/node-linux-pam/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "optional": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-linux-pam/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/node-linux-pam/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/node-linux-pam/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "optional": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-linux-pam/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "optional": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-linux-pam/node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-linux-pam/node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "optional": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-linux-pam/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "optional": true + }, + "node_modules/node-linux-pam/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "optional": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-linux-pam/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "optional": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "dependencies": { + "process-on-spawn": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-releases": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", + "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==", + "dev": true + }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "optional": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "optional": true, + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, + "dependencies": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "bin": { + "nyc": "bin/nyc.js" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/nyc/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/nyc/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nyc/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/nyc/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/os-shim": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz", + "integrity": "sha512-jd0cvB8qQ5uVt0lvCIexBaROw1KyKm5sbulg2fWOHjETisuCzWyt+eTZKEMs8v6HwzoGs8xik26jg7eCM6pS+A==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "devOptional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, + "node_modules/param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==", + "dev": true, + "dependencies": { + "no-case": "^2.2.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/pg": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.8.0.tgz", + "integrity": "sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw==", + "dependencies": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "^2.5.0", + "pg-pool": "^3.5.2", + "pg-protocol": "^1.5.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-connection-string": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-minify": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/pg-minify/-/pg-minify-1.6.2.tgz", + "integrity": "sha512-1KdmFGGTP6jplJoI8MfvRlfvMiyBivMRP7/ffh4a11RUFJ7kC2J0ZHlipoKiH/1hz+DVgceon9U2qbaHpPeyPg==", + "engines": { + "node": ">=8.0" + } + }, + "node_modules/pg-pool": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.2.tgz", + "integrity": "sha512-His3Fh17Z4eg7oANLob6ZvH8xIVen3phEZh2QuyrIl4dQSDVEabNducv6ysROKpDNPSD+12tONZVWfSgMvDD9w==", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-promise": { + "version": "10.15.4", + "resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-10.15.4.tgz", + "integrity": "sha512-BKlHCMCdNUmF6gagVbehRWSEiVcZzPVltEx14OJExR9Iz9/1R6KETDWLLGv2l6yRqYFnEZZy1VDjRhArzeIGrw==", + "dependencies": { + "assert-options": "0.8.0", + "pg": "8.8.0", + "pg-minify": "1.6.2", + "spex": "3.2.0" + }, + "engines": { + "node": ">=12.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz", + "integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ==" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pre-commit": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/pre-commit/-/pre-commit-1.2.2.tgz", + "integrity": "sha512-qokTiqxD6GjODy5ETAIgzsRgnBWWQHQH2ghy86PU7mIn/wuWeTwF3otyNQZxWBwVn8XNr8Tdzj/QfUXpH+gRZA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "cross-spawn": "^5.0.1", + "spawn-sync": "^1.0.15", + "which": "1.2.x" + } + }, + "node_modules/pre-commit/node_modules/cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", + "dev": true, + "dependencies": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "node_modules/pre-commit/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/pre-commit/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pre-commit/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pre-commit/node_modules/which": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", + "integrity": "sha512-16uPglFkRPzgiUXYMi1Jf8Z5EzN1iB4V0ZtMXcHZnwsBtQhhHeCqoWw7tsUY42hJGNDWtUsVLTjakIa5BgAxCw==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/pre-commit/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "dev": true + }, + "node_modules/prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "devOptional": true + }, + "node_modules/process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "dependencies": { + "fromentries": "^1.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regexp-tree": { + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz", + "integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==", + "dev": true, + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", + "dev": true, + "dependencies": { + "es6-error": "^4.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "devOptional": true + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "devOptional": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dev": true, + "dependencies": { + "regexp-tree": "~0.1.1" + } + }, + "node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "devOptional": true + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "devOptional": true + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/sinon": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.0.1.tgz", + "integrity": "sha512-PZXKc08f/wcA/BMRGBze2Wmw50CWPiAH3E21EOi4B49vJ616vW4DQh4fQrqsYox2aNR/N3kCqLuB0PwwOucQrg==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^2.0.0", + "@sinonjs/fake-timers": "10.0.2", + "@sinonjs/samsam": "^7.0.1", + "diff": "^5.0.0", + "nise": "^5.1.2", + "supports-color": "^7.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spawn-sync": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz", + "integrity": "sha512-9DWBgrgYZzNghseho0JOuh+5fg9u6QWhAWa51QC7+U5rCheZ/j1DrEZnyE0RBBRqZ9uEXGPgSSM0nky6burpVw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "concat-stream": "^1.4.7", + "os-shim": "^0.1.2" + } + }, + "node_modules/spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "dependencies": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/spex": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spex/-/spex-3.2.0.tgz", + "integrity": "sha512-9srjJM7NaymrpwMHvSmpDeIK5GoRMX/Tq0E8aOlDPS54dDnDUIp30DrP9SphMPEETDLzEM9+4qo+KipmbtPecg==", + "engines": { + "node": ">=4.5" + } + }, + "node_modules/split2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz", + "integrity": "sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" + }, + "node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, + "node_modules/string-template": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-1.0.0.tgz", + "integrity": "sha512-SLqR3GBUXuoPP5MmYtD7ompvXiG87QjT6lzOszyXjTM86Uu7At7vNnt2xgyTLq5o9T4IxTYFyGxcULqpsmsfdg==", + "optional": true + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "devOptional": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "devOptional": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tar": { + "version": "6.1.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz", + "integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==", + "optional": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^4.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/tar-stream/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/tar-stream/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "optional": true + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/uglify-js": { + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", + "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==", + "dev": true, + "dependencies": { + "commander": "~2.19.0", + "source-map": "~0.6.1" + }, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/uglify-js/node_modules/commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "dev": true + }, + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==", + "dev": true + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "optional": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "optional": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "devOptional": true + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "optional": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workerpool": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@acuminous/bitsyntax": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@acuminous/bitsyntax/-/bitsyntax-0.1.2.tgz", + "integrity": "sha512-29lUK80d1muEQqiUsSo+3A0yP6CdspgC95EnKBMi22Xlwt79i/En4Vr67+cXhU+cZjbti3TgGGC5wy1stIywVQ==", + "requires": { + "buffer-more-ints": "~1.0.0", + "debug": "^4.3.4", + "safe-buffer": "~5.1.2" + } + }, + "@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dev": true, + "requires": { + "@babel/highlight": "^7.18.6" + } + }, + "@babel/compat-data": { + "version": "7.20.10", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz", + "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==", + "dev": true + }, + "@babel/core": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.7.tgz", + "integrity": "sha512-t1ZjCluspe5DW24bn2Rr1CDb2v9rn/hROtg9a2tmd0+QYf4bsloYfLQzjG4qHPNMhWtKdGC33R5AxGR2Af2cBw==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.20.7", + "@babel/helpers": "^7.20.7", + "@babel/parser": "^7.20.7", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", + "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", + "dev": true, + "requires": { + "@babel/types": "^7.20.7", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } + } + }, + "@babel/helper-compilation-targets": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "dev": true + }, + "@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "dev": true, + "requires": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-transforms": { + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", + "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.10", + "@babel/types": "^7.20.7" + } + }, + "@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "dev": true, + "requires": { + "@babel/types": "^7.20.2" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "dev": true + }, + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "dev": true + }, + "@babel/helpers": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz", + "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==", + "dev": true, + "requires": { + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7" + } + }, + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz", + "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==", + "dev": true + }, + "@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + } + }, + "@babel/traverse": { + "version": "7.20.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.10.tgz", + "integrity": "sha512-oSf1juCgymrSez8NI4A2sr4+uB/mFd9MXplYGPEBnfAuWmmyeVcHa6xLPiaRBcXkcb/28bgxmQLTVwFKE1yfsg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, + "@eslint/eslintrc": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.0.tgz", + "integrity": "sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + } + }, + "@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "@mapbox/node-pre-gyp": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz", + "integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==", + "optional": true, + "requires": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@phc/format": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@phc/format/-/format-1.0.0.tgz", + "integrity": "sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==", + "optional": true + }, + "@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^2.0.0" + } + }, + "@sinonjs/samsam": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-7.0.1.tgz", + "integrity": "sha512-zsAk2Jkiq89mhZovB2LLOdTCxJF4hqqTToGP0ASWlhp4I1hqOjcfmZGafXntCN7MDC6yySH0mFHrYtHceOeLmw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^2.0.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", + "dev": true + }, + "@squeep/amqp-helper": { + "version": "git+https://git.squeep.com/squeep-amqp-helper#174280d3f44ba13dac0b26d42d968189a4f4fa93", + "from": "@squeep/amqp-helper@git+https://git.squeep.com/squeep-amqp-helper#v1.0.0", + "requires": { + "amqplib": "^0.10.3" + } + }, + "@squeep/api-dingus": { + "version": "git+https://git.squeep.com/squeep-api-dingus/#3b15b5ff792fc5d61be8337989058c297460cd99", + "from": "@squeep/api-dingus@git+https://git.squeep.com/squeep-api-dingus/#v1.2.9", + "requires": { + "mime-db": "^1.52.0", + "uuid": "^9.0.0" + } + }, + "@squeep/authentication-module": { + "version": "git+https://git.squeep.com/squeep-authentication-module/#9a7d5352698481c0857ba8827e31c7cb97625133", + "from": "@squeep/authentication-module@git+https://git.squeep.com/squeep-authentication-module/#v1.2.12", + "requires": { + "@squeep/api-dingus": "git+https://git.squeep.com/squeep-api-dingus/#v1.2.9", + "@squeep/html-template-helper": "git+https://git.squeep.com/squeep-html-template-helper#v1.4.0", + "@squeep/indieauth-helper": "git+https://git.squeep.com/squeep-indieauth-helper/#v1.1.7", + "@squeep/mystery-box": "^1.2.0", + "argon2": "^0.30.1", + "node-linux-pam": "^0.2.1" + } + }, + "@squeep/base64url": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@squeep/base64url/-/base64url-1.0.5.tgz", + "integrity": "sha512-J1UBXYQ4tBuHGnFfg0MdmxCP3oEti7jJWK/qBsg520d8tZd10sL6TXiMDGdBiH9GD3OtlfSYf6wWIN4QfdW21A==" + }, + "@squeep/chores": { + "version": "git+https://git.squeep.com/squeep-chores/#d98a3c114eb33bd68477c0ca750e6f82b4d02964", + "from": "@squeep/chores@git+https://git.squeep.com/squeep-chores/#v1.0.0" + }, + "@squeep/html-template-helper": { + "version": "git+https://git.squeep.com/squeep-html-template-helper#100046316a87631fb8814f80b35647709e6c7319", + "from": "@squeep/html-template-helper@git+https://git.squeep.com/squeep-html-template-helper#v1.4.0", + "requires": { + "@squeep/lazy-property": "^1.1.2" + } + }, + "@squeep/indieauth-helper": { + "version": "git+https://git.squeep.com/squeep-indieauth-helper/#9d77dc15cee59356a4a4f7935db6a450b04a083c", + "from": "@squeep/indieauth-helper@git+https://git.squeep.com/squeep-indieauth-helper/#v1.2.2", + "requires": { + "@squeep/base64url": "^1.0.5", + "@squeep/web-linking": "^1.0.7", + "axios": "^1.2.1", + "iconv": "^3.0.1", + "ip-address": "^8.1.0", + "microformats-parser": "^1.4.1" + } + }, + "@squeep/lazy-property": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@squeep/lazy-property/-/lazy-property-1.1.2.tgz", + "integrity": "sha512-wRdR4IOqWXoDMArx0HPo5MtM2Wk5wemAULbZ6PabVw1ylSQekkzKfoAUuupxsKuzjcRPjZvbpGDv+i04hBMnQw==" + }, + "@squeep/logger-json-console": { + "version": "git+https://git.squeep.com/squeep-logger-json-console#dbff0fa5f018f7a302f73250e55f761c0ccf24b1", + "from": "@squeep/logger-json-console@git+https://git.squeep.com/squeep-logger-json-console#v1.0.2" + }, + "@squeep/mystery-box": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@squeep/mystery-box/-/mystery-box-1.2.0.tgz", + "integrity": "sha512-HYxsF+mv2yrOsgQO2am2i07SRgp5L4o0CySmlM3rIsVWJXlywVPGk9xZFpKtk49BXCGxopWfvtPhpM8U0roaRg==", + "requires": { + "@squeep/base64url": "^1.0.5" + } + }, + "@squeep/resource-authentication-module": { + "version": "git+https://git.squeep.com/squeep-resource-authentication-module#69a2f5e7d73dd3f58e07b652c306daa8b253245d", + "from": "@squeep/resource-authentication-module@git+https://git.squeep.com/squeep-resource-authentication-module#v1.0.0", + "requires": { + "@squeep/api-dingus": "git+https://git.squeep.com/squeep-api-dingus/#v1.2.8", + "@squeep/base64url": "^1.0.5", + "uuid": "^9.0.0" + } + }, + "@squeep/roman": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@squeep/roman/-/roman-1.0.0.tgz", + "integrity": "sha512-D02jDw/we8tc6QiCPor7tWVviY8MLITyp/egqp3XqrrKtsFMYdguAhaFKUmIBu1ZL1uPKgoLBOy8hIptmh8cWA==" + }, + "@squeep/test-helper": { + "version": "git+https://git.squeep.com/squeep-test-helper#7a5a384abb99757b53c8898c508023f0ba9e94b1", + "dev": true, + "from": "@squeep/test-helper@git+https://git.squeep.com/squeep-test-helper#v1.0.0", + "requires": { + "eslint": "^8.23.1", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-security": "^1.5.0", + "eslint-plugin-sonarjs": "^0.15.0", + "mocha": "^10.0.0", + "nyc": "^15.1.0", + "pre-commit": "^1.2.2", + "sinon": "^14.0.0" + }, + "dependencies": { + "@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + }, + "dependencies": { + "@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + } + } + }, + "eslint-plugin-sonarjs": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.15.0.tgz", + "integrity": "sha512-LuxHdAe6VqSbi1phsUvNjbmXLuvlobmryQJJNyQYbdubCfz6K8tmgoqNiJPnz0pP2AbYDbtuPm0ajOMgMrC+dQ==", + "dev": true, + "requires": {} + }, + "sinon": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-14.0.2.tgz", + "integrity": "sha512-PDpV0ZI3ZCS3pEqx0vpNp6kzPhHrLx72wA0G+ZLaaJjLIYeE0n8INlgaohKuGy7hP0as5tbUd23QWu5U233t+w==", + "dev": true, + "requires": { + "@sinonjs/commons": "^2.0.0", + "@sinonjs/fake-timers": "^9.1.2", + "@sinonjs/samsam": "^7.0.1", + "diff": "^5.0.0", + "nise": "^5.1.2", + "supports-color": "^7.2.0" + } + } + } + }, + "@squeep/web-linking": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@squeep/web-linking/-/web-linking-1.0.7.tgz", + "integrity": "sha512-9d3QijrWc/WNE7p/K7NLUHbmPf92CURRqfzDLV0cGqYNA4QWAPfzwC8hxWpdUkUnep3KakvLKK60l0kEBMM3ag==" + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "optional": true + }, + "acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "optional": true, + "requires": { + "debug": "4" + } + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "amqplib": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.10.3.tgz", + "integrity": "sha512-UHmuSa7n8vVW/a5HGh2nFPqAEr8+cD4dEZ6u9GjP91nHfr1a54RyAKyra7Sb5NH7NBKOUlyQSMXIp0qAixKexw==", + "requires": { + "@acuminous/bitsyntax": "^0.1.2", + "buffer-more-ints": "~1.0.0", + "readable-stream": "1.x >=1.1.9", + "url-parse": "~1.5.10" + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "devOptional": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "devOptional": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "requires": { + "default-require-extensions": "^3.0.0" + } + }, + "aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "optional": true + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", + "dev": true + }, + "are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "optional": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "optional": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "optional": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "argon2": { + "version": "0.30.2", + "resolved": "https://registry.npmjs.org/argon2/-/argon2-0.30.2.tgz", + "integrity": "sha512-RBbXTUsrJUQH259/72CCJxQa0hV961pV4PyZ7R1czGkArSsQP4DToCS2axmNfHywXaBNEMPWMW6rM82EArulYA==", + "optional": true, + "requires": { + "@mapbox/node-pre-gyp": "^1.0.10", + "@phc/format": "^1.0.0", + "node-addon-api": "^5.0.0" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "assert-options": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/assert-options/-/assert-options-0.8.0.tgz", + "integrity": "sha512-qSELrEaEz4sGwTs4Qh+swQkjiHAysC4rot21+jzXU86dJzNG+FDqBzyS3ohSoTRf4ZLA3FSwxQdiuNl5NXUtvA==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "axios": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.1.tgz", + "integrity": "sha512-I88cFiGu9ryt/tfVEi4kX2SITsvDddTajXTOFmt2uK1ZVA8LytjtdeyefdQWEf5PU8w+4SSJDoYnggflB5tW4A==", + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "devOptional": true + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "better-sqlite3": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-8.0.1.tgz", + "integrity": "sha512-JhTZjpyapA1icCEjIZB4TSSgkGdFgpWZA2Wszg7Cf4JwJwKQmbvuNnJBeR+EYG/Z29OXvR4G//Rbg31BW/Z7Yg==", + "requires": { + "bindings": "^1.5.0", + "prebuild-install": "^7.1.0" + } + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "devOptional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "buffer-more-ints": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", + "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==" + }, + "buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" + }, + "caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "requires": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", + "dev": true, + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "devOptional": true + }, + "caniuse-lite": { + "version": "1.0.30001441", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001441.tgz", + "integrity": "sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "optional": true + }, + "clean-css": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", + "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", + "dev": true, + "requires": { + "source-map": "~0.6.0" + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "optional": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "devOptional": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "devOptional": true + }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "optional": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "devOptional": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "optional": true + }, + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "devOptional": true + }, + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "requires": { + "mimic-response": "^3.1.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "default-require-extensions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", + "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", + "dev": true, + "requires": { + "strip-bom": "^4.0.0" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "optional": true + }, + "detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==" + }, + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "electron-to-chromium": { + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "devOptional": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint": { + "version": "8.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.30.0.tgz", + "integrity": "sha512-MGADB39QqYuzEGov+F/qb18r4i7DohCDOfatHaxI2iGlPuC65bwG2gxgO+7DkyL38dRFaRH7RaRAgU6JKL9rMQ==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.4.0", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + } + }, + "eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "requires": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "eslint-plugin-promise": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", + "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", + "dev": true, + "requires": {} + }, + "eslint-plugin-security": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-security/-/eslint-plugin-security-1.5.0.tgz", + "integrity": "sha512-hAFVwLZ/UeXrlyVD2TDarv/x00CoFVpaY0IUZhKjPjiFxqkuQVixsK4f2rxngeQOqSxi6OUjzJM/jMwKEVjJ8g==", + "dev": true, + "requires": { + "safe-regex": "^2.1.1" + } + }, + "eslint-plugin-sonarjs": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.17.0.tgz", + "integrity": "sha512-jtGtxI49UbJJeJj7CVRLI3+LLH+y+hkR3GOOwM7vBbci9DEFIRGCWvEd2BJScrzltZ6D6iubukTAfc9cyG7sdw==", + "dev": true, + "requires": {} + }, + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + }, + "espree": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "dev": true, + "requires": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "fastq": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz", + "integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, + "foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + } + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "optional": true, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "optional": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + } + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "devOptional": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "optional": true, + "requires": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + } + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "devOptional": true + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "devOptional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "globals": { + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "optional": true + }, + "hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "requires": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "html-minifier": { + "version": "3.5.21", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", + "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", + "dev": true, + "requires": { + "camel-case": "3.0.x", + "clean-css": "4.2.x", + "commander": "2.17.x", + "he": "1.2.x", + "param-case": "2.1.x", + "relateurl": "0.2.x", + "uglify-js": "3.4.x" + } + }, + "html-minifier-lint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/html-minifier-lint/-/html-minifier-lint-2.0.0.tgz", + "integrity": "sha512-halWZUg/us7Y16irVM90DTdyAUP3ksFthWfFPJTG1jpBaYYyGHt9azTW9H++hZ8LWRArzQm9oIcrfM/o/CO+4A==", + "dev": true, + "requires": { + "html-minifier": "3.x" + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "optional": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "iconv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/iconv/-/iconv-3.0.1.tgz", + "integrity": "sha512-lJnFLxVc0d82R7GfU7a9RujKVUQ3Eee19tPKWZWBJtAEGRHVEyFzCtbNl3GPKuDnHBBRT4/nDS4Ru9AIDT72qA==" + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "devOptional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "ip-address": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-8.1.0.tgz", + "integrity": "sha512-Wz91gZKpNKoXtqvY8ScarKYwhXoK4r/b5QuT+uywe/azv0/nUCo7Bh0IRRI7F9DHR06kJNWtzMGLIbXavngbKA==", + "requires": { + "jsbn": "1.1.0", + "sprintf-js": "1.1.2" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "devOptional": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "requires": { + "append-transform": "^2.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "istanbul-lib-processinfo": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", + "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.3", + "istanbul-lib-coverage": "^3.2.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^8.3.2" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "js-sdsl": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", + "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==" + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "json5": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", + "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==", + "dev": true + }, + "just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", + "dev": true + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==", + "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "devOptional": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "devOptional": true + } + } + }, + "microformats-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/microformats-parser/-/microformats-parser-1.4.1.tgz", + "integrity": "sha512-BSg9Y/Aik8hvvme/fkxnXMRvTKuVwOeTapeZdaPQ+92DEubyM31iMtwbgFZ1383om643UvfYY5G23E9s1FY2KQ==", + "requires": { + "parse5": "^6.0.0" + } + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "devOptional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==" + }, + "minipass": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.0.0.tgz", + "integrity": "sha512-g2Uuh2jEKoht+zvO6vJqXmYpflPqzRBT+Th2h01DKh5z7wbY/AZ2gCQ78cP70YoHPyFdY30YBV5WxgLOEwOykw==", + "optional": true, + "requires": { + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + } + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "optional": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "optional": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + } + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "optional": true + }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, + "mocha": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", + "dev": true, + "requires": { + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "mocha-steps": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/mocha-steps/-/mocha-steps-1.3.0.tgz", + "integrity": "sha512-KZvpMJTqzLZw3mOb+EEuYi4YZS41C9iTnb7skVFRxHjUd1OYbl64tCMSmpdIRM9LnwIrSOaRfPtNpF5msgv6Eg==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "nanoid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "dev": true + }, + "napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "nise": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", + "integrity": "sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^2.0.0", + "@sinonjs/fake-timers": "^10.0.2", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + } + }, + "no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "dev": true, + "requires": { + "lower-case": "^1.1.1" + } + }, + "node-abi": { + "version": "3.30.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.30.0.tgz", + "integrity": "sha512-qWO5l3SCqbwQavymOmtTVuCWZE23++S+rxyoHjXqUmPyzRcaoI4lA2gO55/drddGnedAyjA7sk76SfQ5lfUMnw==", + "requires": { + "semver": "^7.3.5" + } + }, + "node-addon-api": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.0.0.tgz", + "integrity": "sha512-CvkDw2OEnme7ybCykJpVcKH+uAOLV2qLqiyla128dN9TkEWfrYmxG6C2boDe5KcNQqZF3orkqzGgOMvZ/JNekA==", + "optional": true + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "optional": true, + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "node-linux-pam": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-linux-pam/-/node-linux-pam-0.2.1.tgz", + "integrity": "sha512-OeMZW0Bs1bffsvXI/bJQbU0rkiWTOo0ceT6+mrbU84TJ33vAKykIZrLI+ApfRqkBQW5jzW5rJ7x+NSyToafqig==", + "optional": true, + "requires": { + "@mapbox/node-pre-gyp": "1.0.5", + "bindings": "1.5.0", + "node-addon-api": "3.1.0", + "string-template": "1.0.0", + "yargs": "15.4.1" + }, + "dependencies": { + "@mapbox/node-pre-gyp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz", + "integrity": "sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA==", + "optional": true, + "requires": { + "detect-libc": "^1.0.3", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.1", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "rimraf": "^3.0.2", + "semver": "^7.3.4", + "tar": "^6.1.0" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "optional": true + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "optional": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "optional": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "optional": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "optional": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "optional": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "optional": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "optional": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "node-addon-api": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.1.0.tgz", + "integrity": "sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw==", + "optional": true + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "optional": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "optional": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "optional": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "optional": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "optional": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "optional": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "optional": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "optional": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "requires": { + "process-on-spawn": "^1.0.0" + } + }, + "node-releases": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", + "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==", + "dev": true + }, + "nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "optional": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "optional": true, + "requires": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "optional": true + }, + "nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, + "requires": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "dependencies": { + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "optional": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "os-shim": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz", + "integrity": "sha512-jd0cvB8qQ5uVt0lvCIexBaROw1KyKm5sbulg2fWOHjETisuCzWyt+eTZKEMs8v6HwzoGs8xik26jg7eCM6pS+A==", + "dev": true + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "devOptional": true + }, + "package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, + "param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==", + "dev": true, + "requires": { + "no-case": "^2.2.0" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "devOptional": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "devOptional": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + }, + "pg": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.8.0.tgz", + "integrity": "sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw==", + "requires": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "^2.5.0", + "pg-pool": "^3.5.2", + "pg-protocol": "^1.5.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + } + }, + "pg-connection-string": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" + }, + "pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" + }, + "pg-minify": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/pg-minify/-/pg-minify-1.6.2.tgz", + "integrity": "sha512-1KdmFGGTP6jplJoI8MfvRlfvMiyBivMRP7/ffh4a11RUFJ7kC2J0ZHlipoKiH/1hz+DVgceon9U2qbaHpPeyPg==" + }, + "pg-pool": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.2.tgz", + "integrity": "sha512-His3Fh17Z4eg7oANLob6ZvH8xIVen3phEZh2QuyrIl4dQSDVEabNducv6ysROKpDNPSD+12tONZVWfSgMvDD9w==", + "requires": {} + }, + "pg-promise": { + "version": "10.15.4", + "resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-10.15.4.tgz", + "integrity": "sha512-BKlHCMCdNUmF6gagVbehRWSEiVcZzPVltEx14OJExR9Iz9/1R6KETDWLLGv2l6yRqYFnEZZy1VDjRhArzeIGrw==", + "requires": { + "assert-options": "0.8.0", + "pg": "8.8.0", + "pg-minify": "1.6.2", + "spex": "3.2.0" + } + }, + "pg-protocol": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz", + "integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ==" + }, + "pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "requires": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + } + }, + "pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "requires": { + "split2": "^4.1.0" + } + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + } + } + }, + "postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" + }, + "postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==" + }, + "postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==" + }, + "postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "requires": { + "xtend": "^4.0.0" + } + }, + "pre-commit": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/pre-commit/-/pre-commit-1.2.2.tgz", + "integrity": "sha512-qokTiqxD6GjODy5ETAIgzsRgnBWWQHQH2ghy86PU7mIn/wuWeTwF3otyNQZxWBwVn8XNr8Tdzj/QfUXpH+gRZA==", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "spawn-sync": "^1.0.15", + "which": "1.2.x" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true + }, + "which": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", + "integrity": "sha512-16uPglFkRPzgiUXYMi1Jf8Z5EzN1iB4V0ZtMXcHZnwsBtQhhHeCqoWw7tsUY42hJGNDWtUsVLTjakIa5BgAxCw==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "dev": true + } + } + }, + "prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "requires": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "devOptional": true + }, + "process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "requires": { + "fromentries": "^1.2.0" + } + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" + } + } + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "regexp-tree": { + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz", + "integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==", + "dev": true + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "dev": true + }, + "release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "devOptional": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "devOptional": true + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "devOptional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dev": true, + "requires": { + "regexp-tree": "~0.1.1" + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "requires": { + "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "devOptional": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "devOptional": true + }, + "simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" + }, + "simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "requires": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "sinon": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.0.1.tgz", + "integrity": "sha512-PZXKc08f/wcA/BMRGBze2Wmw50CWPiAH3E21EOi4B49vJ616vW4DQh4fQrqsYox2aNR/N3kCqLuB0PwwOucQrg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^2.0.0", + "@sinonjs/fake-timers": "10.0.2", + "@sinonjs/samsam": "^7.0.1", + "diff": "^5.0.0", + "nise": "^5.1.2", + "supports-color": "^7.2.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "spawn-sync": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz", + "integrity": "sha512-9DWBgrgYZzNghseho0JOuh+5fg9u6QWhAWa51QC7+U5rCheZ/j1DrEZnyE0RBBRqZ9uEXGPgSSM0nky6burpVw==", + "dev": true, + "requires": { + "concat-stream": "^1.4.7", + "os-shim": "^0.1.2" + } + }, + "spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "requires": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + } + }, + "spex": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spex/-/spex-3.2.0.tgz", + "integrity": "sha512-9srjJM7NaymrpwMHvSmpDeIK5GoRMX/Tq0E8aOlDPS54dDnDUIp30DrP9SphMPEETDLzEM9+4qo+KipmbtPecg==" + }, + "split2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz", + "integrity": "sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==" + }, + "sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, + "string-template": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-1.0.0.tgz", + "integrity": "sha512-SLqR3GBUXuoPP5MmYtD7ompvXiG87QjT6lzOszyXjTM86Uu7At7vNnt2xgyTLq5o9T4IxTYFyGxcULqpsmsfdg==", + "optional": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "devOptional": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "devOptional": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "tar": { + "version": "6.1.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz", + "integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==", + "optional": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^4.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + } + } + }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + }, + "dependencies": { + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + } + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "optional": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "uglify-js": { + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", + "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==", + "dev": true, + "requires": { + "commander": "~2.19.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "dev": true + } + } + }, + "update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dev": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==", + "dev": true + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "optional": true + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "optional": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "devOptional": true + }, + "wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "workerpool": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + } + } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..24e8e44 --- /dev/null +++ b/package.json @@ -0,0 +1,64 @@ +{ + "name": "@squeep/indie-auther", + "version": "1.0.0", + "description": "A stand-alone IndieAuth identity-provider service, for most of your IndieAuth endpoint needs.", + "keywords": [ + "IdP", + "Identity Provider", + "IndieAuth", + "IndieWeb", + "OAuth2", + "Authentication" + ], + "main": "server.js", + "scripts": { + "coverage": "nyc npm test", + "coverage-check": "nyc check-coverage", + "eslint": "eslint *.js src", + "test": "mocha --recursive" + }, + "pre-commit": [ + "eslint", + "coverage", + "coverage-check" + ], + "engines": { + "node": ">=14.0" + }, + "repository": { + "type": "git", + "url": "https://git.squeep.com/squeep-indie-auther/" + }, + "author": "Justin Wind <jwind-indieauther@squeep.com>", + "license": "ISC", + "dependencies": { + "@squeep/amqp-helper": "git+https://git.squeep.com/squeep-amqp-helper#v1.0.0", + "@squeep/api-dingus": "git+https://git.squeep.com/squeep-api-dingus/#v1.2.9", + "@squeep/authentication-module": "git+https://git.squeep.com/squeep-authentication-module/#v1.2.12", + "@squeep/chores": "git+https://git.squeep.com/squeep-chores/#v1.0.0", + "@squeep/html-template-helper": "git+https://git.squeep.com/squeep-html-template-helper#v1.4.0", + "@squeep/indieauth-helper": "git+https://git.squeep.com/squeep-indieauth-helper/#v1.2.2", + "@squeep/logger-json-console": "git+https://git.squeep.com/squeep-logger-json-console#v1.0.2", + "@squeep/mystery-box": "^1.2.0", + "@squeep/resource-authentication-module": "git+https://git.squeep.com/squeep-resource-authentication-module#v1.0.0", + "@squeep/roman": "^1.0.0", + "@squeep/web-linking": "^1.0.7", + "better-sqlite3": "^8.0.1", + "pg-promise": "^10.15.4", + "uuid": "^9.0.0" + }, + "devDependencies": { + "@squeep/test-helper": "git+https://git.squeep.com/squeep-test-helper#v1.0.0", + "eslint": "^8.30.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-security": "^1.5.0", + "eslint-plugin-sonarjs": "^0.17.0", + "html-minifier-lint": "^2.0.0", + "mocha": "^10.2.0", + "mocha-steps": "^1.3.0", + "nyc": "^15.1.0", + "pre-commit": "^1.2.2", + "sinon": "^15.0.1" + } +} diff --git a/server.js b/server.js new file mode 100644 index 0000000..1e9c089 --- /dev/null +++ b/server.js @@ -0,0 +1,39 @@ +'use strict'; + +const http = require('http'); + +const Config = require('./config'); +const DB = require('./src/db'); +const Service = require('./src/service'); +const Logger = require('./src/logger'); +const { fileScope } = require('./src/common'); +const _fileScope = fileScope(__filename); +const { version } = require('./package.json'); + +const PORT = process.env.PORT || 3002; +const ADDR = process.env.LISTEN_ADDR || '127.0.0.1'; + +(async function main () { + const _scope = _fileScope('main'); + let config, logger, db, service; + try { + config = new Config(process.env.NODE_ENV); + logger = new Logger(config); + db = new DB(logger, config); + await db.initialize(); + service = new Service(logger, db, config); + await service.initialize(); + + http.createServer((req, res) => { + service.dispatch(req, res); + }).listen(PORT, ADDR, (err) => { + if (err) { + logger.error(_scope, 'error starting server', err); + throw err; + } + logger.info(_scope, 'server started', { version, listenAddress: ADDR, listenPort: PORT }); + }); + } catch (e) { + (logger || console).error(_scope, 'error starting server', e); + } +})(); \ No newline at end of file diff --git a/src/chores.js b/src/chores.js new file mode 100644 index 0000000..0f3d379 --- /dev/null +++ b/src/chores.js @@ -0,0 +1,70 @@ +'use strict'; + +const common = require('./common'); +const Enum = require('./enum'); +const { Chores: BaseChores } = require('@squeep/chores'); +const _fileScope = common.fileScope(__filename); + +/** + * Wrangle periodic tasks what need doing. + */ + +class Chores extends BaseChores { + constructor(logger, db, options) { + super(logger); + this.options = options; + this.db = db; + + this.establishChore(Enum.Chore.CleanTokens, this.cleanTokens.bind(this), options?.chores?.tokenCleanupMs); + this.establishChore(Enum.Chore.CleanScopes, this.cleanScopes.bind(this), options?.chores?.scopeCleanupMs); + } + + /** + * Attempt to remove tokens which are expired or otherwise no longer valid. + * @param {Number} atLeastMsSinceLast + */ + async cleanTokens(atLeastMsSinceLast = this.options?.chores?.tokenCleanupMs || 0) { + const _scope = _fileScope('cleanTokens'); + this.logger.debug(_scope, 'called', atLeastMsSinceLast); + + let tokensCleaned; + try { + await this.db.context(async (dbCtx) => { + const codeValidityTimeoutSeconds = Math.ceil(this.options.manager.codeValidityTimeoutMs / 1000); + tokensCleaned = await this.db.tokenCleanup(dbCtx, codeValidityTimeoutSeconds, atLeastMsSinceLast); + }); // dbCtx + if (tokensCleaned) { + this.logger.info(_scope, 'finished', { tokensCleaned }); + } + } catch (e) { + this.logger.error(_scope, 'failed', { error: e }); + throw e; + } + } + + + /** + * Attempt to remove ephemeral scopes which are no longer referenced by tokens. + * @param {Number} atLeastMsSinceLast + */ + async cleanScopes(atLeastMsSinceLast = this.options?.chores?.scopeCleanupMs || 0) { + const _scope = _fileScope('cleanScopes'); + this.logger.debug(_scope, 'called', atLeastMsSinceLast); + + let scopesCleaned; + try { + await this.db.context(async (dbCtx) => { + scopesCleaned = await this.db.scopeCleanup(dbCtx, atLeastMsSinceLast); + }); // dbCtx + if (scopesCleaned) { + this.logger.info(_scope, 'finished', { scopesCleaned }); + } + } catch (e) { + this.logger.error(_scope, 'failed', { error: e }); + throw e; + } + } + +} // IAChores + +module.exports = Chores; \ No newline at end of file diff --git a/src/common.js b/src/common.js new file mode 100644 index 0000000..d58f535 --- /dev/null +++ b/src/common.js @@ -0,0 +1,167 @@ +'use strict'; + +const { common } = require('@squeep/api-dingus'); + +const { randomBytes } = require('crypto'); +const { promisify } = require('util'); +const randomBytesAsync = promisify(randomBytes); + +/** + * Pick out useful axios response fields. + * @param {*} res + * @returns + */ +const axiosResponseLogData = (res) => { + const data = common.pick(res, [ + 'status', + 'statusText', + 'headers', + 'elapsedTimeMs', + 'data', + ]); + if (data.data) { + data.data = logTruncate(data.data, 100); + } + return data; +}; + +/** + * Limit length of string to keep logs sane + * @param {String} str + * @param {Number} len + * @returns {String} + */ +const logTruncate = (str, len) => { + if (typeof str !== 'string' || str.toString().length <= len) { + return str; + } + return str.toString().slice(0, len) + `... (${str.toString().length} bytes)`; +}; + +/** + * Turn a snake into a camel. + * @param {String} snakeCase + * @param {String|RegExp} delimiter + * @returns {String} + */ +const camelfy = (snakeCase, delimiter = '_') => { + if (!snakeCase || typeof snakeCase.split !== 'function') { + return undefined; + } + const words = snakeCase.split(delimiter); + return [ + words.shift(), + ...words.map((word) => word.charAt(0).toUpperCase() + word.slice(1)), + ].join(''); +}; + +/** + * Return an array containing x if x is not an array. + * @param {*} x + */ +const ensureArray = (x) => { + if (x === undefined) { + return []; + } + if (!Array.isArray(x)) { + return Array(x); + } + return x; +}; + +/** + * Recursively freeze an object. + * @param {Object} o + * @returns {Object} + */ +const freezeDeep = (o) => { + Object.freeze(o); + Object.getOwnPropertyNames(o).forEach((prop) => { + if (Object.hasOwnProperty.call(o, prop) + && ['object', 'function'].includes(typeof o[prop]) // eslint-disable-line security/detect-object-injection + && !Object.isFrozen(o[prop])) { // eslint-disable-line security/detect-object-injection + return freezeDeep(o[prop]); // eslint-disable-line security/detect-object-injection + } + }); + return o; +}; + + +/** Oauth2.1 §3.2.3.1 + * %x20-21 / %x23-5B / %x5D-7E + * @param {String} char + */ +const validErrorChar = (char) => { + const value = char.charCodeAt(0); + return value === 0x20 || value === 0x21 + || (value >= 0x23 && value <= 0x5b) + || (value >= 0x5d && value <= 0x7e); +}; + + +/** + * Determine if an OAuth error message is valid. + * @param {String} error + * @returns {Boolean} + */ +const validError = (error) => { + return error && error.split('').filter((c) => !validErrorChar(c)).length === 0 || false; +}; + + +/** + * OAuth2.1 §3.2.2.1 + * scope-token = 1*( %x21 / %x23-5B / %x5D-7E ) + * @param {String} char + */ +const validScopeChar = (char) => { + const value = char.charCodeAt(0); + return value === 0x21 + || (value >= 0x23 && value <= 0x5b) + || (value >= 0x5d && value <= 0x7e); +}; + + +/** + * Determine if a scope has a valid name. + * @param {String} scope + * @returns {Boolean} + */ +const validScope = (scope) => { + return scope && scope.split('').filter((c) => !validScopeChar(c)).length === 0 || false; +}; + + +/** + * + * @param {Number} bytes + */ +const newSecret = async (bytes = 64) => { + return (await randomBytesAsync(bytes * 3 / 4)).toString('base64'); +}; + + +/** + * Convert a Date object to epoch seconds. + * @param {Date=} date + * @returns {Number} + */ +const dateToEpoch = (date) => { + const dateMs = date ? date.getTime() : Date.now(); + return Math.ceil(dateMs / 1000); +}; + +module.exports = { + ...common, + axiosResponseLogData, + camelfy, + dateToEpoch, + ensureArray, + freezeDeep, + logTruncate, + newSecret, + randomBytesAsync, + validScope, + validError, +}; + diff --git a/src/db/abstract.js b/src/db/abstract.js new file mode 100644 index 0000000..26867e4 --- /dev/null +++ b/src/db/abstract.js @@ -0,0 +1,563 @@ +/* eslint-disable no-unused-vars */ +'use strict'; + +const common = require('../common'); +const DatabaseErrors = require('./errors'); +const svh = require('./schema-version-helper'); +const uuid = require('uuid'); + +const _fileScope = common.fileScope(__filename); + +class Database { + constructor(logger, options) { + this.logger = logger; + this.options = options; + } + + + /** + * Perform tasks needed to prepare database for use. Ensure this is called + * after construction, and before any other database activity. + * At the minimum, this will validate a compatible schema is present and usable. + * Some engines will also perform other initializations or async actions which + * are easier handled outside the constructor. + */ + async initialize() { + const _scope = _fileScope('initialize'); + + const currentSchema = await this._currentSchema(); + const current = svh.schemaVersionObjectToNumber(currentSchema); + const min = svh.schemaVersionObjectToNumber(this.schemaVersionsSupported.min); + const max = svh.schemaVersionObjectToNumber(this.schemaVersionsSupported.max); + if (current >= min && current <= max) { + this.logger.debug(_scope, 'schema supported', { currentSchema, schemaVersionsSupported: this.schemaVersionsSupported }); + } else { + this.logger.error(_scope, 'schema not supported', { currentSchema, schemaVersionsSupported: this.schemaVersionsSupported }); + throw new DatabaseErrors.MigrationNeeded(); + } + } + + + /** + * Query the current schema version. + * This is a standalone query function, as it is called before statements are loaded. + * @returns {Object} version + * @returns {Number} version.major + * @returns {Number} version.minor + * @returns {Number} version.patch + */ + async _currentSchema() { + this._notImplemented('_currentSchema', arguments); + } + + + /** + * Perform db connection health-check, if applicable. + * Throw something if a database situation should pull us out of a load-balancer. + */ + async healthCheck() { + this._notImplemented('healthCheck', arguments); + } + + + /** + * Wrap a function call in a database context. + * @param {Function} fn fn(ctx) + */ + async context(fn) { + this._notImplemented('context', arguments); + } + + /** + * Wrap a function call in a transaction context. + * @param {*} dbCtx + * @param {Function} fn fn(txCtx) + */ + async transaction(dbCtx, fn) { + this._notImplemented('transaction', arguments); + } + + + /** + * @param {*} x + * @returns {Boolean} + */ + static _isUUID(x) { + try { + uuid.parse(x); + return true; + } catch (e) { + return false; + } + } + + + /** + * @param {*} x + * @returns {Boolean} + */ + static _isInfinites(x) { + return typeof(x) === 'number' + && Math.abs(x) === Infinity; + } + + /** + * Basic type checking of object properties. + * @param {Object} object + * @param {String[]} properties + * @param {String[]} types + */ + _ensureTypes(object, properties, types) { + const _scope = _fileScope('_ensureTypes'); + + if (!(object && properties && types)) { + this.logger.error(_scope, 'undefined argument', { object, properties, types }); + throw new DatabaseErrors.DataValidation(); + } + properties.forEach((p) => { + // eslint-disable-next-line security/detect-object-injection + const pObj = object[p]; + const pType = typeof pObj; + if (!types.includes(pType) + && !(types.includes('array') && Array.isArray(pObj)) + && !(types.includes('buffer') && pObj instanceof Buffer) + && !(types.includes('date') && pObj instanceof Date) + && !(types.includes('infinites')) + && !(types.includes('null') && pObj === null) + && !(types.includes('number') && pType === 'bigint') + && !(types.includes('uuid') && Database._isUUID(pObj))) { + const reason = `'${p}' is '${pType}', but must be ${types.length > 1 ? 'one of ' : ''}'${types}'`; + this.logger.error(_scope, reason, {}); + throw new DatabaseErrors.DataValidation(reason); + } + }); + } + + + /** + * @typedef {Object} Authentication + * @property {String} identifier + * @property {String=} credential + * @property {Date} created + * @property {Date=} lastAuthenticated + */ + /** + * @param {Authentication} authentication + */ + _validateAuthentication(authentication) { + [ + [['identifier'], ['string']], + [['credential'], ['string', 'null']], + [['created'], ['date']], + [['lastAuthenticated'], ['date', 'infinites']], + ].forEach(([properties, types]) => this._ensureTypes(authentication, properties, types)); + } + + + /** + * @typedef {Object} Resource + * @property {String} resourceId - uuid + * @property {String} secret + * @property {String} description + * @property {Date} created + */ + /** + * @param {Resource} resource + */ + _validateResource(resource) { + [ + [['resourceId', 'secret', 'description'], ['string']], + [['resourceId'], ['uuid']], + [['created'], ['date']], + ].forEach(([properties, types]) => this._ensureTypes(resource, properties, types)); + } + + + /** + * @typedef {Object} Token + * @property {String} codeId - uuid + * @property {String} profile + * @property {Date} created + * @property {Date=} expires + * @property {Date=} refreshExpires + * @property {Date=} refreshed + * @property {*=} duration + * @property {*=} refreshDuration + * @property {Number|BigInt=} refresh_count + * @property {Boolean} is_revoked + * @property {Boolean} is_token + * @property {String} client_id + * @property {String[]} scopes + * @property {Object=} profileData + */ + /** + * @param {Token} token + */ + _validateToken(token) { + [ + [['codeId', 'profile', 'clientId'], ['string']], + [['codeId'], ['uuid']], + [['created'], ['date']], + [['expires', 'refreshExpires', 'refreshed'], ['date', 'null']], + [['isToken', 'isRevoked'], ['boolean']], + [['scopes'], ['array']], + [['profileData'], ['object', 'null']], + ].forEach(([properties, types]) => this._ensureTypes(token, properties, types)); + this._ensureTypes(token.scopes, Object.keys(token.scopes), ['string']); + } + + + /** + * Interface methods need implementations. Ensure the db-interaction + * methods on the base class call this, so they may be overridden by + * implementation classes. + * @param {String} method + * @param {arguments} args + */ + _notImplemented(method, args) { + this.logger.error(_fileScope(method), 'abstract method called', Array.from(args)); + throw new DatabaseErrors.NotImplemented(method); + } + + + /** + * Get all the almanac entries. + * @param {*} dbCtx + */ + async almanacGetAll(dbCtx) { + this._notImplemented('almanacGetAll', arguments); + } + + + /** + * Fetch the authentication record for an identifier. + * @param {*} dbCtx + * @param {String} identifier + * @returns {Promise<Authentication>} + */ + async authenticationGet(dbCtx, identifier) { + this._notImplemented('authenticationGet', arguments); + } + + + /** + * Update the authentication record for the identifier that + * correct credentials have been supplied. + * @param {*} dbCtx + * @param {String} identifier + * @returns {Promise<void>} + */ + async authenticationSuccess(dbCtx, identifier) { + this._notImplemented('authenticationSuccess', arguments); + } + + + /** + * Insert or update the credential for an identifier. + * @param {*} dbCtx + * @param {String} identifier + * @param {String} credential + * @returns {Promise<void>} + */ + async authenticationUpsert(dbCtx, identifier, credential) { + this._notImplemented('authenticationUpsert', arguments); + } + + + /** + * Determine if profile url is known to this service. + * @param {*} dbCtx + * @param {String} profile + * @returns {Promise<Boolean>} + */ + async profileIsValid(dbCtx, profile) { + this._notImplemented('profileGet', arguments); + } + + + /** + * Insert a new relationship between a profile endpoint and + * an authenticated identifier. + * @param {*} dbCtx + * @param {String} profile + * @param {String} identifier + * @returns {Promise<void>} + */ + async profileIdentifierInsert(dbCtx, profile, identifier) { + this._notImplemented('profileIdentifierInsert', arguments); + } + + + /** + * Adds a scope to be available for a profile to include on any authorization request. + * @param {*} dbCtx + * @param {String} profile + * @param {String} scope + * @returns {Promise<void>} + */ + async profileScopeInsert(dbCtx, profile, scope) { + this._notImplemented('profileScopeInsert', arguments); + } + + + /** + * @typedef {Object} ScopeDetails + * @property {String} description + * @property {String[]=} profiles + */ + /** + * @typedef {Object.<String, Object>} ProfileScopes + * @property {Object.<String, Object>} profile + * @property {Object.<String, ScopeDetails>} profile.scope + */ + /** + * @typedef {Object.<String, Object>} ScopeIndex + * @property {ScopeDetails} scope + */ + /** + * @typedef {Object} ProfilesScopesReturn + * @property {ProfileScopes} profileScopes + * @property {ScopeIndex} scopeIndex + * @property {String[]} profiles + */ + /** + * Returns an object containing: + * - an object with profiles as keys to objects with scopes as keys to scope objects, + * which each contain a description of the scope and a list of profiles offering it + * - an object with scopes as keys to the same scope objects + * - a list of profiles + * @param {*} dbCtx + * @param {String} identifier + * @returns {Promise<ProfileScopesReturn>} + */ + async profilesScopesByIdentifier(dbCtx, identifier) { + this._notImplemented('profilesScopesByIdentifier', arguments); + } + + + /** + * @typedef ProfileScopesRow + * @property profile + * @property scope + * @property description + * @property application + * @property isPermanent + * @property isManuallyAdded + */ + /** + * Convert db row data into associative structures. + * Same behavior is shared by multiple engines. + * @param {ProfileScopesRow[]} profileScopesRows + * @returns {ProfileScopesReturn} + */ + static _profilesScopesBuilder(profileScopesRows) { + const scopeIndex = {}; + const profileScopes = {}; + const profileSet = new Set(); + + (profileScopesRows || []).forEach(({ profile, scope, description, application, isPermanent, isManuallyAdded }) => { + if (scope && !(scope in scopeIndex)) { + scopeIndex[scope] = { // eslint-disable-line security/detect-object-injection + description, + application, + isPermanent, + isManuallyAdded, + profiles: [], + }; + } + if (profile) { + profileSet.add(profile); + if (!(profile in profileScopes)) { + profileScopes[profile] = {}; // eslint-disable-line security/detect-object-injection + } + } + if (profile && scope) { + scopeIndex[scope].profiles.push(profile); // eslint-disable-line security/detect-object-injection + profileScopes[profile][scope] = scopeIndex[scope]; // eslint-disable-line security/detect-object-injection + } + }); + + return { + profiles: [...profileSet], + profileScopes, + scopeIndex, + }; + } + + + /** + * Sets list of additional scopes available to profile. + * @param {*} dbCtx + * @param {String} profile + * @param {String[]} scopes + * @returns {Promise<void>} + */ + async profileScopesSetAll(dbCtx, profile, scopes) { + this._notImplemented('profileScopesSetAll', arguments); + } + + + /** + * Create (or revoke a duplicate) code as a token entry. + * @param {*} dbCtx + * @param {Object} data + * @param {String} data.codeId + * @param {Date} data.created + * @param {Boolean} data.isToken + * @param {String} data.clientId + * @param {String} data.profile - profile uri + * @param {String} data.identifier + * @param {String[]} data.scopes + * @param {Number|Null} data.lifespanSeconds - null sets expiration to Infinity + * @param {Number|Null} data.refreshLifespanSeconds - null sets refresh to none + * @param {String|Null} data.resource + * @param {Object|Null} data.profileData - profile data from profile uri + * @returns {Promise<Boolean>} whether redemption was successful + */ + async redeemCode(dbCtx, { codeId, created, isToken, clientId, profile, identifier, scopes, lifespanSeconds, refreshLifespanSeconds, profileData } = {}) { + this._notImplemented('redeemCode', arguments); + } + + + /** + * @typedef {Object} RefreshedToken + * @property {Date} expires + * @property {Date} refreshExpires + * @property {String[]=} scopes if scopes were reduced + */ + /** + * Redeem a refresh token to renew token codeId. + * @param {*} dbCtx + * @param {String} codeId + * @param {Date} refreshed + * @param {String[]} removeScopes + * @returns {Promise<RefreshedToken>} + */ + async refreshCode(dbCtx, codeId, refreshed, removeScopes) { + this._notImplemented('refreshCode', arguments); + } + + + /** + * Fetch a resource server record. + * @param {*} dbCtx + * @param {String} identifier uuid + * @returns {Promise<Resource>} + */ + async resourceGet(dbCtx, resourceId) { + this._notImplemented('resourceGet', arguments); + } + + + /** + * Create, or update description of, a resourceId. + * @param {*} dbCtx + * @param {String=} resourceId uuid + * @param {String=} secret + * @param {String=} description + * @returns {Promise<void>} + */ + async resourceUpsert(dbCtx, resourceId, secret, description) { + this._notImplemented('resourceUpsert', arguments); + } + + + /** + * Register a scope and its description. + * @param {*} dbCtx + * @param {String} scope + * @param {String} application + * @param {String} description + * @returns {Promise<void>} + */ + async scopeUpsert(dbCtx, scope, application, description, manuallyAdded = false) { + this._notImplemented('scopeUpsert', arguments); + } + + + /** + * Remove a non-permanent scope if it is not currently in use. + * @param {*} dbCtx + * @param {String} scope + * @returns {Promise<Boolean>} + */ + async scopeDelete(dbCtx, scope) { + this._notImplemented('scopeDelete', arguments); + } + + + /** + * @typedef {Number|BigInt} CleanupResult + */ + /** + * @typedef {Object} CleanupResult + */ + /** + * Remove any non-permanent and non-manually-created scopes not currently in use. + * @param {*} dbCtx + * @param {Number} atLeastMsSinceLast skip cleanup if already executed this recently + * @returns {Promise<CleanupResult>} + */ + async scopeCleanup(dbCtx, atLeastMsSinceLast) { + this._notImplemented('scopeClean', arguments); + } + + + /** + * Forget tokens after they have expired, and redeemed codes after they have expired. + * @param {*} dbCtx + * @param {Number} codeLifespanSeconds + * @param {Number} atLeastMsSinceLast skip cleanup if already executed this recently + * @returns {Promise<CleanupResult>} + */ + async tokenCleanup(dbCtx, codeLifespanSeconds, atLeastMsSinceLast) { + this._notImplemented('tokenCleanup', arguments); + } + + + /** + * Look up a redeemed token by code_id. + * @param {*} dbCtx + * @param {String} codeId + * @returns {Promise<Token>} + */ + async tokenGetByCodeId(dbCtx, codeId) { + this._notImplemented('tokenGetByCodeId', arguments); + } + + + /** + * Sets a redeemed token as revoked. + * @param {*} dbCtx + * @param {String} codeId - uuid + * @returns {Promise<void>} + */ + async tokenRevokeByCodeId(dbCtx, codeId) { + this._notImplemented('tokenRevokeByCodeId', arguments); + } + + + /** + * Revoke the refreshability of a codeId. + * @param {*} dbCtx + * @param {String} codeId - uuid + * @returns {Promise<void>} + */ + async tokenRefreshRevokeByCodeId(dbCtx, codeId) { + this._notImplemented('tokenRefreshRevokeByCodeId', arguments); + } + + + /** + * Get all tokens assigned to identifier. + * @param {*} dbCtx + * @param {String} identifier + * @returns {Promise<Tokens[]>} + */ + async tokensGetByIdentifier(dbCtx, identifier) { + this._notImplemented('tokensGetByIdentifier', arguments); + } + +} + +module.exports = Database; \ No newline at end of file diff --git a/src/db/errors.js b/src/db/errors.js new file mode 100644 index 0000000..cd43239 --- /dev/null +++ b/src/db/errors.js @@ -0,0 +1,56 @@ +'use strict'; + +class DatabaseError extends Error { + constructor(...args) { + super(...args); + Error.captureStackTrace(DatabaseError); + } + + get name() { + /* istanbul ignore next */ + return this.constructor.name; + } +} + +class DataValidation extends DatabaseError { + constructor(...args) { + super(...args); + Error.captureStackTrace(DataValidation); + } +} + +class NotImplemented extends DatabaseError { + constructor(...args) { + super(...args); + Error.captureStackTrace(NotImplemented); + } +} + +class UnexpectedResult extends DatabaseError { + constructor(...args) { + super(...args); + Error.captureStackTrace(UnexpectedResult); + } +} + +class UnsupportedEngine extends DatabaseError { + constructor(...args) { + super(...args); + Error.captureStackTrace(UnsupportedEngine); + } +} + +class MigrationNeeded extends DatabaseError { + constructor(...args) { + super(...args); + } +} + +module.exports = { + DatabaseError, + DataValidation, + MigrationNeeded, + NotImplemented, + UnexpectedResult, + UnsupportedEngine, +}; diff --git a/src/db/index.js b/src/db/index.js new file mode 100644 index 0000000..0d5ef16 --- /dev/null +++ b/src/db/index.js @@ -0,0 +1,42 @@ +'use strict'; + +const common = require('../common'); +const DatabaseErrors = require('./errors'); + +const _fileScope = common.fileScope(__filename); + +class DatabaseFactory { + constructor(logger, options, ...rest) { + const _scope = _fileScope('constructor'); + + const connectionString = options.db.connectionString || ''; + const protocol = connectionString.slice(0, connectionString.indexOf('://')).toLowerCase(); + + let Engine; + switch (protocol) { + case DatabaseFactory.Engines.PostgreSQL: + Engine = require('./postgres'); + break; + + case DatabaseFactory.Engines.SQLite: + Engine = require('./sqlite'); + break; + + default: + logger.error(_scope, 'unsupported connectionString', { protocol, options }); + throw new DatabaseErrors.UnsupportedEngine(protocol); + } + + return new Engine(logger, options, ...rest); + } + + static get Engines() { + return { + PostgreSQL: 'postgresql', + SQLite: 'sqlite', + }; + } + +} + +module.exports = DatabaseFactory; diff --git a/src/db/postgres/index.js b/src/db/postgres/index.js new file mode 100644 index 0000000..54c6e9b --- /dev/null +++ b/src/db/postgres/index.js @@ -0,0 +1,638 @@ +/* eslint-disable security/detect-object-injection */ +'use strict'; + +const pgpInitOptions = { + capSQL: true, +}; + +const path = require('path'); +const pgp = require('pg-promise')(pgpInitOptions); +const svh = require('../schema-version-helper'); +const Database = require('../abstract'); +const DBErrors = require('../errors'); +const common = require('../../common'); + +const _fileScope = common.fileScope(__filename); + +const PGTypeIdINT8 = 20; // Type Id 20 == INT8 (BIGINT) +const PGTYpeIdINT8Array = 1016; //Type Id 1016 == INT8[] (BIGINT[]) +pgp.pg.types.setTypeParser(PGTypeIdINT8, BigInt); // Type Id 20 = INT8 (BIGINT) +const parseBigIntArray = pgp.pg.types.getTypeParser(PGTYpeIdINT8Array); // Type Id 1016 = INT8[] (BIGINT[]) +pgp.pg.types.setTypeParser(PGTYpeIdINT8Array, (a) => parseBigIntArray(a).map(BigInt)); + +const schemaVersionsSupported = { + min: { + major: 1, + minor: 0, + patch: 0, + }, + max: { + major: 1, + minor: 0, + patch: 0, + }, +}; + +class DatabasePostgres extends Database { + constructor(logger, options, _pgp = pgp) { + super(logger, options); + + this.db = _pgp(options.db.connectionString); + this.schemaVersionsSupported = schemaVersionsSupported; + + // Suppress QF warnings when running tests + this.noWarnings = options.db.noWarnings; + + // Log queries + const queryLogLevel = options.db.queryLogLevel; + if (queryLogLevel) { + const queryScope = _fileScope('pgp:query'); + pgpInitOptions.query = (event) => { + this.logger[queryLogLevel](queryScope, '', { ...common.pick(event, ['query', 'params']) }); + }; + } + + // Log errors + const errorScope = _fileScope('pgp:error'); + pgpInitOptions.error = (err, event) => { + this.logger.error(errorScope, '', { err, event }); + }; + + // Deophidiate column names in-place, log results + pgpInitOptions.receive = (data, result, event) => { + const exemplaryRow = data[0]; + for (const prop in exemplaryRow) { + const camel = common.camelfy(prop); + if (!(camel in exemplaryRow)) { + for (const d of data) { + d[camel] = d[prop]; + delete d[prop]; + } + } + } + if (queryLogLevel) { + // Omitting .rows + const resultLog = common.pick(result, ['command', 'rowCount', 'duration']); + this.logger[queryLogLevel](_fileScope('pgp:result'), '', { query: event.query, ...resultLog }); + } + }; + + // Expose these for test coverage + this.pgpInitOptions = pgpInitOptions; + this._pgp = _pgp; + + this._initStatements(_pgp); + } + + + _queryFileHelper(_pgp) { + return (file) => { + const _scope = _fileScope('_queryFile'); + /* istanbul ignore next */ + const qfParams = { + minify: true, + ...(this.noWarnings && { noWarnings: this.noWarnings }), + }; + const qf = new _pgp.QueryFile(file, qfParams); + if (qf.error) { + this.logger.error(_scope, 'failed to create SQL statement', { error: qf.error, file }); + throw qf.error; + } + return qf; + }; + } + + + async initialize(applyMigrations = true) { + const _scope = _fileScope('initialize'); + this.logger.debug(_scope, 'called', { applyMigrations }); + if (applyMigrations) { + await this._initTables(); + } + await super.initialize(); + if (this.listener) { + await this.listener.start(); + } + } + + + async _initTables(_pgp) { + const _scope = _fileScope('_initTables'); + this.logger.debug(_scope, 'called', {}); + + const _queryFile = this._queryFileHelper(_pgp || this._pgp); + + // Migrations rely upon this table, ensure it exists. + const metaVersionTable = '_meta_schema_version'; + + const tableExists = async (name) => this.db.oneOrNone('SELECT table_name FROM information_schema.tables WHERE table_name=$(name)', { name }); + let metaExists = await tableExists(metaVersionTable); + if (!metaExists) { + const fPath = path.join(__dirname, 'sql', 'schema', 'init.sql'); + const initSql = _queryFile(fPath); + const results = await this.db.multiResult(initSql); + this.logger.debug(_scope, 'executed init sql', { results }); + metaExists = await tableExists(metaVersionTable); + /* istanbul ignore if */ + if (!metaExists) { + throw new DBErrors.UnexpectedResult(`did not create ${metaVersionTable} table`); + } + this.logger.info(_scope, 'created schema version table', { metaVersionTable }); + } + + // Apply migrations + const currentSchema = await this._currentSchema(); + const migrationsWanted = svh.unappliedSchemaVersions(__dirname, currentSchema, this.schemaVersionsSupported); + this.logger.debug(_scope, 'schema migrations wanted', { migrationsWanted }); + for (const v of migrationsWanted) { + const fPath = path.join(__dirname, 'sql', 'schema', v, 'apply.sql'); + const migrationSql = _queryFile(fPath); + const results = await this.db.multiResult(migrationSql); + this.logger.debug(_scope, 'executed migration sql', { version: v, results }); + this.logger.info(_scope, 'applied migration', { version: v }); + } + } + + + _initStatements(_pgp) { + const _scope = _fileScope('_initStatements'); + const _queryFile = this._queryFileHelper(_pgp); + this.statement = _pgp.utils.enumSql(path.join(__dirname, 'sql'), {}, _queryFile); + this.logger.debug(_scope, 'statements initialized', { statements: Object.keys(this.statement).length }); + } + + + async healthCheck() { + const _scope = _fileScope('healthCheck'); + this.logger.debug(_scope, 'called', {}); + const c = await this.db.connect(); + c.done(); + return { serverVersion: c.client.serverVersion }; + } + + + async _currentSchema() { + return this.db.one('SELECT major, minor, patch FROM _meta_schema_version ORDER BY major DESC, minor DESC, patch DESC LIMIT 1'); + } + + + async _closeConnection() { + const _scope = _fileScope('_closeConnection'); + try { + if (this.listener) { + await this.listener.stop(); + } + await this._pgp.end(); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e }); + throw e; + } + } + + + /* istanbul ignore next */ + async _purgeTables(really = false) { + const _scope = _fileScope('_purgeTables'); + try { + if (really) { + await this.db.tx(async (t) => { + await t.batch([ + 'authentication', + 'resource', + 'profile', + 'token', + ].map(async (table) => t.query('TRUNCATE TABLE $(table:name) CASCADE', { table }))); + }); + } + } catch (e) { + this.logger.error(_scope, 'failed', { error: e }); + throw e; + } + } + + + async context(fn) { + return this.db.task(async (t) => fn(t)); + } + + + // eslint-disable-next-line class-methods-use-this + async transaction(dbCtx, fn) { + return dbCtx.txIf(async (t) => fn(t)); + } + + + async almanacGetAll(dbCtx) { + const _scope = _fileScope('almanacGetAll'); + this.logger.debug(_scope, 'called'); + + try { + return await dbCtx.manyOrNone(this.statement.almanacGetAll); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e }); + throw e; + } + } + + + async authenticationGet(dbCtx, identifier) { + const _scope = _fileScope('authenticationGet'); + this.logger.debug(_scope, 'called', { identifier }); + + try { + return await dbCtx.oneOrNone(this.statement.authenticationGet, { identifier }); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, identifier }); + throw e; + } + } + + + async authenticationSuccess(dbCtx, identifier) { + const _scope = _fileScope('authenticationSuccess'); + this.logger.debug(_scope, 'called', { identifier }); + + try { + const result = await dbCtx.result(this.statement.authenticationSuccess, { identifier }); + if (result.rowCount != 1) { + throw new DBErrors.UnexpectedResult('did not update authentication success event'); + } + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, identifier }); + throw e; + } + } + + + async authenticationUpsert(dbCtx, identifier, credential) { + const _scope = _fileScope('authenticationUpsert'); + const scrubbedCredential = '*'.repeat((credential || '').length); + this.logger.debug(_scope, 'called', { identifier, scrubbedCredential }); + + try { + const result = await dbCtx.result(this.statement.authenticationUpsert, { identifier, credential }); + if (result.rowCount != 1) { + throw new DBErrors.UnexpectedResult('did not upsert authentication'); + } + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, identifier, scrubbedCredential }); + throw e; + } + } + + + async profileIdentifierInsert(dbCtx, profile, identifier) { + const _scope = _fileScope('profileIdentifierInsert'); + this.logger.debug(_scope, 'called', { profile, identifier }); + + try { + const result = await dbCtx.result(this.statement.profileIdentifierInsert, { profile, identifier }); + if (result.rowCount != 1) { + throw new DBErrors.UnexpectedResult('did not insert identifier'); + } + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, profile, identifier }); + throw e; + } + } + + + async profileIsValid(dbCtx, profile) { + const _scope = _fileScope('profileIsValid'); + this.logger.debug(_scope, 'called', { profile }); + + try { + const profileResponse = await dbCtx.oneOrNone(this.statement.profileGet, { profile }); + return !!profileResponse; + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, profile }); + throw e; + } + } + + + async profileScopeInsert(dbCtx, profile, scope) { + const _scope = _fileScope('profileScopeInsert'); + this.logger.debug(_scope, 'called', { profile, scope }); + + try { + const result = await dbCtx.result(this.statement.profileScopeInsert, { profile, scope }); + // Duplicate inserts get ignored + if (result.rowCount != 1 && result.rowCount != 0) { + throw new DBErrors.UnexpectedResult('did not insert profile scope'); + } + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, profile, scope }); + throw e; + } + } + + + async profileScopesSetAll(dbCtx, profile, scopes) { + const _scope = _fileScope('profileScopesSetAll'); + this.logger.debug(_scope, 'called', { profile, scopes }); + + try { + await this.transaction(dbCtx, async (txCtx) => { + await txCtx.result(this.statement.profileScopesClear, { profile }); + if (scopes.length) { + await txCtx.result(this.statement.profileScopesSetAll, { profile, scopes }); + } + }); // transaction + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, profile, scopes }); + throw e; + } + } + + + async profilesScopesByIdentifier(dbCtx, identifier) { + const _scope = _fileScope('profilesScopesByIdentifier'); + this.logger.debug(_scope, 'called', { identifier }); + + try { + const profileScopesRows = await dbCtx.manyOrNone(this.statement.profilesScopesByIdentifier, { identifier }); + return Database._profilesScopesBuilder(profileScopesRows); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, identifier }); + throw e; + } + } + + + async redeemCode(dbCtx, { codeId, created, isToken, clientId, profile, identifier, scopes, lifespanSeconds, refreshLifespanSeconds, resource, profileData }) { + const _scope = _fileScope('redeemCode'); + this.logger.debug(_scope, 'called', { codeId, created, isToken, clientId, profile, identifier, scopes, lifespanSeconds, refreshLifespanSeconds, resource, profileData }); + + let result, ret = false; + try { + await this.transaction(dbCtx, async (txCtx) => { + result = await txCtx.result(this.statement.redeemCode, { codeId, created, isToken, clientId, profile, identifier, lifespanSeconds, refreshLifespanSeconds, resource, profileData }); + if (result.rowCount != 1) { + this.logger.error(_scope, 'failed', { result }); + throw new DBErrors.UnexpectedResult('did not redeem code'); + } + // Abort and return false if redemption resulted in revocation. + if (result.rows[0].isRevoked) { + return; + } + this.logger.debug(_scope, 'code redeemed', { redeemed: result.rows[0] }); + + // Ensure there are entries for all scopes. + if (scopes.length !== 0) { + await txCtx.result(this.statement.scopesInsert, { scopes }); + } + + // Record accepted scopes for this token. + result = await txCtx.result(this.statement.tokenScopesSet, { codeId, scopes }); + if (result.rowCount != scopes.length) { + this.logger.error(_scope, 'token scope count mismatch', { codeId, scopes, result }); + throw new DBErrors.UnexpectedResult('did not set all scopes on token'); + } + ret = true; + }); // txCtx + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, codeId, created, isToken, clientId, profile, identifier, scopes, lifespanSeconds, refreshLifespanSeconds, profileData }); + throw e; + } + + return ret; + } + + + async refreshCode(dbCtx, codeId, refreshed, removeScopes) { + const _scope = _fileScope('refreshCode'); + this.logger.debug(_scope, 'called', { codeId, refreshed, removeScopes }); + + try { + return await this.transaction(dbCtx, async (txCtx) => { + const refreshedToken = await txCtx.oneOrNone(this.statement.refreshCode, { codeId, refreshed }); + if (refreshedToken) { + if (removeScopes.length) { + const removeResult = await txCtx.result(this.statement.tokenScopesRemove, { codeId, removeScopes }); + if (removeResult.rowCount != removeScopes.length) { + this.logger.error(_scope, 'failed to remove token scopes', { actual: removeResult.rowCount, expected: removeScopes.length }); + throw new DBErrors.UnexpectedResult('did not remove scopes from token'); + } + } else { + delete refreshedToken.scopes; // Not updated, remove from response. + } + } else { + this.logger.debug(_scope, 'did not refresh token', {}); + } + return refreshedToken; + }); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, codeId }); + throw e; + } + } + + + async resourceGet(dbCtx, resourceId) { + const _scope = _fileScope('resourceGet'); + this.logger.debug(_scope, 'called', { resourceId }); + + try { + return await dbCtx.oneOrNone(this.statement.resourceGet, { resourceId }); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, resourceId }); + throw e; + } + } + + + async resourceUpsert(dbCtx, resourceId, secret, description) { + const _scope = _fileScope('resourceUpsert'); + const logSecret = secret?.length && common.logTruncate('*'.repeat(secret.length), 3) || undefined; + this.logger.debug(_scope, 'called', { resourceId, secret: logSecret, description }); + + try { + const result = await dbCtx.result(this.statement.resourceUpsert, { resourceId, secret, description }); + if (result.rowCount != 1) { + throw new DBErrors.UnexpectedResult('did not upsert resource'); + } + return result.rows[0]; + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, resourceId, secret: logSecret, description }); + throw e; + } + } + + + async scopeCleanup(dbCtx, atLeastMsSinceLast) { + const _scope = _fileScope('scopeCleanup'); + this.logger.debug(_scope, 'called', { atLeastMsSinceLast }); + + const almanacEvent = 'scopeCleanup'; + try { + return await this.transaction(dbCtx, async (txCtx) => { + + // Check that enough time has passed since last cleanup + const now = new Date(); + const cleanupNotAfter = new Date(now.getTime() - atLeastMsSinceLast); + const { date: lastCleanupDate } = await txCtx.oneOrNone(this.statement.almanacGet, { event: almanacEvent }) || { date: new Date(0) }; + if (lastCleanupDate >= cleanupNotAfter) { + this.logger.debug(_scope, 'skipping token cleanup, too soon', { lastCleanupDate, cleanupNotAfter, atLeastMsSinceLast }); + return; + } + + // Do the cleanup + const { rowCount: scopesRemoved } = await txCtx.result(this.statement.scopeCleanup); + + // Update the last cleanup time + const result = await txCtx.result(this.statement.almanacUpsert, { event: almanacEvent, date: now }); + if (result.rowCount != 1) { + throw new DBErrors.UnexpectedResult('did not update almanac'); + } + + this.logger.debug(_scope, 'completed', { scopesRemoved, atLeastMsSinceLast }); + return scopesRemoved; + }); // tx + + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, atLeastMsSinceLast }); + throw e; + } + } + + + async scopeDelete(dbCtx, scope) { + const _scope = _fileScope('scopeDelete'); + this.logger.debug(_scope, 'called', { scope }); + + try { + return await this.transaction(dbCtx, async (txCtx) => { + const { inUse } = await txCtx.one(this.statement.scopeInUse, { scope }); + if (inUse) { + this.logger.debug(_scope, 'not deleted, in use', { scope }); + return false; + } + const result = await txCtx.result(this.statement.scopeDelete, { scope }); + if (result.rowCount == 0) { + this.logger.debug(_scope, 'no such scope', { scope }); + } else { + this.logger.debug(_scope, 'deleted', { scope }); + } + return true; + }); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, scope }); + throw e; + } + } + + + async scopeUpsert(dbCtx, scope, application, description, manuallyAdded = false) { + const _scope = _fileScope('scopeUpsert'); + this.logger.debug(_scope, 'called', { scope, description }); + + try { + const result = await dbCtx.result(this.statement.scopeUpsert, { scope, application, description, manuallyAdded }); + if (result.rowCount != 1) { + throw new DBErrors.UnexpectedResult('did not upsert scope'); + } + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, scope, application, description }); + throw e; + } + } + + + async tokenCleanup(dbCtx, codeLifespanSeconds, atLeastMsSinceLast) { + const _scope = _fileScope('tokenCleanup'); + this.logger.debug(_scope, 'called', { codeLifespanSeconds, atLeastMsSinceLast }); + + const almanacEvent = 'tokenCleanup'; + try { + return await this.transaction(dbCtx, async (txCtx) => { + + // Check that enough time has passed since last cleanup + const now = new Date(); + const cleanupNotAfter = new Date(now.getTime() - atLeastMsSinceLast); + const { date: lastCleanupDate } = await txCtx.oneOrNone(this.statement.almanacGet, { event: almanacEvent }) || { date: new Date(0) }; + if (lastCleanupDate >= cleanupNotAfter) { + this.logger.debug(_scope, 'skipping token cleanup, too soon', { lastCleanupDate, cleanupNotAfter, codeLifespanSeconds, atLeastMsSinceLast }); + return; + } + + // Do the cleanup + const { rowCount: tokensRemoved } = await txCtx.result(this.statement.tokenCleanup, { codeLifespanSeconds }); + + // Update the last cleanup time + const result = await txCtx.result(this.statement.almanacUpsert, { event: almanacEvent, date: now }); + if (result.rowCount != 1) { + throw new DBErrors.UnexpectedResult('did not update almanac'); + } + + this.logger.debug(_scope, 'completed', { tokensRemoved, codeLifespanSeconds, atLeastMsSinceLast }); + return tokensRemoved; + }); // tx + + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, atLeastMsSinceLast }); + throw e; + } + } + + + async tokenGetByCodeId(dbCtx, codeId) { + const _scope = _fileScope('tokenGetByCodeId'); + this.logger.debug(_scope, 'called', { codeId }); + + try { + return await dbCtx.oneOrNone(this.statement.tokenGetByCodeId, { codeId }); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, codeId }); + throw e; + } + } + + + async tokenRevokeByCodeId(dbCtx, codeId) { + const _scope = _fileScope('tokenRevokeByCodeId'); + this.logger.debug(_scope, 'called', { codeId }); + + try { + const result = await dbCtx.result(this.statement.tokenRevokeByCodeId, { codeId }); + if (result.rowCount != 1) { + throw new DBErrors.UnexpectedResult('did not revoke token'); + } + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, codeId }); + throw e; + } + } + + + async tokenRefreshRevokeByCodeId(dbCtx, codeId) { + const _scope = _fileScope('tokenRefreshRevokeByCodeId'); + this.logger.debug(_scope, 'called', { codeId }); + + try { + const result = await dbCtx.result(this.statement.tokenRefreshRevokeByCodeId, { codeId }); + if (result.rowCount != 1) { + throw new DBErrors.UnexpectedResult('did not revoke token'); + } + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, codeId }); + throw e; + } + } + + + async tokensGetByIdentifier(dbCtx, identifier) { + const _scope = _fileScope('tokensGetByIdentifier'); + this.logger.debug(_scope, 'called', { identifier }); + + try { + return await dbCtx.manyOrNone(this.statement.tokensGetByIdentifier, { identifier }); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, identifier }); + throw e; + } + } + +} + +module.exports = DatabasePostgres; diff --git a/src/db/postgres/sql/almanac-get-all.sql b/src/db/postgres/sql/almanac-get-all.sql new file mode 100644 index 0000000..b534d20 --- /dev/null +++ b/src/db/postgres/sql/almanac-get-all.sql @@ -0,0 +1,3 @@ +-- +SELECT * FROM almanac + diff --git a/src/db/postgres/sql/almanac-get.sql b/src/db/postgres/sql/almanac-get.sql new file mode 100644 index 0000000..077dfe2 --- /dev/null +++ b/src/db/postgres/sql/almanac-get.sql @@ -0,0 +1,6 @@ +-- +SELECT date +FROM almanac +WHERE event = $(event) +FOR UPDATE + diff --git a/src/db/postgres/sql/almanac-upsert.sql b/src/db/postgres/sql/almanac-upsert.sql new file mode 100644 index 0000000..4bda1bc --- /dev/null +++ b/src/db/postgres/sql/almanac-upsert.sql @@ -0,0 +1,9 @@ +-- +INSERT INTO almanac + (event, date) +VALUES + ($(event), $(date)) +ON CONFLICT (event) DO UPDATE +SET + date = $(date) + diff --git a/src/db/postgres/sql/authentication-get.sql b/src/db/postgres/sql/authentication-get.sql new file mode 100644 index 0000000..f75533e --- /dev/null +++ b/src/db/postgres/sql/authentication-get.sql @@ -0,0 +1,4 @@ +-- +SELECT * +FROM authentication +WHERE identifier = $(identifier) diff --git a/src/db/postgres/sql/authentication-success.sql b/src/db/postgres/sql/authentication-success.sql new file mode 100644 index 0000000..81983ea --- /dev/null +++ b/src/db/postgres/sql/authentication-success.sql @@ -0,0 +1,4 @@ +-- +UPDATE authentication + SET last_authentication = now() + WHERE identifier = $(identifier) diff --git a/src/db/postgres/sql/authentication-upsert.sql b/src/db/postgres/sql/authentication-upsert.sql new file mode 100644 index 0000000..e86d4fb --- /dev/null +++ b/src/db/postgres/sql/authentication-upsert.sql @@ -0,0 +1,9 @@ +-- +INSERT INTO authentication + (identifier, credential) +VALUES + ($(identifier), $(credential)) +ON CONFLICT (identifier) DO UPDATE +SET + identifier = $(identifier), + credential = $(credential) diff --git a/src/db/postgres/sql/profile-get.sql b/src/db/postgres/sql/profile-get.sql new file mode 100644 index 0000000..e4172d1 --- /dev/null +++ b/src/db/postgres/sql/profile-get.sql @@ -0,0 +1,3 @@ +-- +SELECT * FROM profile +WHERE profile = $(profile) diff --git a/src/db/postgres/sql/profile-identifier-insert.sql b/src/db/postgres/sql/profile-identifier-insert.sql new file mode 100644 index 0000000..2c42fac --- /dev/null +++ b/src/db/postgres/sql/profile-identifier-insert.sql @@ -0,0 +1,4 @@ +-- +INSERT INTO profile (profile, identifier_id) + SELECT $(profile), identifier_id FROM authentication WHERE identifier = $(identifier) +ON CONFLICT (identifier_id, profile) DO NOTHING diff --git a/src/db/postgres/sql/profile-scope-insert.sql b/src/db/postgres/sql/profile-scope-insert.sql new file mode 100644 index 0000000..26cc6bb --- /dev/null +++ b/src/db/postgres/sql/profile-scope-insert.sql @@ -0,0 +1,5 @@ +-- +INSERT INTO profile_scope (profile_id, scope_id) + SELECT p.profile_id, s.scope_id FROM profile p, scope s + WHERE p.profile = $(profile) AND s.scope = $(scope) +ON CONFLICT (profile_id, scope_id) DO NOTHING diff --git a/src/db/postgres/sql/profile-scopes-clear.sql b/src/db/postgres/sql/profile-scopes-clear.sql new file mode 100644 index 0000000..bd7827b --- /dev/null +++ b/src/db/postgres/sql/profile-scopes-clear.sql @@ -0,0 +1,6 @@ +-- +DELETE FROM profile_scope +WHERE profile_id IN ( + SELECT profile_id FROM profile WHERE profile = $(profile) +) + diff --git a/src/db/postgres/sql/profile-scopes-set-all.sql b/src/db/postgres/sql/profile-scopes-set-all.sql new file mode 100644 index 0000000..a7e74cf --- /dev/null +++ b/src/db/postgres/sql/profile-scopes-set-all.sql @@ -0,0 +1,5 @@ +-- +INSERT INTO profile_scope (profile_id, scope_id) + SELECT p.profile_id, s.scope_id FROM profile p, scope s + WHERE p.profile = $(profile) AND s.scope = ANY ($(scopes)) + diff --git a/src/db/postgres/sql/profiles-scopes-by-identifier.sql b/src/db/postgres/sql/profiles-scopes-by-identifier.sql new file mode 100644 index 0000000..525ced6 --- /dev/null +++ b/src/db/postgres/sql/profiles-scopes-by-identifier.sql @@ -0,0 +1,10 @@ +-- +SELECT p.profile, s.* + FROM profile p + INNER JOIN authentication a USING (identifier_id) + FULL JOIN profile_scope ps USING (profile_id) + FULL JOIN scope s USING (scope_id) + WHERE a.identifier = $(identifier) +UNION ALL SELECT NULL AS profile, * + FROM scope + WHERE is_manually_added OR is_permanent diff --git a/src/db/postgres/sql/redeem-code.sql b/src/db/postgres/sql/redeem-code.sql new file mode 100644 index 0000000..e61d503 --- /dev/null +++ b/src/db/postgres/sql/redeem-code.sql @@ -0,0 +1,30 @@ +-- +INSERT INTO token ( + created, + code_id, + is_token, + client_id, + profile_id, + duration, + expires, + refresh_duration, + refresh_expires, + resource, + profile_data +) SELECT + $(created)::timestamptz, + $(codeId), + $(isToken), + $(clientId), + p.profile_id, + $(lifespanSeconds)::text::interval, + CASE WHEN $(lifespanSeconds) IS NULL THEN NULL ELSE $(created)::timestamptz + $(lifespanSeconds)::text::interval END, + $(refreshLifespanSeconds)::text::interval, + CASE WHEN $(refreshLifespanSeconds) IS NULL THEN NULL ELSE $(created)::timestamptz + $(refreshLifespanSeconds)::text::interval END, + $(resource), + $(profileData) +FROM profile p INNER JOIN authentication a USING (identifier_id) +WHERE p.profile = $(profile) AND a.identifier = $(identifier) +ON CONFLICT (code_id) DO UPDATE -- repeated redemption attempt invalidates existing token + SET is_revoked = true +RETURNING * diff --git a/src/db/postgres/sql/refresh-code.sql b/src/db/postgres/sql/refresh-code.sql new file mode 100644 index 0000000..339e488 --- /dev/null +++ b/src/db/postgres/sql/refresh-code.sql @@ -0,0 +1,19 @@ +-- +UPDATE token SET + expires = $(refreshed)::timestamptz + duration, + refreshed = $(refreshed)::timestamptz, + refresh_expires = $(refreshed)::timestamptz + refresh_duration, + refresh_count = refresh_count + 1 +WHERE + code_id = $(codeId) +AND + NOT is_revoked +AND + (refresh_expires IS NOT NULL AND refresh_expires > $(refreshed)::timestamptz) +RETURNING + expires, + refresh_expires, + ARRAY( + SELECT s.scope FROM token_scope ts INNER JOIN scope s USING (scope_id) + WHERE ts.code_id = code_id + ) AS scopes diff --git a/src/db/postgres/sql/resource-get.sql b/src/db/postgres/sql/resource-get.sql new file mode 100644 index 0000000..53100f1 --- /dev/null +++ b/src/db/postgres/sql/resource-get.sql @@ -0,0 +1,4 @@ +-- +SELECT * +FROM resource +WHERE resource_id = $(resourceId) diff --git a/src/db/postgres/sql/resource-upsert.sql b/src/db/postgres/sql/resource-upsert.sql new file mode 100644 index 0000000..51d4e94 --- /dev/null +++ b/src/db/postgres/sql/resource-upsert.sql @@ -0,0 +1,10 @@ +-- +INSERT INTO resource + (resource_id, secret, description) +VALUES + (COALESCE($(resourceId)::UUID, uuid_generate_v4()), $(secret), $(description)) +ON CONFLICT (resource_id) DO UPDATE +SET + secret = COALESCE(EXCLUDED.secret, resource.secret), + description = COALESCE(EXCLUDED.description, resource.description) +RETURNING * diff --git a/src/db/postgres/sql/schema/1.0.0/apply.sql b/src/db/postgres/sql/schema/1.0.0/apply.sql new file mode 100644 index 0000000..274dd7a --- /dev/null +++ b/src/db/postgres/sql/schema/1.0.0/apply.sql @@ -0,0 +1,147 @@ +BEGIN; + + CREATE TABLE almanac ( + event TEXT NOT NULL PRIMARY KEY, + date TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT '-infinity'::timestamptz + ); + COMMENT ON TABLE almanac IS $docstring$ +Notable events for service administration. + $docstring$; + + CREATE TABLE authentication ( + identifier_id BIGINT NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY, + created TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), + last_authentication TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT '-infinity'::timestamptz, + identifier TEXT NOT NULL UNIQUE, + credential TEXT + ); + COMMENT ON TABLE authentication IS $docstring$ +Users and their credentials. + $docstring$; + + CREATE TABLE resource ( + resource_id UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v4(), -- few insertions, v4 preferred over v1 + description TEXT NOT NULL DEFAULT '', + created TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), + secret TEXT NOT NULL CHECK(length(secret) > 0) + ); + COMMENT ON TABLE resource IS $docstring$ +External resource servers and their credentials. + $docstring$; + + CREATE TABLE profile ( + profile_id BIGINT NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY, + identifier_id BIGINT NOT NULL REFERENCES authentication(identifier_id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, + profile TEXT NOT NULL, + CONSTRAINT unique_identifier_id_profile UNIQUE (identifier_id, profile) + ); + CREATE INDEX profile_identifier_id_idx ON profile(identifier_id); + CREATE INDEX profile_profile_idx ON profile(profile); + COMMENT ON TABLE profile IS $docstring$ +Profile URIs and the users they are associated with. +$docstring$; + + CREATE TABLE scope ( + scope_id BIGINT NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY, + scope TEXT NOT NULL UNIQUE, + description TEXT NOT NULL DEFAULT '', + application TEXT NOT NULL DEFAULT '', + is_permanent BOOLEAN NOT NULL DEFAULT false, + is_manually_added BOOLEAN NOT NULL DEFAULT false + ); + COMMENT ON TABLE scope IS $docstring$ +All and any scopes encountered. +$docstring$; + COMMENT ON COLUMN scope.is_permanent IS $docstring$ +Prevents deletion of scope, set on seeded scope rows. +$docstring$; + COMMENT ON COLUMN scope.is_manually_added IS $docstring$ +Prevents deletion of scope when no longer referenced, set on user-added scopes. +User can still delete manually. +$docstring$; + CREATE INDEX scope_garbage_collectable_idx ON scope(scope_id) WHERE NOT (is_permanent OR is_manually_added); + COMMENT ON INDEX scope_garbage_collectable_idx IS $docstring$ +Shadow the primary index with a partial to help GC cleanup of client-provided scopes. +$docstring$; + CREATE INDEX scope_is_permanent_idx ON scope(scope_id) WHERE is_permanent; + CREATE INDEX scope_is_manual_idx ON scope(scope_id) WHERE is_manually_added; + + CREATE TABLE profile_scope ( + profile_id BIGINT NOT NULL REFERENCES profile(profile_id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, + scope_id BIGINT NOT NULL REFERENCES scope(scope_id) ON DELETE NO ACTION ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, + PRIMARY KEY (profile_id, scope_id) + ); + COMMENT ON TABLE profile_scope IS $docstring$ +Convenience bindings of available scopes for a profile. +$docstring$; + CREATE INDEX profile_scope_scope_id_idx ON profile_scope(scope_id); + + CREATE TABLE token ( + code_id UUID NOT NULL PRIMARY KEY, + profile_id BIGINT NOT NULL REFERENCES profile(profile_id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, + created TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), + expires TIMESTAMP WITH TIME ZONE, + refresh_expires TIMESTAMP WITH TIME ZONE, + refreshed TIMESTAMP WITH TIME ZONE, + duration INTERVAL, + CONSTRAINT expires_needs_duration CHECK (expires IS NULL OR duration IS NOT NULL), + refresh_duration INTERVAL, + CONSTRAINT refresh_expires_needs_refresh_duration CHECK (refresh_expires IS NULL OR refresh_duration IS NOT NULL), + refresh_count BIGINT NOT NULL DEFAULT 0, + is_revoked BOOLEAN NOT NULL DEFAULT false, + is_token BOOLEAN NOT NULL, + client_id TEXT NOT NULL, + resource TEXT, + profile_data JSONB + ); + CREATE INDEX token_profile_id_idx ON token(profile_id); + CREATE INDEX token_created_idx ON token(created); + CREATE INDEX token_expires_idx ON token(expires); + CREATE INDEX token_refresh_expires_idx ON token(refresh_expires); + CREATE INDEX token_is_revoked_idx ON token(is_revoked) WHERE is_revoked; + COMMENT ON TABLE token IS $docstring$ +Redeemed codes and their current states. +$docstring$; + COMMENT ON COLUMN token.is_token IS $docstring$ +Whether code was redeemed for a token, or only a profile. +We track non-token redemptions to prevent re-redemption while +code is still valid. +$docstring$; + COMMENT ON COLUMN token.resource IS $docstring$ +Tokens granted by ticket redemption are associated with a +resource url for which they are valid. +$docstring$; + COMMENT ON INDEX token_is_revoked_idx IS $docstring$ +A partial index on revoked tokens, to ease cleanup query. +$docstring$; + + CREATE TABLE token_scope ( + code_id UUID NOT NULL REFERENCES token(code_id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, + scope_id BIGINT NOT NULL REFERENCES scope(scope_id) ON DELETE NO ACTION ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, + PRIMARY KEY (code_id, scope_id) + ); + COMMENT ON TABLE token_scope IS $docstring$ +Scopes associated with a token. +$docstring$; + CREATE INDEX token_scope_scope_id_idx ON token_scope(scope_id); + + -- Update schema version + INSERT INTO _meta_schema_version (major, minor, patch) VALUES (1, 0, 0); + + -- Seed scope data + INSERT INTO scope (scope, description, application, is_permanent) VALUES + ('profile', 'Access detailed profile information, including name, image, and url.', 'IndieAuth', true), + ('email', 'Include email address with detailed profile information.', 'IndieAuth', true), + ('create', 'Create new items.', 'MicroPub', true), + ('draft', 'All created items are drafts.', 'MicroPub', true), + ('update', 'Edit existing items.', 'MicroPub', true), + ('delete', 'Remove items.', 'MicroPub', true), + ('media', 'Allow file uploads.', 'MicroPub', true), + ('read', 'Read access to channels.', 'MicroSub', true), + ('follow', 'Management of following list.', 'MicroSub', true), + ('mute', 'Management of user muting.', 'MicroSub', true), + ('block', 'Management of user blocking.', 'MicroSub', true), + ('channels', 'Management of channels.', 'MicroSub', true) + ; + +COMMIT; diff --git a/src/db/postgres/sql/schema/1.0.0/er.dot b/src/db/postgres/sql/schema/1.0.0/er.dot new file mode 100644 index 0000000..147f50b --- /dev/null +++ b/src/db/postgres/sql/schema/1.0.0/er.dot @@ -0,0 +1,105 @@ +digraph indieAutherERD { + graph[ + rankdir=LR, + overlap=false, + splines=true, + label="IndieAuther Entity-Relations\nPostgres\nSchema 1.0.0", + labelloc="t", + fontsize=26, + ]; + // layout=neato; + node[shape=plain]; + edge[arrowhead=crow]; + + token [label=< + <table cellspacing="0" cellborder="1" border="0"> + <tr><td border="2" bgcolor="lightblue">TOKEN</td></tr> + <tr><td port="pk_code_id">code_id</td></tr> + <tr><td port="fk_profile_id">profile_id</td></tr> + <tr><td port="">created</td></tr> + <tr><td port="">expires</td></tr> + <tr><td port="">refresh_expires</td></tr> + <tr><td port="">refreshed</td></tr> + <tr><td port="">duration</td></tr> + <tr><td port="">refresh_duration</td></tr> + <tr><td port="">refresh_count</td></tr> + <tr><td port="">is_revoked</td></tr> + <tr><td port="">is_token</td></tr> + <tr><td port="">client_id</td></tr> + <tr><td port="">resource</td></tr> + <tr><td port="">profile_data</td></tr> + </table> + >]; + profile:pk_profile_id -> token:fk_profile_id; + + scope [label=< + <table cellspacing="0" cellborder="1" border="0"> + <tr><td border="2" bgcolor="lightblue">SCOPE</td></tr> + <tr><td port="pk_scope_id">scope_id</td></tr> + <tr><td port="">scope</td></tr> + <tr><td port="">description</td></tr> + <tr><td port="">application</td></tr> + <tr><td port="">is_permanent</td></tr> + <tr><td port="">is_manually_added</td></tr> + </table> + >]; + + token_scope [label=< + <table cellspacing="0" cellborder="1" border="0"> + <tr><td border="2" bgcolor="lightblue">TOKEN_SCOPE</td></tr> + <tr><td port="fk_code_id">code_id</td></tr> + <tr><td port="fk_scope_id">scope_id</td></tr> + </table> + >]; + token:pk_code_id -> token_scope:fk_code_id; + scope:pk_scope_id -> token_scope:fk_scope_id; + + profile [label=< + <table cellspacing="0" cellborder="1" border="0"> + <tr><td border="2" bgcolor="lightblue">PROFILE</td></tr> + <tr><td port="pk_profile_id">profile_id</td></tr> + <tr><td port="fk_identifier_id">identifier_id</td></tr> + <tr><td port="">profile</td></tr> + </table> + >]; + authentication:pk_identifier_id -> profile:fk_identifier_id; + + profile_scope [label=< + <table cellspacing="0" cellborder="1" border="0"> + <tr><td border="2" bgcolor="lightblue">PROFILE_SCOPE</td></tr> + <tr><td port="fk_profile_id">profile_id</td></tr> + <tr><td port="fk_scope_id">scope_id</td></tr> + </table> + >]; + profile:pk_profile_id -> profile_scope:fk_profile_id; + scope:pk_scope_id -> profile_scope:fk_scope_id; + + authentication [label=< + <table cellspacing="0" cellborder="1" border="0"> + <tr><td border="2" bgcolor="lightblue">AUTHENTICATION</td></tr> + <tr><td port="pk_identifier_id">identifier_id</td></tr> + <tr><td port="">created</td></tr> + <tr><td port="">last_authenticated</td></tr> + <tr><td port="">identifier</td></tr> + <tr><td port="">credential</td></tr> + </table> + >]; + + resource [label=< + <table cellspacing="0" cellborder="1" border="0"> + <tr><td border="2" bgcolor="lightblue">RESOURCE</td></tr> + <tr><td port="pk_resource_id">resource_id</td></tr> + <tr><td port="">description</td></tr> + <tr><td port="">created</td></tr> + <tr><td port="">secret</td></tr> + </table> + >]; + + almanac [label=< + <table cellspacing="0" cellborder="1" border="0"> + <tr><td border="2" bgcolor="lightblue">ALMANAC</td></tr> + <tr><td port="pk_event">event</td></tr> + <tr><td port="">date</td></tr> + </table> + >]; +} diff --git a/src/db/postgres/sql/schema/1.0.0/revert.sql b/src/db/postgres/sql/schema/1.0.0/revert.sql new file mode 100644 index 0000000..af4665a --- /dev/null +++ b/src/db/postgres/sql/schema/1.0.0/revert.sql @@ -0,0 +1,9 @@ +BEGIN; + DROP TABLE authentication CASCADE; + DROP TABLE profile CASCADE; + DROP TABLE token CASCADE; + DROP TABLE scope CASCADE; + DROP TABLE profile_scope CASCADE; + + DELETE FROM _meta_schema_version WHERE major = 1 AND minor = 0 AND patch = 0; +COMMIT; diff --git a/src/db/postgres/sql/schema/init.sql b/src/db/postgres/sql/schema/init.sql new file mode 100644 index 0000000..618781f --- /dev/null +++ b/src/db/postgres/sql/schema/init.sql @@ -0,0 +1,15 @@ +-- +CREATE EXTENSION IF NOT EXISTS pg_stat_statements; +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; + +-- +BEGIN; +CREATE TABLE IF NOT EXISTS _meta_schema_version ( + major BIGINT NOT NULL, + minor BIGINT NOT NULL, + patch BIGINT NOT NULL, + applied TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), + PRIMARY KEY (major, minor, patch) +); +INSERT INTO _meta_schema_version (major, minor, patch) VALUES (0, 0, 0); +COMMIT; diff --git a/src/db/postgres/sql/scope-cleanup.sql b/src/db/postgres/sql/scope-cleanup.sql new file mode 100644 index 0000000..120e3d6 --- /dev/null +++ b/src/db/postgres/sql/scope-cleanup.sql @@ -0,0 +1,8 @@ +-- Remove any un-used, non-permament, non-manually-created scopes. +DELETE FROM scope WHERE scope_id NOT IN ( + SELECT scope_id FROM scope s + INNER JOIN profile_scope ps USING (scope_id) + UNION All + SELECT scope_id FROM scope s + INNER JOIN token_scope ts USING (scope_id) +) AND NOT (is_permanent OR is_manually_added) diff --git a/src/db/postgres/sql/scope-delete.sql b/src/db/postgres/sql/scope-delete.sql new file mode 100644 index 0000000..9fd42a2 --- /dev/null +++ b/src/db/postgres/sql/scope-delete.sql @@ -0,0 +1,3 @@ +-- remove an inpermanent scope +DELETE FROM scope + WHERE scope = $(scope) AND is_permanent = false diff --git a/src/db/postgres/sql/scope-in-use.sql b/src/db/postgres/sql/scope-in-use.sql new file mode 100644 index 0000000..a09c540 --- /dev/null +++ b/src/db/postgres/sql/scope-in-use.sql @@ -0,0 +1,13 @@ +-- return whether a scope is currently in use, either a profile setting or on a token +SELECT EXISTS ( + SELECT 1 FROM scope s + INNER JOIN profile_scope ps USING (scope_id) + WHERE s.scope = $(scope) + UNION All + SELECT 1 FROM scope s + INNER JOIN token_scope ts USING (scope_id) + WHERE s.scope = $(scope) + UNION All + SELECT 1 FROM scope s + WHERE s.scope = $(scope) AND s.is_permanent +) AS in_use diff --git a/src/db/postgres/sql/scope-upsert.sql b/src/db/postgres/sql/scope-upsert.sql new file mode 100644 index 0000000..543d89d --- /dev/null +++ b/src/db/postgres/sql/scope-upsert.sql @@ -0,0 +1,14 @@ +-- +-- N.B. weirdness with postgres empty string null equivalence and coalesce +INSERT INTO scope ( + scope, application, description, is_manually_added +) VALUES ( + $(scope), + CASE WHEN $(application) IS NULL THEN '' ELSE $(application) END, + CASE WHEN $(description) IS NULL THEN '' ELSE $(description) END, + COALESCE($(manuallyAdded), false) +) ON CONFLICT (scope) DO UPDATE +SET + application = CASE WHEN $(application) IS NULL THEN EXCLUDED.application ELSE $(application) END, + description = CASE WHEN $(description) IS NULL THEN EXCLUDED.description ELSE $(description) END, + is_manually_added = EXCLUDED.is_manually_added OR COALESCE($(manuallyAdded), false) diff --git a/src/db/postgres/sql/scopes-insert.sql b/src/db/postgres/sql/scopes-insert.sql new file mode 100644 index 0000000..a933e28 --- /dev/null +++ b/src/db/postgres/sql/scopes-insert.sql @@ -0,0 +1,6 @@ +-- Insert an externally-provided scope, or ignore. +INSERT INTO scope + (scope) +SELECT + unnest(${scopes}) +ON CONFLICT (scope) DO NOTHING diff --git a/src/db/postgres/sql/token-cleanup.sql b/src/db/postgres/sql/token-cleanup.sql new file mode 100644 index 0000000..9c2c744 --- /dev/null +++ b/src/db/postgres/sql/token-cleanup.sql @@ -0,0 +1,26 @@ +-- Remove tokens no longer in use. +-- only clean after code has expired +WITH +cleanable_codes AS ( + SELECT t.code_id, t.is_token, t.is_revoked, t.expires, t.refresh_expires FROM token t + WHERE t.created < (now() - $(codeLifespanSeconds)::text::interval) +) +DELETE FROM token WHERE code_id IN ( + SELECT code_id FROM cleanable_codes + WHERE + NOT is_token -- profile-only redemptions + OR ( + is_token AND ( + is_revoked -- revoked + OR ( + expires < now() AND ( + -- expired and unrefreshable + refresh_expires IS NULL + OR + -- expired and refresh expired + (refresh_expires IS NOT NULL AND refresh_expires < now()) + ) + ) + ) + ) +) diff --git a/src/db/postgres/sql/token-get-by-code-id.sql b/src/db/postgres/sql/token-get-by-code-id.sql new file mode 100644 index 0000000..23f0f73 --- /dev/null +++ b/src/db/postgres/sql/token-get-by-code-id.sql @@ -0,0 +1,24 @@ +-- +SELECT + t.code_id, + p.profile, + t.created, + t.expires, + t.refresh_expires, + t.refreshed, + t.duration, + t.refresh_duration, + t.refresh_count, + t.is_revoked, + t.is_token, + t.client_id, + t.profile_data, + a.identifier, + ARRAY( + SELECT s.scope FROM token_scope ts INNER JOIN scope s USING (scope_id) + WHERE ts.code_id = t.code_id + ) AS scopes +FROM token t + INNER JOIN profile p USING (profile_id) + INNER JOIN authentication a USING (identifier_id) +WHERE code_id = $(codeId) diff --git a/src/db/postgres/sql/token-refresh-revoke-by-code-id.sql b/src/db/postgres/sql/token-refresh-revoke-by-code-id.sql new file mode 100644 index 0000000..4c7033d --- /dev/null +++ b/src/db/postgres/sql/token-refresh-revoke-by-code-id.sql @@ -0,0 +1,5 @@ +-- Revoke the refresh-token for a token +UPDATE token SET + refresh_expires = NULL, + refresh_duration = NULL +WHERE code_id = $(codeId) diff --git a/src/db/postgres/sql/token-revoke-by-code-id.sql b/src/db/postgres/sql/token-revoke-by-code-id.sql new file mode 100644 index 0000000..7a57efc --- /dev/null +++ b/src/db/postgres/sql/token-revoke-by-code-id.sql @@ -0,0 +1,5 @@ +-- +UPDATE token SET + is_revoked = true, + refresh_expires = NULL +WHERE code_id = $(codeId) diff --git a/src/db/postgres/sql/token-scopes-remove.sql b/src/db/postgres/sql/token-scopes-remove.sql new file mode 100644 index 0000000..dd667f2 --- /dev/null +++ b/src/db/postgres/sql/token-scopes-remove.sql @@ -0,0 +1,7 @@ +-- +DELETE FROM token_scope +WHERE (code_id, scope_id) IN ( + SELECT code_id, scope_id FROM token_scope ts + INNER JOIN scope s USING (scope_id) + WHERE scope = ANY($(removeScopes)) AND code_id = $(codeId) +) diff --git a/src/db/postgres/sql/token-scopes-set.sql b/src/db/postgres/sql/token-scopes-set.sql new file mode 100644 index 0000000..1557179 --- /dev/null +++ b/src/db/postgres/sql/token-scopes-set.sql @@ -0,0 +1,4 @@ +-- +INSERT INTO token_scope (code_id, scope_id) + SELECT $(codeId), scope_id FROM scope WHERE scope = ANY ($(scopes)) + diff --git a/src/db/postgres/sql/tokens-get-by-identifier.sql b/src/db/postgres/sql/tokens-get-by-identifier.sql new file mode 100644 index 0000000..f8ec90e --- /dev/null +++ b/src/db/postgres/sql/tokens-get-by-identifier.sql @@ -0,0 +1,26 @@ +-- +SELECT + t.code_id, + p.profile, + t.created, + t.expires, + t.refresh_expires, + t.refreshed, + t.duration, + t.refresh_duration, + t.refresh_count, + t.is_revoked, + t.is_token, + t.client_id, + t.resource, + t.profile_data, + a.identifier, + ARRAY( + SELECT s.scope FROM token_scope ts INNER JOIN scope s USING (scope_id) + WHERE ts.code_id = t.code_id + ) AS scopes +FROM token t + INNER JOIN profile p USING (profile_id) + INNER JOIN authentication a USING (identifier_id) + WHERE a.identifier = $(identifier) + ORDER BY GREATEST(t.created, t.refreshed) DESC diff --git a/src/db/schema-version-helper.js b/src/db/schema-version-helper.js new file mode 100644 index 0000000..65a1e39 --- /dev/null +++ b/src/db/schema-version-helper.js @@ -0,0 +1,131 @@ +'use strict'; + +const fs = require('fs'); +const path = require('path'); + +/** + * Utility functions for wrangling schema migrations. + * This mostly just deals with sorting and comparing 'x.y.z' version + * strings, with some presumptions about directory layouts and whatnot. + */ + +/** + * @typedef {Object} SchemaVersionObject + * @property {Number} major + * @property {Number} minor + * @property {Number} patch + */ + + +/** + * Split a dotted version string into parts. + * @param {String} v + * @returns {SchemaVersionObject} + */ +function schemaVersionStringToObject(v) { + const [ major, minor, patch ] = v.split('.', 3).map((x) => parseInt(x, 10)); + return { major, minor, patch }; +} + + +/** + * Render a version object numerically. + * @param {SchemaVersionObject} v + * @returns {Number} + */ +function schemaVersionObjectToNumber(v) { + const vScale = 1000; + return parseInt(v.major) * vScale * vScale + parseInt(v.minor) * vScale + parseInt(v.patch); +} + + +/** + * Convert dotted version string into number. + * @param {String} v + * @returns {Number} + */ +function schemaVersionStringToNumber(v) { + return schemaVersionObjectToNumber(schemaVersionStringToObject(v)); +} + + +/** + * Version string comparison, for sorting. + * @param {String} a + * @param {String} b + * @returns {Number} + */ +function schemaVersionStringCmp(a, b) { + return schemaVersionStringToNumber(a) - schemaVersionStringToNumber(b); +} + + +/** + * Check if an entry in a directory is a directory containing a migration file. + * @param {String} schemaDir + * @param {String} name + * @returns {Boolean} + */ +function isSchemaMigrationDirectory(schemaDir, name, migrationFile = 'apply.sql') { + // eslint-disable-next-line security/detect-non-literal-fs-filename + const nameStat = fs.statSync(path.join(schemaDir, name)); + if (nameStat.isDirectory()) { + let applyStat; + try { + // eslint-disable-next-line security/detect-non-literal-fs-filename + applyStat = fs.statSync(path.join(schemaDir, name, migrationFile)); + return applyStat.isFile(); + } catch (e) { + return false; + } + } + return false; +} + + +/** + * Return an array of schema migration directory names within engineDir, + * sorted in increasing order. + * @param {String} engineDir + * @returns {String[]} + */ +function allSchemaVersions(engineDir) { + const schemaDir = path.join(engineDir, 'sql', 'schema'); + // eslint-disable-next-line security/detect-non-literal-fs-filename + const availableVersions = fs.readdirSync(schemaDir).filter((d) => isSchemaMigrationDirectory(schemaDir, d)); + availableVersions.sort(schemaVersionStringCmp); + return availableVersions; +} + + +/** + * Return an array of schema migration directory names within engineDir, + * which are within supported range, and are greater than the current + * @param {String} engineDir + * @param {SchemaVersionObject} current + * @param {Object} supported + * @param {SchemaVersionObject} supported.min + * @param {SchemaVersionObject} supported.max + * @returns {String[]} + */ +function unappliedSchemaVersions(engineDir, current, supported) { + const min = schemaVersionObjectToNumber(supported.min); + const max = schemaVersionObjectToNumber(supported.max); + const cur = schemaVersionObjectToNumber(current); + const available = allSchemaVersions(engineDir); + return available.filter((a) => { + a = schemaVersionStringToNumber(a); + return a >= min && a <= max && a > cur; + }); +} + + +module.exports = { + schemaVersionStringToObject, + schemaVersionObjectToNumber, + schemaVersionStringToNumber, + schemaVersionStringCmp, + isSchemaMigrationDirectory, + allSchemaVersions, + unappliedSchemaVersions, +}; \ No newline at end of file diff --git a/src/db/sqlite/index.js b/src/db/sqlite/index.js new file mode 100644 index 0000000..878a004 --- /dev/null +++ b/src/db/sqlite/index.js @@ -0,0 +1,739 @@ +'use strict'; + +const common = require('../../common'); +const Database = require('../abstract'); +const DBErrors = require('../errors'); +const svh = require('../schema-version-helper'); +const SQLite = require('better-sqlite3'); +const fs = require('fs'); +const path = require('path'); +const uuid = require('uuid'); +const { performance } = require('perf_hooks'); + +const _fileScope = common.fileScope(__filename); + +const schemaVersionsSupported = { + min: { + major: 1, + minor: 0, + patch: 0, + }, + max: { + major: 1, + minor: 0, + patch: 0, + }, +}; + +// max of signed int64 (2^63 - 1), should be enough +// const EPOCH_FOREVER = BigInt('9223372036854775807'); + +class DatabaseSQLite extends Database { + constructor(logger, options) { + super(logger, options); + + const connectionString = options.db.connectionString || 'sqlite://:memory:'; + const csDelim = '://'; + const dbFilename = connectionString.slice(connectionString.indexOf(csDelim) + csDelim.length); + + const queryLogLevel = options.db.queryLogLevel; + + const sqliteOptions = { + ...(queryLogLevel && { + // eslint-disable-next-line security/detect-object-injection + verbose: (query) => this.logger[queryLogLevel](_fileScope('SQLite:verbose'), '', { query }), + }), + }; + this.db = new SQLite(dbFilename, sqliteOptions); + this.schemaVersionsSupported = schemaVersionsSupported; + this.changesSinceLastOptimize = BigInt(0); + this.optimizeAfterChanges = options.db.sqliteOptimizeAfterChanges || 0; // Default to no periodic optimization. + this.db.pragma('foreign_keys = on'); // Enforce consistency. + this.db.pragma('journal_mode = WAL'); // Be faster, expect local filesystem. + this.db.defaultSafeIntegers(true); // This probably isn't necessary, but by using these BigInts we keep weird floats out of the query logs. + + this._initTables(); + this._initStatements(); + } + + + /** + * Boolean to 0/1 representation for SQLite params. + * @param {Boolean} bool + * @returns {Number} + */ + static _booleanToNumeric(bool) { + // eslint-disable-next-line security/detect-object-injection + return { + true: 1, + false: 0, + }[bool]; + } + + + /** + * SQLite cannot prepare its statements without a schema, ensure such exists. + */ + _initTables() { + const _scope = _fileScope('_initTables'); + + // Migrations rely upon this table, ensure it exists. + const metaVersionTable = '_meta_schema_version'; + const tableExists = this.db.prepare('SELECT name FROM sqlite_master WHERE type=:type AND name=:name').pluck(true).bind({ type: 'table', name: metaVersionTable }); + let metaExists = tableExists.get(); + if (metaExists === undefined) { + const fPath = path.join(__dirname, 'sql', 'schema', 'init.sql'); + // eslint-disable-next-line security/detect-non-literal-fs-filename + const fSql = fs.readFileSync(fPath, { encoding: 'utf8' }); + this.db.exec(fSql); + metaExists = tableExists.get(); + /* istanbul ignore if */ + if (metaExists === undefined) { + throw new DBErrors.UnexpectedResult(`did not create ${metaVersionTable} table`); + } + this.logger.info(_scope, 'created schema version table', { metaVersionTable }); + } + + // Apply migrations + const currentSchema = this._currentSchema(); + const migrationsWanted = svh.unappliedSchemaVersions(__dirname, currentSchema, this.schemaVersionsSupported); + this.logger.debug(_scope, 'schema migrations wanted', { migrationsWanted }); + migrationsWanted.forEach((v) => { + const fPath = path.join(__dirname, 'sql', 'schema', v, 'apply.sql'); + // eslint-disable-next-line security/detect-non-literal-fs-filename + const fSql = fs.readFileSync(fPath, { encoding: 'utf8' }); + this.logger.info(_scope, 'applying migration', { version: v }); + this.db.exec(fSql); + }); + } + + + _initStatements() { + const _scope = _fileScope('_initStatements'); + const sqlDir = path.join(__dirname, 'sql'); + this.statement = {}; + + // Decorate the statement calls we use with timing and logging. + const wrapFetch = (logName, statementName, fn) => { + const _wrapScope = _fileScope(logName); + return (...args) => { + const startTimestampMs = performance.now(); + const rows = fn(...args); + DatabaseSQLite._deOphidiate(rows); + const elapsedTimeMs = performance.now() - startTimestampMs; + this.logger.debug(_wrapScope, 'complete', { statementName, elapsedTimeMs }); + return rows; + }; + }; + const wrapRun = (logName, statementName, fn) => { + const _wrapScope = _fileScope(logName); + return (...args) => { + const startTimestampMs = performance.now(); + const result = fn(...args); + const elapsedTimeMs = performance.now() - startTimestampMs; + this._updateChanges(result); + this.logger.debug(_wrapScope, 'complete', { ...result, statementName, elapsedTimeMs }); + result.duration = elapsedTimeMs; + return result; + }; + }; + + // eslint-disable-next-line security/detect-non-literal-fs-filename + for (const f of fs.readdirSync(sqlDir)) { + const fPath = path.join(sqlDir, f); + const { name: fName, ext: fExt } = path.parse(f); + // eslint-disable-next-line security/detect-non-literal-fs-filename + const stat = fs.statSync(fPath); + if (!stat.isFile() + || fExt.toLowerCase() !== '.sql') { + continue; + } + // eslint-disable-next-line security/detect-non-literal-fs-filename + const fSql = fs.readFileSync(fPath, { encoding: 'utf8' }); + const statementName = common.camelfy(fName.toLowerCase(), '-'); + let statement; + try { + statement = this.db.prepare(fSql); + } catch (e) /* istanbul ignore next */ { + this.logger.error(_scope, 'failed to prepare statement', { error: e, file: f }); + throw e; + } + // eslint-disable-next-line security/detect-object-injection + this.statement[statementName] = statement; + const { get: origGet, all: origAll, run: origRun } = statement; + statement.get = wrapFetch('SQLite:get', statementName, origGet.bind(statement)); + statement.all = wrapFetch('SQLite:all', statementName, origAll.bind(statement)); + statement.run = wrapRun('SQLite:run', statementName, origRun.bind(statement)); + } + this.statement._optimize = this.db.prepare('SELECT * FROM pragma_optimize(0xffff)'); + + this.logger.debug(_scope, 'statements initialized', { statements: Object.keys(this.statement).length }); + } + + + static _deOphidiate(rows) { + const rowsIsArray = Array.isArray(rows); + if (!rowsIsArray) { + rows = [rows]; + } + const exemplaryRow = rows[0]; + for (const prop in exemplaryRow) { + const camel = common.camelfy(prop); + if (!(camel in exemplaryRow)) { + for (const d of rows) { + d[camel] = d[prop]; // eslint-disable-line security/detect-object-injection + delete d[prop]; // eslint-disable-line security/detect-object-injection + } + } + } + return rowsIsArray ? rows : rows[0]; + } + + + _currentSchema() { + return this.db.prepare('SELECT major, minor, patch FROM _meta_schema_version ORDER BY major DESC, minor DESC, patch DESC LIMIT 1').get(); + } + + + healthCheck() { + const _scope = _fileScope('healthCheck'); + this.logger.debug(_scope, 'called', {}); + if (!this.db.open) { + throw new DBErrors.UnexpectedResult('database is not open'); + } + return { open: this.db.open }; + } + + + _closeConnection() { + this.db.close(); + } + + + _optimize() { + const _scope = _fileScope('_optimize'); + + const optimize = this.statement._optimize.all(); + this.logger.debug(_scope, 'optimize', { optimize, changes: this.changesSinceLastOptimize }); + this.db.pragma('optimize'); + this.changesSinceLastOptimize = BigInt(0); + } + + + _updateChanges(dbResult) { + if (this.optimizeAfterChanges) { + this.changesSinceLastOptimize += BigInt(dbResult.changes); + if (this.changesSinceLastOptimize >= this.optimizeAfterChanges) { + this._optimize(); + } + } + } + + + _purgeTables(really) { + if (really) { + [ + 'authentication', + 'profile', + 'token', + ].map((table) => { + const result = this.db.prepare(`DELETE FROM ${table}`).run(); + this.logger.debug(_fileScope('_purgeTables'), 'success', { table, result }); + }); + } + } + + + context(fn) { + return fn(this.db); + } + + + transaction(dbCtx, fn) { + dbCtx = dbCtx || this.db; + return dbCtx.transaction(fn)(); + } + + + static _almanacToNative(entry) { + return { + event: entry.event, + date: new Date(Number(entry.epoch) * 1000), + }; + } + + almanacGetAll(dbCtx) { // eslint-disable-line no-unused-vars + const _scope = _fileScope('almanacGetAll'); + this.logger.debug(_scope, 'called'); + + try { + const entries = this.statement.almanacGetAll.all(); + return entries.map((entry) => DatabaseSQLite._almanacToNative(entry)); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e }); + throw e; + } + } + + + static _authenticationToNative(authentication) { + if (authentication) { + authentication.created = new Date(Number(authentication.created) * 1000); + authentication.lastAuthentication = new Date(Number(authentication.lastAuthentication) * 1000); + } + return authentication; + } + + + authenticationGet(dbCtx, identifier) { + const _scope = _fileScope('authenticationGet'); + this.logger.debug(_scope, 'called', { identifier }); + + try { + const authentication = this.statement.authenticationGet.get({ identifier }); + return DatabaseSQLite._authenticationToNative(authentication); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, identifier }); + throw e; + } + } + + + authenticationSuccess(dbCtx, identifier) { + const _scope = _fileScope('authenticationSuccess'); + this.logger.debug(_scope, 'called', { identifier }); + + try { + const result = this.statement.authenticationSuccess.run({ identifier }); + if (result.changes != 1) { + throw new DBErrors.UnexpectedResult('did not update authentication success'); + } + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, identifier }); + throw e; + } + } + + + authenticationUpsert(dbCtx, identifier, credential) { + const _scope = _fileScope('authenticationUpsert'); + const scrubbedCredential = '*'.repeat((credential || '').length); + this.logger.debug(_scope, 'called', { identifier, scrubbedCredential }); + + let result; + try { + result = this.statement.authenticationUpsert.run({ identifier, credential }); + if (result.changes != 1) { + throw new DBErrors.UnexpectedResult('did not upsert authentication'); + } + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, identifier, scrubbedCredential }); + throw e; + } + } + + + profileIdentifierInsert(dbCtx, profile, identifier) { + const _scope = _fileScope('profileIdentifierInsert'); + this.logger.debug(_scope, 'called', { profile, identifier }); + + try { + const result = this.statement.profileIdentifierInsert.run({ profile, identifier }); + if (result.changes != 1) { + throw new DBErrors.UnexpectedResult('did not insert profile identifier relationship'); + } + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, profile, identifier }); + throw e; + } + } + + + profileIsValid(dbCtx, profile) { + const _scope = _fileScope('profileIsValid'); + this.logger.debug(_scope, 'called', { profile }); + + try { + const profileResponse = this.statement.profileGet.get({ profile }); + return !!profileResponse; + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, profile }); + throw e; + } + } + + + profileScopeInsert(dbCtx, profile, scope) { + const _scope = _fileScope('profileScopeInsert'); + this.logger.debug(_scope, 'called', { profile, scope }); + + try { + const result = this.statement.profileScopeInsert.run({ profile, scope }); + // Duplicate inserts get ignored + if (result.changes != 1 && result.changes != 0) { + throw new DBErrors.UnexpectedResult('did not insert profile scope'); + } + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, profile, scope }); + throw e; + } + } + + + profileScopesSetAll(dbCtx, profile, scopes) { + const _scope = _fileScope('profileScopesSetAll'); + this.logger.debug(_scope, 'called', { profile, scopes }); + + try { + this.transaction(dbCtx, () => { + this.statement.profileScopesClear.run({ profile }); + if (scopes.length) { + scopes.forEach((scope) => { + this.statement.profileScopeInsert.run({ profile, scope }); + }); + } + }); // transaction + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, profile, scopes }); + throw e; + } + } + + + profilesScopesByIdentifier(dbCtx, identifier) { + const _scope = _fileScope('profilesScopesByIdentifier'); + this.logger.debug(_scope, 'called', { identifier }); + + try { + const profileScopesRows = this.statement.profilesScopesByIdentifier.all({ identifier }); + return Database._profilesScopesBuilder(profileScopesRows); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, identifier }); + throw e; + } + } + + + redeemCode(dbCtx, { codeId, created, isToken, clientId, profile, identifier, scopes, lifespanSeconds, refreshLifespanSeconds, profileData }) { + const _scope = _fileScope('redeemCode'); + this.logger.debug(_scope, 'called', { codeId, created, isToken, clientId, profile, identifier, scopes, lifespanSeconds, refreshLifespanSeconds, profileData }); + + let result, ret = false; + try { + if (profileData) { + profileData = JSON.stringify(profileData); + } + this.transaction(dbCtx, () => { + result = this.statement.redeemCode.get({ codeId, created: common.dateToEpoch(created), isToken: DatabaseSQLite._booleanToNumeric(isToken), clientId, profile, identifier, lifespanSeconds, refreshLifespanSeconds, profileData }); + if (!result) { + this.logger.error(_scope, 'failed', { result }); + throw new DBErrors.UnexpectedResult('did not redeem code'); + } + // Abort and return false if redemption resulted in revocation. + if (result.isRevoked) { + return; + } + + // Ensure there are entries for all scopes, and associate with token. + scopes.forEach((scope) => { + this.statement.scopeInsert.run({ scope }); + this.statement.tokenScopeSet.run({ codeId, scope }); + }); + ret = true; + }); // tx + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, codeId, isToken, clientId, profile, identifier, scopes, lifespanSeconds, refreshLifespanSeconds, profileData }); + throw e; + } + return ret; + } + + + static _refreshCodeResponseToNative(refreshResponse) { + if (refreshResponse) { + ['expires', 'refreshExpires'].forEach((epochField) => { + if (refreshResponse[epochField]) { // eslint-disable-line security/detect-object-injection + refreshResponse[epochField] = new Date(Number(refreshResponse[epochField]) * 1000); // eslint-disable-line security/detect-object-injection + } + }); + } + return refreshResponse; + } + + + refreshCode(dbCtx, codeId, refreshed, removeScopes) { + const _scope = _fileScope('refreshCode'); + this.logger.debug(_scope, 'called', { codeId, refreshed, removeScopes }); + + try { + return this.transaction(dbCtx, () => { + const refreshResponse = this.statement.refreshCode.get({ codeId, refreshed: common.dateToEpoch(refreshed) }); + if (refreshResponse) { + removeScopes.forEach((scope) => { + const result = this.statement.tokenScopeRemove.run({ codeId, scope }); + if (result?.changes != 1) { + this.logger.error(_scope, 'failed to remove token scope', { codeId, scope }); + throw new DBErrors.UnexpectedResult('did not remove scope from token'); + } + }); + if (removeScopes.length) { + refreshResponse.scopes = (this.statement.tokenScopesGetByCodeId.all({ codeId }) || []) + .map((row) => row.scope); + } + } else { + this.logger.debug(_scope, 'did not refresh token', {}); + } + return DatabaseSQLite._refreshCodeResponseToNative(refreshResponse); + }); // tx + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, codeId, refreshed }); + throw e; + } + } + + + static _resourceToNative(resource) { + if (resource) { + resource.created = new Date(Number(resource.created) * 1000); + } + return resource; + } + + + resourceGet(dbCtx, resourceId) { + const _scope = _fileScope('resourceGet'); + this.logger.debug(_scope, 'called', { resourceId }); + + try { + const resource = this.statement.resourceGet.get({ resourceId }); + return DatabaseSQLite._resourceToNative(resource); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, resourceId }); + throw e; + } + } + + + resourceUpsert(dbCtx, resourceId, secret, description) { + const _scope = _fileScope('resourceUpsert'); + this.logger.debug(_scope, 'called', { resourceId }); + + try { + if (!resourceId) { + resourceId = uuid.v4(); + } + const result = this.statement.resourceUpsert.run({ resourceId, secret, description }); + if (result.changes != 1) { + throw new DBErrors.UnexpectedResult('did not upsert resource'); + } + const resource = this.statement.resourceGet.get({ resourceId }); + return DatabaseSQLite._resourceToNative(resource); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, resourceId, secret, description }); + throw e; + } + } + + + scopeCleanup(dbCtx, atLeastMsSinceLast) { + const _scope = _fileScope('scopeCleanup'); + this.logger.debug(_scope, 'called', { atLeastMsSinceLast }); + + const almanacEvent = 'scopeCleanup'; + try { + return this.db.transaction(() => { + + // Check that enough time has passed since last cleanup + const nowEpoch = BigInt(common.dateToEpoch()); + const { epoch: lastCleanupEpoch } = this.statement.almanacGet.get({ event: almanacEvent }) || { epoch: 0n }; + const elapsedMs = (nowEpoch - lastCleanupEpoch) * 1000n; + if (elapsedMs < atLeastMsSinceLast) { + this.logger.debug(_scope, 'skipping token cleanup, too soon', { lastCleanupEpoch, elapsedMs, atLeastMsSinceLast }); + return; + } + + // Do the cleanup + const { changes: scopesRemoved } = this.statement.scopeCleanup.run(); + + // Update the last cleanup time + const result = this.statement.almanacUpsert.run({ event: almanacEvent, epoch: nowEpoch }); + if (result.changes != 1) { + throw new DBErrors.UnexpectedResult('did not update almanac'); + } + + this.logger.debug(_scope, 'finished', { scopesRemoved, atLeastMsSinceLast }); + return scopesRemoved; + }).exclusive(); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, atLeastMsSinceLast }); + throw e; + } + } + + + scopeDelete(dbCtx, scope) { + const _scope = _fileScope('scopeDelete'); + this.logger.debug(_scope, 'called', { scope }); + + try { + return this.transaction(dbCtx, () => { + const { inUse } = this.statement.scopeInUse.get({ scope }); + if (inUse) { + this.logger.debug(_scope, 'not deleted, in use', { scope }); + return false; + } + const result = this.statement.scopeDelete.run({ scope }); + if (result.changes == 0) { + this.logger.debug(_scope, 'no such scope', { scope }); + } else { + this.logger.debug(_scope, 'deleted', { scope }); + } + return true; + }); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, scope }); + throw e; + } + } + + + scopeUpsert(dbCtx, scope, application, description, manuallyAdded) { + const _scope = _fileScope('scopeUpsert'); + this.logger.debug(_scope, 'called', { scope, application, description, manuallyAdded }); + + try { + const result = this.statement.scopeUpsert.run({ scope, application, description, manuallyAdded: DatabaseSQLite._booleanToNumeric(manuallyAdded) }); + if (result.changes != 1) { + throw new DBErrors.UnexpectedResult('did not upsert scope'); + } + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, scope, application, description, manuallyAdded }); + throw e; + } + } + + + tokenCleanup(dbCtx, codeLifespanSeconds, atLeastMsSinceLast) { + const _scope = _fileScope('tokenCleanup'); + this.logger.debug(_scope, 'called', { codeLifespanSeconds, atLeastMsSinceLast }); + + const almanacEvent = 'tokenCleanup'; + try { + return this.db.transaction(() => { + + // Check that enough time has passed since last cleanup + const nowEpoch = BigInt(common.dateToEpoch()); + const { epoch: lastCleanupEpoch } = this.statement.almanacGet.get({ event: almanacEvent }) || { epoch: 0n }; + const elapsedMs = (nowEpoch - lastCleanupEpoch) * 1000n; + if (elapsedMs < atLeastMsSinceLast) { + this.logger.debug(_scope, 'skipping token cleanup, too soon', { lastCleanupEpoch, elapsedMs, atLeastMsSinceLast }); + return; + } + + // Do the cleanup + const { changes: tokensRemoved } = this.statement.tokenCleanup.run({ codeLifespanSeconds }); + + // Update the last cleanup time + const result = this.statement.almanacUpsert.run({ event: almanacEvent, epoch: nowEpoch }); + if (result.changes != 1) { + throw new DBErrors.UnexpectedResult('did not update almanac'); + } + + this.logger.debug(_scope, 'finished', { tokensRemoved, codeLifespanSeconds, atLeastMsSinceLast }); + return tokensRemoved; + }).exclusive(); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, codeLifespanSeconds, atLeastMsSinceLast }); + throw e; + } + } + + + static _tokenToNative(token) { + if (token) { + token.created = new Date(Number(token.created) * 1000); + if (token.expires || token.expires == 0) { + token.expires = new Date(Number(token.expires) * 1000); + } + if (token.refreshExpires || token.refreshExpires == 0) { + token.refreshExpires = new Date(Number(token.refreshExpires) * 1000); + } + if (token.refreshed || token.refreshed == 0) { + token.refreshed = new Date(Number(token.refreshed) * 1000); + } + token.isRevoked = !!token.isRevoked; + token.isToken = !!token.isToken; + if (token.profileData) { + token.profileData = JSON.parse(token.profileData); + } + } + return token; + } + + + tokenGetByCodeId(dbCtx, codeId) { + const _scope = _fileScope('tokenGetByCodeId'); + this.logger.debug(_scope, 'called', { codeId }); + + try { + return this.transaction(dbCtx, () => { + const token = this.statement.tokenGetByCodeId.get({ codeId }); + token.scopes = (this.statement.tokenScopesGetByCodeId.all({ codeId }) || []) + .map((row) => row.scope); + return DatabaseSQLite._tokenToNative(token); + }); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, codeId }); + throw e; + } + } + + + tokenRefreshRevokeByCodeId(dbCtx, codeId) { + const _scope = _fileScope('tokenRefreshRevokeByCodeId'); + this.logger.debug(_scope, 'called', { codeId }); + + try { + const result = this.statement.tokenRefreshRevokeByCodeId.run({ codeId }); + if (result.changes != 1) { + throw new DBErrors.UnexpectedResult('did not revoke refresh'); + } + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, codeId }); + throw e; + } + } + + + tokenRevokeByCodeId(dbCtx, codeId) { + const _scope = _fileScope('tokenRevokeByCodeId'); + this.logger.debug(_scope, 'called', { codeId }); + + try { + const result = this.statement.tokenRevokeByCodeId.run({ codeId }); + if (result.changes != 1) { + throw new DBErrors.UnexpectedResult('did not revoke token'); + } + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, codeId }); + throw e; + } + } + + + tokensGetByIdentifier(dbCtx, identifier) { + const _scope = _fileScope('tokensGetByIdentifier'); + this.logger.debug(_scope, 'called', { identifier }); + + try { + const tokens = this.statement.tokensGetByIdentifier.all({ identifier }); + return tokens.map(DatabaseSQLite._tokenToNative); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, identifier }); + throw e; + } + } + +} + +module.exports = DatabaseSQLite; \ No newline at end of file diff --git a/src/db/sqlite/sql/almanac-get-all.sql b/src/db/sqlite/sql/almanac-get-all.sql new file mode 100644 index 0000000..fddd282 --- /dev/null +++ b/src/db/sqlite/sql/almanac-get-all.sql @@ -0,0 +1,2 @@ +-- +SELECT * FROM almanac diff --git a/src/db/sqlite/sql/almanac-get.sql b/src/db/sqlite/sql/almanac-get.sql new file mode 100644 index 0000000..00dc708 --- /dev/null +++ b/src/db/sqlite/sql/almanac-get.sql @@ -0,0 +1,2 @@ +-- +SELECT epoch FROM almanac WHERE event = :event diff --git a/src/db/sqlite/sql/almanac-upsert.sql b/src/db/sqlite/sql/almanac-upsert.sql new file mode 100644 index 0000000..fc8be48 --- /dev/null +++ b/src/db/sqlite/sql/almanac-upsert.sql @@ -0,0 +1,9 @@ +-- +INSERT INTO almanac + (event, epoch) +VALUES + (:event, :epoch) +ON CONFLICT (event) DO UPDATE +SET + epoch = :epoch + diff --git a/src/db/sqlite/sql/authentication-get.sql b/src/db/sqlite/sql/authentication-get.sql new file mode 100644 index 0000000..687e54a --- /dev/null +++ b/src/db/sqlite/sql/authentication-get.sql @@ -0,0 +1,8 @@ +-- +SELECT + created, + last_authentication, + identifier, + credential +FROM authentication +WHERE identifier = :identifier diff --git a/src/db/sqlite/sql/authentication-success.sql b/src/db/sqlite/sql/authentication-success.sql new file mode 100644 index 0000000..b4c45a6 --- /dev/null +++ b/src/db/sqlite/sql/authentication-success.sql @@ -0,0 +1,4 @@ +-- +UPDATE authentication + SET last_authentication = strftime('%s', 'now') + WHERE identifier = :identifier diff --git a/src/db/sqlite/sql/authentication-upsert.sql b/src/db/sqlite/sql/authentication-upsert.sql new file mode 100644 index 0000000..8a141ee --- /dev/null +++ b/src/db/sqlite/sql/authentication-upsert.sql @@ -0,0 +1,9 @@ +-- +INSERT INTO authentication + (identifier, credential) +VALUES + (:identifier, :credential) +ON CONFLICT (identifier) DO UPDATE +SET + identifier = :identifier, + credential = :credential diff --git a/src/db/sqlite/sql/profile-get.sql b/src/db/sqlite/sql/profile-get.sql new file mode 100644 index 0000000..74aa7a5 --- /dev/null +++ b/src/db/sqlite/sql/profile-get.sql @@ -0,0 +1,3 @@ +-- +SELECT * FROM profile +WHERE profile = :profile diff --git a/src/db/sqlite/sql/profile-identifier-insert.sql b/src/db/sqlite/sql/profile-identifier-insert.sql new file mode 100644 index 0000000..b357dce --- /dev/null +++ b/src/db/sqlite/sql/profile-identifier-insert.sql @@ -0,0 +1,4 @@ +-- +INSERT INTO profile (profile, identifier_id) + SELECT :profile, identifier_id FROM authentication WHERE identifier = :identifier + diff --git a/src/db/sqlite/sql/profile-scope-insert.sql b/src/db/sqlite/sql/profile-scope-insert.sql new file mode 100644 index 0000000..be4f212 --- /dev/null +++ b/src/db/sqlite/sql/profile-scope-insert.sql @@ -0,0 +1,5 @@ +-- +INSERT INTO profile_scope (profile_id, scope_id) + SELECT p.profile_id, s.scope_id FROM profile p, scope s + WHERE p.profile = :profile AND s.scope = :scope +ON CONFLICT (profile_id, scope_id) DO NOTHING diff --git a/src/db/sqlite/sql/profile-scopes-clear.sql b/src/db/sqlite/sql/profile-scopes-clear.sql new file mode 100644 index 0000000..be544fc --- /dev/null +++ b/src/db/sqlite/sql/profile-scopes-clear.sql @@ -0,0 +1,5 @@ +-- +DELETE FROM profile_scope +WHERE profile_id IN( + SELECT profile_id FROM profile WHERE profile = :profile +) diff --git a/src/db/sqlite/sql/profiles-scopes-by-identifier.sql b/src/db/sqlite/sql/profiles-scopes-by-identifier.sql new file mode 100644 index 0000000..485d043 --- /dev/null +++ b/src/db/sqlite/sql/profiles-scopes-by-identifier.sql @@ -0,0 +1,10 @@ +-- +SELECT p.profile, s.* + FROM profile p + INNER JOIN authentication a USING (identifier_id) + FULL JOIN profile_scope ps USING (profile_id) + FULL JOIN scope s USING (scope_id) + WHERE a.identifier = :identifier +UNION ALL SELECT NULL AS profile, * + FROM scope + WHERE is_manually_added OR is_permanent diff --git a/src/db/sqlite/sql/redeem-code.sql b/src/db/sqlite/sql/redeem-code.sql new file mode 100644 index 0000000..5f237e8 --- /dev/null +++ b/src/db/sqlite/sql/redeem-code.sql @@ -0,0 +1,27 @@ +-- +INSERT INTO token ( + code_id, + created, + is_token, + client_id, + profile_id, + expires, + duration, + refresh_expires, + refresh_duration +) + SELECT + :codeId, + :created, + :isToken, + :clientId, + p.profile_id, + CASE WHEN :lifespanSeconds IS NULL THEN NULL ELSE :created + :lifespanSeconds END, + :lifespanSeconds, + CASE WHEN :refreshLifespanSeconds IS NULL THEN NULL ELSE :created + :refreshLifespanSeconds END, + :refreshLifespanSeconds + FROM profile p INNER JOIN authentication a USING (identifier_id) + WHERE p.profile = :profile AND a.identifier = :identifier +ON CONFLICT (code_id) DO UPDATE + SET is_revoked = true +RETURNING is_revoked diff --git a/src/db/sqlite/sql/refresh-code.sql b/src/db/sqlite/sql/refresh-code.sql new file mode 100644 index 0000000..e2820c8 --- /dev/null +++ b/src/db/sqlite/sql/refresh-code.sql @@ -0,0 +1,15 @@ +-- +UPDATE token set + refreshed = :refreshed, + expires = :refreshed + duration, + refresh_expires = :refreshed + refresh_duration, + refresh_count = refresh_count + 1 +WHERE + code_id = :codeId +AND + NOT is_revoked +AND + (refresh_expires IS NOT NULL AND refresh_expires > :refreshed) +RETURNING + expires, + refresh_expires diff --git a/src/db/sqlite/sql/resource-get.sql b/src/db/sqlite/sql/resource-get.sql new file mode 100644 index 0000000..6e481d5 --- /dev/null +++ b/src/db/sqlite/sql/resource-get.sql @@ -0,0 +1,4 @@ +-- +SELECT * +FROM resource +WHERE resource_id = :resourceId diff --git a/src/db/sqlite/sql/resource-upsert.sql b/src/db/sqlite/sql/resource-upsert.sql new file mode 100644 index 0000000..84d333c --- /dev/null +++ b/src/db/sqlite/sql/resource-upsert.sql @@ -0,0 +1,9 @@ +-- +INSERT INTO resource + (resource_id, secret, description) +VALUES (:resourceId, :secret, :description) +ON CONFLICT (resource_id) DO UPDATE +SET + secret = COALESCE(EXCLUDED.secret, resource.secret), + description = COALESCE(EXCLUDED.description, resource.description) +RETURNING * diff --git a/src/db/sqlite/sql/schema/1.0.0/apply.sql b/src/db/sqlite/sql/schema/1.0.0/apply.sql new file mode 100644 index 0000000..2b2be31 --- /dev/null +++ b/src/db/sqlite/sql/schema/1.0.0/apply.sql @@ -0,0 +1,97 @@ +BEGIN; + + CREATE TABLE almanac ( + event TEXT NOT NULL PRIMARY KEY CHECK (typeof(event) = 'text'), + epoch INTEGER NOT NULL DEFAULT 0 CHECK (typeof(epoch) = 'integer') + ); + + CREATE TABLE authentication ( + identifier_id INTEGER NOT NULL PRIMARY KEY, + created INTEGER NOT NULL DEFAULT (strftime('%s', 'now')) CHECK (typeof(created) = 'integer'), + last_authentication INTEGER NOT NULL DEFAULT 0 CHECK (typeof(last_authentication) = 'integer'), + identifier TEXT NOT NULL UNIQUE CHECK (typeof(identifier) = 'text'), + credential TEXT CHECK (typeof(credential) IN ('text', 'null')) + ); + + CREATE TABLE resource ( + resource_id TEXT NOT NULL PRIMARY KEY CHECK (typeof(resource_id) = 'text'), + description TEXT NOT NULL DEFAULT '' CHECK (typeof(description) = 'text'), + created INTEGER NOT NULL DEFAULT (strftime('%s', 'now')) CHECK (typeof(created) = 'integer'), + secret TEXT NOT NULL CHECK (typeof(secret) = 'text') + ); + + CREATE TABLE profile ( + profile_id INTEGER NOT NULL PRIMARY KEY, + identifier_id INTEGER NOT NULL REFERENCES authentication(identifier_id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, + profile TEXT NOT NULL CHECK (typeof(profile) = 'text'), + UNIQUE (identifier_id, profile) ON CONFLICT IGNORE + ); + CREATE INDEX profile_identifier_id_idx ON profile(identifier_id); + CREATE INDEX profile_profile_idx ON profile(profile); + + CREATE TABLE scope ( + scope_id INTEGER NOT NULL PRIMARY KEY, + scope TEXT NOT NULL UNIQUE CHECK (typeof(scope) = 'text'), + description TEXT NOT NULL ON CONFLICT REPLACE DEFAULT '' CHECK (typeof(description) = 'text'), + application TEXT NOT NULL ON CONFLICT REPLACE DEFAULT '' CHECK (typeof(application) = 'text'), + is_permanent INTEGER NOT NULL DEFAULT 0 CHECK (typeof(is_permanent) = 'integer' AND is_permanent IN (0, 1)), + is_manually_added INTEGER NOT NULL DEFAULT 0 CHECK (typeof(is_manually_added) = 'integer' AND is_manually_added IN (0, 1)) + ); + + CREATE TABLE profile_scope ( + profile_id INTEGER NOT NULL REFERENCES profile(profile_id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, + scope_id INTEGER NOT NULL REFERENCES scope(scope_id) ON DELETE NO ACTION ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, + PRIMARY KEY (profile_id, scope_id) + ); + CREATE INDEX profile_scope_scope_id_idx ON profile_scope(scope_id); + + CREATE TABLE token ( + code_id TEXT NOT NULL PRIMARY KEY CHECK (typeof(code_id) = 'text'), + profile_id INTEGER NOT NULL REFERENCES profile (profile_id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, + created INTEGER NOT NULL DEFAULT (strftime('%s', 'now')) CHECK (typeof(created) = 'integer'), + expires INTEGER CHECK (typeof(expires) IN ('integer', 'null')), + refresh_expires INTEGER CHECK (typeof(refresh_expires) IN ('integer', 'null')), + refreshed INTEGER CHECK (typeof(refreshed) IN ('integer', 'null')), + duration INTEGER CHECK (typeof(duration) IN ('integer', 'null')), + refresh_duration INTEGER CHECK (typeof(refresh_duration) IN ('integer', 'null')), + refresh_count INTEGER NOT NULL DEFAULT 0 CHECK (typeof(refresh_count) = 'integer'), + is_revoked INTEGER NOT NULL DEFAULT 0 CHECK (typeof(is_revoked) = 'integer' AND is_revoked IN (0, 1)), + is_token INTEGER NOT NULL CHECK (typeof(is_token) = 'integer' AND is_token IN (0, 1)), + client_id TEXT NOT NULL CHECK (typeof(client_id) = 'text'), + resource TEXT CHECK (typeof(resource) IN ('integer', 'null')), + profile_data TEXT, + CONSTRAINT expires_needs_duration CHECK (expires IS NULL OR duration IS NOT NULL), + CONSTRAINT refresh_expires_needs_refresh_duration CHECK (refresh_expires IS NULL OR refresh_duration IS NOT NULL) + ); + CREATE INDEX token_profile_id_idx ON token(profile_id); + CREATE INDEX token_created_idx ON token(created); + CREATE INDEX token_expires_idx ON token(expires) WHERE expires IS NOT NULL; + CREATE INDEX token_refresh_expires_idx ON token(refresh_expires) WHERE refresh_expires IS NOT NULL; + + CREATE TABLE token_scope ( + code_id TEXT NOT NULL REFERENCES token(code_id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, + scope_id INTEGER NOT NULL REFERENCES scope(scope_id) ON DELETE NO ACTION ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, + PRIMARY KEY (code_id, scope_id) + ); + CREATE INDEX token_scope_scope_id_idx ON token_scope(scope_id); + + -- Update schema version + INSERT INTO _meta_schema_version (major, minor, patch) VALUES (1, 0, 0); + + -- Seed scope data + INSERT INTO scope (scope, description, application, is_permanent) VALUES + ('profile', 'Access detailed profile information, including name, image, and url.', 'IndieAuth', 1), + ('email', 'Include email address with detailed profile information.', 'IndieAuth', 1), + ('create', 'Create new items.', 'MicroPub', 1), + ('draft', 'All created items are drafts.', 'MicroPub', 1), + ('update', 'Edit existing items.', 'MicroPub', 1), + ('delete', 'Remove items.', 'MicroPub', 1), + ('media', 'Allow file uploads.', 'MicroPub', 1), + ('read', 'Read access to channels.', 'MicroSub', 1), + ('follow', 'Management of following list.', 'MicroSub', 1), + ('mute', 'Management of user muting.', 'MicroSub', 1), + ('block', 'Management of user blocking.', 'MicroSub', 1), + ('channels', 'Management of channels.', 'MicroSub', 1) + ; + +COMMIT; diff --git a/src/db/sqlite/sql/schema/1.0.0/er.dot b/src/db/sqlite/sql/schema/1.0.0/er.dot new file mode 100644 index 0000000..2e43133 --- /dev/null +++ b/src/db/sqlite/sql/schema/1.0.0/er.dot @@ -0,0 +1,106 @@ +digraph indieAutherERD { + graph[ + rankdir=LR, + overlap=false, + splines=true, + label="IndieAuther Entity-Relations\SQLite\nSchema 1.0.0", + labelloc="t", + fontsize=26, + ]; + // layout=neato; + node[shape=plain]; + edge[arrowhead=crow]; + + token [label=< + <table cellspacing="0" cellborder="1" border="0"> + <tr><td border="2" bgcolor="lightblue">TOKEN</td></tr> + <tr><td port="pk_code_id">code_id</td></tr> + <tr><td port="fk_profile_id">profile_id</td></tr> + <tr><td port="">created</td></tr> + <tr><td port="">expires</td></tr> + <tr><td port="">refresh_expires</td></tr> + <tr><td port="">refreshed</td></tr> + <tr><td port="">duration</td></tr> + <tr><td port="">refresh_duration</td></tr> + <tr><td port="">refresh_count</td></tr> + <tr><td port="">is_revoked</td></tr> + <tr><td port="">is_token</td></tr> + <tr><td port="">client_id</td></tr> + <tr><td port="">resource</td></tr> + <tr><td port="">profile_data</td></tr> + </table> + >]; + profile:pk_profile_id -> token:fk_profile_id; + + scope [label=< + <table cellspacing="0" cellborder="1" border="0"> + <tr><td border="2" bgcolor="lightblue">SCOPE</td></tr> + <tr><td port="pk_scope_id">scope_id</td></tr> + <tr><td port="">scope</td></tr> + <tr><td port="">description</td></tr> + <tr><td port="">application</td></tr> + <tr><td port="">is_permanent</td></tr> + <tr><td port="">is_manually_added</td></tr> + </table> + >]; + + token_scope [label=< + <table cellspacing="0" cellborder="1" border="0"> + <tr><td border="2" bgcolor="lightblue">TOKEN_SCOPE</td></tr> + <tr><td port="fk_code_id">code_id</td></tr> + <tr><td port="fk_scope_id">scope_id</td></tr> + </table> + >]; + token:pk_code_id -> token_scope:fk_code_id; + scope:pk_scope_id -> token_scope:fk_scope_id; + + profile [label=< + <table cellspacing="0" cellborder="1" border="0"> + <tr><td border="2" bgcolor="lightblue">PROFILE</td></tr> + <tr><td port="pk_profile_id">profile_id</td></tr> + <tr><td port="fk_identifier_id">identifier_id</td></tr> + <tr><td port="">profile</td></tr> + </table> + >]; + authentication:pk_identifier_id -> profile:fk_identifier_id; + + profile_scope [label=< + <table cellspacing="0" cellborder="1" border="0"> + <tr><td border="2" bgcolor="lightblue">PROFILE_SCOPE</td></tr> + <tr><td port="fk_profile_id">profile_id</td></tr> + <tr><td port="fk_scope_id">scope_id</td></tr> + </table> + >]; + profile:pk_profile_id -> profile_scope:fk_profile_id; + scope:pk_scope_id -> profile_scope:fk_scope_id; + + authentication [label=< + <table cellspacing="0" cellborder="1" border="0"> + <tr><td border="2" bgcolor="lightblue">AUTHENTICATION</td></tr> + <tr><td port="pk_identifier_id">identifier_id</td></tr> + <tr><td port="">created</td></tr> + <tr><td port="">last_authenticated</td></tr> + <tr><td port="">identifier</td></tr> + <tr><td port="">credential</td></tr> + </table> + >]; + + resource [label=< + <table cellspacing="0" cellborder="1" border="0"> + <tr><td border="2" bgcolor="lightblue">RESOURCE</td></tr> + <tr><td port="pk_resource_id">resource_id</td></tr> + <tr><td port="">description</td></tr> + <tr><td port="">created</td></tr> + <tr><td port="">secret</td></tr> + </table> + >]; + + almanac [label=< + <table cellspacing="0" cellborder="1" border="0"> + <tr><td border="2" bgcolor="lightblue">ALMANAC</td></tr> + <tr><td port="pk_event">event</td></tr> + <tr><td port="">epoch</td></tr> + </table> + >]; + +} diff --git a/src/db/sqlite/sql/schema/1.0.0/revert.sql b/src/db/sqlite/sql/schema/1.0.0/revert.sql new file mode 100644 index 0000000..20ccf68 --- /dev/null +++ b/src/db/sqlite/sql/schema/1.0.0/revert.sql @@ -0,0 +1,7 @@ +BEGIN; + DROP TABLE authentication; + DROP TABLE profile; + DROP TABLE token; + DROP TABLE scope; + DROP TABLE profile_scope; +COMMIT; \ No newline at end of file diff --git a/src/db/sqlite/sql/schema/init.sql b/src/db/sqlite/sql/schema/init.sql new file mode 100644 index 0000000..8e2a475 --- /dev/null +++ b/src/db/sqlite/sql/schema/init.sql @@ -0,0 +1,11 @@ +-- +BEGIN; + CREATE TABLE _meta_schema_version ( + major INTEGER NOT NULL CHECK (typeof(major) = 'integer'), + minor INTEGER NOT NULL CHECK (typeof(minor) = 'integer'), + patch INTEGER NOT NULL CHECK (typeof(patch) = 'integer'), + applied INTEGER NOT NULL DEFAULT (strftime('%s', 'now')) CHECK (typeof(applied) = 'integer'), + PRIMARY KEY (major DESC, minor DESC, patch DESC) + ) WITHOUT ROWID; + INSERT INTO _meta_schema_version (major, minor, patch) VALUES (0, 0, 0); +COMMIT; diff --git a/src/db/sqlite/sql/scope-cleanup.sql b/src/db/sqlite/sql/scope-cleanup.sql new file mode 100644 index 0000000..4e9bd37 --- /dev/null +++ b/src/db/sqlite/sql/scope-cleanup.sql @@ -0,0 +1,8 @@ +-- Remove any un-used, non-permanent, non-manually-created scopes. +DELETE FROM scope WHERE scope_id NOT IN ( + SELECT scope_id FROM scope s + INNER JOIN profile_scope ps USING (scope_id) + UNION ALL + SELECT scope_id FROM scope s + INNER JOIN token_scope ts USING (scope_id) +) AND NOT (is_permanent OR is_manually_added) diff --git a/src/db/sqlite/sql/scope-delete.sql b/src/db/sqlite/sql/scope-delete.sql new file mode 100644 index 0000000..562bb58 --- /dev/null +++ b/src/db/sqlite/sql/scope-delete.sql @@ -0,0 +1,3 @@ +-- remove an impermanent scope +DELETE FROM scope + WHERE scope = :scope AND is_permanent = false diff --git a/src/db/sqlite/sql/scope-in-use.sql b/src/db/sqlite/sql/scope-in-use.sql new file mode 100644 index 0000000..1129caf --- /dev/null +++ b/src/db/sqlite/sql/scope-in-use.sql @@ -0,0 +1,13 @@ +-- return whether a scope is currently in use, either a profile setting or on a token +SELECT EXISTS ( + SELECT 1 FROM scope s + INNER JOIN profile_scope ps USING (scope_id) + WHERE s.scope = :scope + UNION All + SELECT 1 FROM scope s + INNER JOIN token_scope ts USING (scope_id) + WHERE s.scope = :scope + UNION All + SELECT 1 FROM scope s + WHERE s.scope = :scope AND s.is_permanent +) AS in_use diff --git a/src/db/sqlite/sql/scope-insert.sql b/src/db/sqlite/sql/scope-insert.sql new file mode 100644 index 0000000..78d26c0 --- /dev/null +++ b/src/db/sqlite/sql/scope-insert.sql @@ -0,0 +1,5 @@ +-- Insert an externally-provided scope, or ignore. +INSERT INTO scope + (scope) +VALUES (:scope) +ON CONFLICT (scope) DO NOTHING diff --git a/src/db/sqlite/sql/scope-upsert.sql b/src/db/sqlite/sql/scope-upsert.sql new file mode 100644 index 0000000..cb2770f --- /dev/null +++ b/src/db/sqlite/sql/scope-upsert.sql @@ -0,0 +1,16 @@ +-- +INSERT INTO scope ( + scope, + description, + application, + is_manually_added +) VALUES ( + :scope, + CASE WHEN :application IS NULL THEN '' ELSE :application END, + CASE WHEN :description IS NULL THEN '' ELSE :description END, + COALESCE(:manuallyAdded, false) +) ON CONFLICT (scope) DO UPDATE +SET + application = COALESCE(:application, EXCLUDED.application), + description = COALESCE(:description, EXCLUDED.description), + is_manually_added = EXCLUDED.is_manually_added OR COALESCE(:manuallyAdded, false) diff --git a/src/db/sqlite/sql/token-cleanup.sql b/src/db/sqlite/sql/token-cleanup.sql new file mode 100644 index 0000000..45f16b7 --- /dev/null +++ b/src/db/sqlite/sql/token-cleanup.sql @@ -0,0 +1,32 @@ +-- Remove tokens no longer in use. +WITH +-- reduce verbosity of using epoch timestamps +times AS ( + SELECT + (strftime('%s', 'now') - :codeLifespanSeconds) AS code_valid_offset, + strftime('%s', 'now') AS now +), +-- only clean after code has expired +cleanable_codes AS ( + SELECT t.code_id, t.is_token, t.is_revoked, t.expires, t.refresh_expires FROM token t, times + WHERE t.created < times.code_valid_offset +) +DELETE FROM token WHERE code_id IN ( + SELECT code_id FROM cleanable_codes c, times + WHERE + NOT c.is_token -- profile-only redemption + OR ( + c.is_token AND ( + c.is_revoked -- revoked + OR ( + c.expires < times.now AND ( + -- expired and unrefreshable + refresh_expires IS NULL + OR + -- expired and refresh expired + (refresh_expires IS NOT NULL AND refresh_expires < times.now) + ) + ) + ) + ) +) \ No newline at end of file diff --git a/src/db/sqlite/sql/token-get-by-code-id.sql b/src/db/sqlite/sql/token-get-by-code-id.sql new file mode 100644 index 0000000..c3ea5bb --- /dev/null +++ b/src/db/sqlite/sql/token-get-by-code-id.sql @@ -0,0 +1,20 @@ +-- +SELECT + t.code_id, + p.profile, + t.created, + t.expires, + t.refresh_expires, + t.refreshed, + t.duration, + t.refresh_duration, + t.refresh_count, + t.is_revoked, + t.is_token, + t.client_id, + t.profile_data, + a.identifier +FROM token t + INNER JOIN profile p USING (profile_id) + INNER JOIN authentication a USING (identifier_id) +WHERE code_id = :codeId diff --git a/src/db/sqlite/sql/token-refresh-revoke-by-code-id.sql b/src/db/sqlite/sql/token-refresh-revoke-by-code-id.sql new file mode 100644 index 0000000..52a851c --- /dev/null +++ b/src/db/sqlite/sql/token-refresh-revoke-by-code-id.sql @@ -0,0 +1,5 @@ +-- Revoke the refreshability for a token +UPDATE token SET + refresh_expires = NULL, + refresh_duration = NULL +WHERE code_id = :codeId diff --git a/src/db/sqlite/sql/token-revoke-by-code-id.sql b/src/db/sqlite/sql/token-revoke-by-code-id.sql new file mode 100644 index 0000000..27febe1 --- /dev/null +++ b/src/db/sqlite/sql/token-revoke-by-code-id.sql @@ -0,0 +1,5 @@ +-- +UPDATE token SET + is_revoked = true, + refresh_expires = NULL +WHERE code_id = :codeId diff --git a/src/db/sqlite/sql/token-scope-remove.sql b/src/db/sqlite/sql/token-scope-remove.sql new file mode 100644 index 0000000..94debac --- /dev/null +++ b/src/db/sqlite/sql/token-scope-remove.sql @@ -0,0 +1,3 @@ +-- +DELETE FROM token_scope +WHERE code_id = :codeId AND scope_id = (SELECT scope_id FROM scope WHERE scope = :scope) diff --git a/src/db/sqlite/sql/token-scope-set.sql b/src/db/sqlite/sql/token-scope-set.sql new file mode 100644 index 0000000..7b52dc6 --- /dev/null +++ b/src/db/sqlite/sql/token-scope-set.sql @@ -0,0 +1,3 @@ +-- +INSERT INTO token_scope (code_id, scope_id) + SELECT :codeId, scope_id FROM scope WHERE scope = :scope diff --git a/src/db/sqlite/sql/token-scopes-get-by-code-id.sql b/src/db/sqlite/sql/token-scopes-get-by-code-id.sql new file mode 100644 index 0000000..5bd7b30 --- /dev/null +++ b/src/db/sqlite/sql/token-scopes-get-by-code-id.sql @@ -0,0 +1,4 @@ +-- +SELECT s.scope FROM token_scope ts + INNER JOIN scope s USING (scope_id) + WHERE ts.code_id = :codeId diff --git a/src/db/sqlite/sql/tokens-get-by-identifier.sql b/src/db/sqlite/sql/tokens-get-by-identifier.sql new file mode 100644 index 0000000..63a3f2c --- /dev/null +++ b/src/db/sqlite/sql/tokens-get-by-identifier.sql @@ -0,0 +1,21 @@ +-- +SELECT + t.code_id, + p.profile, + t.created, + t.expires, + t.refresh_expires, + t.refreshed, + t.duration, + t.refresh_duration, + t.refresh_count, + t.is_revoked, + t.is_token, + t.client_id, + t.profile_data, + a.identifier +FROM token t + INNER JOIN profile p USING (profile_id) + INNER JOIN authentication a USING (identifier_id) +WHERE a.identifier = :identifier +ORDER BY max(t.created, COALESCE(t.refreshed, 0)) DESC diff --git a/src/enum.js b/src/enum.js new file mode 100644 index 0000000..8179941 --- /dev/null +++ b/src/enum.js @@ -0,0 +1,27 @@ +'use strict'; +const common = require('./common'); +const { Enum } = require('@squeep/api-dingus'); + +common.mergeEnum(Enum, { + Specification: 'living-standard-20220212', + + ContentType: { + ApplicationOctetStream: 'application/octet-stream', + }, + + Header: { + Authorization: 'Authorization', + Link: 'Link', + Location: 'Location', + Pragma: 'Pragma', + UserAgent: 'User-Agent', + WWWAuthenticate: 'WWW-Authenticate', + }, + + Chore: { + CleanTokens: 'cleanTokens', + CleanScopes: 'cleanScopes', + }, +}); + +module.exports = Enum; diff --git a/src/errors.js b/src/errors.js new file mode 100644 index 0000000..9f4cb2b --- /dev/null +++ b/src/errors.js @@ -0,0 +1,21 @@ +'use strict'; + +const { Errors } = require('@squeep/api-dingus'); + +/** + * A stack-less exception for general data issues. + */ +class ValidationError extends Error { + constructor(...args) { + super(...args); + delete this.stack; + } + + get name() { + return this.constructor.name; + } +} +module.exports = { + ...Errors, + ValidationError, +}; \ No newline at end of file diff --git a/src/logger/data-sanitizers.js b/src/logger/data-sanitizers.js new file mode 100644 index 0000000..450842e --- /dev/null +++ b/src/logger/data-sanitizers.js @@ -0,0 +1,116 @@ +'use strict'; + +/** + * Scrub credential from POST login body data. + * @param {Object} data + * @param {Boolean} sanitize + * @returns {Boolean} + */ +function sanitizePostCredential(data, sanitize = true) { + let unclean = false; + + const credentialLength = data?.ctx?.parsedBody?.credential?.length; + if (credentialLength) { + unclean = true; + } + if (unclean && sanitize) { + data.ctx.parsedBody.credential = '*'.repeat(credentialLength); + } + + return unclean; +} + + +/** + * Reduce logged data about scopes from profilesScopes. + * For all referenced scopes, only include profiles list. + * Remove scopes without profile references from scopeIndex. + * @param {Object} data + * @param {Boolean} sanitize + */ +function reduceScopeVerbosity(data, sanitize = true) { + let unclean = false; + + const { + scopesEntries: ctxScopesEntries, + profilesEntries: ctxProfilesEntries, + needsSanitize: ctxNeedsSanitize, + } = _scopesFrom(data?.ctx?.profilesScopes); + + const { + scopesEntries: sessionScopesEntries, + profilesEntries: sessionProfilesEntries, + needsSanitize: sessionNeedsSanitize, + } = _scopesFrom(data?.ctx?.session); + + if (ctxNeedsSanitize || sessionNeedsSanitize) { + unclean = true; + } + if (unclean && sanitize) { + if (ctxNeedsSanitize) { + Object.assign(data.ctx.profilesScopes, _sanitizeProfilesScopes(ctxScopesEntries, ctxProfilesEntries)); + } + if (sessionNeedsSanitize) { + Object.assign(data.ctx.session, _sanitizeProfilesScopes(sessionScopesEntries, sessionProfilesEntries)); + } + } + + return unclean; +} + + +/** + * Return any scope entries on an object, and whether sanitization is needed. + * @param {Object=} obj + * @returns {Object} + */ +const _scopesFrom = (obj) => { + const scopesEntries = Object.entries(obj?.scopeIndex || {}); + const profilesEntries = Object.entries(obj?.profileScopes || {}); + const needsSanitize = scopesEntries.length || profilesEntries.length; + return { + scopesEntries, + profilesEntries, + needsSanitize, + }; +}; + + +/** + * @typedef {[String, Object]} ScopeEntry + */ +/** + * Return new list of entries with scrubbed scopeDetails. + * @param {ScopeEntry[]} entries + * @returns {ScopeEntry[]} + */ +const _scopeEntriesScrubber = (entries) => entries.map(([scopeName, scopeDetails]) => ([scopeName, { profiles: scopeDetails.profiles }])); + + +/** + * Create a new profilesScopes type object with scrubbed scope details. + * @param {ScopeEntry[]} scopesEntries + * @param {ScopeEntry[]} profilesEntries + * @returns {Object} + */ +const _sanitizeProfilesScopes = (scopesEntries, profilesEntries) => { + const referencedScopesEntries = scopesEntries.filter(([_scopeName, scopeDetails]) => scopeDetails?.profiles?.length); // eslint-disable-line no-unused-vars + const scrubbedScopesEntries = _scopeEntriesScrubber(referencedScopesEntries); + + const scrubbedProfilesEntries = profilesEntries.map(([profileName, profileScopes]) => { + const profileScopeEntries = Object.entries(profileScopes); + const scrubbedProfileScopeEntries = _scopeEntriesScrubber(profileScopeEntries); + const scrubbedProfileScopes = Object.fromEntries(scrubbedProfileScopeEntries); + return [profileName, scrubbedProfileScopes]; + }); + + return { + scopeIndex: Object.fromEntries(scrubbedScopesEntries), + profileScopes: Object.fromEntries(scrubbedProfilesEntries), + }; +}; + +module.exports = { + sanitizePostCredential, + reduceScopeVerbosity, +}; \ No newline at end of file diff --git a/src/logger/index.js b/src/logger/index.js new file mode 100644 index 0000000..7944cf6 --- /dev/null +++ b/src/logger/index.js @@ -0,0 +1,13 @@ +'use strict'; + +const BaseLogger = require('@squeep/logger-json-console'); +const dataSanitizers = require('./data-sanitizers'); + +class Logger extends BaseLogger { + constructor(options, ...args) { + super(options, ...args); + Array.prototype.push.apply(this.dataSanitizers, Object.values(dataSanitizers)); + } +} + +module.exports = Logger; \ No newline at end of file diff --git a/src/manager.js b/src/manager.js new file mode 100644 index 0000000..6c16414 --- /dev/null +++ b/src/manager.js @@ -0,0 +1,2015 @@ +'use strict'; + +const common = require('./common'); +const { ResponseError, ValidationError } = require('./errors'); +const Enum = require('./enum'); +const { Communication, Errors: CommunicationErrors } = require('@squeep/indieauth-helper'); +const Template = require('./template'); +const { MysteryBox } = require('@squeep/mystery-box'); +const DBErrors = require('./db/errors'); +const Chores = require('./chores'); +const { Publisher: QueuePublisher } = require('@squeep/amqp-helper'); + +const _fileScope = common.fileScope(__filename); + +// These are used during request ingestion and validation +const validBase64URLRE = /^[-A-Za-z0-9_]+$/; +const scopeSplitRE = / +/; + +const supportedCodeChallengeMethods = ['S256', 'SHA256']; + +class Manager { + constructor(logger, db, options) { + this.options = options; + this.logger = logger; + this.db = db; + this.chores = new Chores(logger, db, options); + this.communication = new Communication(logger, options); + if (options.queues.amqp.url) { + this.queuePublisher = new QueuePublisher(logger, options.queues.amqp); + } + this.mysteryBox = new MysteryBox(logger, options); + + // We need to know how the outside world sees us, to verify if a + // profile indicates us as the auth server. + // selfBaseUrl should already include proxy prefix and end with a / + this.selfAuthorizationEndpoint = options.dingus.selfBaseUrl + options.route.authorization; + } + + + /** + * Perform any async startup tasks. + */ + async initialize() { + if (this.queuePublisher) { + await this._connectQueues(); + } + } + + + async _connectQueues() { + await this.queuePublisher.connect(); + await this.queuePublisher.establishAMQPPlumbing(this.options.queues.ticketPublishName); + } + + + /** + * Add an error to a session, keeping only the most-severe code, but all descriptions. + * This error is sent along on the redirection back to client endpoint. + * @param {Object} ctx + * @param {Object} ctx.session + * @param {String[]=} ctx.session.errorDescriptions + * @param {String=} ctx.session.error + * @param {String} error + * @param {String} errorDescription + */ + static _setError(ctx, error, errorDescription) { + const errorPrecedence = [ // By increasing severity + 'invalid_scope', + 'unsupported_response_type', + 'access_denied', + 'unauthorized_client', + 'invalid_grant', + 'invalid_request', + 'temporarily_unavailable', + 'server_error', + ]; + if (!(errorPrecedence.includes(error))) { + throw new RangeError(`invalid error value '${error}'`); + } + if (!ctx.session.errorDescriptions) { + ctx.session.errorDescriptions = []; + } + if (!common.validError(errorDescription)) { + throw new RangeError(`invalid error description '${errorDescription}'`); + } + const isHigherPrecedence = errorPrecedence.indexOf(error) > errorPrecedence.indexOf(ctx.session.error); + if (!ctx.session.error || isHigherPrecedence) { + ctx.session.error = error; + } + if (isHigherPrecedence) { + ctx.session.errorDescriptions.unshift(errorDescription); + } else { + ctx.session.errorDescriptions.push(errorDescription); + } + } + + + /** + * Discourage caching of a response. + * OAuth 2.1 §3.2.3 + * The authorization server MUST include the HTTP Cache-Control response + * header field with a value of no-store in any response + * containing tokens, credentials, or other sensitive information. + * @param {http.ServerResponse} res + */ + static _sensitiveResponse(res) { + Object.entries({ + [Enum.Header.CacheControl]: 'no-store', + [Enum.Header.Pragma]: 'no-cache', + }).forEach(([k, v]) => res.setHeader(k, v)); + } + + + /** + * Sets params entries as url search parameters. + * @param {URL} url + * @param {Object} params + */ + static _setSearchParams(url, params) { + Object.entries(params).forEach((param) => url.searchParams.set(...param)); + } + + + /** + * Serve the informational root page. + * @param {http.ClientRequest} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async getRoot(res, ctx) { + const _scope = _fileScope('getRoot'); + this.logger.debug(_scope, 'called', { ctx }); + + res.end(Template.rootHTML(ctx, this.options)); + this.logger.info(_scope, 'finished', { ctx }); + } + + + /** + * Serve the metadata for this service. + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async getMeta(res, ctx) { + const _scope = _fileScope('getMeta'); + this.logger.debug(_scope, 'called', { ctx }); + + const base = this.options.dingus.selfBaseUrl; + const endpoint = (r) => `${base}${this.options.route[r]}`; // eslint-disable-line security/detect-object-injection + + const metadata = { + issuer: base, + 'authorization_endpoint': endpoint('authorization'), + 'token_endpoint': endpoint('token'), + ...(this.queuePublisher && { 'ticket_endpoint': endpoint('ticket') }), + 'introspection_endpoint': endpoint('introspection'), + 'introspection_endpoint_auth_methods_supported': ['Bearer'], + 'revocation_endpoint': endpoint('revocation'), + 'revocation_endpoint_auth_methods_supported': ['none'], + 'scopes_supported': ['profile', 'email'], // only advertise minimum IA scopes + 'response_types_supported': 'code', + 'grant_types_supported': [ + 'authorization_code', + 'refresh_token', + ...(this.queuePublisher && ['ticket'] || []), + ], + 'service_documentation': 'https://indieauth.spec.indieweb.org/', + 'code_challenge_methods_supported': supportedCodeChallengeMethods, + 'authorization_response_iss_parameter_supported': true, + 'userinfo_endpoint': endpoint('userinfo'), + }; + + res.end(JSON.stringify(metadata)); + this.logger.info(_scope, 'finished', { ctx }); + } + + + /** + * Process an authorization request from a client. + * User has authenticated, check if user matches profile, + * present user with consent form. + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async getAuthorization(res, ctx) { + const _scope = _fileScope('getAuthorization'); + this.logger.debug(_scope, 'called', { ctx }); + + ctx.session = Object.assign({}, ctx.session, { + errorDescriptions: [], + }); + + // Ingest and validate expected data, populating ctx.session. + await this._clientIdRequired(ctx); + Manager._redirectURIRequired(ctx); + Manager._responseTypeRequired(ctx); + Manager._stateRequired(ctx); + this._codeChallengeMethodRequired(ctx); + this._codeChallengeRequired(ctx); + this._scopeOptional(ctx); + await this._meOptional(ctx); + + if (!ctx.session.clientIdentifier || !ctx.session.redirectUri) { + // Do not redirect if either of these fields were invalid, just report error. + this.logger.debug(_scope, 'invalid request, not redirecting', { ctx }); + + // Set error response for template to render. + ctx.errors.push('Cannot redirect to client application.'); + ctx.errorContent = [ + 'There was an error in the request sent by the application attempting to authenticate you. Check with that service.', + ]; + res.statusCode = 400; + res.end(Template.authorizationErrorHTML(ctx, this.options)); + this.logger.info(_scope, 'bad request', { ctx }); + return; + } + + await this.db.context(async (dbCtx) => { + const profilesScopes = await this.db.profilesScopesByIdentifier(dbCtx, ctx.authenticationId); + Object.assign(ctx.session, { + profiles: [], + profileScopes: {}, + scopeIndex: {}, + }, profilesScopes); + }); // dbCtx + + if (!ctx.session.profiles.length) { + this.logger.error(_scope, 'identifier has no profiles', { ctx }); + Manager._setError(ctx, 'access_denied', 'Profile not valid for the authenticated user.'); + } + + if (!this._profileValidForIdentifier(ctx)) { + // if the hinted profile supplied in me does not match any known + // profile mappings for the authenticated identifier, remove the + // hint. UI will prompt to choose from available profiles. + this.logger.debug(_scope, 'removing provided me hint, not valid for identifier', { ctx }); + delete ctx.session.me; + } + + // Ugly support logic for allowing legacy non-pkce requests, for the micropub.rocks site until it is updated. + // Require both be missing to qualify as a legacy request, otherwise still fail. + const isMissingBothPKCE = (!ctx.session.codeChallengeMethod) && (!ctx.session.codeChallenge); + if (isMissingBothPKCE && this.options.manager.allowLegacyNonPKCE) { + ctx.notifications.push('<div class="legacy-warning">This request was submitted using an unsupported legacy format, which does not include PKCE safeguards! This is a security issue! This request should not be accepted!</div>'); + } else { + if (!ctx.session.codeChallenge) { + Manager._setError(ctx, 'invalid_request', 'missing required parameter \'code_challenge\''); + } + if (!ctx.session.codeChallengeMethod) { + Manager._setError(ctx, 'invalid_request', 'missing required parameter \'code_challenge_method\''); + } + } + + // If anything went wrong, redirect with error report. + if (ctx.session.error) { + // Valid redirect_url and client_id, errors hop back to them. + this.logger.debug(_scope, 'invalid request, redirecting', { ctx }); + + Manager._setSearchParams(ctx.session.redirectUri, { + 'state': ctx.session.state, + 'error': ctx.session.error, + 'error_description': ctx.session.errorDescriptions.join(', '), + }); + res.statusCode = 302; // Found + res.setHeader(Enum.Header.Location, ctx.session.redirectUri.href); + res.end(); + this.logger.info(_scope, 'bad request', { ctx }); + return; + } + + // Store the current state of this session, to be forwarded on to consent processing. + // This blob will be passed on as a form field in consent response. + ctx.session.persist = await this.mysteryBox.pack({ + id: common.requestId(), // codeId in database + clientId: ctx.session.clientId.href, + clientIdentifier: ctx.session.clientIdentifier, + redirectUri: ctx.session.redirectUri.href, + responseType: ctx.session.responseType, + state: ctx.session.state, + codeChallengeMethod: ctx.session.codeChallengeMethod, + codeChallenge: ctx.session.codeChallenge, + me: ctx.session.me, + profiles: ctx.session.profiles, + requestedScopes: ctx.session.scope, + authenticationId: ctx.authenticationId, + }); + + // Present authenticated user the option to submit consent + const content = Template.authorizationRequestHTML(ctx, this.options); + res.end(content); + + this.logger.info(_scope, 'finished', { ctx }); + } + + + /** + * Validates, fetches, and parses client_id url, populating clientIdentifier with client h-app data. + * @param {Object} ctx + */ + async _clientIdRequired(ctx) { + if (ctx.queryParams['client_id']) { + try { + ctx.session.clientId = await this.communication.validateClientIdentifier(ctx.queryParams['client_id']); + ctx.session.clientIdentifier = await this.communication.fetchClientIdentifier(ctx.session.clientId); + if (!ctx.session.clientIdentifier) { + Manager._setError(ctx, 'invalid_request', 'invalid client_id: could not fetch'); + throw new ValidationError('could not fetch'); + } + } catch (e) { + ctx.session.clientId = undefined; + if (e instanceof CommunicationErrors.ValidationError) { + Manager._setError(ctx, 'invalid_request', e.message); + } + Manager._setError(ctx, 'invalid_request', 'invalid value for parameter \'client_id\''); + } + } else { + Manager._setError(ctx, 'invalid_request', 'missing required parameter \'client_id\''); + } + } + + + /** + * Ensure redirect_uri exists and is corroborated by clientIdentifier data. + * @param {Object} ctx + */ + static _redirectURIRequired(ctx) { + if (ctx.queryParams['redirect_uri']) { + try { + ctx.session.redirectUri = new URL(ctx.queryParams['redirect_uri']); + + if (ctx.session.clientId) { + // Either all these parts must match, or a specific alternative must be specified. + const redirectMatchesClientId = ['protocol', 'hostname', 'port'] + .map((p) => ctx.session.redirectUri[p] == ctx.session.clientId[p]) // eslint-disable-line security/detect-object-injection + .reduce((acc, match) => acc && match, true); + + // Check for alternate redirect_uri entries on client_id data if no initial match + if (!redirectMatchesClientId) { + const validRedirectUris = ctx.session?.clientIdentifier?.['rels']?.['redirect_uri'] || []; + if (!validRedirectUris.includes(ctx.session.redirectUri.href)) { + Manager._setError(ctx, 'invalid_request', 'redirect_uri not valid for that client_id'); + // Remove invalid redirect_uri from session; doing this eases error routing. + ctx.session.redirectUri = undefined; + } + } + } + } catch (e) { + Manager._setError(ctx, 'invalid_request', 'invalid value for parameter \'redirect_uri\''); + } + } else { + Manager._setError(ctx, 'invalid_request', 'missing required parameter \'redirect_uri\''); + } + } + + + /** + * response_type must be valid + * @param {Object} ctx + */ + static _responseTypeRequired(ctx) { + ctx.session.responseType = ctx.queryParams['response_type']; + if (ctx.session.responseType) { + // Must be one of these types + if (!['code'].includes(ctx.session.responseType)) { + Manager._setError(ctx, 'unsupported_response_type', 'invalid value for parameter \'response_type\''); + } + } else { + Manager._setError(ctx, 'invalid_request', 'missing required parameter \'response_type\''); + } + } + + + /** + * A state parameter must be present + * @param {Object} ctx + */ + static _stateRequired(ctx) { + ctx.session.state = ctx.queryParams['state']; + if (ctx.session.state) { + // No restrictions on content of this + } else { + Manager._setError(ctx, 'invalid_request', 'missing required parameter \'state\''); + } + } + + + /** + * A code_challenge_method must be present and valid + * @param {Object} ctx + */ + _codeChallengeMethodRequired(ctx) { + ctx.session.codeChallengeMethod = ctx.queryParams['code_challenge_method']; + if (ctx.session.codeChallengeMethod) { + if (!supportedCodeChallengeMethods.includes(ctx.session.codeChallengeMethod)) { + Manager._setError(ctx, 'invalid_request', 'unsupported code_challenge_method'); + } + } else { + if (this.options.manager.allowLegacyNonPKCE) { + return; + } + Manager._setError(ctx, 'invalid_request', 'missing required parameter \'code_challenge_method\''); + } + } + + + /** + * A code_challenge must be present + * @param {Object} ctx + */ + _codeChallengeRequired(ctx) { + ctx.session.codeChallenge = ctx.queryParams['code_challenge']; + if (ctx.session.codeChallenge) { + if (!validBase64URLRE.test(ctx.session.codeChallenge)) { + Manager._setError(ctx, 'invalid_request', 'invalid value for parameter \'code_challenge\''); + } + } else { + if (this.options.manager.allowLegacyNonPKCE) { + return; + } + Manager._setError(ctx, 'invalid_request', 'missing required parameter \'code_challenge\''); + } + } + + + /** + * Scopes may be present, with one known combination limitation + * @param {Object} ctx + */ + _scopeOptional(ctx) { + const _scope = _fileScope('_scopeOptional'); + const scope = ctx.queryParams['scope']; + ctx.session.scope = []; + if (scope) { + const allScopes = scope.split(scopeSplitRE); + const validScopes = allScopes.filter((s) => common.validScope(s)); + ctx.session.scope.push(...validScopes); + if (allScopes.length != validScopes.length) { + const invalidScopes = allScopes.filter((s) => !common.validScope(s)); + this.logger.debug(_scope, 'client requested invalid scope', { ctx, invalidScopes }); + } + } + // If email scope is requested, profile scope must also be explicitly requested. + if (ctx.session.scope.includes('email') + && !ctx.session.scope.includes('profile')) { + Manager._setError(ctx, 'invalid_scope', 'cannot provide \'email\' scope without \'profile\' scope'); + } + } + + + /** + * Parses me, if provided + * @param {Object} ctx + */ + async _meOptional(ctx) { + const me = ctx.queryParams['me']; + if (me) { + try { + ctx.session.me = await this.communication.validateProfile(me); + } catch (e) { + ctx.session.me = undefined; + } + } + } + + + /** + * Ensure authenticated identifier matches profile. + * @param {Object} ctx + * @returns {Boolean} + */ + _profileValidForIdentifier(ctx) { + const _scope = _fileScope('_profileValidForIdentifier'); + + if (!ctx.session.me) { + this.logger.debug(_scope, 'no profile provided, cannot correlate', { ctx }); + return false; + } + + return ctx.session.profiles.includes(ctx.session.me.href); + } + + + /** + * Get numeric value from form field data. + * @param {*} ctx + * @param {String} field + * @param {String} customField + * @returns {Number=} + */ + _parseLifespan(ctx, field, customField) { + const _scope = _fileScope('_parseLifespan'); + + const presetValues = { + 'never': undefined, + '1d': 86400, + '1w': 86400 * 7, + '1m': 86400 * 31, + }; + const fieldValue = ctx.parsedBody[field]; // eslint-disable-line security/detect-object-injection + if (fieldValue in presetValues) { + return presetValues[fieldValue]; // eslint-disable-line security/detect-object-injection + } + + if (fieldValue === 'custom') { + const expiresSeconds = parseInt(ctx.parsedBody[customField], 10); // eslint-disable-line security/detect-object-injection + if (isFinite(expiresSeconds) && expiresSeconds > 0) { + return expiresSeconds; + } else { + this.logger.debug(_scope, 'invalid custom value', { ctx, field, customField }); + } + } + + this.logger.debug(_scope, 'invalid value', { ctx, field, customField }); + return undefined; + } + + + /** + * Validate any accepted scopes, ensure uniqueness, return as array. + * @param {Object} ctx + * @returns {String=} + */ + _parseConsentScopes(ctx) { + const _scope = _fileScope('_ingestConsentScopes'); + const acceptedScopesSet = new Set(); + const rejectedScopesSet = new Set(); + + const submittedScopes = common.ensureArray(ctx.parsedBody['accepted_scopes']) + .concat((ctx.parsedBody['ad_hoc_scopes'] || '').split(scopeSplitRE)); + submittedScopes.forEach((scope) => { + if (scope) { + (common.validScope(scope) ? acceptedScopesSet : rejectedScopesSet).add(scope); + } + }); + + // If email scope was accepted but profile was not, elide email scope + if (acceptedScopesSet.has('email') + && !acceptedScopesSet.has('profile')) { + acceptedScopesSet.delete('email'); + rejectedScopesSet.add('email (without profile)'); + } + + if (rejectedScopesSet.size) { + this.logger.debug(_scope, 'ignoring invalid scopes', { ctx, rejectedScopes: Array.from(rejectedScopesSet) }); + } + + return Array.from(acceptedScopesSet); + } + + + /** + * Parse and validate selected me is a valid profile option. + * @param {Object} ctx + * @returns {URL} + */ + _parseConsentMe(ctx) { + const _scope = _fileScope('_parseConsentMe'); + const selectedMe = ctx.parsedBody['me']; + try { + const me = new URL(selectedMe); + if (ctx.session.profiles.includes(me.href)) { + return me; + } else { + this.logger.debug(_scope, 'selected \'me\' profile not among available', { me, available: ctx.session.profiles, ctx }); + Manager._setError(ctx, 'invalid_request', 'invalid profile url'); + } + } catch (e) { + this.logger.debug(_scope, 'failed to parse selected \'me\' as url', { error: e, ctx }); + Manager._setError(ctx, 'invalid_request', 'invalid profile url'); + } + return undefined; + } + + + /** + * Get up-to-date profile data from selected profile endpoint. + * @param {Object} ctx + * @returns {Object} + */ + async _fetchConsentProfileData(ctx) { + const _scope = _fileScope('_fetchConsentProfileData'); + try { + const profile = await this.communication.fetchProfile(ctx.session.me); + if (!profile) { + this.logger.debug(_scope, 'no profile data at \'me\' endpoint', { ctx }); + Manager._setError(ctx, 'temporarily_unavailable', 'unable to retrieve profile'); + } else { + // Profile info gets persisted in code, only include known profile fields to help keep size down. + return common.pick(profile, [ + 'name', + 'photo', + 'url', + 'email', + ]); + } + } catch (e) { + this.logger.debug(_scope, 'failed to fetch \'me\' endpoint', { error: e, ctx }); + Manager._setError(ctx, 'temporarily_unavailable', 'could not reach profile endpoint'); + } + return undefined; + } + + + /** + * Ingest user consent response details, redirect as needed. + * Receives POST request from consent page, expecting these form fields: + * session - encrypted data collected from initial auth call + * accept - 'true' if consent was granted + * accepted_scopes - list of scopes to grant + * ad_hoc_scopes - additional scopes specified by user + * me - selected profile to identify as + * expires - optional lifespan + * expires-seconds - optional custom lifespan + * refresh - optional refresh lifespan + * refresh-seconds - optional custom refresh lifespan + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async postConsent(res, ctx) { + const _scope = _fileScope('postConsent'); + this.logger.debug(_scope, 'called', { ctx }); + + // Ensure session exists, persisting any login session data. + ctx.session = Object.assign({}, ctx.session); + try { + // Recover the session established on initial auth request. + const oldSession = await this.mysteryBox.unpack(ctx.parsedBody['session']); + Object.assign(ctx.session, oldSession); + ctx.session.redirectUri = new URL(ctx.session.redirectUri); + ctx.session.clientId = new URL(ctx.session.clientId); + } catch (e) { + this.logger.debug(_scope, 'failed to unpack session', { error: e, ctx }); + Manager._setError(ctx, 'invalid_request', 'un-parsable data in authorization consent'); + } + + // If these are missing, we cannot proceed. + if (!ctx.session.clientId || !ctx.session.redirectUri) { + // Set error response for html template to render. + ctx.errors = [ + 'Cannot redirect to client application.', + ]; + ctx.errorContent = [ + 'There was an error in the request sent by the application attempting to authenticate you. Check with that service.', + ]; + res.statusCode = 400; + res.end(Template.authorizationErrorHTML(ctx, this.options)); + this.logger.info(_scope, 'bad request, cannot redirect', { ctx }); + return; + } + + // TODO: Should probably re-validate more unpacked session values, even though those should be trustable. + + // Check if we need to check anything else. + ctx.session.accept = (ctx.parsedBody['accept'] === 'true'); + if (!ctx.session.accept) { + this.logger.debug(_scope, 'consent denied', { ctx }); + Manager._setError(ctx, 'access_denied', 'authorization was not granted'); + } else { + // Ingest form data. + ctx.session.acceptedScopes = this._parseConsentScopes(ctx); + ctx.session.me = this._parseConsentMe(ctx); + ctx.session.profile = await this._fetchConsentProfileData(ctx); + ctx.session.tokenLifespan = this._parseLifespan(ctx, 'expires', 'expires-seconds'); + if (ctx.session.tokenLifespan) { + ctx.session.refreshLifespan = this._parseLifespan(ctx, 'refresh', 'refresh-seconds'); + } + } + + if (ctx.session.error) { + this.logger.debug(_scope, 'invalid request, redirecting', { ctx }); + + // Set all errors as parameters for client to interpret upon redirection. + Manager._setSearchParams(ctx.session.redirectUri, { + 'state': ctx.session.state, + 'error': ctx.session.error, + 'error_description': ctx.session.errorDescriptions.join(', '), + }); + res.statusCode = 302; // Found + res.setHeader(Enum.Header.Location, ctx.session.redirectUri.href); + res.end(); + this.logger.info(_scope, 'bad request, redirected', { ctx }); + return; + } + + // Consented, off we go. Keep all this session state as the code. + const code = await this.mysteryBox.pack({ + codeId: ctx.session.id, + codeChallengeMethod: ctx.session.codeChallengeMethod, + codeChallenge: ctx.session.codeChallenge, + clientId: ctx.session.clientId.href, + redirectUri: ctx.session.redirectUri.href, + acceptedScopes: ctx.session.acceptedScopes, + tokenLifespan: ctx.session.tokenLifespan, + refreshLifespan: ctx.session.refreshLifespan, + me: ctx.session.me.href, + profile: ctx.session.profile, + identifier: ctx.session.authenticatedIdentifier, // need this to pair with profile + minted: Date.now(), + }); + + Manager._setSearchParams(ctx.session.redirectUri, { + 'code': code, + 'state': ctx.session.state, + 'iss': this.options.dingus.selfBaseUrl, + }); + res.statusCode = 302; + res.setHeader(Enum.Header.Location, ctx.session.redirectUri.href); + res.end(); + + this.logger.info(_scope, 'finished', { ctx }); + } + + + /** + * Redeem a code for a profile url, and maybe more profile info. + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async postAuthorization(res, ctx) { + const _scope = _fileScope('postAuthorization'); + this.logger.debug(_scope, 'called', { ctx }); + + await this._ingestPostAuthorizationRequest(ctx); + + const response = { + me: ctx.session.me, + ...(ctx.session?.acceptedScopes?.includes('profile') && { profile: ctx.session.profile }), + scope: ctx.session.acceptedScopes, + }; + if (response.profile && !ctx.session?.acceptedScopes?.includes('email')) { + delete response.profile.email; + } + + if (!ctx.session.error) { + await this.db.context(async (dbCtx) => { + // Record code redemption without token. + const valid = await this.db.redeemCode(dbCtx, { + codeId: ctx.session.codeId, + created: new Date(), + isToken: false, + clientId: ctx.session.clientId.href, + profile: ctx.session.me, + identifier: ctx.session.identifier, + scopes: ctx.session.acceptedScopes, + lifespanSeconds: Math.ceil(this.options.manager.codeValidityTimeoutMs / 1000), + profileData: response.profile, + }); + if (!valid) { + this.logger.debug(_scope, 'code already redeemed', { ctx }); + Manager._setError(ctx, 'access_denied', 'code already redeemed'); + } + }); // dbCtx + } + + if (ctx.session.error) { + res.statusCode = 400; + res.end(JSON.stringify({ + 'error': ctx.session.error, + 'error_description': ctx.session.errorDescriptions.join(', '), + })); + this.logger.info(_scope, 'invalid request', { ctx }); + return; + } + + res.end(JSON.stringify(response)); + + this.logger.info(_scope, 'finished', { ctx, response }); + } + + + /** + * Ingest an incoming authorization redemption request, parsing fields + * onto a new session object on the context. + * @param {*} dbCtx + * @param {Object} ctx + */ + async _ingestPostAuthorizationRequest(ctx) { + const _scope = _fileScope('_ingestPostAuthorizationRequest'); + + ctx.session = Object.assign({}, ctx.session, { + errorDescriptions: [], + }); + + if (!ctx.parsedBody) { + this.logger.debug(_scope, 'no body data', { ctx }); + Manager._setError(ctx, 'invalid_request', 'missing data'); + } + + await this._restoreSessionFromCode(ctx); + this._checkSessionMatchingClientId(ctx); + this._checkSessionMatchingRedirectUri(ctx); + this._checkGrantType(ctx); + this._checkSessionMatchingCodeVerifier(ctx); + + if (!ctx.session.me || !ctx.session.minted) { + this.logger.debug(_scope, 'session missing fields', { ctx }); + Manager._setError(ctx, 'invalid_request', 'malformed code'); + return; + } + + const expires = new Date(ctx.session.minted + this.options.manager.codeValidityTimeoutMs); + const now = new Date(); + if (expires < now) { + this.logger.debug(_scope, 'code expired', { ctx }); + Manager._setError(ctx, 'invalid_request', 'code has expired'); + } + } + + + /** + * Unpack the session data from provided code overtop of context session .. + * @param {Object} ctx + */ + async _restoreSessionFromCode(ctx) { + const _scope = _fileScope('_restoreSessionFromCode'); + + const code = ctx.parsedBody['code']; + if (code) { + try { + const oldSession = await this.mysteryBox.unpack(code); + + // TODO: Validate unpacked fields better + const missingFields = [ + 'codeId', + 'codeChallengeMethod', + 'codeChallenge', + 'clientId', + 'redirectUri', + 'acceptedScopes', + 'me', + 'profile', + 'identifier', + 'minted', + ].filter((requiredField) => !(requiredField in oldSession)); + if (missingFields.length) { + if (this.options.manager.allowLegacyNonPKCE + && missingFields.length === 2 + && missingFields.includes('codeChallenge') + && missingFields.includes('codeChallengeMethod')) { + this.logger.debug(_scope, 'allowing legacy non-PKCE session', { ctx }); + } else { + this.logger.debug(_scope, 'unpacked code is missing required field', { missingFields, ctx }); + Manager._setError(ctx, 'invalid_request', 'code is not valid'); + } + } + + Object.assign(ctx.session, oldSession); + } catch (e) { + this.logger.debug(_scope, 'failed to parse code', { error: e, ctx }); + Manager._setError(ctx, 'invalid_request', 'code is not valid'); + } + } else { + Manager._setError(ctx, 'invalid_request', 'missing required parameter \'code\''); + } + } + + + /** + * Ensure provided client_id matches session clientId. + * @param {Object} ctx + */ + _checkSessionMatchingClientId(ctx) { + const _scope = _fileScope('_checkSessionMatchingClientId'); + + let clientId = ctx.parsedBody['client_id']; + if (clientId) { + try { + clientId = new URL(clientId); + ctx.session.clientId = new URL(ctx.session.clientId); + } catch (e) { + this.logger.debug(_scope, 'un-parsable client_id url', { ctx }); + delete ctx.session.clientId; + Manager._setError(ctx, 'invalid_request', 'malformed client_id'); + return; + } + if (clientId.href !== ctx.session.clientId.href) { + this.logger.debug(_scope, 'clientId mismatched', { clientId, ctx }); + delete ctx.session.clientId; + Manager._setError(ctx, 'invalid_request', 'code does not belong to that client_id'); + } + } else { + Manager._setError(ctx, 'invalid_request', 'missing required parameter \'client_id\''); + } + } + + + /** + * @param {Object} ctx + */ + _checkSessionMatchingRedirectUri(ctx) { + const _scope = _fileScope('_checkSessionMatchingClientId'); + + let redirectUri = ctx.parsedBody['redirect_uri']; + if (redirectUri) { + try { + redirectUri = new URL(redirectUri); + ctx.session.redirectUri = new URL(ctx.session.redirectUri); + } catch (e) { + this.logger.debug(_scope, 'un-parsable redirect_uri url', { ctx }); + delete ctx.session.redirectUri; + Manager._setError(ctx, 'invalid_request', 'malformed redirect_url'); + return; + } + if (redirectUri.href !== ctx.session.redirectUri.href) { + this.logger.debug(_scope, 'redirectUri mismatched', { redirectUri, ctx }); + delete ctx.session.redirectUri; + Manager._setError(ctx, 'invalid_request', 'code does not belong to that redirect_uri'); + } + } else { + Manager._setError(ctx, 'invalid_request', 'missing required parameter \'redirect_uri\''); + } + } + + + /** + * Validate grant_type, either persist on session or set error. + * @param {Object} ctx + * @param {String[]} validGrantTypes + * @param {Boolean} treatEmptyAs + */ + _checkGrantType(ctx, validGrantTypes = ['authorization_code'], treatEmptyAs = 'authorization_code') { + const _scope = _fileScope('_checkGrantType'); + + const grantType = ctx.parsedBody['grant_type'] || treatEmptyAs; + if (!ctx.parsedBody['grant_type'] && treatEmptyAs) { + this.logger.debug(_scope, `missing grant_type, treating as ${treatEmptyAs}`, { ctx }); + } + if (validGrantTypes.includes(grantType)) { + ctx.session.grantType = grantType; + } else { + Manager._setError(ctx, 'invalid_request', 'grant_type not supported'); + } + } + + + /** + * @param {Object} ctx + */ + _checkSessionMatchingCodeVerifier(ctx) { + const _scope = _fileScope('_checkSessionMatchingCodeVerifier'); + + const codeVerifier = ctx.parsedBody['code_verifier']; + if (codeVerifier) { + try { + const valid = Communication.verifyChallenge(ctx.session.codeChallenge, codeVerifier, ctx.session.codeChallengeMethod); + if (!valid) { + this.logger.debug(_scope, 'challenge mismatched', { ctx }); + Manager._setError(ctx, 'invalid_request', 'challenge verification failed'); + } + } catch (e) /* istanbul ignore next */ { + this.logger.error(_scope, 'challenge validation failed', { error: e, ctx }); + Manager._setError(ctx, 'invalid_request', 'challenge verification failed'); + } + } else { + if (this.options.manager.allowLegacyNonPKCE + && !ctx.session.codeChallenge + && !ctx.session.codeChallengeMethod) { + this.logger.debug(_scope, 'allowing non-PKCE', { ctx }); + return; + } + Manager._setError(ctx, 'invalid_request', 'missing required parameter \'code_verifier\''); + } + } + + + /** + * Attempt to revoke a token. + * @param {*} dbCtx + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async _revokeToken(dbCtx, res, ctx) { + const _scope = _fileScope('_revokeToken'); + try { + const token = ctx.parsedBody['token']; + const tokenTypeHint = ctx.parsedBody['token_type_hint']; + switch (tokenTypeHint) { + case undefined: + break; + case 'access_token': + break; + case 'refresh_token': + break; + default: + this.logger.debug(_scope, 'unknown token_type_hint', { ctx }); + } + if (!token) { + throw new ValidationError('Token Missing'); + } + ctx.token = await this.mysteryBox.unpack(token); + if (!(ctx.token?.c || ctx.token?.rc)) { + throw new ValidationError('Token Invalid'); + } + } catch (e) { + this.logger.debug(_scope, 'invalid token', { error: e, ctx }); + res.statusCode = 400; + res.end(); + this.logger.info(_scope, 'finished, revoke request not valid', { error: e, ctx }); + return; + } + + try { + if (ctx.token.c) { + await this.db.tokenRevokeByCodeId(dbCtx, ctx.token.c); + } else { + await this.db.tokenRefreshRevokeByCodeId(dbCtx, ctx.token.rc); + } + } catch (e) { + if (e instanceof DBErrors.UnexpectedResult) { + res.statusCode = 404; + res.end(); + this.logger.info(_scope, 'finished, no token to revoke', { error: e, ctx }); + return; + } + this.logger.error(_scope, 'revoke token failed', { error: e, ctx }); + throw e; + } + + res.end(); + this.logger.info(_scope, 'finished, token revoked', { ctx }); + } + + + /** + * Legacy token validation flow. + * @param {*} dbCtx + * @param {http.ClientRequest} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async _validateToken(dbCtx, req, res, ctx) { + const _scope = _fileScope('_validateToken'); + await this._checkTokenValidationRequest(dbCtx, req, ctx); + if (ctx.bearer.isValid) { + Manager._sensitiveResponse(res); + res.end(JSON.stringify({ + me: ctx.token.profile, + 'client_id': ctx.token.clientId, + scope: ctx.token.scopes, + })); + this.logger.info(_scope, 'finished, token validated', { ctx }); + } else { + const responseErrorParts = ['Bearer']; + const error = ctx.session.error ? `error="${ctx.session.error}"` : ''; + if (error) { + responseErrorParts.push(error); + } + const errorDescription = ctx.session.errorDescriptions ? `error_description="${ctx.session.errorDescriptions.join(', ')}"` : ''; + if (errorDescription) { + responseErrorParts.push(errorDescription); + } + res.setHeader(Enum.Header.WWWAuthenticate, responseErrorParts.join(', ')); + this.logger.info(_scope, 'finished, token not validated', { ctx }); + throw new ResponseError(Enum.ErrorResponse.Unauthorized); + } + } + + + /** + * Given a list of newly-requested scopes, return a list of scopes + * from previousScopes which are not in requestedScopes. + * @param {String[]} previousScopes + * @param {String[]} requestedScopes + * @returns {String[]} + */ + static _scopeDifference(previousScopes, requestedScopes) { + const scopesToRemove = []; + const existingScopesSet = new Set(previousScopes); + const validRequestedScopes = requestedScopes.filter((s) => common.validScope(s)); + const requestedScopesSet = new Set(validRequestedScopes); + existingScopesSet.forEach((s) => { + if (!requestedScopesSet.has(s)) { + scopesToRemove.push(s); + } + }); + return scopesToRemove; + } + + + /** + * Redeem a refresh token for a new token. + * @param {*} dbCtx + * @param {http.ClientRequest} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async _refreshToken(dbCtx, req, res, ctx) { + const _scope = _fileScope('_refreshToken'); + this.logger.debug(_scope, 'called', { ctx }); + + const { + 'client_id': clientId, + scope, + } = ctx.parsedBody; + + try { + ctx.refreshToken = await this.mysteryBox.unpack(ctx.parsedBody['refresh_token']); + } catch (e) { + this.logger.debug(_scope, 'failed to unpack token', { error: e, ctx }); + } + + const now = new Date(); + const nowEpoch = common.dateToEpoch(now); + + await this.db.transaction(dbCtx, async (txCtx) => { + if (ctx.refreshToken?.rc) { + ctx.token = await this.db.tokenGetByCodeId(txCtx, ctx.refreshToken.rc); + } + + if (!ctx.token) { + this.logger.debug(_scope, 'no token to refresh', { ctx }); + throw new ResponseError(Enum.ErrorResponse.NotFound); + } + + if (!ctx.token.refreshExpires + || ctx.token.refreshExpires < now) { + this.logger.debug(_scope, 'token not refreshable or refresh expired', { ctx }); + throw new ResponseError(Enum.ErrorResponse.BadRequest); + } + + const refreshExpiresEpoch = common.dateToEpoch(ctx.token.refreshExpires); + if (ctx.refreshToken.exp < refreshExpiresEpoch) { + this.logger.debug(_scope, 'token already refreshed', { ctx }); + throw new ResponseError(Enum.ErrorResponse.BadRequest); + } + + if (clientId !== ctx.token.clientId) { + this.logger.debug(_scope, 'client identifier mismatch', { ctx }); + throw new ResponseError(Enum.ErrorResponse.BadRequest); + } + + const scopesToRemove = scope ? Manager._scopeDifference(ctx.token.scopes, scope.split(scopeSplitRE)) : []; + if (scopesToRemove.length) { + this.logger.debug(_scope, 'scope reduction requested', { ctx, scopesToRemove }); + } + + const refreshedTokenData = await this.db.refreshCode(txCtx, ctx.refreshToken.rc, now, scopesToRemove); + if (refreshedTokenData) { + Object.assign(ctx.token, refreshedTokenData); + } else { + this.logger.debug(_scope, 'could not refresh token', { ctx }); + throw new ResponseError(Enum.ErrorResponse.NotFound); + } + }); // tx + + const [token, refreshToken] = await Promise.all([ + { + c: ctx.token.codeId, + ts: nowEpoch, + }, + { + rc: ctx.token.codeId, + ts: nowEpoch, + exp: nowEpoch + ctx.token.refreshDuration, + }, + ].map(this.mysteryBox.pack)); + + const response = { + 'access_token': token, + 'token_type': 'Bearer', + ...(ctx.token.duration && { 'expires_in': nowEpoch + ctx.token.duration }), + ...(refreshToken && { 'refresh_token': refreshToken }), + scope: ctx.token.scopes.join(' '), + me: ctx.session.me, + ...(ctx.token.scopes.includes('profile') && { profile: ctx.token.profileData }), + }; + if (ctx.token.scopes.includes('profile') && !ctx.token.scopes.includes('email')) { + delete response?.profile?.email; + } + + Manager._sensitiveResponse(res); + res.end(JSON.stringify(response)); + this.logger.info(_scope, 'finished', { ctx }); + } + + + /** + * Generate a new ticket for later redemption. + * @param {Object} payload + * @param {} payload.subject deliver ticket to this endpoint + * @param {} payload.resource url the redeemed ticket is valid for accessing + * @param {String[]} payload.scopes list of scopes assigned to ticket + * @param {String} payload.identifier user generating ticket + * @param {} payload.profile profile of user generating ticket + * @param {Number} payload.ticketLifespanSeconds ticket redeemable for this long + * @returns {String} + */ + async _mintTicket({ subject, resource, scopes, identifier, profile, ticketLifespanSeconds }) { + const _scope = _fileScope('_mintTicket'); + this.logger.debug(_scope, 'called', { subject, resource, scopes, identifier, profile, ticketLifespanSeconds }); + + const nowEpoch = common.dateToEpoch(); + return this.mysteryBox.pack({ + c: common.requestId(), + iss: nowEpoch, + exp: nowEpoch + ticketLifespanSeconds, + sub: subject, + res: resource, + scope: scopes, + ident: identifier, + profile: profile, + }); + } + + + /** + * @typedef Ticket + * @property {String} codeId + * @property {Date} issued + * @property {Date} expires + * @property {URL} subject + * @property {URL} resource + * @property {String[]} scopes + * @property {String} identifier + * @property {URL} profile + */ + /** + * + * @param {String} ticket + * @returns {Ticket} + */ + async _unpackTicket(ticket) { + const ticketObj = await this.mysteryBox.unpack(ticket); + return { + codeId: ticketObj.c, + issued: new Date(ticketObj.iss * 1000), + expires: new Date(ticketObj.exp * 1000), + subject: new URL(ticketObj.sub), + resource: new URL(ticketObj.res), + scopes: ticketObj.scope, + identifier: ticketObj.ident, + profile: new URL(ticketObj.profile), + }; + } + + + /** + * Redeem a ticket for a token. + * @param {*} dbCtx + * @param {http.ClientRequest} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async _ticketAuthToken(dbCtx, req, res, ctx) { + const _scope = _fileScope('_ticketAuthToken'); + this.logger.debug(_scope, 'called', { ctx }); + + try { + ctx.ticket = await this._unpackTicket(ctx.parsedBody['ticket']); + } catch (e) { + this.logger.debug(_scope, 'failed to unpack ticket', { error: e, ctx }); + throw new ResponseError(Enum.ErrorResponse.BadRequest); + } + + const now = new Date(); + if (now > ctx.ticket.expires) { + this.logger.debug(_scope, 'ticket has expired', { ctx }); + throw new ResponseError(Enum.ErrorResponse.Forbidden, { reason: 'Ticket has expired.', expired: ctx.ticket.expires }); + } + + const nowEpoch = common.dateToEpoch(now); + const token = await this.mysteryBox.pack({ + c: ctx.ticket.codeId, + ts: nowEpoch, + }); + + const response = { + 'access_token': token, + 'token_type': 'Bearer', + scope: ctx.ticket.scopes.join(' '), + me: ctx.ticket.profile.href, + }; + + const isValid = await this.db.redeemCode(dbCtx, { + created: now, + codeId: ctx.ticket.codeId, + isToken: true, + clientId: ctx.ticket.subject.href, + resource: ctx.ticket.resource.href, + profile: ctx.ticket.profile.href, + identifier: ctx.ticket.identifier, + scopes: ctx.ticket.scopes, + }); + if (!isValid) { + this.logger.debug(_scope, 'redemption failed, already redeemed', { ctx }); + throw new ResponseError(Enum.ErrorResponse.Forbidden); + } + + Manager._sensitiveResponse(res); + res.end(JSON.stringify(response)); + this.logger.info(_scope, 'finished', { ctx }); + } + + + /** + * Redeem a code for a token. + * @param {*} dbCtx + * @param {http.ClientRequest} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async _codeToken(dbCtx, req, res, ctx) { + const _scope = _fileScope('_codeToken'); + this.logger.debug(_scope, 'called', { ctx }); + + await this._restoreSessionFromCode(ctx); + await this._checkSessionMatchingRedirectUri(ctx); + + if (ctx.session.error) { + throw new ResponseError(Enum.ErrorResponse.BadRequest); + } + + /** + * Note the creation date here rather than in database, so that stored + * expire dates are ensured to match those packed in tokens. + * An alternative would be to return the date generated by the database, + * but then we would need to hold the transaction open while minting the + * tokens to ensure success. Perhaps that would be worth it, but for now + * this is how it is. + */ + const now = new Date(); + const nowEpoch = common.dateToEpoch(now); + const tokenMinters = []; + + tokenMinters.push(this.mysteryBox.pack({ + c: ctx.session.codeId, + ts: nowEpoch, + ...(ctx.session.tokenLifespan && { exp: nowEpoch + ctx.session.tokenLifespan }), + })); + + if (ctx.session.tokenLifespan + && ctx.session.refreshLifespan) { + tokenMinters.push(this.mysteryBox.pack({ + rc: ctx.session.codeId, + ts: nowEpoch, + exp: nowEpoch + ctx.session.refreshLifespan, + })); + } + + const [token, refreshToken] = await Promise.all(tokenMinters); + + const response = { + 'access_token': token, + 'token_type': 'Bearer', + ...(ctx.session.tokenLifespan && { 'expires_in': nowEpoch + ctx.session.tokenLifespan }), + ...(refreshToken && { 'refresh_token': refreshToken }), + scope: ctx.session.acceptedScopes.join(' '), + me: ctx.session.me, + ...(ctx.session.acceptedScopes.includes('profile') && { profile: ctx.session.profile }), + }; + if (!ctx.session.acceptedScopes.includes('email') && response.profile) { + delete response.profile.email; + } + + const isValid = await this.db.redeemCode(dbCtx, { + created: now, + codeId: ctx.session.codeId, + isToken: true, + clientId: ctx.session.clientId, + profile: ctx.session.me, + identifier: ctx.session.identifier, + scopes: ctx.session.acceptedScopes, + lifespanSeconds: ctx.session.tokenLifespan, + refreshLifespanSeconds: ctx.session.refreshLifespan, + profileData: response.profile, + }); + if (!isValid) { + this.logger.debug(_scope, 'redemption failed, already redeemed', { ctx }); + throw new ResponseError(Enum.ErrorResponse.Forbidden); + } + + Manager._sensitiveResponse(res); + res.end(JSON.stringify(response)); + this.logger.info(_scope, 'finished', { ctx }); + } + + + /** + * Issue, refresh, or validate a token. + * @param {http.ClientRequest} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async postToken(req, res, ctx) { + const _scope = _fileScope('postToken'); + this.logger.debug(_scope, 'called', { ctx }); + + ctx.session = Object.assign({}, ctx.session); + + await this.db.context(async (dbCtx) => { + + // Is this a (legacy) revocation request? + if (ctx.parsedBody['action'] === 'revoke') { + await this._revokeToken(dbCtx, res, ctx); + return; + } + + // Is this a (legacy) token validation request? + if (req.getHeader(Enum.Header.Authorization)) { + await this._validateToken(dbCtx, res, ctx); + return; + } + + const validGrantTypes = [ + 'authorization_code', + 'refresh_token', + ...(this.queuePublisher && ['ticket'] || []), + ]; + this._checkGrantType(ctx, validGrantTypes, 'authorization_code'); + + switch (ctx.session.grantType) { + case 'refresh_token': + return this._refreshToken(dbCtx, req, res, ctx); + + case 'ticket': + return this._ticketAuthToken(dbCtx, req, res, ctx); + + case 'authorization_code': + return this._codeToken(dbCtx, req, res, ctx); + + default: + this.logger.debug(_scope, 'unknown grant_type', { ctx }); + Manager._setError(ctx, 'invalid_request', 'grant_type not supported'); + } + + // Only way of getting here is due to error. + throw new ResponseError(Enum.ErrorResponse.BadRequest); + }); // dbCtx + } + + + /** + * Ingest token from authorization header, setting ctx.bearer.isValid appropriately. + * ctx.bearer not set if auth method not recognized. + * This is for legacy validation on token endpoint. + * @param {*} dbCtx + * @param {http.ClientRequest} req + * @param {Object} ctx + */ + async _checkTokenValidationRequest(dbCtx, req, ctx) { + const _scope = _fileScope('_checkTokenValidationRequest'); + const authHeader = req.getHeader(Enum.Header.Authorization); + + if (authHeader) { + const [authMethod, authString] = common.splitFirst(authHeader, ' ', ''); + switch (authMethod.toLowerCase()) { // eslint-disable-line sonarjs/no-small-switch + case 'bearer': { + ctx.bearer = { + isValid: false, + }; + try { + Object.assign(ctx.bearer, await this.mysteryBox.unpack(authString)); + } catch (e) { + this.logger.debug(_scope, 'failed to unpack token', { ctx }); + Manager._setError(ctx, 'invalid_request', 'invalid token'); + return; + } + if (!ctx.bearer.c) { + this.logger.debug(_scope, 'incomplete token', { ctx }); + Manager._setError(ctx, 'invalid_request', 'invalid token'); + return; + } + + try { + ctx.token = await this.db.tokenGetByCodeId(dbCtx, ctx.bearer.c); + } catch (e) { + this.logger.error(_scope, 'failed to look up token', { error: e, ctx }); + throw e; + } + + if (!ctx.token) { + this.logger.debug(_scope, 'no token found', { ctx }); + Manager._setError(ctx, 'invalid_request', 'invalid token'); + return; + } + + if (!ctx.token.isRevoked + && ctx.token.expires > new Date()) { + ctx.bearer.isValid = true; + } + break; + } + + default: + this.logger.debug(_scope, 'unknown authorization scheme', { ctx }); + return; + } + } + } + + + /** + * Accept an unsolicited ticket proffering. + * @param {http.ClientRequest} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async postTicket(req, res, ctx) { + const _scope = _fileScope('postTicket'); + this.logger.debug(_scope, 'called', { ctx }); + + if (!this.queuePublisher) { + this.logger.debug(_scope, 'ticket endpoint not configured', { ctx }); + throw new ResponseError(Enum.ErrorResponse.BadRequest); + } + + const queueName = this.options.queues.ticketPublishName; + const { ticket, resource, subject } = ctx.parsedBody; + + try { + new URL(resource); + } catch (e) { + this.logger.debug(_scope, 'unparsable resource', { ticket, resource, subject, ctx }); + throw new ResponseError(Enum.ErrorResponse.BadRequest); + } + + await this.db.context(async (dbCtx) => { + const isValidProfile = await this.db.profileIsValid(dbCtx, subject); + if (!isValidProfile) { + this.logger.debug(_scope, 'invalid subject', { ticket, resource, subject, ctx }); + throw new ResponseError(Enum.ErrorResponse.NotFound, { error: 'subject not under our purview' }); + } + + try { + const result = await this.queuePublisher.publish(queueName, { ticket, resource, subject }); + this.logger.debug(_scope, 'accepted ticket offer', { queueName, ticket, resource, subject, ctx, result }); + } catch (e) { + this.logger.error(_scope, 'failed to publish ticket to queue', { error: e, queueName, ticket, resource, subject, ctx }); + throw e; // return a 500 + } + + res.statusCode = 202; + res.end(); + this.logger.info(_scope, 'finished', { resource, subject, ctx }); + }); + } + + + /** + * Validate a token and return data about it. + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async postIntrospection(res, ctx) { + const _scope = _fileScope('postIntrospection'); + this.logger.debug(_scope, 'called', { ctx }); + + let response = { + active: false, + }; + + const tokenIsTicket = (ctx.parsedBody['token_hint_type'] || '').toLowerCase() === 'ticket'; + + try { + const token = ctx.parsedBody['token']; + if (tokenIsTicket) { + ctx.token = await this._unpackTicket(token); + } else { + ctx.token = await this.mysteryBox.unpack(token); + } + } catch (e) { + this.logger.debug(_scope, 'failed to unpack token', { error: e, ctx }); + } + + if (ctx.token + && !tokenIsTicket) { + await this.db.context(async (dbCtx) => { + ctx.token = await this.db.tokenGetByCodeId(dbCtx, ctx.token.c); + }); // dbCtx + } + + if (ctx.token + && !ctx.token.isRevoked) { + // fuss around for postgres 'Infinity' date + const expiresMs = (ctx.token.expires instanceof Date) ? ctx.token.expires.getTime() : ctx.token.expires; + if (expiresMs > Date.now()) { + response = { + active: true, + me: ctx.token.profile, + ...(ctx.token.clientId && { 'client_id': ctx.token.clientId }), + scope: ctx.token.scopes.join(' '), + iat: common.dateToEpoch(ctx.token.created || ctx.token.issued), + ...(isFinite(expiresMs) && { exp: Math.ceil(expiresMs / 1000) }), + ...(tokenIsTicket && { 'token_type': 'ticket' }), + }; + } + } + + Manager._sensitiveResponse(res); + res.end(JSON.stringify(response)); + this.logger.info(_scope, 'finished', { ctx }); + } + + + /** + * Revoke a token or refresh token. + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async postRevocation(res, ctx) { + const _scope = _fileScope('postRevocation'); + this.logger.debug(_scope, 'called', { ctx }); + + try { + await this.db.context(async (dbCtx) => { + await this._revokeToken(dbCtx, res, ctx); + }); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, ctx }); + throw e; + } + + this.logger.info(_scope, 'finished', { ctx }); + } + + + /** + * Profile information for a token. + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async postUserInfo(res, ctx) { + const _scope = _fileScope('postUserInfo'); + this.logger.debug(_scope, 'called', { ctx }); + + const token = ctx.parsedBody['token']; + if (!token) { + res.statusCode = 400; + res.end('"invalid_request"'); + this.logger.info(_scope, 'finished, invalid request', { ctx }); + return; + } + + try { + ctx.token = await this.mysteryBox.unpack(ctx.parsedBody['token']); + } catch (e) { + this.logger.debug(_scope, 'failed to unpack token', { error: e, ctx }); + } + + if (ctx.token) { + await this.db.context(async (dbCtx) => { + ctx.token = await this.db.tokenGetByCodeId(dbCtx, ctx.token.c); + }); // dbCtx + } + + if (!ctx.token + || ctx.token.isRevoked + // || tokenIsExpired(token) + ) { + res.statusCode = 401; + res.end('"invalid_token"'); + this.logger.info(_scope, 'finished, invalid token', { ctx }); + return; + } + + if (!ctx.token.scopes.includes('profile')) { + res.statusCode = 403; + res.end('"insufficient_scope"'); + this.logger.info(_scope, 'finished, insufficient scope', { ctx }); + return; + } + + const response = { + ...ctx.token.profile, + }; + if (!ctx.token.scopes.includes('email')) { + delete response.email; + } + + Manager._sensitiveResponse(res); + res.end(JSON.stringify(response)); + + this.logger.info(_scope, 'finished', { ctx }); + } + + + /** + * Show admin interface, allowing manipulation of profiles and scopes. + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async getAdmin(res, ctx) { + const _scope = _fileScope('getAdmin'); + this.logger.debug(_scope, 'called', { ctx }); + + const identifier = ctx.session.authenticatedIdentifier; + + await this.db.context(async (dbCtx) => { + ctx.profilesScopes = await this.db.profilesScopesByIdentifier(dbCtx, identifier); + ctx.tokens = await this.db.tokensGetByIdentifier(dbCtx, identifier); + }); // dbCtx + + res.end(Template.adminHTML(ctx, this.options)); + + this.logger.info(_scope, 'finished', { ctx }); + } + + + /** + * Process admin interface events. + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async postAdmin(res, ctx) { + const _scope = _fileScope('postAdmin'); + this.logger.debug(_scope, 'called', { ctx }); + + await this.db.context(async (dbCtx) => { + const identifier = ctx.session.authenticatedIdentifier; + const action = ctx?.parsedBody?.['action'] || ''; + + if (action === 'save-scopes') { + // Update the convenience scopes set for profiles. + // Expect 'scopes-<profile>' with value of array of scopes + const profileKeys = ctx.parsedBody && Object.keys(ctx.parsedBody) + .filter((k) => k.startsWith('scopes-')); + try { + await this.db.transaction(dbCtx, async (txCtx) => { + await Promise.all( + /* For each scopes-profile submitted, set those. */ + profileKeys.map((profileKey) => { + /* elide 'scope-' prefix to get the profile */ + const profile = profileKey.slice(7); + /* (should validate profile here) */ + + /* remove invalid scopes from submitted list */ + const scopes = ctx.parsedBody[profileKey].filter((scope) => scope && common.validScope(scope)); // eslint-disable-line security/detect-object-injection + return this.db.profileScopesSetAll(txCtx, profile, scopes); + }), + ); + }); // txCtx + ctx.notifications.push('Profile/Scope Availability Matrix updated!'); + } catch (e) { + this.logger.error(_scope, 'did not set profile scopes', { error: e, ctx }); + ctx.errors.push('Failed to update profile scopes.'); + } + + } else if (action === 'new-profile') { + // Validate and create a new profile uri. + let profile; + const profileUri = ctx.parsedBody['profile']; + try { + profile = await this.communication.validateProfile(profileUri); + } catch (e) { + this.logger.debug(_scope, 'invalid profile url', { error: e, ctx }); + ctx.errors.push(`'${profileUri}' is not a valid profile URI.${(e instanceof CommunicationErrors.ValidationError) ? ('(' + e.message + ')') : ''}`); + } + if (profile) { + // Validate profile uri + const profileData = await this.communication.fetchProfile(profile); + if (profileData.metadata.authorizationEndpoint !== this.selfAuthorizationEndpoint) { + this.logger.debug(_scope, 'profile does not list this server as auth', { profileData, ctx }); + ctx.errors.push('Requested profile does not list this service, not adding.'); + } else { + try { + await this.db.transaction(dbCtx, async (txCtx) => { + await this.db.profileIdentifierInsert(txCtx, profile.href, identifier); + await this.db.profileScopesSetAll(txCtx, profile.href, ['profile', 'email']); + }); // txCtx + ctx.notifications.push('Profile added!'); + } catch (e) { + this.logger.error(_scope, 'did not insert profile', { error: e, ctx }); + ctx.errors.push('Failed to add profile.'); + } + } + } + + } else if (action === 'new-scope') { + // Add or update a manually-added convenience scope. + const { scope, application = '', description = '' } = ctx.parsedBody; + if (scope) { + if (!common.validScope(scope)) { + ctx.errors.push(`"${scope}" is not a valid scope name, did not add it.`); + } else { + try { + await this.db.scopeUpsert(dbCtx, scope, application, description, true); + ctx.notifications.push('Scope List updated!'); + } catch (e) { + this.logger.error(_scope, 'did not upsert scope', { error: e, scope, application, description, ctx }); + ctx.errors.push('Failed to update scope.'); + } + } + } + + } else if (action.startsWith('delete-scope-')) { + // Remove a manually-added convenience scope. + const scope = decodeURIComponent(action.slice(13)); + if (scope) { + try { + const deleted = await this.db.scopeDelete(dbCtx, scope); + if (deleted) { + ctx.notifications.push('Scope deleted.'); + } else { + ctx.notifications.push('Unable to delete scope.'); + } + } catch (e) { + this.logger.error(_scope, 'did not delete scope', { error: e, scope, ctx }); + ctx.errors.push('Failed to delete scope.'); + } + } + + } else if (action.startsWith('revoke-')) { + // Revoke an active token. + const codeId = action.slice(8); + if (codeId) { + try { + await this.db.tokenRevokeByCodeId(dbCtx, codeId, identifier); + ctx.notifications.push('Revoked token!'); + } catch (e) { + this.logger.error(_scope, 'did not revoke token', { error: e, codeId, identifier, ctx }); + ctx.errors.push('Unable to revoke token.'); + } + } + + } else if (action) { + ctx.errors.push(`Do not know how to '${action}'.`); + } + + ctx.profilesScopes = await this.db.profilesScopesByIdentifier(dbCtx, identifier); + ctx.tokens = await this.db.tokensGetByIdentifier(dbCtx, identifier); + }); // dbCtx + + res.end(Template.adminHTML(ctx, this.options)); + + this.logger.info(_scope, 'finished', { ctx }); + } + + + /** + * Show ticket proffer interface. + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async getAdminTicket(res, ctx) { + const _scope = _fileScope('getAdminTicket'); + this.logger.debug(_scope, 'called', { ctx }); + + const identifier = ctx.session.authenticatedIdentifier; + + await this.db.context(async (dbCtx) => { + ctx.profilesScopes = await this.db.profilesScopesByIdentifier(dbCtx, identifier); + ctx.profiles = ctx.profilesScopes.profiles; + ctx.scopes = Object.keys(ctx.profilesScopes.scopeIndex); + }); // dbCtx + + res.end(Template.adminTicketHTML(ctx, this.options)); + + this.logger.info(_scope, 'finished', { ctx }); + } + + + /** + * Handle ticket proffer interface submission. + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async postAdminTicket(res, ctx) { + const _scope = _fileScope('postAdminTicket'); + this.logger.debug(_scope, 'called', { ctx }); + + switch (ctx.parsedBody['action']) { // eslint-disable-line sonarjs/no-small-switch + case 'proffer-ticket': { + const identifier = ctx.session.authenticatedIdentifier; + [ + { ctxProp: 'ticketProfileUrl', bodyParam: 'profile', err: 'Invalid Profile URL selected.' }, + { ctxProp: 'ticketResourceUrl', bodyParam: 'resource', err: 'Invalid Resource URL.' }, + { ctxProp: 'ticketSubjectUrl', bodyParam: 'subject', err: 'Invalid Recipient URL.' }, + ].forEach((param) => { + try { + ctx[param.ctxProp] = new URL(ctx.parsedBody[param.bodyParam]); + } catch (e) { + this.logger.debug(_scope, `invalid ${param.bodyParam}`, { ctx }); + ctx.errors.push(param.err); + } + }); + + const subjectData = await this.communication.fetchProfile(ctx.ticketSubjectUrl); + if (!subjectData?.metadata?.ticketEndpoint) { + this.logger.debug(_scope, 'subject has no ticket endpoint', { ctx }); + ctx.errors.push('Recipient does not list a ticket endpoint to deliver to.'); + } else { + try { + ctx.ticketEndpointUrl = new URL(subjectData.metadata.ticketEndpoint); + } catch (e) { + this.logger.debug(_scope, 'subject has invalid ticket endpoint', { error: e, ctx }); + ctx.errors.push(`Recipient lists an invalid ticket endpoint, cannot deliver. (${e})`); + } + } + + const scopesSet = new Set(); + const rawScopes = [ + ...(common.ensureArray(ctx.parsedBody['scopes'])), + ...((ctx.parsedBody['adhoc'] || '').split(scopeSplitRE)), + ].filter((scope) => scope); + rawScopes.forEach((scope) => { + if (common.validScope(scope)) { + scopesSet.add(scope); + } else { + this.logger.debug(_scope, 'invalid adhoc scope', { scope, ctx }); + ctx.errors.push(`'${scope}' is not a valid scope.`); + } + }); + ctx.ticketScopes = [...scopesSet]; + const actionScopes = ctx.ticketScopes.filter((scope) => !['profile', 'email'].includes(scope)); + if (!actionScopes.length) { + this.logger.debug(_scope, 'no valid scopes included', { ctx }); + ctx.errors.push('At least one actionable scope must be included.'); + } + + if (!ctx.errors.length) { + const ticketData = { + subject: ctx.ticketSubjectUrl.href, + resource: ctx.ticketResourceUrl.href, + scopes: ctx.ticketScopes, + identifier, + profile: ctx.ticketProfileUrl.href, + ticketLifespanSeconds: this.options.manager.ticketLifespanSeconds, + }; + const ticket = await this._mintTicket(ticketData); + + await this.db.context(async (dbCtx) => { + // re-populate form fields + ctx.profilesScopes = await this.db.profilesScopesByIdentifier(dbCtx, identifier); + + // TODO: queue ticket for delivery/retry to subject instead of trying immediately + // ctx.notifications.push('Success! Ticket will be delivered!'); + + this.logger.debug(_scope, 'ticket created', { ctx, ticketData, subjectData }); + + try { + const result = await this.communication.deliverTicket(ctx.ticketEndpointUrl, ctx.ticketResourceUrl, ctx.ticketSubjectUrl, ticket); + ctx.notifications.push(`Success! Ticket was delivered. (${result?.statusText})`); + this.logger.info(_scope, 'ticket delivered', { ctx, result }); + } catch (e) { + this.logger.error(_scope, 'failed to deliver ticket', { ctx, error: e }); + ctx.errors.push(`Failed to deliver ticket. (${e})`); + } + + }); // dbCtx + + } else { + // populate form fields again + await this.db.context(async (dbCtx) => { + ctx.profilesScopes = await this.db.profilesScopesByIdentifier(dbCtx, identifier); + ctx.scopes = Object.keys(ctx.profilesScopes.scopeIndex); + }); // dbCtx + } + + break; + } + + default: + this.logger.debug(_scope, 'unknown action', { ctx }); + } + + res.end(Template.adminTicketHTML(ctx, this.options)); + + this.logger.info(_scope, 'finished', { ctx }); + } + + + /** + * Report on generally uninteresting backend information. + * Also allow a few event invocations. + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async getAdminMaintenance(res, ctx) { + const _scope = _fileScope('getAdminMaintenance'); + this.logger.debug(_scope, 'called', { ctx }); + + const maintenanceTasks = []; + + await this.db.context(async (dbCtx) => { + + Object.values(Enum.Chore).forEach((chore) => { + if (chore in ctx.queryParams) { + maintenanceTasks.push( + this.chores.runChore(chore, 0), // Provide arg to force chore run. + ); + ctx.notifications.push(`Running maintenance chore "${chore}".`); + } + }); + + await Promise.all(maintenanceTasks); + + ctx.almanac = await this.db.almanacGetAll(dbCtx); + }); // dbCtx + + const winnowChoreEntry = ([name, value]) => [name, common.pick(value, ['intervalMs', 'nextSchedule'])]; + ctx.chores = Object.fromEntries( + Object.entries(this.chores.chores).map(winnowChoreEntry), + ); + + res.end(Template.adminMaintenanceHTML(ctx, this.options)); + + this.logger.info(_scope, 'finished', { ctx }); + } + + + /** + * + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async getHealthcheck(res, ctx) { + const _scope = _fileScope('getHealthcheck'); + this.logger.debug(_scope, 'called', { ctx }); + await this.db.healthCheck(); + res.end(); + } + +} + +module.exports = Manager; \ No newline at end of file diff --git a/src/service.js b/src/service.js new file mode 100644 index 0000000..5fbf950 --- /dev/null +++ b/src/service.js @@ -0,0 +1,544 @@ +'use strict'; + +/** + * Here we extend the base API server to define our routes and any route-specific + * behavior (middlewares) before handing off to the manager. + */ + +const path = require('path'); +const { Dingus } = require('@squeep/api-dingus'); +const common = require('./common'); +const Manager = require('./manager'); +const { Authenticator, SessionManager } = require('@squeep/authentication-module'); +const { ResourceAuthenticator } = require('@squeep/resource-authentication-module'); +const { TemplateHelper: { initContext } } = require('@squeep/html-template-helper'); +const Enum = require('./enum'); + +const _fileScope = common.fileScope(__filename); + +class Service extends Dingus { + constructor(logger, db, options) { + super(logger, { + ...options.dingus, + ignoreTrailingSlash: false, + }); + + this.staticPath = path.normalize(path.join(__dirname, '..', 'static')); + this.manager = new Manager(logger, db, options); + this.authenticator = new Authenticator(logger, db, options); + this.sessionManager = new SessionManager(logger, this.authenticator, options); + this.resourceAuthenticator = new ResourceAuthenticator(logger, db, options); + this.loginPath = `${options.dingus.proxyPrefix}/admin/login`; + + // N.B. /admin routes not currently configurable + const route = (r) => `/${options.route[r]}`; // eslint-disable-line security/detect-object-injection + + // Service discovery + this.on(['GET', 'HEAD'], route('metadata'), this.handlerGetMeta.bind(this)); + // Also respond with metadata on well-known oauth2 endpoint if base has no prefix + if ((options?.dingus?.selfBaseUrl?.match(/\//g) || []).length === 3) { + this.on(['GET', 'HEAD'], '/.well-known/oauth-authorization-server', this.handlerGetMeta.bind(this)); + } + + // Primary endpoints + this.on(['GET'], route('authorization'), this.handlerGetAuthorization.bind(this)); + this.on(['POST'], route('authorization'), this.handlerPostAuthorization.bind(this)); + this.on(['POST'], route('consent'), this.handlerPostConsent.bind(this)); + this.on(['POST'], route('revocation'), this.handlerPostRevocation.bind(this)); + this.on(['POST'], route('ticket'), this.handlerPostTicket.bind(this)); + this.on(['POST'], route('token'), this.handlerPostToken.bind(this)); + + // Resource endpoints + this.on('POST', route('introspection'), this.handlerPostIntrospection.bind(this)); + this.on('POST', route('userinfo'), this.handlerPostUserInfo.bind(this)); + + // Information page about service + this.on(['GET', 'HEAD'], '/', this.handlerGetRoot.bind(this)); + + // Give load-balancers something to check + this.on(['GET', 'HEAD'], route('healthcheck'), this.handlerGetHealthcheck.bind(this)); + + // These routes are intended for accessing static content during development. + // In production, a proxy server would likely handle these first. + this.on(['GET', 'HEAD'], '/static', this.handlerRedirect.bind(this), `${options.dingus.proxyPrefix}/static/`); + this.on(['GET', 'HEAD'], '/static/', this.handlerGetStaticFile.bind(this), 'index.html'); + this.on(['GET', 'HEAD'], '/static/:file', this.handlerGetStaticFile.bind(this)); + this.on(['GET', 'HEAD'], '/favicon.ico', this.handlerGetStaticFile.bind(this), 'favicon.ico'); + this.on(['GET', 'HEAD'], '/robots.txt', this.handlerGetStaticFile.bind(this), 'robots.txt'); + + // Profile and token management for authenticated sessions + this.on(['GET', 'HEAD'], '/admin', this.handlerRedirect.bind(this), `${options.dingus.proxyPrefix}/admin/`); + this.on(['GET', 'HEAD'], '/admin/', this.handlerGetAdmin.bind(this)); + this.on(['POST'], '/admin/', this.handlerPostAdmin.bind(this)); + + // Ticket-proffering interface for authenticated sessions + this.on(['GET', 'HEAD'], '/admin/ticket', this.handlerGetAdminTicket.bind(this)); + this.on(['POST'], '/admin/ticket', this.handlerPostAdminTicket.bind(this)); + + // User authentication and session establishment + this.on(['GET', 'HEAD'], '/admin/login', this.handlerGetAdminLogin.bind(this)); + this.on(['POST'], '/admin/login', this.handlerPostAdminLogin.bind(this)); + this.on(['GET'], '/admin/logout', this.handlerGetAdminLogout.bind(this)); + + // Page for upkeep info et cetera + this.on(['GET', 'HEAD'], '/admin/maintenance', this.handlerGetAdminMaintenance.bind(this)); + + } + + + /** + * Perform any async startup tasks. + */ + async initialize() { + await this.manager.initialize(); + } + + + /** + * Do a little more on each request. + * @param {http.IncomingMessage} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async preHandler(req, res, ctx) { + await super.preHandler(req, res, ctx); + ctx.url = req.url; // Persist this for logout redirect + } + + + /** + * @param {http.IncomingMessage} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async handlerGetAdminLogin(req, res, ctx) { + const _scope = _fileScope('handlerGetAdminLogin'); + this.logger.debug(_scope, 'called', { req, ctx }); + + Dingus.setHeadHandler(req, res, ctx); + + this.setResponseType(this.responseTypes, req, res, ctx); + + await this.sessionManager.getAdminLogin(res, ctx); + } + + + /** + * @param {http.IncomingMessage} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async handlerPostAdminLogin(req, res, ctx) { + const _scope = _fileScope('handlerPostAdminLogin'); + this.logger.debug(_scope, 'called', { req, ctx }); + + initContext(ctx); + + this.setResponseType(this.responseTypes, req, res, ctx); + + await this.authenticator.sessionOptionalLocal(req, res, ctx); + + await this.ingestBody(req, res, ctx); + + await this.sessionManager.postAdminLogin(res, ctx); + } + + + /** + * @param {http.IncomingMessage} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async handlerGetAdminLogout(req, res, ctx) { + const _scope = _fileScope('handlerGetAdminLogout'); + this.logger.debug(_scope, 'called', { req, ctx }); + + initContext(ctx); + + this.setResponseType(this.responseTypes, req, res, ctx); + + await this.authenticator.sessionOptionalLocal(req, res, ctx); + + await this.sessionManager.getAdminLogout(res, ctx); + } + + + /** + * @param {http.IncomingMessage} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async handlerGetAdmin(req, res, ctx) { + const _scope = _fileScope('handlerGetAdmin'); + this.logger.debug(_scope, 'called', { req, ctx }); + + initContext(ctx); + + Dingus.setHeadHandler(req, res, ctx); + + this.setResponseType(this.responseTypes, req, res, ctx); + + if (await this.authenticator.sessionRequiredLocal(req, res, ctx, this.loginPath)) { + await this.manager.getAdmin(res, ctx); + } + } + + + /** + * @param {http.IncomingMessage} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async handlerPostAdmin(req, res, ctx) { + const _scope = _fileScope('handlerPostAdmin'); + this.logger.debug(_scope, 'called', { req, ctx }); + + initContext(ctx); + + Dingus.setHeadHandler(req, res, ctx); + + this.setResponseType(this.responseTypes, req, res, ctx); + + if (await this.authenticator.sessionRequiredLocal(req, res, ctx, this.loginPath)) { + await this.ingestBody(req, res, ctx); + await this.manager.postAdmin(res, ctx); + } + } + + + /** + * @param {http.IncomingMessage} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async handlerGetAdminTicket(req, res, ctx) { + const _scope = _fileScope('handlerGetAdminTicket'); + this.logger.debug(_scope, 'called', { req, ctx }); + + initContext(ctx); + + Dingus.setHeadHandler(req, res, ctx); + + this.setResponseType(this.responseTypes, req, res, ctx); + + if (await this.authenticator.sessionRequiredLocal(req, res, ctx, this.loginPath)) { + await this.manager.getAdminTicket(res, ctx); + } + } + + + /** + * @param {http.IncomingMessage} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async handlerPostAdminTicket(req, res, ctx) { + const _scope = _fileScope('handlerPostAdminTicket'); + this.logger.debug(_scope, 'called', { req, ctx }); + + initContext(ctx); + + this.setResponseType(this.responseTypes, req, res, ctx); + + if (await this.authenticator.sessionRequiredLocal(req, res, ctx, this.loginPath)) { + await this.ingestBody(req, res, ctx); + await this.manager.postAdminTicket(res, ctx); + } + } + + + /** + * @param {http.IncomingMessage} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async handlerGetMeta(req, res, ctx) { + const _scope = _fileScope('handlerGetMeta'); + this.logger.debug(_scope, 'called', { req, ctx }); + + const responseTypes = [ + Enum.ContentType.ApplicationJson, + Enum.ContentType.TextPlain, + ]; + + Dingus.setHeadHandler(req, res, ctx); + + this.setResponseType(responseTypes, req, res, ctx); + + await this.authenticator.sessionOptionalLocal(req, res, ctx); + + await this.manager.getMeta(res, ctx); + } + + + /** + * @param {http.IncomingMessage} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async handlerGetAuthorization(req, res, ctx) { + const _scope = _fileScope('handlerGetAuthorization'); + this.logger.debug(_scope, 'called', { req, ctx }); + + initContext(ctx); + + this.setResponseType(this.responseTypes, req, res, ctx); + + if (await this.authenticator.sessionRequiredLocal(req, res, ctx, this.loginPath)) { + await this.manager.getAuthorization(res, ctx); + } + } + + + /** + * @param {http.IncomingMessage} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async handlerPostAuthorization(req, res, ctx) { + const _scope = _fileScope('handlerPostAuthorization'); + this.logger.debug(_scope, 'called', { req, ctx }); + + const responseTypes = [ + Enum.ContentType.ApplicationJson, + Enum.ContentType.TextPlain, + ]; + + this.setResponseType(responseTypes, req, res, ctx); + + await this.authenticator.sessionOptionalLocal(req, res, ctx); + + await this.ingestBody(req, res, ctx); + + await this.manager.postAuthorization(res, ctx); + } + + + /** + * @param {http.IncomingMessage} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async handlerPostConsent(req, res, ctx) { + const _scope = _fileScope('handlerPostConsent'); + this.logger.debug(_scope, 'called', { req, ctx }); + + initContext(ctx); + + this.setResponseType(this.responseTypes, req, res, ctx); + + // This isn't specified as required as any valid payload carries intrinsic auth data. + await this.authenticator.sessionOptionalLocal(req, res, ctx); + + await this.ingestBody(req, res, ctx); + + await this.manager.postConsent(res, ctx); + } + + + /** + * @param {http.IncomingMessage} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async handlerPostTicket(req, res, ctx) { + const _scope = _fileScope('handlerPostTicket'); + this.logger.debug(_scope, 'called', { req, ctx }); + + const responseTypes = [ + Enum.ContentType.ApplicationJson, + Enum.ContentType.TextPlain, + ]; + + this.setResponseType(responseTypes, req, res, ctx); + + await this.ingestBody(req, res, ctx); + + await this.manager.postTicket(req, res, ctx); + } + + + /** + * @param {http.IncomingMessage} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async handlerPostToken(req, res, ctx) { + const _scope = _fileScope('handlerPostToken'); + this.logger.debug(_scope, 'called', { req, ctx }); + + const responseTypes = [ + Enum.ContentType.ApplicationJson, + Enum.ContentType.TextPlain, + ]; + + this.setResponseType(responseTypes, req, res, ctx); + + await this.ingestBody(req, res, ctx); + + await this.manager.postToken(req, res, ctx); + } + + + /** + * @param {http.IncomingMessage} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async handlerPostRevocation(req, res, ctx) { + const _scope = _fileScope('handlerPostRevocation'); + this.logger.debug(_scope, 'called', { req, ctx }); + + const responseTypes = [ + Enum.ContentType.ApplicationJson, + Enum.ContentType.TextPlain, + ]; + + this.setResponseType(responseTypes, req, res, ctx); + + await this.ingestBody(req, res, ctx); + + await this.manager.postRevocation(req, res, ctx); + } + + + /** + * @param {http.IncomingMessage} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async handlerPostIntrospection(req, res, ctx) { + const _scope = _fileScope('handlerPostIntrospection'); + this.logger.debug(_scope, 'called', { req, ctx }); + + const responseTypes = [ + Enum.ContentType.ApplicationJson, + Enum.ContentType.TextPlain, + ]; + + await this.resourceAuthenticator.required(req, res, ctx); + + this.setResponseType(responseTypes, req, res, ctx); + + await this.ingestBody(req, res, ctx); + + await this.manager.postIntrospection(res, ctx); + } + + + /** + * @param {http.IncomingMessage} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async handlerPostUserInfo(req, res, ctx) { + const _scope = _fileScope('handlerPostUserInfo'); + this.logger.debug(_scope, 'called', { req, ctx }); + + const responseTypes = [ + Enum.ContentType.ApplicationJson, + Enum.ContentType.TextPlain, + ]; + + this.setResponseType(responseTypes, req, res, ctx); + + await this.ingestBody(req, res, ctx); + + await this.manager.postUserInfo(res, ctx); + } + + + /** + * @param {http.IncomingMessage} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async handlerGetRoot(req, res, ctx) { + const _scope = _fileScope('handlerGetRoot'); + const responseTypes = [ + Enum.ContentType.TextHTML, + ]; + this.logger.debug(_scope, 'called', { req, ctx }); + + initContext(ctx); + + Dingus.setHeadHandler(req, res, ctx); + + this.setResponseType(responseTypes, req, res, ctx); + + await this.authenticator.sessionOptionalLocal(req, res, ctx); + + await this.manager.getRoot(res, ctx); + } + + + /** + * @param {http.IncomingMessage} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async handlerGetHealthcheck(req, res, ctx) { + const _scope = _fileScope('handlerGetHealthcheck'); + this.logger.debug(_scope, 'called', { req, ctx }); + + Dingus.setHeadHandler(req, res, ctx); + + this.setResponseType(this.responseTypes, req, res, ctx); + + await this.manager.getHealthcheck(res, ctx); + } + + + /** + * @param {http.IncomingMessage} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async handlerGetAdminMaintenance(req, res, ctx) { + const _scope = _fileScope('handlerGetAdminMaintenance'); + this.logger.debug(_scope, 'called', { req, ctx }); + + initContext(ctx); + + Dingus.setHeadHandler(req, res, ctx); + + this.setResponseType(this.responseTypes, req, res, ctx); + + if (await this.authenticator.sessionRequiredLocal(req, res, ctx, this.loginPath)) { + await this.manager.getAdminMaintenance(res, ctx); + } + } + + + /** + * FIXME: This doesn't seem to be working as envisioned. Maybe override render error method instead??? + * Intercept this and redirect if we have enough information, otherwise default to framework. + * The redirect attempt should probably be contained in a Manager method, but here it is for now. + * @param {http.IncomingMessage} req + * @param {http.ServerResponse} res + * @param {Object} ctx + */ + async handlerInternalServerError(req, res, ctx) { + const _scope = _fileScope('handlerInternalServerError'); + this.logger.debug(_scope, 'called', { req, ctx }); + + if (ctx?.session?.redirectUri && ctx?.session?.clientIdentifier) { + Object.entries({ + ...(ctx.session.state && { 'state': ctx.session.state }), + 'error': 'server_error', + 'error_description': 'An internal server error occurred', + }).forEach(([name, value]) => ctx.session.redirectUri.searchParams.set(name, value)); + res.statusCode = 302; // Found + res.setHeader(Enum.Header.Location, ctx.session.redirectUri.href); + res.end(); + return; + } + + super.handlerInternalServerError(req, res, ctx); + } + + +} + +module.exports = Service; + diff --git a/src/template/admin-html.js b/src/template/admin-html.js new file mode 100644 index 0000000..085b95a --- /dev/null +++ b/src/template/admin-html.js @@ -0,0 +1,214 @@ +'use strict'; + +/** + * This renders the administrative view for an account, + * allowing for adding profile URIs, custom scope bundles, + * and management of issued tokens. + */ + +const th = require('./template-helper'); + + +function renderProfileLI(profile) { + return `\t<li><a class="uri" name="${profile}">${profile}</a></li>`; +} + + +function renderProfileScopeIndicator(profile, scope, selected) { + const checked = selected ? ' checked' : ''; + return `\t\t<td> +\t\t\t<input type="checkbox" id="${profile}-${scope}" name="scopes-${profile}" value="${scope}"${checked}> +\t\t</td>`; +} + +function renderScopeRow(scope, details, profiles) { + return `\t<tr class="scope"> +${(profiles || []).map((profile) => renderProfileScopeIndicator(profile, scope, details.profiles.includes(profile))).join('\n')} +\t\t<th scope="row"><label>${scope}<label></th> +\t\t<td class="description">${details.description}</td> +\t\t<td>${details.application}</td> +\t\t<td class="scope-actions">` + + (details.isManuallyAdded ? ` +\t\t\t<button name="action" value="delete-scope-${encodeURIComponent(scope)}">Delete</button> +` : '') + ` +\t\t</td> +\t</tr>`; +} + + +function renderProfileHeader(profile) { + return `<th class="vertical uri"> +\t\t${profile} +</th>`; +} + + +function scopeIndexTable(scopeIndex, profiles) { + return `<table> +<thead> +\t<tr> +${(profiles || []).map((profile) => renderProfileHeader(profile)).join('\n')} +\t\t<th>Scope</th> +\t\t<th>Description</th> +\t\t<th>Application</th> +\t\t<th class="scope-actions"></th> +\t</tr> +</thead> +<tbody> +${Object.entries(scopeIndex).sort(th.scopeCompare).map(([scope, details]) => renderScopeRow(scope, details, profiles)).join('\n')} +</tbody> +</table>`; +} + +function _tokenType(token) { + if (token.resource) { + return 'ticket-token'; + } + if (!token.isToken) { + return 'profile'; + } + return 'token'; +} + +function renderTokenRow(token) { + const createdTitle = token.refreshed ? 'Refreshed At' : 'Created At'; + const createdDate = token.refreshed ? token.refreshed : token.created; + return `\t\t<tr> +<td>${_tokenType(token)}</td> +\t\t\t<td class="uri">${token.clientId}</td> +\t\t\t<td class="uri">${token.profile}</td> +<td class="scope">${(token.scopes || []).join(', ')}</td> +\t\t\t<td class="code">${token.codeId}</td> +\t\t\t<td>${th.timeElement(createdDate, { title: createdTitle })}</td> +\t\t\t<td>${th.timeElement(token.expires, { title: 'Expires At' })}</td> +\t\t\t<td>${token.isRevoked}</td> +<td>${token.resource ? token.resource : ''}</td> +\t\t\t<td>` + ( + token.isRevoked ? '' : ` +\t\t\t\t<button name="action" value="revoke-${token.codeId}">Revoke</button>`) + ` +\t\t\t</td> +\t\t</tr>`; +} + +function noTokensRows() { + return [`\t\t<tr> +\t\t\t<td colspan="100%" class="centered">(No active or recent tokens.)</td> +\t\t</tr>`]; +} + +function tokenTable(tokens) { + const tokenRows = tokens?.length ? tokens.map((token) => renderTokenRow(token)) : noTokensRows(); + return `<table> +\t<thead> +\t\t<tr> +<th>Type</th> +\t\t\t<th>Client Identifier</th> +\t\t\t<th>Profile</th> +<th>Scopes</th> +\t\t\t<th>Code</th> +\t\t\t<th>Created or Refreshed</th> +\t\t\t<th>Expires</th> +\t\t\t<th>Revoked</th> +<th>Resource</th> +\t\t\t<th></th> +\t\t</tr> +\t</thead> +\t<tbody> +${tokenRows.join('\n')} +\t</tbody> +</table>`; +} + +function mainContent(ctx) { + return `<section> +\t<h2>Profiles</h2> +\t<ul> +\t${(ctx.profilesScopes?.profiles || []).map((p) => renderProfileLI(p)).join('\n')} +\t</ul> +\t<form action="" method="POST"> +\t\t<fieldset> +\t\t\t<legend>Add New Profile</legend> +\t\t\t<div> +\t\t\t\tThe profile identity URIs associated with this account. +\t\t\t\tEach must indicate this service as the authorization endpoint. +\t\t\t</div> +\t\t\t<br> +\t\t\t<label for="profile">Profile URL:</label> +\t\t\t<input type="url" id="profile" name="profile" size="96"> +\t\t\t<button name="action" value="new-profile">Add Profile</button> +\t\t</fieldset> +\t</form> +</section> +<section> +\t<h2>Scopes</h2> +\t<form action="" method="POST"> +\t\t<details> +\t\t<summary> +\t\tScopes Associated with Profiles for Convenience +\t\t</summary> +\t\t\t<fieldset> +\t\t\t\t<legend>Manage Additional Profile Scope Availability</legend> +\t\t\t\t<div> +\t\t\t\t\tThis table lists pre-defined scopes which you can choose to add to any authorization request, whether the client requested them or not. +\t\t\t\t\tSelecting one for a profile makes it conveniently available for quick inclusion when authorizing a client request. +\t\t\t\t\tAny scope not in this table or not selected for a profile can always be added in the ad hoc field on the authorization request. +\t\t\t\t</div> +\t\t\t\t<br> +\t\t${scopeIndexTable(ctx.profilesScopes.scopeIndex, ctx.profilesScopes.profiles)} +\t\t\t\t<button name="action" value="save-scopes">Save</button> +\t\t\t</fieldset> +\t\t</form> +\t\t<br> +\t\t<form action="" method="POST"> +\t\t\t<fieldset> +\t\t\t\t<legend>Add New Scope</legend> +\t\t\t\t<label for="scope">Scope:</label> +\t\t\t\t<input type="text" id="scope" name="scope"> +\t\t\t\t<label for="description">Description:</label> +\t\t\t\t<input type="text" id="description" name="description"> +\t\t\t\t<label for="application">Application:</label> +\t\t\t\t<input type="text" id="application" name="application"> +\t\t\t\t<button name="action" value="new-scope">Add Scope</button> +\t\t\t</fieldset> +\t\t</details> +\t</form> +</section> +<section> +\t<h2>Tokens</h2> +\t<form action="" method="POST"> +${tokenTable(ctx.tokens)} +\t</form> +</section>`; +} + + +/** + * + * @param {Object} ctx + * @param {Object} ctx.profilesScopes.scopeIndex + * @param {String[]} ctx.profilesScopes.profiles + * @param {Object[]} ctx.tokens + * @param {Object} options + * @param {Object} options.manager + * @param {String} options.manager.pageTitle + * @param {String} options.manager.logoUrl + * @param {String[]} options.manager.footerEntries + * @returns {String} + */ +module.exports = (ctx, options) => { + const htmlOptions = { + pageTitle: options.manager.pageTitle, + logoUrl: options.manager.logoUrl, + footerEntries: options.manager.footerEntries, + navLinks: [ + { + text: 'Ticket', + href: 'ticket', + }, + ], + }; + const content = [ + mainContent(ctx), + ]; + return th.htmlPage(1, ctx, htmlOptions, content); +}; diff --git a/src/template/admin-maintenance-html.js b/src/template/admin-maintenance-html.js new file mode 100644 index 0000000..031eb30 --- /dev/null +++ b/src/template/admin-maintenance-html.js @@ -0,0 +1,86 @@ +'use strict'; + +const th = require('./template-helper'); + +function renderAlmanacRow(entry) { + const { event, date } = entry; + return `<tr> +\t<td>${event}</td> +\t<td>${th.timeElement(date, { title: 'Occurred' })}</td> +</tr>`; +} + +function almanacSection(almanac) { + return `<section> +\t<h2>Almanac</h2> +\t<table> +\t\t<thead> +\t\t\t<th>Event</th> +\t\t\t<th>Date</th> +\t\t</thead> +\t\t<tbody> +${almanac.map((entry) => renderAlmanacRow(entry)).join('\n')} +\t\t</tbody> +\t<table> +</section>`; +} + +function renderChoreRow(choreName, choreDetails) { + const { intervalMs, nextSchedule } = choreDetails; + return `<tr> +\t<td>${choreName}</td> +\t<td>${th.secondsToPeriod(Math.ceil(intervalMs / 1000))}</td> +\t<td>${th.timeElement(nextSchedule)}</td> +</tr>`; +} + +function choresSection(chores) { + return `<section> +\t<h2>Chores</h2> +\t<table> +\t\t<thead> +\t\t\t<th>Chore</th> +\t\t\t<th>Frequency</th> +\t\t\t<th>Next Run</th> +\t\t</thead> +\t\t<tbody> +${Object.entries(chores).map((chore) => renderChoreRow(...chore)).join('\n')} +\t\t</tbody> +\t<table> +</section>`; +} + +/** + * + * @param {Object} ctx + * @param {Object[]} ctx.almanac + * @param {Object} ctx.chores + * @param {Object} options + * @param {Object} options.manager + * @param {String} options.manager.pageTitle + * @param {String[]} options.manager.footerEntries + * @param {String} options.adminContactHTML + * @returns {String} + */ +module.exports = (ctx, options) => { + const htmlOptions = { + pageTitle: options.manager.pageTitle + ' - Maintenance', + logoUrl: options.manager.logoUrl, + footerEntries: options.manager.footerEntries, + navLinks: [ + { + text: 'Admin', + href: '.', + }, + { + text: 'Ticket', + href: './ticket', + }, + ], + }; + const content = [ + almanacSection(ctx.almanac || []), + choresSection(ctx.chores || {}), + ]; + return th.htmlPage(1, ctx, htmlOptions, content); +}; \ No newline at end of file diff --git a/src/template/admin-ticket-html.js b/src/template/admin-ticket-html.js new file mode 100644 index 0000000..492c40d --- /dev/null +++ b/src/template/admin-ticket-html.js @@ -0,0 +1,98 @@ +'use strict'; + +/** + * This renders the interface for submitting a ticket proffer to a third-party. + */ + +const th = require('./template-helper'); + + +function renderProfileOption(profile) { + return `<option value="${profile}">${profile}</option>`; +} + +function renderScopeCheckboxTR(scope) { + const defaultChecked = ['read']; + const checked = defaultChecked.includes(scope) ? ' checked' : ''; + return `<tr class="scope"> +\t<td><input type="checkbox" id="scopes-${scope}" name="scopes" value="${scope}"${checked}></td> +\t<td>${scope}</td> +</tr>`; +} + +function mainContent(ctx) { + const profileOptions = th.indented(4, (ctx?.profilesScopes?.profiles || []).map((profile) => renderProfileOption(profile))) + .join('\n'); + const elideScopes = ['profile', 'email']; + const allScopes = Object.keys(ctx?.profilesScopes?.scopeIndex || {}); + const displayScopes = (allScopes).filter((scope) => !elideScopes.includes(scope)); + const scopesCheckboxRows = th.indented(4, displayScopes.map((scope) => renderScopeCheckboxTR(scope))) + .join('\n'); + return `<section> +\t<form action="" method="POST"> +\t\t<div> +\t\t\tYou may proactively send a ticket to a third-party site, +\t\t\twhich they may redeem for an access token which grants additional +\t\t\taccess to the specified resource. +\t\t</div> +\t\t<br> +\t\t<fieldset> +\t\t\t<legend>Proffer A Ticket</legend> +\t\t\t<label for="profile-select">Profile Granting this Ticket</label> +\t\t\t<select id="profile-select" name="profile"> +${profileOptions} +\t\t\t</select> +\t\t\t<br> +\t\t\t<label for="resource-url">Resource URL:</label> +\t\t\t<input type="url" id="resource-url" name="resource" size="96"> +\t\t\t<br> +\t\t\t<label for="recipient-url">Recipient URL:</label> +\t\t\t<input type="url" id="recipient-url" name="subject" size="96"> +\t\t\t<br> +<fieldset> +<legend>Scopes</legend> +\t\t\t<table> +${scopesCheckboxRows} +\t\t\t</table> +</fieldset> +\t\t\t<br> +\t\t\t<label for="scopes-adhoc">Additional Scopes (space separated):</label> +\t\t\t<input type="text" id="scopes-adhoc" name="adhoc" size="96"> +\t\t\t<br> +\t\t\t<button name="action" value="proffer-ticket">Send Ticket</button> +\t\t</fieldset> +\t</form> +</section>`; +} + + +/** + * + * @param {Object} ctx + * @param {Object} ctx.profilesScopes.scopeIndex + * @param {String[]} ctx.profileScopes.profiles + * @param {Object} options + * @param {Object} options.manager + * @param {String} options.manager.pageTitle + * @param {String} options.manager.logoUrl + * @param {String[]} options.manager.footerEntries + * @returns {String} + */ +module.exports = (ctx, options) => { + const htmlOptions = { + pageTitle: options.manager.pageTitle + ' - Ticket Proffer', + logoUrl: options.manager.logoUrl, + footerEntries: options.manager.footerEntries, + navLinks: [ + { + text: 'Admin', + href: '../admin/', + }, + ], + errorContent: ['Unable to send ticket.'], + }; + const content = [ + mainContent(ctx), + ]; + return th.htmlPage(2, ctx, htmlOptions, content); +}; \ No newline at end of file diff --git a/src/template/authorization-error-html.js b/src/template/authorization-error-html.js new file mode 100644 index 0000000..ee2e4f2 --- /dev/null +++ b/src/template/authorization-error-html.js @@ -0,0 +1,26 @@ +'use strict'; + +const th = require('./template-helper'); + + +/** + * + * @param {Object} ctx + * @param {Object} ctx.session + * @param {String=} ctx.session.error + * @param {String[]=} ctx.session.errorDescriptions + * @param {Object} options + * @param {Object} options.manager + * @param {String} options.manager.pageTitle + * @param {String} options.manager.footerEntries + * @returns {String} + */ +module.exports = (ctx, options) => { + const htmlOptions = { + pageTitle: options.manager.pageTitle, + logoUrl: options.manager.logoUrl, + footerEntries: options.manager.footerEntries, + errorContent: ctx.errorContent || ['Unknown Error'], + }; + return th.htmlPage(0, ctx, htmlOptions, []); +}; \ No newline at end of file diff --git a/src/template/authorization-request-html.js b/src/template/authorization-request-html.js new file mode 100644 index 0000000..3e312af --- /dev/null +++ b/src/template/authorization-request-html.js @@ -0,0 +1,376 @@ +'use strict'; + +const th = require('./template-helper'); + + +/** + * @param {Object} hApp + * @param {Object} hApp.properties + * @param {String[]=} hApp.properties.url + * @param {String[]=} hApp.properties.summary + * @param {String[]=} hApp.properties.logo + * @param {String[]=} hApp.properties.name + * @returns {String} + */ +function renderClientIdentifierProperties(hApp) { + const properties = hApp.properties || {}; + const parts = []; + let imgTitle = ''; + const { url, summary, logo, name } = properties; + + parts.push('<span class="client-identifier">'); + if (url && url.length) { + parts.push(`<a href="${url[0]}">`); + } + if (summary && summary.length) { + imgTitle = ` title="${summary[0]}"`; + } + if (logo && logo.length) { + let src, alt; + if (typeof logo[0] === 'string') { + src = logo[0]; + alt = 'Client Identifier Logo'; + } else { + ({ value: src, alt } = logo[0]); + } + parts.push(`<img src="${src}" alt="${alt}"${imgTitle}>`); + } + if (name && name.length) { + parts.push(properties['name'][0]); + } + if (url && url.length) { + parts.push('</a>'); + } + parts.push('</span>'); + return parts.join(''); +} + + +/** + * @param {Object} clientIdentifier + * @param {Object[]} clientIdentifier.items + * @returns {String} + */ +function renderClientIdentifier(clientIdentifier) { + const hAppEntries = clientIdentifier && clientIdentifier.items || []; + return hAppEntries.map(renderClientIdentifierProperties).join(''); +} + + +/** + * @param {String} profile + * @param {Boolean} selected + * @returns {String} + */ +function renderProfileOption(profile, selected) { + return `<option value="${profile}"${selected ? ' selected' : ''}>${profile}</option>`; +} + + +/** + * @param {String[]} availableProfiles + * @param {String} hintProfile + * @returns {String} + */ +function renderProfileFieldset(availableProfiles, hintProfile) { + if (!availableProfiles || availableProfiles.length <= 1) { + const profile = availableProfiles && availableProfiles[0] || hintProfile; + return `<input type="hidden" name="me" value="${profile}">`; + } + return ` + <br> + <fieldset> + <legend>Select Profile</legend> + <div> + You may choose to identify to this client with a different profile. + </div> + <label for="me">Choose your identifying profile</label> + <select class="uri" name="me" id="me"> +${availableProfiles.map((profile) => renderProfileOption(profile, profile === hintProfile)).join('\n')} + </select> + </fieldset>`; +} + + +/** + * @param {ScopeDetails} scope + * @param {String} scope.scope + * @param {String} scope.description + * @param {String[]} scope.profiles + * @param {Boolean} checked + * @returns {String} + */ +function renderScopeCheckboxLI(scope, checked) { + let scopeDescription; + if (scope.description) { + scopeDescription = ` + <span class="description">${scope.description}</span>`; + } else { + scopeDescription = ''; + } + let profileClass; + if (scope.profiles && scope.profiles.length) { + profileClass = ['profile-scope'].concat(scope.profiles.map((profile) => th.escapeCSS(profile))).join(' '); + } else { + profileClass = ''; + } + return ` + <li class="${profileClass}"> + <input type="checkbox" id="scope_${scope.scope}" name="accepted_scopes" value="${scope.scope}"${checked ? ' checked' : ''}> + <label for="scope_${scope.scope}">${scope.scope}</label>${scopeDescription} + </li>`; +} + + +function renderRequestedScopes(requestedScopes) { + if (!requestedScopes || !requestedScopes.length) { + return ''; + } + return ` + <br> + <fieldset> + <legend>Grants Requested By Client</legend> + <div> + In addition to identifying you by your profile URL, this client has requested the following additional scope thingies. You may disable any of them here. + </div> + <ul class="scope" id="requested-scope-list"> +${requestedScopes.map((scopeDetails) => renderScopeCheckboxLI(scopeDetails, true)).join('\n')} + </ul> + </fieldset>`; +} + +/** + * @param {ScopeDetails[]} additionalScopes + * @returns {String} + */ +function renderAdditionalScopes(additionalScopes) { + const parts = []; + parts.push(` + <br> + <fieldset> + <legend>Additional Grants</legend>`); + if (additionalScopes?.length) { + parts.push(` + <div> + Your profile has been configured to offer scopes which were not explicitly requested by the client application. + Select any you would like to include. + </div> + <ul class="scope" id="additional-scope-list"> +${additionalScopes.map((scopeDetails) => renderScopeCheckboxLI(scopeDetails, false)).join('\n')} + </ul> + <br>`); + } + parts.push(` + <div> + You may also specify a space-separated list of any additional ad hoc scopes you would like to associate with this authorization request, which were not explicitly requested by the client application. + </div> + <label for="ad-hoc-scopes">Ad Hoc Scopes</label> + <input id="ad-hoc-scopes" name="ad_hoc_scopes" value=""> + </fieldset>`); + return parts.join(''); +} + + +/** + * + */ +function renderExpiration(requestedScopes) { + const tokenableScopes = requestedScopes.filter((s) => !['profile', 'email'].includes(s)); + if (!tokenableScopes.length) { + return ''; + } + return ` +\t<br> +\t<fieldset> +\t\t<legend>Expiration</legend> +\t\t<div> +\t\t\tBy default, tokens issued do not automatically expire, but a longevity can be enforced. +\t\t</div> +\t\t<br> +\t\t<details> +\t\t\t<summary>Set Expiration</summary> +\t\t\t<div> +\t\t\t\t${radioButton('expires', 'never', 'Never', true)} +\t\t\t</div> +\t\t\t<div> +\t\t\t\t${radioButton('expires', '1d', '1 Day')} +\t\t\t</div> +\t\t\t<div> +\t\t\t\t${radioButton('expires', '1w', '1 Week')} +\t\t\t</div> +\t\t\t<div> +\t\t\t\t${radioButton('expires', '1m', '1 Month')} +\t\t\t</div> +\t\t\t<div> +\t\t\t\t${radioButton('expires', 'custom', 'Other:')} +\t\t\t\t<input type="number" id="expires-seconds" name="expires-seconds"> +\t\t\t\t<label for="expires-seconds">seconds</label> +\t\t\t</div> +\t\t\t<br> +\t\t\t<div> +\t\t\t\tTokens with expirations may be allowed to be renewed for a fresh token for an amount of time after they expire. +\t\t\t</div> +\t\t\t<div> +\t\t\t\t${radioButton('refresh', 'none', 'Not Refreshable', true)} +\t\t\t</div> +\t\t\t<div> +\t\t\t\t${radioButton('refresh', '1d', '1 Day')} +\t\t\t</div> +\t\t\t<div> +\t\t\t\t${radioButton('refresh', '1w', '1 Week')} +\t\t\t</div> +\t\t\t<div> +\t\t\t\t${radioButton('refresh', '1m', '1 Month')} +\t\t\t<div> +\t\t\t\t${radioButton('refresh', 'custom', 'Other:')} +\t\t\t\t<input type="number" id="refresh-seconds" name="refresh-seconds"> +\t\t\t\t<label for="refresh-seconds">seconds</label> +\t\t\t </div> +\t\t</details> +\t</fieldset>`; +} + +function radioButton(name, value, label, checked = false, indent = 0) { + const id = `${name}-${value}`; + return th.indented(indent, [ + '<div>', + `\t<input type="radio" name="${name}" id="${id}" value="${value}"${checked ? ' checked' : ''}>`, + `\t<label for="${id}">${label}</label>`, + '</div>', + ]).join(''); +} + +/** + * + * @param {Object} ctx + * @param {Object[]} ctx.notifications + * @param {Object} ctx.session + * @param {String[]=} ctx.session.scope + * @param {URL=} ctx.session.me + * @param {String[]} ctx.session.profiles + * @param {ScopeIndex} ctx.session.scopeIndex + * @param {Object} ctx.session.clientIdentifier + * @param {Object[]} ctx.session.clientIdentifier.items + * @param {Object} ctx.session.clientIdentifier.items.properties + * @param {String[]=} ctx.session.clientIdentifier.items.properties.url + * @param {String[]=} ctx.session.clientIdentifier.items.properties.summary + * @param {String[]=} ctx.session.clientIdentifier.items.properties.logo + * @param {String[]=} ctx.session.clientIdentifier.items.properties.name + * @param {String} ctx.session.clientId + * @param {String} ctx.session.persist + * @param {String} ctx.session.redirectUri + * @param {Object} options + * @returns {String} + */ +function mainContent(ctx, options) { // eslint-disable-line no-unused-vars + const session = ctx.session || {}; + const hintedProfile = (session.me && session.me.href) || (session.profiles && session.profiles.length && session.profiles[0]) || ''; + const scopeIndex = session.scopeIndex || {}; + + // Add requested scopes to index, if not already present, + // and de-associate requested scopes from profiles. + const scopes = session.scope || []; + scopes.forEach((scopeName) => { + if ((scopeName in scopeIndex)) { + scopeIndex[scopeName].profiles = []; // eslint-disable-line security/detect-object-injection + } else { + scopeIndex[scopeName] = { // eslint-disable-line security/detect-object-injection + description: '', + profiles: [], + }; + } + }); + + // Divide scopes between requested and additional from profiles. + const requestedScopes = scopes.map((scope) => ({ + scope, + description: scopeIndex[scope].description, // eslint-disable-line security/detect-object-injection + })); + const additionalScopes = Object.keys(scopeIndex) + .filter((scope) => scopeIndex[scope].profiles.length) // eslint-disable-line security/detect-object-injection + .map((scope) => ({ + scope, + description: scopeIndex[scope].description, // eslint-disable-line security/detect-object-injection + profiles: scopeIndex[scope].profiles, // eslint-disable-line security/detect-object-injection + })); + + return [ + `<section class="information"> +\tThe application client +\t${renderClientIdentifier(session.clientIdentifier)} +\tat <a class="uri" name="${session.clientId}">${session.clientId}</a> would like to identify you as <a class="uri" name="${hintedProfile}">${hintedProfile}</a>. +</section> +<section class="choices"> +\t<form action="consent" method="POST" class="form-consent">`, + renderProfileFieldset(session.profiles, hintedProfile), + renderRequestedScopes(requestedScopes), + renderAdditionalScopes(additionalScopes), + renderExpiration(requestedScopes), + ` +\t\t<br> +\t\t<fieldset> +\t\t\t<legend>Do you want to allow this?</legend> +\t\t\t<button class="button-accept" name="accept" value="true">Accept</button> +\t\t\t<button class="button-decline" name="accept" value="false">Decline</button> +\t\t</fieldset> +\t\t<input type="hidden" name="session" value="${session.persist}"> +\t</form> +\t<br> +\t<div> +\t\tYou will be redirected to <a class="uri" name="${session.redirectUri}">${session.redirectUri}</a>. +\t</div> +</section>`, + ]; +} + +/** + * + * @param {Object} ctx + * @param {Object} ctx.session + * @param {String[]=} ctx.session.scope + * @param {URL=} ctx.session.me + * @param {String[]} ctx.session.profiles + * @param {ScopeIndex} ctx.session.scopeIndex + * @param {Object} ctx.session.clientIdentifier + * @param {String} ctx.session.clientId + * @param {String} ctx.session.persist + * @param {String} ctx.session.redirectUri + * @param {Object} options + * @param {Object} options.manager + * @param {String} options.manager.pageTitle + * @param {String} options.manager.footerEntries + * @returns {String} + */ +module.exports = (ctx, options) => { + const htmlOptions = { + pageTitle: `${options.manager.pageTitle} — Authorization Request`, + logoUrl: options.manager.logoUrl, + footerEntries: options.manager.footerEntries, + headElements: [ + `<script> +function queryAll(query, fn) { + const nodes = document.querySelectorAll(query); + console.log('query ' + query + ' selected ' + nodes.length); + return nodes.forEach(fn); +} +function profileSelected(element) { + const profileClass = CSS.escape(element.value); + console.log('new profile:', element.value, profileClass); + queryAll('.profile-scope input', (n) => n.setAttribute('disabled', true)); + queryAll('.profile-scope', (n) => n.classList.add('disabled')); + const profileQuery = '.profile-scope.' + profileClass; + queryAll(profileQuery + ' input', (n) => n.setAttribute('disabled', false)); + queryAll(profileQuery, (n) => n.classList.remove('disabled')); +} +function onLoad() { + return; // The escaped class selection does not seem to work, so ignore it all for now. + const profileSelect = document.getElementById('me'); + profileSelect.onchange = () => profileSelected(profileSelect); + profileSelected(profileSelect); +} +</script>`, + ], + }; + const content = mainContent(ctx, options); + return th.htmlPage(0, ctx, htmlOptions, content); +}; diff --git a/src/template/index.js b/src/template/index.js new file mode 100644 index 0000000..1278a7d --- /dev/null +++ b/src/template/index.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = { + adminHTML: require('./admin-html'), + adminTicketHTML: require('./admin-ticket-html'), + adminMaintenanceHTML: require('./admin-maintenance-html'), + authorizationRequestHTML: require('./authorization-request-html'), + authorizationErrorHTML: require('./authorization-error-html'), + rootHTML: require('./root-html'), +}; \ No newline at end of file diff --git a/src/template/root-html.js b/src/template/root-html.js new file mode 100644 index 0000000..7baaa41 --- /dev/null +++ b/src/template/root-html.js @@ -0,0 +1,63 @@ +'use strict'; + +const th = require('./template-helper'); + +function aboutSection() { + return ` + <section class="about"> + <h2>What</h2> + <p> + This is an <a class="external" href="https://indieweb.org/IndieAuth">IndieAuth</a> service. + </p> + <p> + It facilitates distributed authentication. + </p> + <p> + If you are not an established user of this service, or some sort of web application, there is very little here for you. + </p> + </section>`; +} + +function contactSection(contactHTML) { + let section = ''; + if (contactHTML) { + section = ` <section> +${contactHTML} + </section>`; + } + return section; +} + +/** + * + * @param {Object} ctx + * @param {Object} options + * @param {Object} options.manager + * @param {String} options.manager.pageTitle + * @param {String[]} options.manager.footerEntries + * @param {String} options.adminContactHTML + * @returns {String} + */ +module.exports = (ctx, options) => { + const contactHTML = options.adminContactHTML; + const htmlOptions = { + pageTitle: options.manager.pageTitle, + logoUrl: options.manager.logoUrl, + footerEntries: options.manager.footerEntries, + navLinks: [ + { + text: 'Admin', + href: 'admin/', + }, + { + text: 'Ticket', + href: 'admin/ticket', + }, + ], + }; + const content = [ + aboutSection(), + contactSection(contactHTML), + ]; + return th.htmlPage(1, ctx, htmlOptions, content); +}; \ No newline at end of file diff --git a/src/template/template-helper.js b/src/template/template-helper.js new file mode 100644 index 0000000..a33c8b0 --- /dev/null +++ b/src/template/template-helper.js @@ -0,0 +1,53 @@ +'use strict'; + +const { TemplateHelper } = require('@squeep/html-template-helper'); + + +/** + * Escape a string to be suitable as a CSS name. + * @param {String} unsafeName + * @returns {String} + */ +function escapeCSS(unsafeName) { + return unsafeName.replace(/([^0-9a-zA-Z-])/g, '\\$1'); +} + + +/** + * Given a pair of Array tuples containing scope names and scope details, + * return the comparison between the two, for sorting. + * Scopes are sorted such that they are grouped by application, then name. + * Empty applications are sorted ahead of extant applications. + * @param {Array} a + * @param {Array} b + * @returns {Number} + */ +function scopeCompare([aScope, aDetails], [bScope, bDetails]) { + const { application: aApp } = aDetails; + const { application: bApp } = bDetails; + if ((aApp || bApp) && (aApp !== bApp)) { + if (!aApp) { + return -1; + } + if (!bApp) { + return 1; + } + if (aApp > bApp) { + return 1; + } + return -1; + } + + if (aScope > bScope) { + return 1; + } else if (aScope < bScope) { + return -1; + } + return 0; +} + + +module.exports = Object.assign(Object.create(TemplateHelper), { + escapeCSS, + scopeCompare, +}); \ No newline at end of file diff --git a/static/.external-link.svg.meta b/static/.external-link.svg.meta new file mode 100644 index 0000000..5be8006 --- /dev/null +++ b/static/.external-link.svg.meta @@ -0,0 +1,2 @@ +Source: https://commons.wikimedia.org/wiki/File:VisualEditor_-_Icon_-_External-link.svg +License: https://commons.wikimedia.org/wiki/Category:Expat/MIT_License diff --git a/static/.favicon.ico.meta b/static/.favicon.ico.meta new file mode 100644 index 0000000..1d975d0 --- /dev/null +++ b/static/.favicon.ico.meta @@ -0,0 +1,3 @@ +Source: https://thenounproject.com/term/passport/1878030/ +License: https://creativecommons.org/licenses/by/3.0/us/legalcode +Author: https://madexmade.com/ diff --git a/static/.logo.svg.meta b/static/.logo.svg.meta new file mode 100644 index 0000000..1d975d0 --- /dev/null +++ b/static/.logo.svg.meta @@ -0,0 +1,3 @@ +Source: https://thenounproject.com/term/passport/1878030/ +License: https://creativecommons.org/licenses/by/3.0/us/legalcode +Author: https://madexmade.com/ diff --git a/static/Makefile b/static/Makefile new file mode 100644 index 0000000..fa512e5 --- /dev/null +++ b/static/Makefile @@ -0,0 +1,14 @@ +.PHONY: all + +SOURCES = theme.css favicon.ico logo.svg +TARGETS = $(SOURCES:=.gz) $(SOURCES:=.br) + +all: $(TARGETS) + +%.br: % + brotli --verbose --no-copy-stat --keep --force "$<" + +%.gz: % + cp "$<" "$<".tmp + gzip "$<".tmp + mv "$<".tmp.gz "$@" diff --git a/static/custom.css b/static/custom.css new file mode 100644 index 0000000..7a7a218 --- /dev/null +++ b/static/custom.css @@ -0,0 +1,6 @@ +header { + background: linear-gradient(0deg, rgba(255,255,255,0) 0%, rgb(230, 230, 230) 100%); +} +footer { + background: linear-gradient(180deg, rgba(255,255,255,0) 0%, rgb(230, 230, 230) 100%); +} diff --git a/static/external-link.svg b/static/external-link.svg new file mode 100644 index 0000000..ae7d45a --- /dev/null +++ b/static/external-link.svg @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="12px" + height="12px" viewBox="0 0 12 12" style="enable-background:new 0 0 12 12;" xml:space="preserve"> +<g id="Icons" style="opacity:0.75;"> + <g id="external"> + <polygon id="box" style="fill-rule:evenodd;clip-rule:evenodd;" points="2,2 5,2 5,3 3,3 3,9 9,9 9,7 10,7 10,10 2,10 "/> + <polygon id="arrow_13_" style="fill-rule:evenodd;clip-rule:evenodd;" points="6.211,2 10,2 10,5.789 8.579,4.368 6.447,6.5 + 5.5,5.553 7.632,3.421 "/> + </g> +</g> +<g id="Guides" style="display:none;"> +</g> +</svg> diff --git a/static/favicon.ico b/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..67b2e3b287a9f17282cacc2560e4c1621580f1bd GIT binary patch literal 105637 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 literal 0 HcmV?d00001 diff --git a/static/index.html b/static/index.html new file mode 100644 index 0000000..9437f20 --- /dev/null +++ b/static/index.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>Static Assets</title> + <link rel="stylesheet" href="theme.css"> +</head> +<body> + <header> + <h1>Static Assets</h1> + </header> + <main> + welcome to my static + </main> +</body> +</html> diff --git a/static/logo.svg b/static/logo.svg new file mode 100644 index 0000000..8d6cd8d --- /dev/null +++ b/static/logo.svg @@ -0,0 +1 @@ +<svg height='300px' width='300px' fill="#000000" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve"><path d="M74.4033203,9.9516602H25.4296875c-3.5458984,0-6.4306641,2.8842773-6.4306641,6.4296875v67.140625 c0,3.5454102,2.8847656,6.4296875,6.4306641,6.4296875h48.9736328c3.5449219,0,6.4296875-2.8842773,6.4296875-6.4296875v-67.140625 C80.8330078,12.8359375,77.9482422,9.9516602,74.4033203,9.9516602z M78.8330078,83.5219727 c0,2.4423828-1.9873047,4.4296875-4.4296875,4.4296875H25.4296875c-2.4433594,0-4.4306641-1.9873047-4.4306641-4.4296875v-67.140625 c0-2.4423828,1.9873047-4.4296875,4.4306641-4.4296875h48.9736328c2.4423828,0,4.4296875,1.9873047,4.4296875,4.4296875V83.5219727z "></path><path d="M54.5175781,40.3291016h15.9443359c0.5527344,0,1-0.4477539,1-1s-0.4472656-1-1-1H54.5175781c-0.5527344,0-1,0.4477539-1,1 S53.9648438,40.3291016,54.5175781,40.3291016z"></path><path d="M54.5175781,21.3291016h15.9443359c0.5527344,0,1-0.4477539,1-1s-0.4472656-1-1-1H54.5175781c-0.5527344,0-1,0.4477539-1,1 S53.9648438,21.3291016,54.5175781,21.3291016z"></path><path d="M54.5175781,30.8291016h15.9443359c0.5527344,0,1-0.4477539,1-1s-0.4472656-1-1-1H54.5175781c-0.5527344,0-1,0.4477539-1,1 S53.9648438,30.8291016,54.5175781,30.8291016z"></path><path d="M73.8515625,48.5791016h-2.4833984c-0.5527344,0-1,0.4477539-1,1s0.4472656,1,1,1h2.4833984c0.5527344,0,1-0.4477539,1-1 S74.4042969,48.5791016,73.8515625,48.5791016z"></path><path d="M66.2871094,48.5791016h-2.4833984c-0.5527344,0-1,0.4477539-1,1s0.4472656,1,1,1h2.4833984c0.5527344,0,1-0.4477539,1-1 S66.8398438,48.5791016,66.2871094,48.5791016z"></path><path d="M56.2392578,48.5791016c-0.5527344,0-1,0.4477539-1,1s0.4472656,1,1,1h2.4833984c0.5527344,0,1-0.4477539,1-1 s-0.4472656-1-1-1H56.2392578z"></path><path d="M48.6738281,50.5791016h2.484375c0.5527344,0,1-0.4477539,1-1s-0.4472656-1-1-1h-2.484375c-0.5527344,0-1,0.4477539-1,1 S48.1210938,50.5791016,48.6738281,50.5791016z"></path><path d="M41.109375,48.5791016c-0.5527344,0-1,0.4477539-1,1s0.4472656,1,1,1h2.484375c0.5527344,0,1-0.4477539,1-1 s-0.4472656-1-1-1H41.109375z"></path><path d="M37.0292969,49.5791016c0-0.5522461-0.4472656-1-1-1h-2.484375c-0.5527344,0-1,0.4477539-1,1s0.4472656,1,1,1h2.484375 C36.5820312,50.5791016,37.0292969,50.1313477,37.0292969,49.5791016z"></path><path d="M28.4648438,48.5791016h-2.484375c-0.5527344,0-1,0.4477539-1,1s0.4472656,1,1,1h2.484375c0.5527344,0,1-0.4477539,1-1 S29.0175781,48.5791016,28.4648438,48.5791016z"></path><path d="M47.0966797,39.5V20.3291016c0-0.5522461-0.4472656-1-1-1H29.6894531c-0.5527344,0-1,0.4477539-1,1V39.5 c0,0.5522461,0.4472656,1,1,1h16.4072266C46.6494141,40.5,47.0966797,40.0522461,47.0966797,39.5z M45.0966797,38.5H30.6894531 V21.3291016h14.4072266V38.5z"></path><path d="M65.4990234,65.6132812c0.3759766-0.2441406,0.5429688-0.7080078,0.4101562-1.1352539 c-0.1337891-0.4277344-0.5361328-0.7368164-0.9814453-0.7026367c-1.6650391,0.0356445-3.2128906-0.7075195-4.140625-2.0092773 c-0.8515625-1.1943359-1.0478516-2.6577148-0.5390625-4.0151367c0.1552734-0.4140625,0.0205078-0.8803711-0.3320312-1.1479492 c-0.3515625-0.2661133-0.8369141-0.2714844-1.1943359-0.0102539c-1.3017578,0.949707-3.0029297,1.2104492-4.5605469,0.6967773 c-1.4824219-0.4902344-2.5849609-1.5849609-3.0244141-3.0029297c-0.1298828-0.418457-0.5166016-0.7036133-0.9550781-0.7036133 s-0.8251953,0.2851562-0.9550781,0.7036133c-0.4394531,1.4179688-1.5419922,2.5126953-3.0244141,3.0029297 c-1.5546875,0.5141602-3.2587891,0.2543945-4.5605469-0.6967773c-0.3554688-0.2612305-0.8408203-0.2558594-1.1943359,0.0102539 c-0.3525391,0.2675781-0.4873047,0.7338867-0.3320312,1.1479492c0.5087891,1.3574219,0.3125,2.8208008-0.5390625,4.015625 c-0.9277344,1.3017578-2.4746094,2.0444336-4.1396484,2.0087891c-0.4433594-0.0332031-0.8476562,0.2749023-0.9814453,0.7026367 c-0.1328125,0.4272461,0.0341797,0.8911133,0.4101562,1.1352539c1.3183594,0.8579102,2.0751953,2.2138672,2.0742188,3.7202148 c0,1.5058594-0.7558594,2.8613281-2.0742188,3.7192383c-0.3759766,0.2441406-0.5429688,0.7080078-0.4101562,1.1352539 c0.1337891,0.4272461,0.5371094,0.7109375,0.9814453,0.7026367c1.6630859-0.0249023,3.2119141,0.7075195,4.1396484,2.0087891 c0.8515625,1.1948242,1.0478516,2.6582031,0.5390625,4.015625c-0.1552734,0.4140625-0.0205078,0.8803711,0.3320312,1.1474609 c0.3535156,0.2680664,0.8388672,0.2724609,1.1943359,0.0107422c1.3007812-0.9501953,3.0019531-1.2109375,4.5605469-0.6962891 c1.4824219,0.4902344,2.5849609,1.5849609,3.0244141,3.0029297c0.1298828,0.418457,0.5166016,0.7036133,0.9550781,0.7036133 s0.8251953-0.2851562,0.9550781-0.7036133c0.4394531-1.4179688,1.5419922-2.5126953,3.0244141-3.0029297 c1.5576172-0.5146484,3.2607422-0.2539062,4.5605469,0.6962891c0.3574219,0.2617188,0.8427734,0.2573242,1.1943359-0.0107422 c0.3525391-0.2670898,0.4873047-0.7333984,0.3320312-1.1474609c-0.5087891-1.3574219-0.3125-2.8208008,0.5390625-4.0151367 c0.9277344-1.3022461,2.4755859-2.0458984,4.140625-2.0092773c0.4453125,0.0087891,0.8476562-0.2753906,0.9814453-0.7026367 c0.1328125-0.4272461-0.0341797-0.8911133-0.4101562-1.1352539c-1.3183594-0.8579102-2.0742188-2.2133789-2.0742188-3.7192383 C63.4238281,67.8271484,64.1806641,66.4711914,65.4990234,65.6132812z M62.7402344,73.1884766 c-1.4384766,0.4326172-2.703125,1.3168945-3.5820312,2.550293c-0.8027344,1.1269531-1.2060547,2.4194336-1.1904297,3.7294922 c-1.4189453-0.4643555-2.9746094-0.472168-4.4345703,0.0097656c-1.3876953,0.4594727-2.5439453,1.2998047-3.3515625,2.4052734 c-0.8076172-1.1054688-1.9638672-1.9458008-3.3515625-2.4052734c-0.7304688-0.2416992-1.4853516-0.3598633-2.234375-0.3598633 c-0.7480469,0-1.4912109,0.1181641-2.2001953,0.3500977c0.015625-1.3105469-0.3876953-2.6025391-1.1904297-3.7294922 c-0.8789062-1.2333984-2.1435547-2.1176758-3.5810547-2.550293c0.84375-1.1030273,1.3154297-2.4482422,1.3154297-3.8549805 c0.0009766-1.4072266-0.4716797-2.7529297-1.3164062-3.855957c1.4384766-0.4326172,2.703125-1.3168945,3.5820312-2.550293 c0.8027344-1.1264648,1.2060547-2.4189453,1.1904297-3.7294922c1.4199219,0.465332,2.9755859,0.4726562,4.4345703-0.0092773 c1.3876953-0.4594727,2.5439453-1.2993164,3.3515625-2.4052734c0.8076172,1.105957,1.9638672,1.9458008,3.3515625,2.4052734 c1.4589844,0.4819336,3.0146484,0.4746094,4.4345703,0.0092773c-0.015625,1.3105469,0.3876953,2.6025391,1.1904297,3.7294922 c0.8798828,1.2333984,2.1435547,2.1176758,3.5820312,2.550293c-0.84375,1.1035156-1.3164062,2.4487305-1.3154297,3.855957 C61.4248047,70.7402344,61.8964844,72.0854492,62.7402344,73.1884766z"></path><path d="M50.1816406,61.0014648c-4.5947266,0-8.3320312,3.7373047-8.3320312,8.331543s3.7373047,8.3320312,8.3320312,8.3320312 s8.3320312-3.737793,8.3320312-8.3320312S54.7763672,61.0014648,50.1816406,61.0014648z M50.1816406,75.6650391 c-3.4912109,0-6.3320312-2.840332-6.3320312-6.3320312c0-3.4912109,2.8408203-6.331543,6.3320312-6.331543 s6.3320312,2.840332,6.3320312,6.331543C56.5136719,72.824707,53.6728516,75.6650391,50.1816406,75.6650391z"></path></svg> \ No newline at end of file diff --git a/static/robots.txt b/static/robots.txt new file mode 100644 index 0000000..1f53798 --- /dev/null +++ b/static/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / diff --git a/static/theme.css b/static/theme.css new file mode 100644 index 0000000..837151d --- /dev/null +++ b/static/theme.css @@ -0,0 +1,175 @@ +html { + height: 100vh; +} +body { + background-color: #fff; + font-family: Helvetica, Verdana, sans-serif; + margin: 0 1em 0 1em; + min-height: 100vh; + display: flex; + flex-direction: column; +} +header {} +header nav { + margin-bottom: 1em; +} +header nav ol { + list-style-type: none; + margin: 0; + padding: 0; +} +header nav ol li { + display: inline; + text-align: center; + border-top: 2px solid #666; + border-bottom: 2px solid #666; + border-left: 1px solid #666; + border-right: 1px solid #666; + padding: .3em .5em .2em .5em; +} +header nav ol li:hover { + background-color: #ddd; +} +header nav ol > li:first-child { + border-left: 2px solid #666; +} +header nav ol > li:last-child { + border-right: 2px solid #666; +} +header nav ol a { + font-variant-caps: small-caps; + text-decoration: none; + font-weight: bold; +} +h1 { + margin-top: 1em; + margin-bottom: 1.25em; + text-align: center; +} +h2 { + background-color: #ddd; + padding: .25em 0 .1em 0.25em; +} +main { + flex-grow: 1; +} +section {} +.logo { + vertical-align: middle; + height: 2em; +} +.about {} +.usage {} +.copyright { + font-size: small; +} +.error ul { + font-weight: bolder; + border: 2px solid red; + padding: 1em; + background-color: lightsalmon; +} +.notification ul { + background-color: aliceblue; + border: 1px solid slateblue; + padding: 1em; +} +.legacy-warning { + background-color: coral; +} +.external { + background-image: url("external-link.svg"); + background-position: right center; + background-repeat: no-repeat; + padding-right: 13px; +} +.information img { + max-width: 4em; + max-height: 4em; + width: 100%; + height: auto; + vertical-align: middle; +} +.uri { + font-family: Courier, monospace, serif; + font-size: 1em; + background-color: lavender; + padding: .16em; +} +.code { + font-family: Courier, monospace, serif; + font-size: .75em; + white-space: nowrap; + overflow-x: hidden; +} +.client-identifier { + display: inline-block; + height: max-content; + padding: .5em; + border: 1px dotted #999; + margin-bottom: .5em; +} +.scope { + list-style-type: none; +} +.scope label { + font-variant: small-caps; + font-weight: bold; +} +.scope .description { + font-size: smaller; + font-style: italic; +} +.scope .disabled { + color: grey; + background-color: #eee; +} +.form-consent button { + border-width: thick; + font-size: x-large; + padding: .5em; + margin-left: .75em; + margin-right: .75em; +} +.button-accept { + background-color: lightgreen; + border-color: lightgreen; +} +.button-decline { + background-color: salmon; + border-color: salmon; +} +.vertical { + writing-mode: vertical-lr; + vertical-align: bottom; +} +table { + border: 0; + width: 100%; +} +thead tr th { + background-color: #ddd; + vertical-align: bottom; + text-align: start; +} +tbody tr th { + text-align: start; +} +tbody tr:nth-child(even) td, tbody tr:nth-child(even) th { + background-color: #eee; +} +tbody tr:nth-child(odd) td, tbody tr:nth-child(odd) th {} +footer { + text-align: center; + width: 100%; + border-top: .33em dotted #666; + margin-top: 1em; +} +footer ol { + list-style-type: none; + margin: .5em; + padding: 0; +} +.centered { + text-align: center; +} \ No newline at end of file diff --git a/test/config.js b/test/config.js new file mode 100644 index 0000000..f2f8018 --- /dev/null +++ b/test/config.js @@ -0,0 +1,23 @@ +/* eslint-env mocha */ +'use strict'; + +const assert = require('assert'); +const Config = require('../config'); + +describe('Config', function () { + it('covers default environment', function () { + const config = new Config(); + assert.strictEqual(config.environment, 'development'); + assert(Object.isFrozen(config)); + }); + it('covers default environment, unfrozen', function () { + const config = new Config(undefined, false); + assert.strictEqual(config.environment, 'development'); + assert(!Object.isFrozen(config)); + }); + it('covers test environment', function () { + const config = new Config('test'); + assert.strictEqual(config.environment, 'test'); + assert(!Object.isFrozen(config)); + }); +}); // Config \ No newline at end of file diff --git a/test/src/chores.js b/test/src/chores.js new file mode 100644 index 0000000..51c015c --- /dev/null +++ b/test/src/chores.js @@ -0,0 +1,140 @@ +/* eslint-env mocha */ +/* eslint-disable node/no-unpublished-require */ +'use strict'; + +const assert = require('assert'); +const sinon = require('sinon'); +const StubDB = require('../stub-db'); +const StubLogger = require('../stub-logger'); +const Chores = require('../../src/chores'); + +const snooze = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); + +const expectedException = new Error('oh no'); + +describe('Chores', function () { + let chores, stubLogger, stubDb, options; + beforeEach(function () { + stubLogger = new StubLogger(); + stubLogger._reset(); + stubDb = new StubDB(); + stubDb._reset(); + }); + afterEach(function () { + chores?.stopAllChores(); + sinon.restore(); + }); + + describe('constructor', function () { + + it('empty options, no cleaning', async function () { + options = undefined; + chores = new Chores(stubLogger, stubDb, options); + assert.strictEqual(chores.chores.cleanTokens.timeoutObj, undefined); + assert.strictEqual(chores.chores.cleanScopes.timeoutObj, undefined); + }); + + it('cleans scopes', async function () { + options = { + chores: { + scopeCleanupMs: 1, + }, + }; + chores = new Chores(stubLogger, stubDb, options); + await snooze(50); + assert(chores.chores.cleanScopes.timeoutObj); + assert(chores.db.scopeCleanup.called); + }); + + it('cleans tokens', async function () { + options = { + chores: { + tokenCleanupMs: 1, + }, + manager: { + codeValidityTimeoutMs: 10, + }, + }; + chores = new Chores(stubLogger, stubDb, options); + await snooze(50); + assert(chores.chores.cleanTokens.timeoutObj); + assert(chores.db.tokenCleanup.called); + }); + + }); // constructor + + describe('cleanTokens', function () { + it('logs cleaning', async function () { + const cleaned = 10; + options = { + chores: { + tokenCleanupMs: 100, + }, + manager: { + codeValidityTimeoutMs: 10, + }, + }; + stubDb.tokenCleanup.resolves(cleaned); + chores = new Chores(stubLogger, stubDb, options); + clearTimeout(chores.cleanTokensTimeout); + await chores.cleanTokens(); + assert(stubLogger.info.called); + }); + it('covers failure', async function () { + options = { + chores: { + tokenCleanupMs: 1, + }, + manager: { + codeValidityTimeoutMs: 10, + }, + }; + stubDb.tokenCleanup.rejects(expectedException); + chores = new Chores(stubLogger, stubDb, options); + await assert.rejects(() => chores.cleanTokens(), expectedException); + }); + it('covers default', async function () { + stubDb.tokenCleanup.resolves(0); + chores = new Chores(stubLogger, stubDb, { + manager: { + codeValidityTimeoutMs: 10, + }, + }); + await chores.cleanTokens(); + assert(stubDb.tokenCleanup.called); + }); + }); // cleanTokens + + describe('cleanScopes', function () { + it('logs cleaning', async function () { + const cleaned = 10; + options = { + chores: { + scopeCleanupMs: 100, + }, + }; + stubDb.scopeCleanup.resolves(cleaned); + chores = new Chores(stubLogger, stubDb, options); + clearTimeout(chores.cleanScopesTimeout); + await chores.cleanScopes(); + assert(stubLogger.info.called); + }); + it('covers failure', async function () { + options = { + chores: { + scopeCleanupMs: 1, + }, + }; + stubDb.scopeCleanup.rejects(expectedException); + chores = new Chores(stubLogger, stubDb, options); + await assert.rejects(() => chores.cleanScopes(), expectedException); + }); + it('covers default', async function () { + stubDb.scopeCleanup.resolves(0); + chores = new Chores(stubLogger, stubDb, {}); + await chores.cleanScopes(); + assert(stubDb.scopeCleanup.called); + }); + }); // cleanScopes + +}); // Chores \ No newline at end of file diff --git a/test/src/common.js b/test/src/common.js new file mode 100644 index 0000000..1115f0a --- /dev/null +++ b/test/src/common.js @@ -0,0 +1,181 @@ +/* eslint-env mocha */ +'use strict'; + +const assert = require('assert'); +const common = require('../../src/common'); + +describe('Common', function () { + + describe('camelfy', function () { + it('covers', function () { + const snake = 'snake_case'; + const expected = 'snakeCase'; + const result = common.camelfy(snake); + assert.strictEqual(result, expected); + }); + it('covers edge-cases', function () { + const kebab = '-kebab-case-'; + const expected = 'KebabCase'; + const result = common.camelfy(kebab, '-'); + assert.strictEqual(result, expected); + }); + it('covers empty input', function () { + const empty = ''; + const expected = undefined; + const result = common.camelfy(empty); + assert.strictEqual(result, expected); + }); + it('covers un-camelfiable input', function () { + const bad = {}; + const expected = undefined; + const result = common.camelfy(bad); + assert.strictEqual(result, expected); + }); + }); // camelfy + + describe('freezeDeep', function () { + it('freezes things', function () { + const obj = { + sub1: { + sub2: { + foo: 'blah', + }, + }, + }; + const result = common.freezeDeep(obj); + assert(Object.isFrozen(result)); + assert(Object.isFrozen(result.sub1)); + assert(Object.isFrozen(result.sub1.sub2)); + assert(Object.isFrozen(result.sub1.sub2.foo)); + }); + }); // freezeDeep + + describe('axiosResponseLogData', function () { + it('covers', function () { + const response = { + status: 200, + statusText: 'OK', + headers: { + 'Content-Type': 'text/plain', + }, + otherData: 'blah', + data: 'Old Mother West Wind had stopped to talk with the Slender Fir Tree. "I\'ve just come across the Green Meadows," said Old Mother West Wind, âand there I saw the Best Thing in the World.â', + }; + const expected = { + status: 200, + statusText: 'OK', + headers: { + 'Content-Type': 'text/plain', + }, + data: 'Old Mother West Wind had stopped to talk with the Slender Fir Tree. "I\'ve just come across the Green... (184 bytes)', + }; + const result = common.axiosResponseLogData(response); + assert.deepStrictEqual(result, expected); + }); + it('covers no data', function () { + const response = { + status: 200, + statusText: 'OK', + headers: { + 'Content-Type': 'text/plain', + }, + }; + const expected = { + status: 200, + statusText: 'OK', + headers: { + 'Content-Type': 'text/plain', + }, + }; + const result = common.axiosResponseLogData(response); + assert.deepStrictEqual(result, expected); + }); + }); // axiosResponseLogData + + describe('logTruncate', function () { + it('returns short string', function () { + const str = 'this is a short string'; + const result = common.logTruncate(str, 100); + assert.strictEqual(result, str); + }); + it('truncates long string', function () { + const str = 'this is not really a very long string but it is long enough for this test'; + const result = common.logTruncate(str, 10); + assert(result.length < str.length); + }); + }); // logTruncate + + describe('ensureArray', function () { + it('returns empty array for no data', function () { + const result = common.ensureArray(); + assert.deepStrictEqual(result, []); + }); + it('returns same array passed in', function () { + const expected = [1, 2, 3, 'foo']; + const result = common.ensureArray(expected); + assert.deepStrictEqual(result, expected); + }); + it('returns array containing non-array data', function () { + const data = 'bar'; + const result = common.ensureArray(data); + assert.deepStrictEqual(result, [data]); + }); + }); // ensureArray + + describe('validError', function () { + it('covers valid', function () { + const result = common.validError('error'); + assert.strictEqual(result, true); + }); + it('covers invalid', function () { + const result = common.validError('ð'); + assert.strictEqual(result, false); + }); + it('covers empty', function () { + const result = common.validError(); + assert.strictEqual(result, false); + }); + }); // validError + + describe('validScope', function () { + it('covers valid', function () { + const result = common.validScope('scope'); + assert.strictEqual(result, true); + }); + it('covers invalid', function () { + const result = common.validScope('ð'); + assert.strictEqual(result, false); + }); + it('covers empty', function () { + const result = common.validScope(); + assert.strictEqual(result, false); + }); + }); // validScope + + describe('newSecret', function () { + it('covers default', async function () { + const result = await common.newSecret(); + assert(result.length); + }); + it('covers specified', async function () { + const result = await common.newSecret(21); + assert(result.length); + }); + }); // newSecret + + describe('dateToEpoch', function () { + it('covers no supplied date', function () { + const nowMs = Date.now() / 1000; + const result = common.dateToEpoch(); + const drift = Math.abs(result - nowMs); + assert(drift < 2000); + }); + it('covers supplied date', function () { + const now = new Date(); + const nowEpoch = Math.ceil(now / 1000); + const result = common.dateToEpoch(now); + assert.strictEqual(result, nowEpoch); + }); + }); // dateToEpoch + +}); // Common diff --git a/test/src/db/abstract.js b/test/src/db/abstract.js new file mode 100644 index 0000000..9d7dbf9 --- /dev/null +++ b/test/src/db/abstract.js @@ -0,0 +1,295 @@ +/* eslint-env mocha */ +'use strict'; + +const assert = require('assert'); +const sinon = require('sinon'); // eslint-disable-line node/no-unpublished-require + +const StubDatabase = require('../../stub-db'); +const StubLogger = require('../../stub-logger'); +const DB = require('../../../src/db/abstract'); +const DBErrors = require('../../../src/db/errors'); + +describe('DatabaseBase', function () { + let db, logger, stubDb; + before(function () { + logger = new StubLogger(); + logger._reset(); + stubDb = new StubDatabase(); + }); + beforeEach(function () { + db = new DB(logger, {}); + }); + afterEach(function () { + sinon.restore(); + }); + + it('covers no options', function () { + db = new DB(); + }); + + describe('Interface', function () { + it('covers abstract methods', async function () { + await Promise.all(stubDb._implementation.map(async (m) => { + try { + // eslint-disable-next-line security/detect-object-injection + await db[m](); + assert.fail(`${m}: did not catch NotImplemented exception`); + } catch (e) { + assert(e instanceof DBErrors.NotImplemented, `${m}: unexpected exception ${e.name}`); + } + })); + }); // covers abstract methods + it('covers private abstract methods', async function () { + [ + ].map((m) => { + try { + // eslint-disable-next-line security/detect-object-injection + db[m](); + } catch (e) { + assert(e instanceof DBErrors.NotImplemented, `${m}: unexpected exception ${e.name}`); + } + }); + }); + }); // Interface + + describe('_isUUID', function () { + it('is a uuid', function () { + const result = DB._isUUID('8fde351e-2d63-11ed-8b0c-0025905f714a'); + assert.strictEqual(result, true); + }); + it('is not a uuid', function () { + const result = DB._isUUID('not a uuid'); + assert.strictEqual(result, false); + }); + }); + + describe('_isInfinites', function () { + it('is true for Infinity', function () { + const result = DB._isInfinites(Infinity); + assert.strictEqual(result, true); + }); + it('is true for negative Infinity', function () { + const result = DB._isInfinites(-Infinity); + assert.strictEqual(result, true); + }); + it('is false for finite value', function () { + const result = DB._isInfinites(5); + assert.strictEqual(result, false); + }); + it('is false for NaN', function () { + const result = DB._isInfinites(NaN); + assert.strictEqual(result, false); + }); + }); + + describe('_ensureTypes', function () { + let object; + beforeEach(function () { + object = { + array: ['foo', 'bar'], + bignum: BigInt(456), + buf: Buffer.from('foop'), + date: new Date(), + num: 123, + obj: {}, + str: 'some words', + uuid: 'a4dd5106-2d64-11ed-a2ba-0025905f714a', + veryNull: null, + }; + }); + it('succeeds', function () { + db._ensureTypes(object, ['array'], ['array']); + db._ensureTypes(object, ['bignum', 'num'], ['number']); + db._ensureTypes(object, ['buf'], ['buffer']); + db._ensureTypes(object, ['date'], ['date']); + db._ensureTypes(object, ['str', 'veryNull'], ['string', 'null']); + }); + it('data failure', function () { + try { + db._ensureTypes(object, ['missingField'], ['string', 'null']); + assert.fail('validation should have failed'); + } catch (e) { + assert(e instanceof DBErrors.DataValidation); + } + }); + it('failure covers singular', function () { + try { + db._ensureTypes(object, ['missingField'], ['string']); + assert.fail('validation should have failed'); + } catch (e) { + assert(e instanceof DBErrors.DataValidation); + } + }); + it('parameter failure', function () { + try { + db._ensureTypes(object, ['missingField'], undefined); + assert.fail('validation should have failed'); + } catch (e) { + assert(e instanceof DBErrors.DataValidation); + } + }); + }); // _ensureTypes + + describe('_validateAuthentication', function () { + let authentication; + beforeEach(function () { + authentication = { + identifier: 'username', + credential: '$plain$secret', + created: new Date(), + lastAuthenticated: -Infinity, + }; + }); + it('covers', function () { + db._validateAuthentication(authentication); + }); + it('covers failure', function () { + assert.throws(() => db._validateAuthentication(undefined), DBErrors.DataValidation); + }); + }); // _validateAuthentication + + describe('_validateResource', function () { + let resource; + beforeEach(function () { + resource = { + resourceId: '42016c1e-2d66-11ed-9e10-0025905f714a', + secret: 'secretSecret', + description: 'Some other service', + created: new Date(), + }; + }); + it('covers', function () { + db._validateResource(resource); + }); + it('covers failure', function () { + assert.throws(() => db._validateResource(undefined), DBErrors.DataValidation); + }); + }); // _validateResource + + describe('_validateToken', function () { + let token; + beforeEach(function () { + token = { + codeId: '9efc7882-2d66-11ed-b03c-0025905f714a', + profile: 'https://profile.example.com/', + resource: null, + clientId: 'https://app.example.com/', + created: new Date(), + expires: new Date(), + refreshExpires: null, + refreshed: null, + isToken: true, + isRevoked: false, + scopes: ['scope'], + profileData: { + name: 'User von Namey', + }, + }; + }); + it('covers', function () { + db._validateToken(token); + }); + it('covers failure', function () { + assert.throws(() => db._validateToken(undefined), DBErrors.DataValidation); + }); + }); // _validateToken + + describe('_profilesScopesBuilder', function () { + it('covers empty', function () { + const result = DB._profilesScopesBuilder(); + assert.deepStrictEqual(result, { + profileScopes: {}, + scopeIndex: {}, + profiles: [], + }); + }); + it('builds expected structure', function () { + const profileScopesRows = [ + { profile: 'https://scopeless.example.com/', scope: null, description: null, application: null, isPermanent: null, isManuallyAdded: null }, + { profile: 'https://profile.example.com/', scope: 'role:private', description: 'level', application: '', isPermanent: false, isManuallyAdded: true }, + { profile: null, scope: 'profile', description: 'profile', application: 'IndieAuth', isPermanent: true, isManuallyAdded: false }, + { profile: null, scope: 'role:private', description: 'level', application: '', isPermanent: false, isManuallyAdded: true }, + { profile: null, scope: 'read', description: 'read', application: 'MicroPub', isPermanent: true, isManuallyAdded: false }, + { profile: 'https://profile.example.com/', scope: 'profile', description: 'profile', application: 'IndieAuth', isPermanent: true, isManuallyAdded: false }, + { profile: 'https://another.example.com/', scope: 'profile', description: 'profile', application: 'IndieAuth', isPermanent: true, isManuallyAdded: false }, + ]; + const expected = { + profileScopes: { + 'https://scopeless.example.com/': {}, + 'https://profile.example.com/': {}, + 'https://another.example.com/': {}, + }, + scopeIndex: { + 'role:private': { + description: 'level', + application: '', + isPermanent: false, + isManuallyAdded: true, + profiles: ['https://profile.example.com/'], + }, + 'profile': { + description: 'profile', + application: 'IndieAuth', + isPermanent: true, + isManuallyAdded: false, + profiles: ['https://profile.example.com/', 'https://another.example.com/'], + }, + 'read': { + description: 'read', + application: 'MicroPub', + isPermanent: true, + isManuallyAdded: false, + profiles: [], + }, + }, + profiles: ['https://scopeless.example.com/', 'https://profile.example.com/', 'https://another.example.com/'], + }; + expected.profileScopes['https://profile.example.com/']['role:private'] = expected.scopeIndex['role:private']; + expected.profileScopes['https://profile.example.com/']['profile'] = expected.scopeIndex['profile']; + expected.profileScopes['https://another.example.com/']['profile'] = expected.scopeIndex['profile']; + + const result = DB._profilesScopesBuilder(profileScopesRows); + assert.deepStrictEqual(result, expected); + }); + }); // _profilesScopesBuilder + + describe('initialize', function () { + let currentSchema; + beforeEach(function () { + currentSchema = { + major: 1, + minor: 0, + patch: 0, + }; + db.schemaVersionsSupported = { + min: { ...currentSchema }, + max: { ...currentSchema }, + }; + sinon.stub(db, '_currentSchema').resolves(currentSchema); + }); + it('covers success', async function () { + await db.initialize(); + }); + it('covers failure', async function() { + db.schemaVersionsSupported = { + min: { + major: 3, + minor: 2, + patch: 1, + }, + max: { + major: 5, + minor: 0, + patch: 0, + }, + }; + try { + await db.initialize(); + assert.fail('did not get expected exception'); + } catch (e) { + assert(e instanceof DBErrors.MigrationNeeded); + } + }); + }); // initialize + +}); // DatabaseBase diff --git a/test/src/db/factory.js b/test/src/db/factory.js new file mode 100644 index 0000000..7b9402c --- /dev/null +++ b/test/src/db/factory.js @@ -0,0 +1,49 @@ +/* eslint-env mocha */ +'use strict'; + +const assert = require('assert'); +const sinon = require('sinon'); // eslint-disable-line node/no-unpublished-require +const common = require('../../../src/common'); +const DB = require('../../../src/db'); +const DBErrors = require('../../../src/db/errors'); +const DatabasePostgres = require('../../../src/db/postgres'); +const DatabaseSQLite = require('../../../src/db/sqlite'); + +describe('DatabaseFactory', function () { + let logger, options; + beforeEach(function () { + logger = common.nullLogger; + options = { + db: { + connectionString: '', + }, + }; + }); + afterEach(function () { + sinon.restore(); + }); + it('gets engines', function () { + const result = DB.Engines; + assert(result instanceof Object); + assert(Object.keys(result).length); + }); + it('creates postgres db', function () { + options.db.connectionString = 'postgresql://blah'; + const db = new DB(logger, options); + assert(db instanceof DatabasePostgres); + }); + it('creates sqlite db', function () { + options.db.connectionString = 'sqlite://:memory:'; + const db = new DB(logger, options); + assert(db instanceof DatabaseSQLite); + }); + it('handles missing db', function () { + delete options.db.connectionString; + try { + new DB(logger, options); + assert.fail('did not get expected exception'); + } catch (e) { + assert(e instanceof DBErrors.UnsupportedEngine); + } + }); +}); // DatabaseFactory diff --git a/test/src/db/integration.js b/test/src/db/integration.js new file mode 100644 index 0000000..7634b30 --- /dev/null +++ b/test/src/db/integration.js @@ -0,0 +1,503 @@ +/* eslint-env mocha */ +/* eslint-disable sonarjs/no-identical-functions */ +'use strict'; + +/** + * These are LIVE FIRE tests to exercise actual database operations. + * They should be configured to use local test databases, as they + * perform DESTRUCTIVE ACTIONS on all tables, beginning with a COMPLETE + * DATA WIPE. + * + * They will only run if all the appropriate environmental settings exist: + * - INTEGRATION_TESTS must be set + * - <ENGINE>_TEST_PATH must point to the endpoint/db + * + * These tests are sequential, relying on the state created along the way. + * + */ + +const assert = require('assert'); +const { step } = require('mocha-steps'); // eslint-disable-line node/no-unpublished-require +const StubLogger = require('../../stub-logger'); +// const DBErrors = require('../../../src/db/errors'); +// const testData = require('../../test-data/db-integration'); + +describe('Database Integration', function () { + const implementations = []; + + if (!process.env.INTEGRATION_TESTS) { + it.skip('integration tests not requested'); + return; + } + + if (process.env.POSTGRES_TEST_PATH) { + implementations.push({ + name: 'PostgreSQL', + module: '../../../src/db/postgres', + config: { + db: { + connectionString: `postgresql://${process.env.POSTGRES_TEST_PATH}`, + queryLogLevel: 'debug', + noWarnings: true, + }, + }, + }); + } + + if (process.env.SQLITE_TEST_PATH) { + implementations.push({ + name: 'SQLite', + module: '../../../src/db/sqlite', + config: { + db: { + connectionString: `sqlite://${process.env.SQLITE_TEST_PATH}`, + queryLogLevel: 'debug', + sqliteOptimizeAfterChanges: 10, + }, + }, + }); + } + + if (!implementations.length) { + it('have some implementations to test', function () { + assert.fail('No implementations have been configured for requested integration tests'); + }); + } + + implementations.forEach(function (i) { + describe(i.name, function () { + let logger; + let DB, db; + let profile, identifier; + + before(async function () { + this.timeout(10 * 1000); // Allow some time for creating tables et cetera. + logger = new StubLogger(); + logger._reset(); + // eslint-disable-next-line security/detect-non-literal-require + DB = require(i.module); + db = new DB(logger, i.config); + await db.initialize(); + await db._purgeTables(true); + }); + after(async function () { + await db._closeConnection(); + }); + + beforeEach(function () { + identifier = 'username'; + profile = 'https://example.com/profile'; + }); + + describe('Healthcheck', function () { + it('should succeed', async function () { + const result = await db.healthCheck(); + assert(result); + }); + }); + + describe('Resources', function () { + let resourceId, secret, description; + before(function () { + secret = 'shared secret'; + description = 'A resource server that needs to verify our tokens.'; + }); + step('returns nothing when resource does not exist', async function () { + await db.context(async (dbCtx) => { + const badResourceId = 'f1669969-c87e-46f8-83bb-a6712981d15d'; + const result = await db.resourceGet(dbCtx, badResourceId); + assert(!result); + }); + }); + step('creates resource', async function () { + await db.context(async (dbCtx) => { + const result = await db.resourceUpsert(dbCtx, undefined, secret, description); + assert(result.resourceId); + resourceId = result.resourceId; + }); + }); + step('gets resource', async function () { + await db.context(async (dbCtx) => { + const result = await db.resourceGet(dbCtx, resourceId); + assert.strictEqual(result.secret, secret); + db._validateResource(result); + }); + }); + step('updates resource', async function () { + await db.context(async (dbCtx) => { + secret = 'new shared secret'; + description = 'Still a resource server, but with a new description.'; + await db.resourceUpsert(dbCtx, resourceId, secret, description); + const result = await db.resourceGet(dbCtx, resourceId); + assert.strictEqual(result.resourceId, resourceId); + assert.strictEqual(result.secret, secret); + assert.strictEqual(result.description, description); + }); + }); + }); // Resources + + describe('Users and Profiles and Scopes', function () { + let credential; + beforeEach(function () { + credential = '$plain$myPassword'; + }); + step('returns nothing when auth does not exist', async function () { + await db.context(async (dbCtx) => { + const result = await db.authenticationGet(dbCtx, identifier); + assert(!result); + }); + }); + step('create auth entry', async function () { + await db.context(async (dbCtx) => { + await db.authenticationUpsert(dbCtx, identifier, credential); + }); + }); + step('get auth entry', async function () { + await db.context(async (dbCtx) => { + const authInfo = await db.authenticationGet(dbCtx, identifier); + assert.strictEqual(authInfo.credential, credential); + db._validateAuthentication(authInfo); + }); + }); + step('valid auth event', async function () { + await db.context(async (dbCtx) => { + await db.authenticationSuccess(dbCtx, identifier); + const authInfo = await db.authenticationGet(dbCtx, identifier); + db._validateAuthentication(authInfo); + assert.notStrictEqual(authInfo.lastAuthentication, undefined); + }); + }); + step('update auth entry', async function () { + await db.context(async (dbCtx) => { + credential = '$plain$myNewPassword'; + await db.authenticationUpsert(dbCtx, identifier, credential); + const authInfo = await db.authenticationGet(dbCtx, identifier); + assert.strictEqual(authInfo.credential, credential); + }); + }); + step('profile is not valid', async function () { + await db.context(async (dbCtx) => { + const isValid = await db.profileIsValid(dbCtx, profile); + assert.strictEqual(isValid, false); + }); + }); + step('user-profile relation does not exist', async function () { + await db.context(async (dbCtx) => { + const { profiles } = await db.profilesScopesByIdentifier(dbCtx, identifier); + const exists = profiles.includes(profile); + assert.strictEqual(exists, false); + }); + }); + step('create user-profile relation', async function () { + await db.context(async (dbCtx) => { + await db.profileIdentifierInsert(dbCtx, profile, identifier); + }); + }); + step('profile is valid', async function () { + await db.context(async (dbCtx) => { + const isValid = await db.profileIsValid(dbCtx, profile); + assert.strictEqual(isValid, true); + }); + }); + step('user-profile relation does exist', async function () { + await db.context(async (dbCtx) => { + const { profiles } = await db.profilesScopesByIdentifier(dbCtx, identifier); + const exists = profiles.includes(profile); + assert.strictEqual(exists, true); + }); + }); + step('create scope', async function () { + await db.context(async (dbCtx) => { + await db.scopeUpsert(dbCtx, 'new_scope', '', 'Allows something to happen.'); + }); + }); + step('create and delete scope', async function () { + await db.context(async (dbCtx) => { + await db.scopeUpsert(dbCtx, 'sacrificial', 'No App', 'Exists to be destroyed.', true); + const result = await db.scopeDelete(dbCtx, 'sacrificial'); + assert.strictEqual(result, true); + }); + }); + step('do not delete in-use scope', async function () { + await db.context(async (dbCtx) => { + const result = await db.scopeDelete(dbCtx, 'profile'); + assert.strictEqual(result, false); + }); + }); + step('ignore delete of non-existent scope', async function () { + await db.context(async (dbCtx) => { + await db.scopeDelete(dbCtx, 'non-existent'); + }); + }); + step('assign scope to profile', async function () { + const scope = 'new_scope'; + await db.context(async (dbCtx) => { + await db.profileScopeInsert(dbCtx, profile, scope); + const { scopeIndex, profileScopes, profiles } = await db.profilesScopesByIdentifier(dbCtx, identifier); + const scopeExistsInProfile = scope in profileScopes[profile]; + const profileExistsInScope = scopeIndex[scope].profiles.includes(profile); + const profileExists = profiles.includes(profile); + assert.strictEqual(scopeExistsInProfile, true); + assert.strictEqual(profileExistsInScope, true); + assert.strictEqual(profileExists, true); + }); + }); + step('update scope', async function () { + await db.context(async (dbCtx) => { + await db.scopeUpsert(dbCtx, 'new_scope', 'Application', 'Updated description.'); + }); + }); + step('re-assigning scope to profile is ignored', async function () { + const scope = 'new_scope'; + await db.context(async (dbCtx) => { + await db.profileScopeInsert(dbCtx, profile, scope); + const { scopeIndex, profileScopes } = await db.profilesScopesByIdentifier(dbCtx, identifier); + const scopeExistsInProfile = scope in profileScopes[profile]; + const profileExistsInScope = scopeIndex[scope].profiles.includes(profile); + assert.strictEqual(scopeExistsInProfile, true); + assert.strictEqual(profileExistsInScope, true); + }); + }); + step('clear all scopes for a profile', async function () { + const scopes = []; + await db.context(async (dbCtx) => { + await db.profileScopesSetAll(dbCtx, profile, scopes); + const { profileScopes } = await db.profilesScopesByIdentifier(dbCtx, identifier); + const exists = profile in profileScopes; + assert(exists); + const numScopes = Object.keys(profileScopes[profile]).length; + assert.strictEqual(numScopes, 0); + }); + }); + step('set multiple scopes for a profile', async function () { + const scopes = ['profile', 'email', 'create']; + await db.context(async (dbCtx) => { + await db.profileScopesSetAll(dbCtx, profile, scopes); + const { profileScopes } = await db.profilesScopesByIdentifier(dbCtx, identifier); + assert.strictEqual(Object.keys(profileScopes[profile]).length, scopes.length); + }); + }); + step('garbage-collect client scopes', async function () { + await db.context(async (dbCtx) => { + await db.scopeUpsert(dbCtx, 'extra_scope', 'useless', 'useless'); + const result = await db.scopeCleanup(dbCtx, 0); + assert(result); + }); + }); + step('too-soon garbage-collect skips', async function () { + await db.context(async (dbCtx) => { + const result = await db.scopeCleanup(dbCtx, 86400000); + assert.strictEqual(result, undefined); + }); + }); + }); // Users and Profiles and Scopes + + describe('Token', function () { + let created, codeId, profileCodeId, ticketCodeId, scopes, clientId, lifespanSeconds, resource; + beforeEach(function () { + created = new Date(); + codeId = '907a95fc-384b-11ec-a541-0025905f714a'; + profileCodeId = '93d6314a-384e-11ec-94e4-0025905f714a'; + ticketCodeId = 'bc5c39a8-5ca0-11ed-94cd-0025905f714a'; + clientId = 'https://app.example.com/'; + scopes = ['create', 'email', 'profile']; + lifespanSeconds = 600; + resource = 'https://example.com/profile/feed'; + }); + step('redeems code for token', async function () { + await db.context(async (dbCtx) => { + lifespanSeconds = null; + const result = await db.redeemCode(dbCtx, { + created, + codeId, + isToken: true, + clientId, + profile, + identifier, + scopes, + lifespanSeconds, + refreshLifespanSeconds: null, + profileData: null, + }); + assert.strictEqual(result, true); + const t = await db.tokenGetByCodeId(dbCtx, codeId); + assert(t); + db._validateToken(t); + }); + }); + step('revokes token', async function () { + await db.context(async (dbCtx) => { + await db.tokenRevokeByCodeId(dbCtx, codeId, identifier); + const t = await db.tokenGetByCodeId(dbCtx, codeId); + assert.strictEqual(t.isRevoked, true); + }); + }); + step('redeems code for profile', async function () { + await db.context(async (dbCtx) => { + await db.redeemCode(dbCtx, { + created, + codeId: profileCodeId, + isToken: false, + clientId, + profile, + identifier, + lifespanSeconds, + scopes, + }); + const t = await db.tokenGetByCodeId(dbCtx, codeId); + assert(t); + db._validateToken(t); + }); + }); + step('redeems ticket', async function () { + await db.context(async (dbCtx) => { + await db.redeemCode(dbCtx, { + created, + codeId: ticketCodeId, + isToken: true, + clientId, + resource, + profile, + identifier, + scopes, + }); + }); + }); + step('gets tokens', async function () { + await db.context(async (dbCtx) => { + const tokens = await db.tokensGetByIdentifier(dbCtx, identifier); + assert(tokens.length); + }); + }); + step('revokes multiply-redeemed code', async function () { + await db.context(async (dbCtx) => { + const result = await db.redeemCode(dbCtx, { + created, + codeId, + isToken: false, + clientId, + profile, + identifier, + scopes, + }); + assert.strictEqual(result, false); + const t = await db.tokenGetByCodeId(dbCtx, codeId); + assert.strictEqual(t.isRevoked, true); + }); + }); + step('garbage-collect tokens', async function () { + await db.context(async (dbCtx) => { + const result = await db.tokenCleanup(dbCtx, -86400, 0); + assert(result); + }); + }); + step('too-soon garbage-collect skips', async function () { + await db.context(async (dbCtx) => { + const result = await db.tokenCleanup(dbCtx, 0, 86400000); + assert.strictEqual(result, undefined); + }); + }); + step('garbage collection is recorded', async function () { + await db.context(async (dbCtx) => { + const result = await db.almanacGetAll(dbCtx); + assert(result?.length); + }); + }); + }); // Token + + describe('Refreshable Token', function () { + let created, codeId, scopes, clientId, profileData, lifespanSeconds, refreshLifespanSeconds, removeScopes; + beforeEach(function () { + created = new Date(); + codeId = '20ff1c5e-24d9-11ed-83b9-0025905f714a'; + scopes = ['profile', 'email', 'create', 'fancy:scope']; + clientId = 'https://app.example.com/'; + lifespanSeconds = 86400; + refreshLifespanSeconds = 172800; + profileData = { + url: 'https://profile.example.com/', + name: 'Namey McUser', + photo: 'https://profile.example.com/picture.jpg', + email: 'usey@example.com', + }; + removeScopes = []; + }); + step('redeems code for refreshable token', async function () { + await db.context(async (dbCtx) => { + const result = await db.redeemCode(dbCtx, { + created, + codeId, + isToken: true, + clientId, + profile, + identifier, + scopes, + lifespanSeconds, + refreshLifespanSeconds, + profileData, + }); + assert.strictEqual(result, true); + const t = await db.tokenGetByCodeId(dbCtx, codeId); + assert(t); + db._validateToken(t); + const requestedScopesSet = new Set(scopes); + const tokenScopesSet = new Set(t.scopes); + for (const s of tokenScopesSet) { + if (requestedScopesSet.has(s)) { + requestedScopesSet.delete(s); + } else { + requestedScopesSet.add(s); + } + } + assert(!requestedScopesSet.size, [...requestedScopesSet].toString()); + }); + }); + step('refreshes token', async function () { + await db.context(async (dbCtx) => { + const result = await db.refreshCode(dbCtx, codeId, new Date(), removeScopes); + assert(result); + assert(result.expires); + assert(result.refreshExpires); + assert(!result.scopes); + }); + }); + step('refreshes token and reduces scope', async function () { + await db.context(async (dbCtx) => { + removeScopes = ['create', 'fancy:scope']; + const result = await db.refreshCode(dbCtx, codeId, new Date(), removeScopes); + assert(result); + assert(result.scopes); + const t = await db.tokenGetByCodeId(dbCtx, codeId); + const remainingScopesSet = new Set(scopes); + removeScopes.forEach((s) => remainingScopesSet.delete(s)); + const tokenScopesSet = new Set(t.scopes); + for (const s of tokenScopesSet) { + if (remainingScopesSet.has(s)) { + remainingScopesSet.delete(s); + } else { + remainingScopesSet.add(s); + } + } + assert(!remainingScopesSet.size, [...remainingScopesSet].toString()); + + }); + }); + step('revokes token refreshability', async function () { + await db.context(async (dbCtx) => { + await db.tokenRefreshRevokeByCodeId(dbCtx, codeId); + const t = await db.tokenGetByCodeId(dbCtx, codeId); + assert(!t.refreshExpires); + }); + }); + step('token not refreshable', async function () { + await db.context(async (dbCtx) => { + const result = await db.refreshCode(dbCtx, codeId, new Date(), removeScopes); + assert(!result); + }); + }); + }); // Refreshable Token + + }); // specific implementation + }); // foreach + +}); // Database Integration diff --git a/test/src/db/postgres.js b/test/src/db/postgres.js new file mode 100644 index 0000000..02f8986 --- /dev/null +++ b/test/src/db/postgres.js @@ -0,0 +1,953 @@ +/* eslint-disable sonarjs/no-identical-functions */ +/* eslint-env mocha */ +/* eslint-disable sonarjs/no-duplicate-string */ +'use strict'; + +/* This provides implementation coverage, stubbing pg-promise. */ + +const assert = require('assert'); +const sinon = require('sinon'); // eslint-disable-line node/no-unpublished-require +const StubLogger = require('../../stub-logger'); +const StubDatabase = require('../../stub-db'); +const DB = require('../../../src/db/postgres'); +const DBErrors = require('../../../src/db/errors'); +const common = require('../../../src/common'); +const Config = require('../../../config'); + +const expectedException = new Error('oh no'); + +describe('DatabasePostgres', function () { + let db, logger, options, pgpStub; + let dbCtx; + before(function () { + pgpStub = () => { + const stub = { + result: () => ({ rows: [] }), + all: common.nop, + get: common.nop, + run: common.nop, + one: common.nop, + manyOrNone: common.nop, + oneOrNone: common.nop, + query: common.nop, + batch: common.nop, + multiResult: common.nop, + connect: common.nop, + }; + stub.tx = (fn) => fn(stub); + stub.txIf = (fn) => fn(stub); + stub.task = (fn) => fn(stub); + return stub; + }; + pgpStub.utils = { + enumSql: () => ({}), + }; + pgpStub.QueryFile = class {}; + pgpStub.end = common.nop; + }); + beforeEach(function () { + logger = new StubLogger(); + logger._reset(); + options = new Config('test'); + db = new DB(logger, options, pgpStub); + dbCtx = db.db; + }); + afterEach(function () { + sinon.restore(); + }); + + it('covers no query logging', function () { + delete options.db.queryLogLevel; + db = new DB(logger, options, pgpStub); + }); + + + // Ensure all interface methods are implemented + describe('Implementation', function () { + it('implements interface', async function () { + const stubDb = new StubDatabase(); + const results = await Promise.allSettled(stubDb._implementation.map(async (fn) => { + try { + // eslint-disable-next-line security/detect-object-injection + await db[fn](db.db); + } catch (e) { + assert(!(e instanceof DBErrors.NotImplemented), `${fn} not implemented`); + } + })); + const failures = results.filter((x) => x.status === 'rejected'); + assert(!failures.length, failures.map((x) => { + x = x.reason.toString(); + return x.slice(x.indexOf(': ')); + })); + }); + }); // Implementation + + describe('pgpInitOptions', function () { + describe('error', function () { + it('covers', function () { + const err = {}; + const event = {}; + db.pgpInitOptions.error(err, event); + assert(db.logger.error.called); + }); + }); // error + describe('query', function () { + it('covers', function () { + const event = {}; + db.pgpInitOptions.query(event); + assert(db.logger.debug.called); + }); + }); // query + describe('receive', function () { + it('covers', function () { + const data = [ + { + column_one: 'one', // eslint-disable-line camelcase + column_two: 2, // eslint-disable-line camelcase + }, + { + column_one: 'foo', // eslint-disable-line camelcase + column_two: 4, // eslint-disable-line camelcase + }, + ]; + const result = {}; + const event = {}; + const expectedData = [ + { + columnOne: 'one', + columnTwo: 2, + }, + { + columnOne: 'foo', + columnTwo: 4, + }, + ]; + db.pgpInitOptions.receive(data, result, event) + assert(db.logger.debug.called); + assert.deepStrictEqual(data, expectedData); + }); + it('covers no query logging', function () { + delete options.db.queryLogLevel; + db = new DB(logger, options, pgpStub); + const data = [ + { + column_one: 'one', // eslint-disable-line camelcase + column_two: 2, // eslint-disable-line camelcase + }, + { + column_one: 'foo', // eslint-disable-line camelcase + column_two: 4, // eslint-disable-line camelcase + }, + ]; + const result = {}; + const event = {}; + const expectedData = [ + { + columnOne: 'one', + columnTwo: 2, + }, + { + columnOne: 'foo', + columnTwo: 4, + }, + ]; + db.pgpInitOptions.receive(data, result, event) + assert(db.logger.debug.called); + assert.deepStrictEqual(data, expectedData); + }); + + }); // receive + }); // pgpInitOptions + + describe('_initTables', function () { + beforeEach(function () { + sinon.stub(db.db, 'oneOrNone'); + sinon.stub(db.db, 'multiResult'); + sinon.stub(db, '_currentSchema'); + }); + + it('covers apply', async function() { + db.db.oneOrNone.onCall(0).resolves(null).onCall(1).resolves({}); + db._currentSchema.resolves({ major: 0, minor: 0, patch: 0 }); + await db._initTables(); + }); + it('covers exists', async function() { + db.db.oneOrNone.resolves({}); + db._currentSchema.resolves(db.schemaVersionsSupported.max); + await db._initTables(); + }); + }); // _initTables + + describe('initialize', function () { + after(function () { + delete db.listener; + }); + it('passes supported version', async function () { + const version = { major: 1, minor: 0, patch: 0 }; + sinon.stub(db.db, 'one').resolves(version); + await db.initialize(false); + }); + it('fails low version', async function () { + const version = { major: 0, minor: 0, patch: 0 }; + sinon.stub(db.db, 'one').resolves(version); + await assert.rejects(() => db.initialize(false), DBErrors.MigrationNeeded); + }); + it('fails high version', async function () { + const version = { major: 100, minor: 100, patch: 100 }; + sinon.stub(db.db, 'one').resolves(version); + await assert.rejects(() => db.initialize(false)); + }); + it('covers migration', async function() { + sinon.stub(db.db, 'oneOrNone').resolves({}); + sinon.stub(db.db, 'multiResult'); + sinon.stub(db, '_currentSchema').resolves(db.schemaVersionsSupported.max); + sinon.stub(db.db, 'one').resolves(db.schemaVersionsSupported.max); + await db.initialize(); + }); + it('covers listener', async function() { + db.listener = { + start: sinon.stub(), + }; + const version = { major: 1, minor: 0, patch: 0 }; + sinon.stub(db.db, 'one').resolves(version); + await db.initialize(false); + assert(db.listener.start.called); + }); + }); // initialize + + describe('healthCheck', function () { + beforeEach(function () { + sinon.stub(db.db, 'connect').resolves({ + done: () => {}, + client: { + serverVersion: '0.0', + }, + }); + }); + it('covers', async function () { + const result = await db.healthCheck(); + assert.deepStrictEqual(result, { serverVersion: '0.0' }); + }); + }); // healthCheck + + describe('_queryFileHelper', function () { + it('covers success', function () { + const _queryFile = db._queryFileHelper(pgpStub); + _queryFile(); + }); + it('covers failure', function () { + pgpStub.QueryFile = class { + constructor() { + this.error = expectedException; + } + }; + const _queryFile = db._queryFileHelper(pgpStub); + assert.throws(() => _queryFile(), expectedException); + }); + }); // _queryFileHelper + + describe('_closeConnection', function () { + after(function () { + delete db.listener; + }); + it('success', async function () { + sinon.stub(db._pgp, 'end'); + await db._closeConnection(); + assert(db._pgp.end.called); + }); + it('failure', async function () { + sinon.stub(db._pgp, 'end').throws(expectedException); + await assert.rejects(() => db._closeConnection(), expectedException); + }); + it('covers listener', async function () { + db.listener = { + stop: sinon.stub(), + }; + sinon.stub(db._pgp, 'end'); + await db._closeConnection(); + assert(db._pgp.end.called); + }); + }); // _closeConnection + + describe('_purgeTables', function () { + it('covers not really', async function () { + sinon.stub(db.db, 'tx'); + await db._purgeTables(false); + assert(!db.db.tx.called); + }); + it('success', async function () { + sinon.stub(db.db, 'batch'); + await db._purgeTables(true); + assert(db.db.batch.called); + }); + it('failure', async function () { + sinon.stub(db.db, 'tx').rejects(expectedException) + await assert.rejects(() => db._purgeTables(true), expectedException); + }); + }); // _purgeTables + + describe('context', function () { + it('covers', async function () { + await db.context(common.nop); + }); + }); // context + + describe('transaction', function () { + it('covers', async function () { + await db.transaction(db.db, common.nop); + }); + }); // transaction + + describe('almanacGetAll', function () { + beforeEach(function () { + sinon.stub(db.db, 'manyOrNone'); + }); + it('success', async function () { + const expected = [{ event: 'someEvent', date: new Date() }]; + db.db.manyOrNone.resolves(expected); + const result = await db.almanacGetAll(dbCtx); + assert.deepStrictEqual(result, expected); + }); + it('failure', async function () { + db.db.manyOrNone.rejects(expectedException); + await assert.rejects(() => db.almanacGetAll(dbCtx), expectedException); + }); + }); // almanacGetAll + + describe('authenticationSuccess', function () { + let identifier; + beforeEach(function () { + identifier = 'username'; + }); + it('success', async function () { + const dbResult = { + rowCount: 1, + rows: undefined, + duration: 22, + }; + sinon.stub(db.db, 'result').resolves(dbResult); + await db.authenticationSuccess(dbCtx, identifier); + }); + it('failure', async function() { + const dbResult = { + rowCount: 0, + rows: undefined, + duration: 22, + }; + sinon.stub(db.db, 'result').resolves(dbResult); + await assert.rejects(() => db.authenticationSuccess(dbCtx, identifier), DBErrors.UnexpectedResult); + }); + }); // authenticationSuccess + + describe('authenticationGet', function () { + let identifier, credential; + beforeEach(function () { + identifier = 'username'; + credential = '$z$foo'; + }); + it('success', async function () { + const dbResult = { identifier, credential }; + sinon.stub(db.db, 'oneOrNone').resolves(dbResult); + const result = await db.authenticationGet(dbCtx, identifier); + assert.deepStrictEqual(result, dbResult); + }); + it('failure', async function() { + sinon.stub(db.db, 'oneOrNone').rejects(expectedException); + await assert.rejects(() => db.authenticationGet(dbCtx, identifier, credential), expectedException); + }); + }); // authenticationGet + + describe('authenticationUpsert', function () { + let identifier, credential; + beforeEach(function () { + identifier = 'username'; + credential = '$z$foo'; + }); + it('success', async function () { + const dbResult = { + rowCount: 1, + rows: undefined, + duration: 22, + }; + sinon.stub(db.db, 'result').resolves(dbResult); + await db.authenticationUpsert(dbCtx, identifier, credential); + }); + it('failure', async function() { + credential = undefined; + const dbResult = { + rowCount: 0, + rows: undefined, + duration: 22, + }; + sinon.stub(db.db, 'result').resolves(dbResult); + await assert.rejects(() => db.authenticationUpsert(dbCtx, identifier, credential), DBErrors.UnexpectedResult); + }); + }); // authenticationUpsert + + describe('profileIdentifierInsert', function () { + let profile, identifier; + beforeEach(function () { + profile = 'https://profile.example.com/'; + identifier = 'username'; + }); + it('success', async function () { + const dbResult = { + rowCount: 1, + }; + sinon.stub(db.db, 'result').resolves(dbResult); + await db.profileIdentifierInsert(dbCtx, profile, identifier); + }); + it('failure', async function () { + const dbResult = { + rowCount: 0, + }; + sinon.stub(db.db, 'result').resolves(dbResult); + await assert.rejects(() => db.profileIdentifierInsert(dbCtx, profile, identifier), DBErrors.UnexpectedResult); + }); + }); // profileIdentifierInsert + + describe('profileIsValid', function () { + let profile; + beforeEach(function () { + profile = 'https://profile.exmaple.com'; + }); + it('valid profile', async function () { + sinon.stub(db.db, 'oneOrNone').resolves({ profile }); + const result = await db.profileIsValid(dbCtx, profile); + assert.strictEqual(result, true); + }); + it('invalid profile', async function () { + sinon.stub(db.db, 'oneOrNone').resolves(); + const result = await db.profileIsValid(dbCtx, profile); + assert.strictEqual(result, false); + }); + it('failure', async function () { + sinon.stub(db.db, 'oneOrNone').rejects(expectedException); + await assert.rejects(() => db.profileIsValid(dbCtx, profile), expectedException); + }); + }); // profileIsValid + + describe('tokenGetByCodeId', function () { + let codeId; + beforeEach(function () { + sinon.stub(db.db, 'oneOrNone'); + codeId = 'xxxxxxxx'; + }); + it('success', async function() { + const dbResult = { + token: '', + codeId, + created: new Date(), + expires: new Date(Date.now() + 24 * 60 * 60 * 1000), + }; + db.db.oneOrNone.resolves(dbResult); + const result = await db.tokenGetByCodeId(dbCtx, codeId); + assert.deepStrictEqual(result, dbResult); + }); + it('failure', async function () { + db.db.oneOrNone.rejects(expectedException); + await assert.rejects(() => db.tokenGetByCodeId(dbCtx, codeId), expectedException); + }); + }); // tokenGetByCodeId + + describe('profileScopeInsert', function () { + let profile, scope; + beforeEach(function () { + profile = 'https://profile.example.com/'; + scope = 'scope'; + }); + it('success', async function () { + const dbResult = { + rowCount: 1, + }; + sinon.stub(db.db, 'result').resolves(dbResult); + await db.profileScopeInsert(dbCtx, profile, scope); + }); + it('failure', async function () { + sinon.stub(db.db, 'result').rejects(expectedException); + await assert.rejects(() => db.profileScopeInsert(dbCtx, profile, scope), expectedException); + }); + it('failure', async function () { + const dbResult = { + rowCount: 2, + }; + sinon.stub(db.db, 'result').resolves(dbResult); + await assert.rejects(() => db.profileScopeInsert(dbCtx, profile, scope), DBErrors.UnexpectedResult); + }); + }); // profileScopeInsert + + describe('profileScopesSetAll', function () { + let profile, scopes; + beforeEach(function () { + profile = 'https://example.com/'; + scopes = []; + sinon.stub(db.db, 'result'); + }); + it('success, no scopes', async function () { + db.db.result.resolves(); + await db.profileScopesSetAll(dbCtx, profile, scopes); + }); + it('success, scopes', async function () { + db.db.result.resolves(); + scopes.push('profile', 'email', 'create'); + await db.profileScopesSetAll(dbCtx, profile, scopes); + }); + it('failure', async function () { + db.db.result.rejects(expectedException); + await assert.rejects(() => db.profileScopesSetAll(dbCtx, profile, scopes), expectedException); + }); + }); // profileScopesSetAll + + describe('profilesScopesByIdentifier', function () { + let identifier, scopeIndex, profileScopes, profiles; + beforeEach(function () { + identifier = 'identifier'; + scopeIndex = { + 'scope': { + description: 'A scope.', + application: 'test', + isPermanent: false, + isManuallyAdded: true, + profiles: ['https://first.example.com/', 'https://second.example.com/'], + }, + 'another_scope': { + description: 'Another scope.', + application: 'another test', + isPermanent: true, + isManuallyAdded: false, + profiles: ['https://first.example.com/'], + }, + 'no_app_scope': { + description: 'A scope without application.', + application: '', + isPermanent: false, + isManuallyAdded: false, + profiles: ['https://second.example.com/'], + }, + 'no_profile_scope': { + description: 'A scope without profiles.', + application: 'test', + isPermanent: false, + isManuallyAdded: false, + profiles: [], + }, + }; + profileScopes = { + 'https://first.example.com/': { + 'scope': scopeIndex['scope'], + 'another_scope': scopeIndex['another_scope'], + }, + 'https://second.example.com/': { + 'scope': scopeIndex['scope'], + 'no_app_scope': scopeIndex['no_app_scope'], + }, + 'https://scopeless.example.com/': {}, + }; + profiles = [ + 'https://first.example.com/', + 'https://second.example.com/', + 'https://scopeless.example.com/', + ]; + }); + it('success', async function () { + const dbResult = [ + { profile: 'https://first.example.com/', scope: 'scope', application: 'test', description: 'A scope.', isPermanent: false, isManuallyAdded: true }, + { profile: 'https://first.example.com/', scope: 'another_scope', application: 'another test', description: 'Another scope.', isPermanent: true, isManuallyAdded: false }, + { profile: 'https://second.example.com/', scope: 'no_app_scope', application: '', description: 'A scope without application.', isPermanent: false, isManuallyAdded: false }, + { profile: 'https://second.example.com/', scope: 'scope', application: 'test', description: 'A scope.', isPermanent: false, isManuallyAdded: true }, + { profile: null, scope: 'no_profile_scope', application: 'test', description: 'A scope without profiles.', isPermanent: false, isManuallyAdded: false }, + { profile: 'https://scopeless.example.com/', scope: null, application: null, description: null, isPermanent: null, isManuallyAdded: null }, + ]; + const expected = { + scopeIndex, + profileScopes, + profiles, + }; + sinon.stub(db.db, 'manyOrNone').resolves(dbResult); + const result = await db.profilesScopesByIdentifier(dbCtx, identifier); + assert.deepStrictEqual(result, expected); + }); + it('failure', async function () { + sinon.stub(db.db, 'manyOrNone').rejects(expectedException); + await assert.rejects(() => db.profilesScopesByIdentifier(dbCtx, identifier), expectedException); + }); + }); // profilesScopesByIdentifier + + describe('redeemCode', function () { + let codeId, isToken, clientId, profile, identifier, scopes, lifespanSeconds, refreshId, profileData; + beforeEach(function () { + codeId = '41945b8e-3e82-11ec-82d1-0025905f714a'; + isToken = false; + clientId = 'https://app.example.com/'; + profile = 'https://profile.example.com/'; + identifier = 'username'; + scopes = ['scope1', 'scope2']; + lifespanSeconds = 600; + refreshId = undefined; + profileData = undefined; + }); + it('success redeem', async function () { + const dbResult = { + rowCount: 1, + rows: [{ isRevoked: false }], + duration: 22, + }; + const dbResultScopes = { + rowCount: scopes.length, + rows: [], + duration: 22, + }; + sinon.stub(db.db, 'result').resolves(dbResult).onCall(2).resolves(dbResultScopes); + const result = await db.redeemCode(dbCtx, { codeId, isToken, clientId, profile, identifier, scopes, lifespanSeconds, refreshId, profileData }); + assert.strictEqual(result, true); + }); + it('success redeem, no scopes', async function () { + scopes = []; + const dbResult = { + rowCount: 1, + rows: [{ isRevoked: false }], + duration: 22, + }; + const dbResultScopes = { + rowCount: scopes.length, + rows: [], + duration: 22, + }; + sinon.stub(db.db, 'result').resolves(dbResult).onCall(1).resolves(dbResultScopes); + const result = await db.redeemCode(dbCtx, { codeId, isToken, clientId, profile, identifier, scopes, lifespanSeconds, refreshId, profileData }); + assert.strictEqual(result, true); + }); + it('success revoke', async function () { + const dbResult = { + rowCount: 1, + rows: [{ isRevoked: true }], + duration: 22, + }; + sinon.stub(db.db, 'result').resolves(dbResult); + const result = await db.redeemCode(dbCtx, { codeId, isToken, clientId, profile, identifier, scopes, lifespanSeconds, refreshId, profileData }); + assert.strictEqual(result, false); + }); + it('failure', async function() { + const dbResult = { + rowCount: 0, + rows: undefined, + duration: 22, + }; + sinon.stub(db.db, 'result').resolves(dbResult); + await assert.rejects(() => db.redeemCode(dbCtx, { codeId, clientId, profile, identifier, scopes, lifespanSeconds, refreshId, profileData }), DBErrors.UnexpectedResult); + }); + it('failure token scopes', async function () { + const dbResult = { + rowCount: 1, + rows: [{ isRevoked: false }], + duration: 22, + }; + const dbResultNone = { + rowCount: 0, + rows: undefined, + duration: 22, + }; + sinon.stub(db.db, 'result').resolves(dbResult).onCall(2).resolves(dbResultNone); + await assert.rejects(() => db.redeemCode(dbCtx, { codeId, clientId, profile, identifier, scopes, lifespanSeconds, refreshId, profileData }), DBErrors.UnexpectedResult); + }); + }); // redeemCode + + describe('refreshCode', function () { + let codeId, now, removeScopes; + beforeEach(function () { + codeId = '41945b8e-3e82-11ec-82d1-0025905f714a'; + now = new Date(); + removeScopes = []; + sinon.stub(db.db, 'result').resolves({ rowCount: removeScopes.length }); + sinon.stub(db.db, 'oneOrNone'); + }); + it('success', async function () { + db.db.oneOrNone.resolves({ + expires: now, + refreshExpires: now, + }); + const result = await db.refreshCode(dbCtx, codeId, now, removeScopes); + assert(db.db.result.notCalled); + assert(result); + assert(result.expires); + assert(result.refreshExpires); + assert(!result.scopes); + }); + it('success with scope reduction', async function () { + removeScopes = ['create']; + db.db.oneOrNone.resolves({ + expires: now, + refreshExpires: now, + scopes: [], + }); + db.db.result.resolves({ rowCount: removeScopes.length }); + const result = await db.refreshCode(dbCtx, codeId, now, removeScopes); + assert(result); + assert(result.expires); + assert(result.refreshExpires); + assert(!result.scopes.includes('create')); + }); + it('failure', async function () { + db.db.oneOrNone.rejects(expectedException); + await assert.rejects(async () => db.refreshCode(dbCtx, codeId, now, removeScopes), expectedException); + }); + it('failure with scope reduction', async function () { + removeScopes = ['create']; + db.db.oneOrNone.resolves({}); + db.db.result.resolves({ rowCount: 0 }); + await assert.rejects(async () => db.refreshCode(dbCtx, codeId, now, removeScopes), DBErrors.UnexpectedResult); + }); + }); // refreshCode + + describe('resourceGet', function () { + let identifier; + beforeEach(function () { + sinon.stub(db.db, 'oneOrNone'); + identifier = '05b81112-b224-11ec-a9c6-0025905f714a'; + }); + it('success', async function () { + const dbResult = { + identifier, + secret: 'secrety', + }; + db.db.oneOrNone.resolves(dbResult); + const result = await db.resourceGet(dbCtx, identifier); + assert.deepStrictEqual(result, dbResult); + }); + it('failure', async function() { + db.db.oneOrNone.rejects(expectedException); + await assert.rejects(() => db.resourceGet(dbCtx, identifier), expectedException); + }); + }); // resourceGet + + describe('resourceUpsert', function () { + let resourceId, secret, description; + beforeEach(function () { + resourceId = '98b8d9ec-f8e2-11ec-aceb-0025905f714a'; + secret = 'supersecret'; + description = 'some service'; + }); + it('success', async function () { + const dbResult = { + rowCount: 1, + rows: [], + duration: 22, + }; + sinon.stub(db.db, 'result').resolves(dbResult); + await db.resourceUpsert(dbCtx, resourceId, secret, description) + }); + it('failure', async function () { + const dbResult = { + rowCount: 0, + rows: undefined, + duration: 22, + }; + sinon.stub(db.db, 'result').resolves(dbResult); + await assert.rejects(() => db.resourceUpsert(dbCtx, resourceId, undefined, description), DBErrors.UnexpectedResult); + }); + }); // resourceUpsert + + describe('scopeCleanup', function () { + let atLeastMsSinceLast; + beforeEach(function () { + sinon.stub(db.db, 'result'); + sinon.stub(db.db, 'oneOrNone'); + atLeastMsSinceLast = 86400000; + }); + it('success, empty almanac', async function () { + const cleaned = 10; + db.db.result + .onFirstCall().resolves({ rowCount: cleaned }) + .onSecondCall().resolves({ rowCount: 1 }); + const result = await db.scopeCleanup(dbCtx, atLeastMsSinceLast); + assert.strictEqual(result, cleaned); + }); + it('success, too soon', async function () { + db.db.oneOrNone.resolves({ date: new Date(Date.now() - 4000) }); + const result = await db.scopeCleanup(dbCtx, atLeastMsSinceLast); + assert.strictEqual(result, undefined); + assert(db.db.result.notCalled); + }); + it('failure', async function () { + db.db.result.resolves({ rowCount: 0 }); + await assert.rejects(async () => db.scopeCleanup(dbCtx, atLeastMsSinceLast), DBErrors.UnexpectedResult); + }); + }); // scopeCleanup + + describe('scopeDelete', function () { + let scope; + beforeEach(function () { + scope = 'somescope'; + }); + it('success', async function () { + const dbResult = { + rowCount: 1, + rows: undefined, + duration: 22, + }; + sinon.stub(db.db, 'one').resolves({ inUse: false }); + sinon.stub(db.db, 'result').resolves(dbResult); + const result = await db.scopeDelete(dbCtx, scope); + assert(db.db.result.called); + assert.strictEqual(result, true); + }); + it('success, no scope', async function () { + const dbResult = { + rowCount: 0, + rows: undefined, + duration: 22, + }; + sinon.stub(db.db, 'one').resolves({ inUse: false }); + sinon.stub(db.db, 'result').resolves(dbResult); + const result = await db.scopeDelete(dbCtx, scope); + assert(db.db.result.called); + assert.strictEqual(result, true); + }); + it('scope in use', async function () { + const dbResult = { + rowCount: 0, + rows: undefined, + duration: 22, + }; + sinon.stub(db.db, 'one').resolves({ inUse: true }); + sinon.stub(db.db, 'result').resolves(dbResult); + const result = await db.scopeDelete(dbCtx, scope); + assert(db.db.result.notCalled); + assert.strictEqual(result, false); + }); + it('failure', async function () { + sinon.stub(db.db, 'one').rejects(expectedException); + await assert.rejects(() => db.scopeDelete(dbCtx, scope), expectedException); + }); + }); // scopeDelete + + describe('scopeUpsert', function () { + let scope, description; + beforeEach(function () { + scope = 'username'; + description = '$z$foo'; + }); + it('success', async function () { + const dbResult = { + rowCount: 1, + rows: undefined, + duration: 22, + }; + sinon.stub(db.db, 'result').resolves(dbResult); + await db.scopeUpsert(dbCtx, scope, description); + }); + it('failure', async function() { + scope = undefined; + const dbResult = { + rowCount: 0, + rows: undefined, + duration: 22, + }; + sinon.stub(db.db, 'result').resolves(dbResult); + await assert.rejects(() => db.scopeUpsert(dbCtx, scope, description), DBErrors.UnexpectedResult); + }); + }); // scopeUpsert + + describe('tokenCleanup', function () { + let codeLifespanSeconds, atLeastMsSinceLast; + beforeEach(function () { + sinon.stub(db.db, 'result'); + sinon.stub(db.db, 'oneOrNone'); + codeLifespanSeconds = 600000; + atLeastMsSinceLast = 86400000; + }); + it('success, empty almanac', async function () { + const cleaned = 10; + db.db.result + .onFirstCall().resolves({ rowCount: cleaned }) + .onSecondCall().resolves({ rowCount: 1 }); + const result = await db.tokenCleanup(dbCtx, codeLifespanSeconds, atLeastMsSinceLast); + assert.strictEqual(result, cleaned); + }); + it('success, too soon', async function () { + db.db.oneOrNone.resolves({ date: new Date(Date.now() - 4000) }); + const result = await db.tokenCleanup(dbCtx, codeLifespanSeconds, atLeastMsSinceLast); + assert.strictEqual(result, undefined); + assert(db.db.result.notCalled); + }); + it('failure', async function () { + db.db.result.resolves({ rowCount: 0 }); + await assert.rejects(() => db.tokenCleanup(dbCtx, codeLifespanSeconds, atLeastMsSinceLast), DBErrors.UnexpectedResult); + }); + }); // tokenCleanup + + describe('tokenRevokeByCodeId', function () { + let codeId; + beforeEach(function () { + codeId = 'a74bda94-3dae-11ec-8908-0025905f714a'; + }); + it('success', async function () { + const dbResult = { + rowCount: 1, + rows: undefined, + duration: 22, + }; + sinon.stub(db.db, 'result').resolves(dbResult); + await db.tokenRevokeByCodeId(dbCtx, codeId); + }); + it('failure', async function() { + const dbResult = { + rowCount: 0, + rows: undefined, + duration: 22, + }; + sinon.stub(db.db, 'result').resolves(dbResult); + await assert.rejects(() => db.tokenRevokeByCodeId(dbCtx, codeId), DBErrors.UnexpectedResult); + }); + }); // tokenRevokeByCodeId + + describe('tokenRefreshRevokeByCodeId', function () { + let codeId; + beforeEach(function () { + codeId = '279947c8-2584-11ed-a2d6-0025905f714a'; + sinon.stub(db.db, 'result'); + }); + it('success', async function () { + db.db.result.resolves({ rowCount: 1 }); + await db.tokenRefreshRevokeByCodeId(dbCtx, codeId); + }); + it('failure, no code', async function () { + db.db.result.resolves({ rowCount: 0 }); + assert.rejects(async () => db.tokenRefreshRevokeByCodeId(dbCtx, codeId), DBErrors.UnexpectedResult); + }); + it('failure', async function () { + db.db.result.rejects(expectedException); + assert.rejects(async () => db.tokenRefreshRevokeByCodeId(dbCtx, codeId), expectedException); + }); + }); // tokenRefreshRevokeByCodeId + + describe('tokensGetByIdentifier', function () { + let identifier; + beforeEach(function () { + identifier = 'identifier'; + }); + it('success', async function () { + const dbResult = [ + { + 'created': new Date(), + 'expires': new Date(), + 'isRevoked': false, + 'token': '', + 'codeId': '', + 'profile': '', + 'identifier': '', + }, + ]; + const expected = dbResult; + sinon.stub(db.db, 'manyOrNone').resolves(dbResult); + const result = await db.tokensGetByIdentifier(dbCtx, identifier); + assert.deepStrictEqual(result, expected); + }); + it('failure', async function () { + sinon.stub(db.db, 'manyOrNone').rejects(expectedException); + await assert.rejects(() => db.tokensGetByIdentifier(dbCtx, identifier), expectedException); + }); + }); // tokensGetByIdentifier + + +}); // DatabasePostgres diff --git a/test/src/db/schema-version-helper.js b/test/src/db/schema-version-helper.js new file mode 100644 index 0000000..b69735e --- /dev/null +++ b/test/src/db/schema-version-helper.js @@ -0,0 +1,159 @@ +/* eslint-env mocha */ +'use strict'; + +const assert = require('assert'); +const sinon = require('sinon'); // eslint-disable-line node/no-unpublished-require +const fs = require('fs'); +const svh = require('../../../src/db/schema-version-helper'); + +describe('SchemaVersionHelper', function () { + const isDir = { + isDirectory: () => true, + }; + const isMig = { + isFile: () => true, + }; + const notDir = { + isDirectory: () => false, + }; + afterEach(function () { + sinon.restore(); + }); + describe('schemaVersionStringToObject', function () { + it('covers', function () { + const expected = { + major: 1, + minor: 2, + patch: 3, + }; + const result = svh.schemaVersionStringToObject('1.2.3'); + assert.deepStrictEqual(result, expected); + }); + }); // schemaVersionStringToObject + + describe('schemaVersionObjectToNumber', function () { + it('covers', function () { + const expected = 1002003; + const result = svh.schemaVersionObjectToNumber({ + major: 1, + minor: 2, + patch: 3, + }); + assert.strictEqual(result, expected); + }); + }); // schemaVersionObjectToNumber + + describe('schemaVersionStringToNumber', function () { + it('covers', function () { + const expected = 1002003; + const result = svh.schemaVersionStringToNumber('1.2.3'); + assert.strictEqual(result, expected); + }); + }); // schemaVersionStringToNumber + + describe('schemaVersionStringCmp', function () { + it('sorts', function () { + const expected = ['0.0.0', '1.0.0', '1.5.3', '64.123.998', '64.123.999']; + const source = ['1.5.3', '64.123.998', '1.0.0', '64.123.999', '0.0.0']; + source.sort(svh.schemaVersionStringCmp); + assert.deepStrictEqual(source, expected); + }); + }); // schemaVersionStringCmp + + describe('isSchemaMigrationDirectory', function () { + beforeEach(function () { + sinon.stub(fs, 'statSync'); + }); + it('is directory, is file', function () { + fs.statSync.returns({ + isDirectory: () => true, + isFile: () => true, + }); + const result = svh.isSchemaMigrationDirectory('path', '1.0.0'); + assert.strictEqual(result, true); + }); + it('is directory, not file', function () { + fs.statSync.returns({ + isDirectory: () => true, + isFile: () => false, + }); + const result = svh.isSchemaMigrationDirectory('path', '1.0.0'); + assert.strictEqual(result, false); + }); + it('not directory', function () { + fs.statSync.returns({ + isDirectory: () => false, + isFile: () => { + throw new Error('unexpected invocation'); + }, + }); + const result = svh.isSchemaMigrationDirectory('path', '1.0.0'); + assert.strictEqual(result, false); + }); + it('file error', function () { + fs.statSync.returns({ + isDirectory: () => true, + isFile: () => { + throw new Error('expected error'); + }, + }); + const result = svh.isSchemaMigrationDirectory('path', '1.0.0'); + assert.strictEqual(result, false); + }); + }); // isSchemaMigrationDirectory + + describe('allSchemaVersions', function () { + beforeEach(function () { + sinon.stub(fs, 'readdirSync'); + sinon.stub(fs, 'statSync'); + sinon.stub(svh, 'isSchemaMigrationDirectory'); + }); + it('covers', function () { + const expected = ['1.0.0', '1.0.1', '1.1.0', '1.1.1', '1.1.2']; + fs.readdirSync.returns(['1.1.2', 'file.txt', '1.1.0', '1.1.1', 'init.sql', '1.0.1', '1.0.0']); + // cannot seem to stub isSchemaMigration, so here are the internals of it stubbed + let i = 0; + fs.statSync + .onCall(i++).returns(isDir).onCall(i++).returns(isMig) // '1.1.2' + .onCall(i++).returns(notDir) // 'file.txt' + .onCall(i++).returns(isDir).onCall(i++).returns(isMig) // '1.1.0' + .onCall(i++).returns(isDir).onCall(i++).returns(isMig) // '1.1.1' + .onCall(i++).returns(notDir) // 'init.sql' + .onCall(i++).returns(isDir).onCall(i++).returns(isMig) // '1.0.1' + .onCall(i++).returns(isDir).onCall(i++).returns(isMig) // '1.0.0' + const result = svh.allSchemaVersions('path'); + assert.deepStrictEqual(result, expected); + }); + }); // allSchemaVersions + + describe('unappliedSchemaVersions', function () { + let current, supported; + beforeEach(function () { + sinon.stub(fs, 'readdirSync'); + sinon.stub(fs, 'statSync'); + sinon.stub(svh, 'isSchemaMigrationDirectory'); + supported = { + min: { major: 1, minor: 0, patch: 1 }, + max: { major: 1, minor: 1, patch: 1 }, + }; + current = { major: 1, minor: 0, patch: 1 }; + }); + it('covers', function () { + const expected = ['1.1.0', '1.1.1']; + fs.readdirSync.returns(['1.1.2', 'file.txt', '1.1.0', '1.1.1', 'init.sql', '1.0.1', '1.0.0']); + // cannot seem to stub isSchemaMigration, so here are the internals of it stubbed + let i = 0; + fs.statSync + .onCall(i++).returns(isDir).onCall(i++).returns(isMig) // '1.1.2' + .onCall(i++).returns(notDir) // 'file.txt' + .onCall(i++).returns(isDir).onCall(i++).returns(isMig) // '1.1.0' + .onCall(i++).returns(isDir).onCall(i++).returns(isMig) // '1.1.1' + .onCall(i++).returns(notDir) // 'init.sql' + .onCall(i++).returns(isDir).onCall(i++).returns(isMig) // '1.0.1' + .onCall(i++).returns(isDir).onCall(i++).returns(isMig) // '1.0.0' + const result = svh.unappliedSchemaVersions('path', current, supported); + assert.deepStrictEqual(result, expected); + }); + }); // unappliedSchemaVersions + +}); \ No newline at end of file diff --git a/test/src/db/sqlite.js b/test/src/db/sqlite.js new file mode 100644 index 0000000..f693594 --- /dev/null +++ b/test/src/db/sqlite.js @@ -0,0 +1,918 @@ +/* eslint-disable sonarjs/no-identical-functions */ +/* eslint-env mocha */ +/* eslint-disable sonarjs/no-duplicate-string */ +'use strict'; + +/* This provides implementation coverage, stubbing parts of better-sqlite3. */ + +const assert = require('assert'); +const sinon = require('sinon'); // eslint-disable-line node/no-unpublished-require +const StubDatabase = require('../../stub-db'); +const StubLogger = require('../../stub-logger'); +const DB = require('../../../src/db/sqlite'); +const DBErrors = require('../../../src/db/errors'); +const common = require('../../../src/common'); +const Config = require('../../../config'); + +const expectedException = new Error('oh no'); + +describe('DatabaseSQLite', function () { + let db, options, logger, stubDb; + let dbCtx; + before(function () { + logger = new StubLogger(); + logger._reset(); + stubDb = new StubDatabase(); + }); + beforeEach(function () { + options = new Config('test'); + options.db.connectionString = 'sqlite://:memory:'; + db = new DB(logger, options); + dbCtx = db.db; + }); + afterEach(function () { + sinon.restore(); + }); + + it('covers constructor options', function () { + delete options.db.connectionString; + db = new DB(logger, options); + }); + + // Ensure all interface methods are implemented + describe('Implementation', function () { + it('implements interface', async function () { + const results = await Promise.allSettled(stubDb._implementation.map((fn) => { + try { + // eslint-disable-next-line security/detect-object-injection + db[fn](db.db); + } catch (e) { + assert(!(e instanceof DBErrors.NotImplemented), `${fn} not implemented`); + } + })); + const failures = results.filter((x) => x.status === 'rejected'); + assert(!failures.length, failures.map((x) => { + x = x.reason.toString(); + return x.slice(x.indexOf(': ')); + })); + }); + }); // Implementation + + describe('_currentSchema', function () { + it('covers', function () { + const version = { major: 1, minor: 0, patch: 0 }; + sinon.stub(db.db, 'prepare').returns({ + get: () => version, + }); + const result = db._currentSchema(); + assert.deepStrictEqual(result, version); + }); + }); // _currentSchema + + describe('_closeConnection', function () { + it('success', function () { + sinon.stub(db.db, 'close'); + db._closeConnection(); + assert(db.db.close.called); + }); + it('failure', function () { + sinon.stub(db.db, 'close').throws(expectedException); + assert.throws(() => db._closeConnection(), expectedException); + }); + }); // _closeConnection + + describe('_purgeTables', function () { + beforeEach(function () { + sinon.stub(db.db, 'prepare').returns({ + run: sinon.stub(), + }); + }); + it('covers not really', function () { + db._purgeTables(false); + assert(!db.db.prepare.called); + }); + it('success', function () { + db._purgeTables(true); + assert(db.db.prepare.called); + }); + it('failure', function () { + db.db.prepare.restore(); + sinon.stub(db.db, 'prepare').throws(expectedException); + assert.throws(() => db._purgeTables(true), expectedException); + }); + }); // _purgeTables + + describe('_optimize', function () { + beforeEach(function () { + sinon.stub(db.statement._optimize, 'all'); + sinon.stub(db.db, 'pragma'); + }); + it('covers', function () { + db.changesSinceLastOptimize = BigInt(20); + db._optimize(); + assert(db.db.pragma.called); + assert(db.statement._optimize.all.called); + assert.strictEqual(db.changesSinceLastOptimize, 0n) + }); + }); // _optimize + + describe('_updateChanges', function () { + let dbResult; + beforeEach(function () { + dbResult = { + changes: 4, + }; + sinon.stub(db, '_optimize'); + }); + it('does not optimize if not wanted', function () { + db.optimizeAfterChanges = 0n; + db._updateChanges(dbResult); + assert(db._optimize.notCalled); + }); + it('does not optimize if under threshold', function () { + db.optimizeAfterChanges = 100n; + db._updateChanges(dbResult); + assert(db._optimize.notCalled); + }); + it('optimizes over threshold', function () { + db.optimizeAfterChanges = 1n; + db._updateChanges(dbResult); + assert(db._optimize.called); + }); + }); // _updateChanges + + describe('_deOphidiate', function () { + it('covers non-array', function () { + const obj = { + 'snake_case': 1, + }; + const expected = { + snakeCase: 1, + }; + const result = DB._deOphidiate(obj); + assert.deepStrictEqual(result, expected); + }); + it('covers array', function () { + const rows = [ + { + 'snek_field': 'foo', + }, + { + 'snek_field': 'bar', + }, + ]; + const expected = [ + { + snekField: 'foo', + }, + { + snekField: 'bar', + }, + ]; + const result = DB._deOphidiate(rows); + assert.deepStrictEqual(result, expected); + }); + }); // _deOphidiate + + describe('healthCheck', function () { + it('covers', function () { + db.healthCheck(); + }); + it('covers failure', function () { + db.db = { open: false }; + assert.throws(() => db.healthCheck(), DBErrors.UnexpectedResult); + }); + }); // healthCheck + + describe('context', function () { + it('covers', function () { + db.context(common.nop); + }); + }); // context + + describe('transaction', function () { + it('covers', function () { + db.transaction(db.db, common.nop); + }); + it('covers no context', function () { + db.transaction(undefined, common.nop); + }); + }); // transaction + + describe('almanacGetAll', function () { + beforeEach(function () { + sinon.stub(db.statement.almanacGetAll, 'all'); + }); + it('success', function () { + const dbResult = [{ event: 'someEvent', epoch: '1668887796' } ]; + const expected = [{ event: 'someEvent', date: new Date('Sat Nov 19 11:56:36 AM PST 2022') }]; + db.statement.almanacGetAll.all.returns(dbResult); + const result = db.almanacGetAll(dbCtx); + assert.deepStrictEqual(result, expected); + }); + it('failure', function () { + db.statement.almanacGetAll.all.throws(expectedException); + assert.throws(() => db.almanacGetAll(dbCtx), expectedException); + }); + }); // almanacGetAll + + describe('authenticationGet', function () { + let identifier, credential; + beforeEach(function () { + identifier = 'username'; + credential = '$z$foo'; + sinon.stub(db.statement.authenticationGet, 'get'); + }); + it('success', function() { + const expected = { + identifier, + credential, + }; + db.statement.authenticationGet.get.returns(expected); + const result = db.authenticationGet(dbCtx, identifier); + assert.deepStrictEqual(result, expected); + }); + it('failure', function () { + db.statement.authenticationGet.get.throws(expectedException); + assert.throws(() => db.authenticationGet(dbCtx, identifier), expectedException); + }); + }); // authenticationGet + + describe('authenticationSuccess', function () { + let dbResult, identifier; + beforeEach(function () { + identifier = 'username'; + sinon.stub(db.statement.authenticationSuccess, 'run'); + dbResult = { + changes: 1, + lastInsertRowid: undefined, + }; + }); + it('success', function() { + db.statement.authenticationSuccess.run.returns(dbResult); + db.authenticationSuccess(dbCtx, identifier); + }); + it('failure', function () { + dbResult.changes = 0; + db.statement.authenticationSuccess.run.returns(dbResult); + assert.throws(() => db.authenticationSuccess(dbCtx, identifier), DBErrors.UnexpectedResult); + }); + }); // authenticationSuccess + + describe('authenticationUpsert', function () { + let identifier, credential; + beforeEach(function () { + identifier = 'username'; + credential = '$z$foo'; + }); + it('success', function() { + const dbResult = { + changes: 1, + lastInsertRowid: undefined, + }; + sinon.stub(db.statement.authenticationUpsert, 'run').returns(dbResult); + db.authenticationUpsert(dbCtx, identifier, credential); + }); + it('failure', function () { + const dbResult = { + changes: 0, + lastInsertRowid: undefined, + }; + sinon.stub(db.statement.authenticationUpsert, 'run').returns(dbResult); + assert.throws(() => db.authenticationUpsert(dbCtx, identifier, credential), DBErrors.UnexpectedResult); + }); + }); // authenticationUpsert + + describe('profileIdentifierInsert', function () { + let profile, identifier; + beforeEach(function () { + profile = 'https://profile.example.com/'; + identifier = 'identifier'; + sinon.stub(db.statement.profileIdentifierInsert, 'run'); + }); + it('success', function () { + db.statement.profileIdentifierInsert.run.returns({ changes: 1 }); + db.profileIdentifierInsert(dbCtx, profile, identifier); + }); + it('failure', function () { + db.statement.profileIdentifierInsert.run.returns({ changes: 0 }); + assert.throws(() => db.profileIdentifierInsert(dbCtx, profile, identifier), DBErrors.UnexpectedResult); + }); + }); // profileIdentifierInsert + + describe('profileScopeInsert', function () { + let profile, scope; + beforeEach(function () { + profile = 'https://profile.example.com/'; + scope = 'scope'; + sinon.stub(db.statement.profileScopeInsert, 'run'); + }); + it('success', function () { + db.statement.profileScopeInsert.run.returns({ changes: 1 }); + db.profileScopeInsert(dbCtx, profile, scope); + }); + it('failure', function () { + db.statement.profileScopeInsert.run.returns({ changes: 2 }); + assert.throws(() => db.profileScopeInsert(dbCtx, profile, scope), DBErrors.UnexpectedResult); + }); + }); // profileScopeInsert + + describe('profileIsValid', function () { + let profile; + beforeEach(function () { + profile = 'https://profile.exmaple.com'; + }); + it('valid profile', function () { + sinon.stub(db.statement.profileGet, 'get').returns({ profile }); + const result = db.profileIsValid(dbCtx, profile); + assert.deepStrictEqual(result, true); + }); + it('invalid profile', function () { + sinon.stub(db.statement.profileGet, 'get').returns(); + const result = db.profileIsValid(dbCtx, profile); + assert.deepStrictEqual(result, false); + }); + it('failure', function() { + sinon.stub(db.statement.profileGet, 'get').throws(expectedException); + assert.throws(() => db.profileIsValid(dbCtx, profile), expectedException); + }); + }); // profileIsValid + + describe('profilesScopesByIdentifier', function () { + let identifier, scopeIndex, profileScopes, profiles; + beforeEach(function () { + identifier = 'identifier'; + scopeIndex = { + 'scope': { + description: 'A scope.', + application: 'test', + isPermanent: false, + isManuallyAdded: false, + profiles: ['https://first.example.com/', 'https://second.example.com/'], + }, + 'another_scope': { + description: 'Another scope.', + application: 'another test', + isPermanent: false, + isManuallyAdded: false, + profiles: ['https://first.example.com/'], + }, + }; + profileScopes = { + 'https://first.example.com/': { + 'scope': scopeIndex['scope'], + 'another_scope': scopeIndex['another_scope'], + }, + 'https://second.example.com/': { + 'scope': scopeIndex['scope'], + }, + }; + profiles = ['https://first.example.com/', 'https://second.example.com/']; + }); + it('success', function () { + const dbResult = [ + { profile: 'https://first.example.com/', scope: 'scope', application: 'test', description: 'A scope.', isPermanent: false, isManuallyAdded: false }, + { profile: 'https://first.example.com/', scope: 'another_scope', application: 'another test', description: 'Another scope.', isPermanent: false, isManuallyAdded: false }, + { profile: 'https://second.example.com/', scope: 'scope', application: 'test', description: 'A scope.', isPermanent: false, isManuallyAdded: false }, + ]; + const expected = { + scopeIndex, + profileScopes, + profiles, + }; + sinon.stub(db.statement.profilesScopesByIdentifier, 'all').returns(dbResult); + const result = db.profilesScopesByIdentifier(dbCtx, identifier); + assert.deepStrictEqual(result, expected); + }); + it('failure', function() { + sinon.stub(db.statement.profilesScopesByIdentifier, 'all').throws(expectedException); + assert.throws(() => db.profilesScopesByIdentifier(dbCtx, identifier), expectedException); + }); + }); // profilesScopesByIdentifier + + describe('profileScopesSetAll', function () { + let profile, scopes; + beforeEach(function () { + profile = 'https://example.com/'; + scopes = ['scope1', 'scope2']; + sinon.stub(db.statement.profileScopesClear, 'run').returns(); + sinon.stub(db.statement.profileScopeInsert, 'run'); + }); + it('success, no scopes', function () { + db.statement.profileScopeInsert.run.returns(); + scopes = []; + db.profileScopesSetAll(dbCtx, profile, scopes); + }); + it('success, scopes', function () { + db.statement.profileScopeInsert.run.returns(); + scopes.push('profile', 'email', 'create'); + db.profileScopesSetAll(dbCtx, profile, scopes); + }); + it('failure', function () { + db.statement.profileScopeInsert.run.throws(expectedException); + assert.throws(() => db.profileScopesSetAll(dbCtx, profile, scopes), expectedException); + }); + + }); // profileScopesSetAll + + describe('redeemCode', function () { + let codeId, created, isToken, clientId, profile, identifier, scopes, lifespanSeconds, profileData; + beforeEach(function () { + codeId = '2f226616-3e79-11ec-ad0f-0025905f714a'; + isToken = false; + clientId = 'https://app.exmaple.com/'; + profile = 'https://profile.example.com/'; + identifier = 'username'; + scopes = ['scope1', 'scope2']; + lifespanSeconds = 600; + profileData = undefined; + created = new Date(); + + sinon.stub(db.statement.scopeInsert, 'run'); + sinon.stub(db.statement.tokenScopeSet, 'run'); + sinon.stub(db.statement.redeemCode, 'get'); + }); + it('success', function() { + const dbResult = { + changes: 1, + lastInsertRowid: undefined, + }; + const dbGet = { + isRevoked: false, + }; + db.statement.scopeInsert.run.returns(dbResult); + db.statement.tokenScopeSet.run.returns(dbResult); + db.statement.redeemCode.get.returns(dbGet); + profileData = { + name: 'Some Name', + }; + const result = db.redeemCode(dbCtx, { codeId, created, isToken, clientId, profile, identifier, scopes, lifespanSeconds, profileData }); + assert.strictEqual(result, true); + }); + it('success (revoked)', function() { + const dbResult = { + changes: 1, + lastInsertRowid: undefined, + }; + const dbGet = { + isRevoked: true, + }; + db.statement.scopeInsert.run.returns(dbResult); + db.statement.tokenScopeSet.run.returns(dbResult); + db.statement.redeemCode.get.returns(dbGet); + const result = db.redeemCode(dbCtx, { codeId, created, isToken, clientId, profile, identifier, scopes, lifespanSeconds, profileData }); + assert.strictEqual(result, false); + }); + it('failure', function () { + db.statement.scopeInsert.run.throws(); + db.statement.tokenScopeSet.run.throws(); + db.statement.redeemCode.get.returns(); + assert.throws(() => db.redeemCode(dbCtx, { codeId, created, isToken, clientId, profile, identifier, scopes, lifespanSeconds }), DBErrors.UnexpectedResult); + }); + }); // redeemCode + + describe('refreshCode', function () { + let refreshResponse, removeResponse, scopesResponse, codeId, refreshed, removeScopes; + beforeEach(function () { + sinon.stub(db.statement.refreshCode, 'get'); + sinon.stub(db.statement.tokenScopeRemove, 'run'); + sinon.stub(db.statement.tokenScopesGetByCodeId, 'all'); + codeId = '73db7b18-27bb-11ed-8edd-0025905f714a'; + refreshed = new Date(); + removeScopes = ['foop']; + const refreshedEpoch = Math.ceil(refreshed.getTime() / 1000); + refreshResponse = { + expires: refreshedEpoch + 86400, + refreshExpires: refreshedEpoch + 172800, + }; + removeResponse = { + changes: removeScopes.length, + }; + scopesResponse = [ + { scope: 'blah' }, + ]; + }); + it('success', function () { + db.statement.refreshCode.get.returns(refreshResponse); + db.statement.tokenScopeRemove.run.returns(removeResponse); + db.statement.tokenScopesGetByCodeId.all.returns(scopesResponse); + const expectedResponse = { + expires: new Date(refreshResponse.expires * 1000), + refreshExpires: new Date(refreshResponse.refreshExpires * 1000), + scopes: ['blah'], + } + const response = db.refreshCode(dbCtx, codeId, refreshed, removeScopes); + assert.deepStrictEqual(response, expectedResponse); + }); + it('success without scope removal', function () { + db.statement.refreshCode.get.returns(refreshResponse); + db.statement.tokenScopeRemove.run.returns(removeResponse); + const expectedResponse = { + expires: new Date(refreshResponse.expires * 1000), + refreshExpires: new Date(refreshResponse.refreshExpires * 1000), + } + removeScopes = []; + const response = db.refreshCode(dbCtx, codeId, refreshed, removeScopes); + assert.deepStrictEqual(response, expectedResponse); + }); + it('success with no scopes left', function () { + db.statement.refreshCode.get.returns(refreshResponse); + db.statement.tokenScopeRemove.run.returns(removeResponse); + const expectedResponse = { + expires: new Date(refreshResponse.expires * 1000), + refreshExpires: new Date(refreshResponse.refreshExpires * 1000), + scopes: [], + } + const response = db.refreshCode(dbCtx, codeId, refreshed, removeScopes); + assert.deepStrictEqual(response, expectedResponse); + }); + it('no code', function () { + db.statement.refreshCode.get.returns(); + removeResponse.changes = 0; + db.statement.tokenScopeRemove.run.returns(); + const expectedResponse = undefined; + const response = db.refreshCode(dbCtx, codeId, refreshed, removeScopes); + assert.deepStrictEqual(response, expectedResponse); + }); + it('failure', function () { + db.statement.refreshCode.get.throws(expectedException); + assert.throws(() => db.refreshCode(dbCtx, codeId, refreshed, removeScopes), expectedException); + }); + it('scope removal failure', function () { + removeResponse.changes = 0; + db.statement.tokenScopeRemove.run.returns(removeResponse); + db.statement.refreshCode.get.returns(refreshResponse); + assert.throws(() => db.refreshCode(dbCtx, codeId, refreshed, removeScopes), DBErrors.UnexpectedResult); + }); + + describe('_refreshCodeResponseToNative', function () { + it('coverage', function () { + const expected = { foo: 'bar' }; + const result = DB._refreshCodeResponseToNative(expected); + assert.deepStrictEqual(result, expected); + }); + it('coverage', function () { + const result = DB._refreshCodeResponseToNative(); + assert.strictEqual(result, undefined); + }); + }); + }); // refreshCode + + describe('resourceGet', function () { + let identifier; + beforeEach(function () { + sinon.stub(db.statement.resourceGet, 'get'); + identifier = '05b81112-b224-11ec-a9c6-0025905f714a'; + }); + it('success', function () { + const dbResult = { + identifier, + secret: 'secrety', + }; + db.statement.resourceGet.get.returns(dbResult); + const result = db.resourceGet(dbCtx, identifier); + assert.deepStrictEqual(result, dbResult); + }); + it('failure', function() { + db.statement.resourceGet.get.throws(expectedException); + assert.throws(() => db.resourceGet(dbCtx, identifier), expectedException); + }); + }); // resourceGet + + describe('resourceUpsert', function () { + let resourceId, secret, description; + beforeEach(function () { + resourceId = '4086661a-f980-11ec-ba19-0025905f714a'; + secret = 'secret'; + description = 'some application'; + }); + it('success', function() { + const dbResult = { + changes: 1, + lastInsertRowid: undefined, + }; + sinon.stub(db.statement.resourceUpsert, 'run').returns(dbResult); + db.resourceUpsert(dbCtx, resourceId, secret, description); + }); + it('creates id if not provided', function () { + resourceId = undefined; + const dbResult = { + changes: 1, + lastInsertRowid: undefined, + }; + sinon.stub(db.statement.resourceUpsert, 'run').returns(dbResult); + db.resourceUpsert(dbCtx, resourceId, secret, description); + }); + it('failure', function () { + const dbResult = { + changes: 0, + lastInsertRowid: undefined, + }; + sinon.stub(db.statement.resourceUpsert, 'run').returns(dbResult); + assert.throws(() => db.resourceUpsert(dbCtx, resourceId, secret, description), DBErrors.UnexpectedResult); + }); + }); // resourceUpsert + + describe('scopeCleanup', function () { + let atLeastMsSinceLast; + beforeEach(function () { + atLeastMsSinceLast = 86400000; + sinon.stub(db.statement.scopeCleanup, 'run'); + sinon.stub(db.statement.almanacGet, 'get'); + sinon.stub(db.statement.almanacUpsert, 'run'); + }); + it('success, empty almanac', function () { + const cleaned = 10n; + db.statement.almanacGet.get.returns(); + db.statement.scopeCleanup.run.returns({ changes: cleaned }); + db.statement.almanacUpsert.run.returns({ changes: 1 }); + const result = db.scopeCleanup(dbCtx, atLeastMsSinceLast); + assert.strictEqual(result, cleaned); + }); + it('success, too soon', function () { + db.statement.almanacGet.get.returns({ epoch: BigInt(Math.ceil(Date.now() / 1000) - 4) }); + const result = db.scopeCleanup(dbCtx, atLeastMsSinceLast); + assert.strictEqual(result, undefined); + assert(db.statement.scopeCleanup.run.notCalled); + }); + it('failure', function () { + db.statement.almanacGet.get.returns({ epoch: 0n }); + db.statement.scopeCleanup.run.returns({ changes: 1 }); + db.statement.almanacUpsert.run.returns({ changes: 0 }); + assert.throws(() => db.scopeCleanup(dbCtx, atLeastMsSinceLast), DBErrors.UnexpectedResult); + }); + }); // scopeCleanup + + describe('scopeDelete', function () { + let dbGetResult, dbRunResult, scope; + beforeEach(function () { + sinon.stub(db.statement.scopeInUse, 'get'); + dbGetResult = { + inUse: false, + } + sinon.stub(db.statement.scopeDelete, 'run'); + dbRunResult = { + changes: 1, + }; + scope = 'some_scope'; + }); + it('success', function () { + db.statement.scopeInUse.get.returns(dbGetResult); + db.statement.scopeDelete.run.returns(dbRunResult); + const result = db.scopeDelete(dbCtx, scope); + assert.strictEqual(result, true); + }); + it('in use', function () { + dbGetResult.inUse = true; + db.statement.scopeInUse.get.returns(dbGetResult); + db.statement.scopeDelete.run.returns(dbRunResult); + const result = db.scopeDelete(dbCtx, scope); + assert.strictEqual(result, false); + }); + it('no scope', function () { + dbRunResult.changes = 0; + db.statement.scopeInUse.get.returns(dbGetResult); + db.statement.scopeDelete.run.returns(dbRunResult); + const result = db.scopeDelete(dbCtx, scope); + assert.strictEqual(result, true); + }); + it('failure', function () { + db.statement.scopeInUse.get.throws(expectedException); + assert.throws(() => db.scopeDelete(dbCtx, scope), expectedException); + }); + }); // scopeDelete + + describe('scopeUpsert', function () { + let dbResult, scope, application, description; + beforeEach(function () { + scope = 'scope'; + application = undefined; + description = 'description'; + sinon.stub(db.statement.scopeUpsert, 'run'); + dbResult = { + changes: 1, + lastInsertRowid: undefined, + }; + }); + it('success', function() { + db.statement.scopeUpsert.run.returns(dbResult); + db.scopeUpsert(dbCtx, scope, application, description); + }); + it('failure', function () { + dbResult.changes = 0; + db.statement.scopeUpsert.run.returns(dbResult); + assert.throws(() => db.scopeUpsert(dbCtx, scope, application, description), DBErrors.UnexpectedResult); + }); + it('failure, error', function () { + db.statement.scopeUpsert.run.throws(expectedException); + assert.throws(() => db.scopeUpsert(dbCtx, scope, application, description), expectedException); + }); + }); // scopeUpsert + + describe('tokenCleanup', function () { + let codeLifespanSeconds, atLeastMsSinceLast; + beforeEach(function () { + codeLifespanSeconds = 600; + atLeastMsSinceLast = 86400000; + sinon.stub(db.statement.tokenCleanup, 'run'); + sinon.stub(db.statement.almanacGet, 'get'); + sinon.stub(db.statement.almanacUpsert, 'run'); + }); + it('success, empty almanac', function() { + const cleaned = 10n; + db.statement.almanacGet.get.returns(); + db.statement.tokenCleanup.run.returns({ changes: cleaned }); + db.statement.almanacUpsert.run.returns({ changes: 1 }); + const result = db.tokenCleanup(dbCtx, codeLifespanSeconds, atLeastMsSinceLast); + assert.strictEqual(result, cleaned); + }); + it('success, too soon', function () { + db.statement.almanacGet.get.returns({ epoch: BigInt(Math.ceil(Date.now() / 1000) - 4) }); + const result = db.tokenCleanup(dbCtx, codeLifespanSeconds, atLeastMsSinceLast); + assert.strictEqual(result, undefined); + assert(db.statement.tokenCleanup.run.notCalled); + }); + it('failure', function () { + db.statement.almanacGet.get.returns({ epoch: 0n }); + db.statement.tokenCleanup.run.returns({ changes: 10 }); + db.statement.almanacUpsert.run.returns({ changes: 0 }); + assert.throws(() => db.tokenCleanup(dbCtx, codeLifespanSeconds, atLeastMsSinceLast), DBErrors.UnexpectedResult); + }); + }); // tokenCleanup + + describe('tokenGetByCodeId', function () { + let codeId, token; + beforeEach(function () { + codeId = '184a26f6-2612-11ec-9e88-0025905f714a'; + token = 'TokenTokenTokenToken'; + sinon.stub(db.statement.tokenGetByCodeId, 'get'); + sinon.stub(db.statement.tokenScopesGetByCodeId, 'all'); + }); + it('success', function() { + const now = new Date(); + const nowEpoch = Math.ceil(now / 1000); + const expected = { + created: new Date(nowEpoch * 1000), + expires: null, + refreshExpires: null, + refreshed: null, + isRevoked: false, + isToken: false, + token, + codeId, + scopes: [], + profileData: { + name: 'Some Name', + }, + }; + const dbResult = { + created: Math.ceil(nowEpoch), + expires: null, + refreshExpires: null, + refreshed: null, + isToken: 0, + token, + codeId, + profileData: '{"name":"Some Name"}', + }; + db.statement.tokenGetByCodeId.get.returns(dbResult); + const result = db.tokenGetByCodeId(dbCtx, codeId); + assert.deepStrictEqual(result, expected); + }); + it('success without profile data', function () { + const now = new Date(); + const nowEpoch = Math.ceil(now / 1000); + const expected = { + created: new Date(nowEpoch * 1000), + expires: null, + refreshExpires: null, + refreshed: null, + isRevoked: false, + isToken: false, + token, + codeId, + scopes: ['foop', 'baa'], + }; + const dbResult = { + created: Math.ceil(nowEpoch), + expires: null, + refreshExpires: null, + refreshed: null, + isToken: 0, + token, + codeId, + }; + db.statement.tokenGetByCodeId.get.returns(dbResult); + db.statement.tokenScopesGetByCodeId.all.returns([{ scope: 'foop' }, { scope: 'baa' }]); + const result = db.tokenGetByCodeId(dbCtx, codeId); + assert.deepStrictEqual(result, expected); + }); + it('failure', function () { + db.statement.tokenGetByCodeId.get.throws(expectedException); + assert.throws(() => db.tokenGetByCodeId(dbCtx, codeId), expectedException); + }); + + describe('_tokenToNative', function () { + it('covers', function () { + const result = DB._tokenToNative(); + assert.strictEqual(result, undefined); + }); + }); // _tokenToNative + }); // tokenGetByCodeId + + describe('tokenRevokeByCodeId', function () { + let dbResult, codeId; + beforeEach(function () { + codeId = '2f226616-3e79-11ec-ad0f-0025905f714a'; + sinon.stub(db.statement.tokenRevokeByCodeId, 'run') + dbResult = { + changes: 1, + lastInsertRowid: undefined, + }; + }); + it('success', function() { + db.statement.tokenRevokeByCodeId.run.returns(dbResult); + db.tokenRevokeByCodeId(dbCtx, codeId); + }); + it('failure', function () { + dbResult.changes = 0; + db.statement.tokenRevokeByCodeId.run.returns(dbResult); + assert.throws(() => db.tokenRevokeByCodeId(dbCtx, codeId), DBErrors.UnexpectedResult); + }); + it('failure, error', function () { + db.statement.tokenRevokeByCodeId.run.throws(expectedException); + assert.throws(() => db.tokenRevokeByCodeId(dbCtx, codeId), expectedException); + }); + }); // tokenRevokeByCodeId + + describe('tokenRefreshRevokeByCodeId', function () { + let dbResult, codeId; + beforeEach(function () { + dbResult = { + changes: 1, + lastInsertRowid: undefined, + }; + codeId = 'eabba58e-2633-11ed-bbad-0025905f714a'; + sinon.stub(db.statement.tokenRefreshRevokeByCodeId, 'run'); + }); + it('success', function () { + db.statement.tokenRefreshRevokeByCodeId.run.returns(dbResult); + db.tokenRefreshRevokeByCodeId(dbCtx, codeId); + }); + it('failure', function () { + dbResult.changes = 0; + db.statement.tokenRefreshRevokeByCodeId.run.returns(dbResult); + assert.throws(() => db.tokenRefreshRevokeByCodeId(dbCtx, codeId), DBErrors.UnexpectedResult); + }); + it('failure, error', function () { + const expected = new Error('oh no'); + db.statement.tokenRefreshRevokeByCodeId.run.throws(expected); + assert.throws(() => db.tokenRefreshRevokeByCodeId(dbCtx, codeId), expected); + }); + }); // tokenRefreshRevokeByCodeId + + describe('tokensGetByIdentifier', function () { + let identifier; + beforeEach(function () { + identifier = 'identifier'; + sinon.stub(db.statement.tokensGetByIdentifier, 'all'); + }); + it('success', function () { + const nowEpoch = Math.ceil(Date.now() / 1000); + const dbResult = [ + { + created: nowEpoch, + expires: nowEpoch + 86400, + duration: 86400, + refreshed: nowEpoch + 600, + refreshExpires: nowEpoch + 172800, + isRevoked: false, + isToken: true, + codeId: 'c0a7cef4-2637-11ed-a830-0025905f714a', + profile: 'https://profile.example.com/', + profileData: '{"name":"Some Name"}', + identifier: 'username', + }, + ]; + const expected = [ + Object.assign({}, dbResult[0], { + created: new Date(dbResult[0].created * 1000), + expires: new Date(dbResult[0].expires * 1000), + refreshed: new Date(dbResult[0].refreshed * 1000), + refreshExpires: new Date(dbResult[0].refreshExpires * 1000), + profileData: { + name: 'Some Name', + }, + }), + ]; + db.statement.tokensGetByIdentifier.all.returns(dbResult); + const result = db.tokensGetByIdentifier(dbCtx, identifier); + assert.deepStrictEqual(result, expected); + }); + it('failure', function() { + db.statement.tokensGetByIdentifier.all.throws(expectedException); + assert.throws(() => db.tokensGetByIdentifier(dbCtx, identifier), expectedException); + }); + }); // tokensGetByIdentifier + +}); // DatabaseSQLite diff --git a/test/src/errors.js b/test/src/errors.js new file mode 100644 index 0000000..509f3b1 --- /dev/null +++ b/test/src/errors.js @@ -0,0 +1,15 @@ +/* eslint-env mocha */ +'use strict'; + +const assert = require('assert'); +const Errors = require('../../src/errors'); + +describe('Errors', function () { + describe('ValidationError', function () { + it('covers', function () { + const e = new Errors.ValidationError('message'); + assert.strictEqual(e.name, 'ValidationError'); + assert.strictEqual(e.stack, undefined); + }); + }); +}); // Errors \ No newline at end of file diff --git a/test/src/logger.js b/test/src/logger.js new file mode 100644 index 0000000..3441f94 --- /dev/null +++ b/test/src/logger.js @@ -0,0 +1,136 @@ +/* eslint-env mocha */ +'use strict'; + +const assert = require('assert'); +const sinon = require('sinon'); // eslint-disable-line node/no-unpublished-require +const Logger = require('../../src/logger'); +const Config = require('../../config'); + +describe('Logger', function () { + let config; + let logger; + + beforeEach(function () { + config = new Config('test'); + logger = new Logger(config); + Object.keys(Logger.nullLogger).forEach((level) => sinon.stub(logger.backend, level)); + }); + + afterEach(function () { + sinon.restore(); + }); + + it('logs', function () { + logger.info('testScope', 'message', { baz: 'quux' }, { foo: 1 }, 'more other'); + assert(logger.backend.info.called); + }); + + it('logs BigInts', function () { + logger.info('testScope', 'message', { aBigInteger: BigInt(2) }); + assert(logger.backend.info.called); + assert(logger.backend.info.args[0][0].includes('"2"')); + }); + + it('logs Errors', function () { + logger.error('testScope', 'message', { e: new Error('an error') }); + assert(logger.backend.error.called); + assert(logger.backend.error.args[0][0].includes('an error')); + }); + + it('masks credentials', function () { + logger.info('testScope', 'message', { + ctx: { + parsedBody: { + identity: 'username', + credential: 'password', + }, + }, + }); + assert(logger.backend.info.called); + assert(logger.backend.info.args[0][0].includes('"username"')); + assert(logger.backend.info.args[0][0].includes('"********"')); + }); + + it('strips uninteresting scope dross', function () { + logger.info('testScope', 'message', { + ctx: { + profilesScopes: { + profileScopes: { + 'https://thuza.ratfeathers.com/': { + profile: { + description: 'Access detailed profile information, including name, image, and url.', + application: 'IndieAuth', + profiles: [ + 'https://thuza.ratfeathers.com/', + ], + isPermanent: true, + isManuallyAdded: false, + }, + }, + }, + scopeIndex: { + profile: { + description: 'Access detailed profile information, including name, image, and url.', + application: 'IndieAuth', + profiles: [ + 'https://thuza.ratfeathers.com/', + ], + isPermanent: true, + isManuallyAdded: false, + }, + email: { + description: 'Include email address with detailed profile information.', + application: 'IndieAuth', + profiles: [], + isPermanent: true, + isManuallyAdded: false, + }, + }, + }, + }, + }); + assert(logger.backend.info.called); + }); + + it('strips uninteresting scope dross from session', function () { + logger.info('testScope', 'message', { + ctx: { + session: { + profileScopes: { + 'https://thuza.ratfeathers.com/': { + profile: { + description: 'Access detailed profile information, including name, image, and url.', + application: 'IndieAuth', + profiles: [ + 'https://thuza.ratfeathers.com/', + ], + isPermanent: true, + isManuallyAdded: false, + }, + }, + }, + scopeIndex: { + profile: { + description: 'Access detailed profile information, including name, image, and url.', + application: 'IndieAuth', + profiles: [ + 'https://thuza.ratfeathers.com/', + ], + isPermanent: true, + isManuallyAdded: false, + }, + email: { + description: 'Include email address with detailed profile information.', + application: 'IndieAuth', + profiles: [], + isPermanent: true, + isManuallyAdded: false, + }, + }, + }, + }, + }); + assert(logger.backend.info.called); + }); + +}); // Logger diff --git a/test/src/manager.js b/test/src/manager.js new file mode 100644 index 0000000..7336e1f --- /dev/null +++ b/test/src/manager.js @@ -0,0 +1,2323 @@ +/* eslint-env mocha */ +/* eslint-disable capitalized-comments, sonarjs/no-duplicate-string, sonarjs/no-identical-functions */ + +'use strict'; + +const assert = require('assert'); +const sinon = require('sinon'); // eslint-disable-line node/no-unpublished-require + +const Manager = require('../../src/manager'); +const Config = require('../../config'); +const Enum = require('../../src/enum'); +const { ResponseError } = require('../../src/errors'); +const { UnexpectedResult } = require('../../src/db/errors'); +const dns = require('dns'); + +const StubDatabase = require('../stub-db'); +const StubLogger = require('../stub-logger'); + +const expectedException = new Error('oh no'); +const noExpectedException = 'did not get expected exception'; + +describe('Manager', function () { + let manager, options, stubDb, logger; + let req, res, ctx; + + beforeEach(function () { + logger = new StubLogger(); + logger._reset(); + stubDb = new StubDatabase(); + stubDb._reset(); + options = new Config('test'); + req = { + getHeader : sinon.stub(), + }; + res = { + end: sinon.stub(), + setHeader: sinon.stub(), + statusCode: 200, + }; + ctx = { + params: {}, + parsedBody: {}, + queryParams: {}, + session: {}, + errors: [], + notifications: [], + }; + manager = new Manager(logger, stubDb, options); + sinon.stub(manager.communication, 'fetchProfile'); + sinon.stub(manager.communication, 'fetchClientIdentifier'); + sinon.stub(manager.communication, 'deliverTicket'); + sinon.stub(dns, 'lookupAsync').resolves([{ family: 4, address: '10.11.12.13' }]); + sinon.stub(manager.queuePublisher, 'connect'); + sinon.stub(manager.queuePublisher, 'establishAMQPPlumbing'); + sinon.stub(manager.queuePublisher, 'publish'); + }); + + afterEach(function () { + sinon.restore(); + }); + + describe('constructor', function () { + it('instantiates', function () { + assert(manager); + }); + it('covers no queuing', function () { + options.queues.amqp.url = undefined; + manager = new Manager(logger, stubDb, options); + assert(manager); + }); + }); // constructor + + describe('initialize', function () { + let spy; + beforeEach(function () { + spy = sinon.spy(manager, '_connectQueues'); + }); + it('covers', async function () { + await manager.initialize(); + assert(spy.called); + }); + it('covers no queue', async function () { + delete options.queues.amqp.url; + manager = new Manager(logger, stubDb, options); + await manager.initialize(); + assert(spy.notCalled); + }); + }); // initialize + + describe('getRoot', function () { + it('normal response', async function () { + await manager.getRoot(res, ctx); + assert(res.end.called); + }); + }); // getRoot + + describe('getMeta', function () { + it('normal response', async function () { + await manager.getMeta(res, ctx); + assert(res.end.called); + JSON.parse(res.end.args[0][0]); + }); + it('covers no ticket queue', async function () { + delete options.queues.amqp.url; + manager = new Manager(logger, stubDb, options); + await manager.getMeta(res, ctx); + assert(res.end.called); + }); + }); // getMeta + + describe('getHealthcheck', function () { + it('normal response', async function () { + await manager.getHealthcheck(res, ctx); + assert(res.end.called); + }); + }); // getHealthcheck + + describe('getAuthorization', function () { + it('covers missing redirect fields', async function () { + await manager.getAuthorization(res, ctx); + assert.strictEqual(res.statusCode, 400); + }); + it('requires a configured profile', async function () { + manager.db.profilesScopesByIdentifier.resolves({ + profileScopes: { + }, + scopeIndex: { + 'profile': { + description: '', + profiles: [], + }, + 'email': { + description: '', + profiles: [], + }, + }, + profiles: [], + }); + manager.communication.fetchClientIdentifier.resolves({ + items: [], + }); + ctx.authenticationId = 'username'; + Object.assign(ctx.queryParams, { + 'client_id': 'https://client.example.com/', + 'redirect_uri': 'https://client.example.com/action', + 'response_type': 'code', + 'state': '123456', + 'code_challenge_method': 'S256', + 'code_challenge': 'IZ9Jmupp0tvhT37e1KxfSZQXwcAGKHuVE51Z3xf5eog', + 'scope': 'profile email', + }); + await manager.getAuthorization(res, ctx); + assert.strictEqual(res.statusCode, 302); + assert(ctx.session.error); + assert(res.setHeader.called); + }); + it('covers valid', async function () { + manager.db.profilesScopesByIdentifier.resolves({ + profileScopes: { + 'https://profile.example.com/': { + 'create': { + description: '', + profiles: ['https://profile.example.com'], + }, + }, + }, + scopeIndex: { + 'profile': { + description: '', + profiles: [], + }, + 'email': { + description: '', + profiles: [], + }, + 'create': { + description: '', + profiles: ['https://profile.example.com/'], + }, + }, + profiles: ['https://profile.example.com/'], + }); + manager.communication.fetchClientIdentifier.resolves({ + items: [], + }); + ctx.authenticationId = 'username'; + Object.assign(ctx.queryParams, { + 'client_id': 'https://client.example.com/', + 'redirect_uri': 'https://client.example.com/action', + 'response_type': 'code', + 'state': '123456', + 'code_challenge_method': 'S256', + 'code_challenge': 'IZ9Jmupp0tvhT37e1KxfSZQXwcAGKHuVE51Z3xf5eog', + 'scope': 'profile email', + 'me': 'https://profile.example.com/', + }); + await manager.getAuthorization(res, ctx); + assert.strictEqual(res.statusCode, 200); + assert.strictEqual(ctx.session.error, undefined); + assert.strictEqual(ctx.session.errorDescriptions.length, 0); + assert.strictEqual(ctx.notifications.length, 0); + }); + it('succeeds with mismatched profile hint', async function () { + manager.db.profilesScopesByIdentifier.resolves({ + profileScopes: { + 'https://profile.example.com/': { + 'create': { + description: '', + profiles: ['https://profile.example.com'], + }, + }, + }, + scopeIndex: { + 'profile': { + description: '', + profiles: [], + }, + 'email': { + description: '', + profiles: [], + }, + 'create': { + description: '', + profiles: ['https://profile.example.com/'], + }, + }, + profiles: ['https://profile.example.com/'], + }); + manager.communication.fetchClientIdentifier.resolves({ + items: [], + }); + ctx.authenticationId = 'username'; + Object.assign(ctx.queryParams, { + 'client_id': 'https://client.example.com/', + 'redirect_uri': 'https://client.example.com/action', + 'response_type': 'code', + 'state': '123456', + 'code_challenge_method': 'S256', + 'code_challenge': 'IZ9Jmupp0tvhT37e1KxfSZQXwcAGKHuVE51Z3xf5eog', + 'scope': 'profile email', + 'me': 'https://somethingelse.example.com/', + }); + await manager.getAuthorization(res, ctx); + assert(!('me' in ctx.session)); + assert.strictEqual(res.statusCode, 200); + assert.strictEqual(ctx.session.error, undefined); + assert.strictEqual(ctx.session.errorDescriptions.length, 0); + }); + it('covers invalid redirect', async function () { + manager.db.profilesScopesByIdentifier.resolves({ + profileScopes: { + 'https://profile.example.com/': { + 'create': { + description: '', + profiles: ['https://profile.example.com'], + }, + }, + }, + scopeIndex: { + 'profile': { + description: '', + profiles: [], + }, + 'email': { + description: '', + profiles: [], + }, + 'create': { + description: '', + profiles: ['https://profile.example.com/'], + }, + }, + profiles: ['https://profile.example.com/'], + }); + manager.communication.fetchClientIdentifier.resolves({ + items: [], + }); + ctx.authenticationId = 'username'; + Object.assign(ctx.queryParams, { + 'client_id': 'https://client.example.com/', + 'redirect_uri': 'https://client.example.com/action', + 'response_type': 'blargl', + 'state': '', + 'code_challenge_method': 'S256', + 'code_challenge': 'IZ9Jmupp0tvhT37e1KxfSZQXwcAGKHuVE51Z3xf5eog', + }); + await manager.getAuthorization(res, ctx); + assert.strictEqual(res.statusCode, 302); + assert.strictEqual(ctx.session.error, 'invalid_request'); + assert.strictEqual(ctx.session.errorDescriptions.length, 2); + }); + it('covers legacy non-PKCE missing fields', async function () { + manager.db.profilesScopesByIdentifier.resolves({ + profileScopes: { + 'https://profile.example.com/': { + 'create': { + description: '', + profiles: ['https://profile.example.com'], + }, + }, + }, + scopeIndex: { + 'profile': { + description: '', + profiles: [], + }, + 'email': { + description: '', + profiles: [], + }, + 'create': { + description: '', + profiles: ['https://profile.example.com/'], + }, + }, + profiles: ['https://profile.example.com/'], + }); + manager.communication.fetchClientIdentifier.resolves({ + items: [], + }); + ctx.authenticationId = 'username'; + Object.assign(ctx.queryParams, { + 'client_id': 'https://client.example.com/', + 'redirect_uri': 'https://client.example.com/action', + 'response_type': 'code', + 'state': '123456', + 'scope': 'profile email', + 'me': 'https://profile.example.com/', + }); + manager.options.manager.allowLegacyNonPKCE = true; + + await manager.getAuthorization(res, ctx); + assert.strictEqual(res.statusCode, 200); + assert.strictEqual(ctx.session.error, undefined); + assert.strictEqual(ctx.session.errorDescriptions.length, 0); + }); + it('rejects legacy non-PKCE not missing all fields', async function () { + manager.db.profilesScopesByIdentifier.resolves({ + profileScopes: { + 'https://profile.example.com/': { + 'create': { + description: '', + profiles: ['https://profile.example.com'], + }, + }, + }, + scopeIndex: { + 'profile': { + description: '', + profiles: [], + }, + 'email': { + description: '', + profiles: [], + }, + 'create': { + description: '', + profiles: ['https://profile.example.com/'], + }, + }, + profiles: ['https://profile.example.com/'], + }); + manager.communication.fetchClientIdentifier.resolves({ + items: [], + }); + ctx.authenticationId = 'username'; + Object.assign(ctx.queryParams, { + 'client_id': 'https://client.example.com/', + 'redirect_uri': 'https://client.example.com/action', + 'response_type': 'code', + 'code_challenge_method': 'S256', + 'state': '123456', + 'scope': 'profile email', + 'me': 'https://profile.example.com/', + }); + manager.options.manager.allowLegacyNonPKCE = true; + + await manager.getAuthorization(res, ctx); + assert.strictEqual(res.statusCode, 302); + assert.strictEqual(ctx.session.error, 'invalid_request'); + assert.strictEqual(ctx.session.errorDescriptions.length, 1); + }); + it('rejects legacy non-PKCE not missing all fields', async function () { + manager.db.profilesScopesByIdentifier.resolves({ + profileScopes: { + 'https://profile.example.com/': { + 'create': { + description: '', + profiles: ['https://profile.example.com'], + }, + }, + }, + scopeIndex: { + 'profile': { + description: '', + profiles: [], + }, + 'email': { + description: '', + profiles: [], + }, + 'create': { + description: '', + profiles: ['https://profile.example.com/'], + }, + }, + profiles: ['https://profile.example.com/'], + }); + manager.communication.fetchClientIdentifier.resolves({ + items: [], + }); + ctx.authenticationId = 'username'; + Object.assign(ctx.queryParams, { + 'client_id': 'https://client.example.com/', + 'redirect_uri': 'https://client.example.com/action', + 'response_type': 'code', + 'code_challenge': 'xxx', + 'state': '123456', + 'scope': 'profile email', + 'me': 'https://profile.example.com/', + }); + manager.options.manager.allowLegacyNonPKCE = true; + + await manager.getAuthorization(res, ctx); + assert.strictEqual(res.statusCode, 302); + assert.strictEqual(ctx.session.error, 'invalid_request'); + assert.strictEqual(ctx.session.errorDescriptions.length, 1); + }); }); // getAuthorization + + describe('_setError', function () { + it('covers', function () { + const err = 'invalid_request'; + const errDesc = 'something went wrong'; + Manager._setError(ctx, err, errDesc); + }); + it('covers bad error', function () { + const err = 'floopy'; + const errDesc = 'something went wrong'; + try { + Manager._setError(ctx, err, errDesc); + assert.fail(noExpectedException); + } catch (e) { + assert(e instanceof RangeError); + } + }); + it('covers invalid error description', function () { + const err = 'invalid_scope'; + const errDesc = 'something "went wrong"!'; + try { + Manager._setError(ctx, err, errDesc); + assert.fail(noExpectedException); + } catch (e) { + assert(e instanceof RangeError); + } + }); + }); // _setError + + describe('_clientIdRequired', function () { + let clientIdentifier; + beforeEach(function () { + clientIdentifier = { + // h-card here + }; + manager.communication.fetchClientIdentifier.resolves(clientIdentifier); + }); + it('covers valid', async function () { + ctx.queryParams['client_id'] = 'https://client.example.com/'; + + await manager._clientIdRequired(ctx); + + assert.deepStrictEqual(ctx.session.clientIdentifier, clientIdentifier); + assert.strictEqual(ctx.session.error, undefined); + assert.deepStrictEqual(ctx.session.errorDescriptions, undefined); + }); + it('requires client_id', async function () { + ctx.queryParams['client_id'] = undefined; + + await manager._clientIdRequired(ctx); + + assert(ctx.session.error); + assert(ctx.session.errorDescriptions.length); + }); + it('requires valid client_id', async function () { + ctx.queryParams['client_id'] = 'not a url'; + + await manager._clientIdRequired(ctx); + + assert(ctx.session.error); + assert(ctx.session.errorDescriptions.length); + }); + it('rejects strange schema', async function () { + ctx.queryParams['client_id'] = 'file:///etc/shadow'; + + await manager._clientIdRequired(ctx); + + assert(ctx.session.error); + assert(ctx.session.errorDescriptions.length); + }); + it('rejects un-allowed parts', async function () { + ctx.queryParams['client_id'] = 'https://user:pass@client.example.com/#here'; + + await manager._clientIdRequired(ctx); + + assert(ctx.session.error); + assert(ctx.session.errorDescriptions.length); + }); + it('rejects relative paths', async function () { + ctx.queryParams['client_id'] = 'https://client.example.com/x/../y/'; + + await manager._clientIdRequired(ctx); + + assert(ctx.session.error); + assert(ctx.session.errorDescriptions.length); + }); + it('rejects ipv6 hostname', async function () { + ctx.queryParams['client_id'] = 'https://[fd12:3456:789a:1::1]/'; + + await manager._clientIdRequired(ctx); + + assert(ctx.session.error); + assert(ctx.session.errorDescriptions.length); + }); + it('allows ipv6 loopback hostname', async function () { + ctx.queryParams['client_id'] = 'https://[::1]/'; + + await manager._clientIdRequired(ctx); + + assert.deepStrictEqual(ctx.session.clientIdentifier, clientIdentifier); + assert.strictEqual(ctx.session.error, undefined); + assert.deepStrictEqual(ctx.session.errorDescriptions, undefined); + }); + it('rejects ipv4 hostname', async function () { + ctx.queryParams['client_id'] = 'https://10.9.8.7/'; + + await manager._clientIdRequired(ctx); + + assert(ctx.session.error); + assert(ctx.session.errorDescriptions.length); + }); + it('allows ipv4 loopback hostname', async function () { + ctx.queryParams['client_id'] = 'https:/127.0.10.100/'; + + await manager._clientIdRequired(ctx); + + assert.deepStrictEqual(ctx.session.clientIdentifier, clientIdentifier); + assert.strictEqual(ctx.session.error, undefined); + assert.deepStrictEqual(ctx.session.errorDescriptions, undefined); + }); + it('requires response', async function () { + manager.communication.fetchClientIdentifier.restore(); + sinon.stub(manager.communication, 'fetchClientIdentifier').resolves(); + ctx.queryParams['client_id'] = 'https://client.example.com/'; + + await manager._clientIdRequired(ctx); + + assert(ctx.session.error); + assert(ctx.session.errorDescriptions.length); + }); + }); // _clientIdRequired + + describe('_redirectURIRequired', function () { + beforeEach(function () { + ctx.session.clientId = new URL('https://client.example.com/'); + ctx.session.clientIdentifier = { + rels: { + 'redirect_uri': ['https://alternate.example.com/', 'https://other.example.com/'], + }, + }; + }); + it('covers valid', function () { + ctx.queryParams['redirect_uri'] = 'https://client.example.com/return'; + + Manager._redirectURIRequired(ctx); + + assert.strictEqual(ctx.session.error, undefined); + assert.deepStrictEqual(ctx.session.errorDescriptions, undefined); + }); + it('requires redirect_uri', function () { + ctx.queryParams['redirect_uri'] = undefined; + + Manager._redirectURIRequired(ctx); + + assert(ctx.session.error); + assert(ctx.session.errorDescriptions.length); + }); + it('requires valid redirect_uri', function () { + ctx.queryParams['redirect_uri'] = 'not a url'; + + Manager._redirectURIRequired(ctx); + + assert(ctx.session.error); + assert(ctx.session.errorDescriptions.length); + }); + it('rejects no matching alternate redirect_uri from client_id', function () { + ctx.queryParams['redirect_uri'] = 'https://unlisted.example.com/'; + + Manager._redirectURIRequired(ctx); + + assert(ctx.session.error); + assert(ctx.session.errorDescriptions.length); + }); + it('allows alternate redirect_uri from client_id', function () { + ctx.queryParams['redirect_uri'] = 'https://alternate.example.com/'; + + Manager._redirectURIRequired(ctx); + + assert.strictEqual(ctx.session.error, undefined); + assert.deepStrictEqual(ctx.session.errorDescriptions, undefined); + }); + }); // _redirectURIRequired + + describe('_responseTypeRequired', function () { + it('covers valid', function () { + ctx.queryParams['response_type'] = 'code'; + + Manager._responseTypeRequired(ctx); + + assert.strictEqual(ctx.session.error, undefined); + assert.deepStrictEqual(ctx.session.errorDescriptions, undefined); + }); + it('requires response_type', function () { + ctx.queryParams['response_type'] = undefined; + + Manager._responseTypeRequired(ctx); + + assert(ctx.session.error); + assert(ctx.session.errorDescriptions.length); + }); + it('rejects invalid', function () { + ctx.queryParams['response_type'] = 'flarp'; + + Manager._responseTypeRequired(ctx); + + assert(ctx.session.error); + assert(ctx.session.errorDescriptions.length); + }); + }); // _responseTypeRequired + + describe('_stateRequired', function () { + it('covers valid', function () { + ctx.queryParams['state'] = 'StateStateState'; + + Manager._stateRequired(ctx); + + assert.strictEqual(ctx.session.error, undefined); + assert.deepStrictEqual(ctx.session.errorDescriptions, undefined); + }); + it('requires state', function () { + ctx.queryParams['state'] = undefined; + + Manager._stateRequired(ctx); + + assert(ctx.session.error); + assert(ctx.session.errorDescriptions.length); + }); + }); // _stateRequired + + describe('_codeChallengeMethodRequired', function () { + it('covers valid', function () { + ctx.queryParams['code_challenge_method'] = 'S256'; + + manager._codeChallengeMethodRequired(ctx); + + assert.strictEqual(ctx.session.error, undefined); + assert.deepStrictEqual(ctx.session.errorDescriptions, undefined); + }); + it('requires code_challenge_method', function () { + ctx.queryParams['code_challenge_method'] = undefined; + + manager._codeChallengeMethodRequired(ctx); + + assert(ctx.session.error); + assert(ctx.session.errorDescriptions.length); + }); + it('rejects invalid', function () { + ctx.queryParams['code_challenge_method'] = 'MD5'; + + manager._codeChallengeMethodRequired(ctx); + + assert(ctx.session.error); + assert(ctx.session.errorDescriptions.length); + }); + it('covers legacy non-PKCE', function () { + ctx.queryParams['code_challenge_method'] = undefined; + manager.options.manager.allowLegacyNonPKCE = true; + + manager._codeChallengeMethodRequired(ctx); + + assert.strictEqual(ctx.session.error, undefined); + assert.deepStrictEqual(ctx.session.errorDescriptions, undefined); + }); + }); // _codeChallengeMethodRequired + + describe('_codeChallengeRequired', function () { + it('covers valid', function () { + ctx.queryParams['code_challenge'] = 'NBKNqs1TfjQFqpewPNOstmQ5MJnLoeTTbjqtQ9JbZOo'; + + manager._codeChallengeRequired(ctx); + + assert.strictEqual(ctx.session.error, undefined); + assert.deepStrictEqual(ctx.session.errorDescriptions, undefined); + }); + it('requires code_challenge', function () { + ctx.queryParams['code_challenge'] = undefined; + + manager._codeChallengeRequired(ctx); + + assert(ctx.session.error); + assert(ctx.session.errorDescriptions.length); + }); + it('rejects invalid', function () { + ctx.queryParams['code_challenge'] = 'not base64/url encoded'; + + manager._codeChallengeRequired(ctx); + + assert(ctx.session.error); + assert(ctx.session.errorDescriptions.length); + }); + it('covers legacy non-PKCE', function () { + ctx.queryParams['code_challenge'] = undefined; + manager.options.manager.allowLegacyNonPKCE = true; + + manager._codeChallengeRequired(ctx); + + assert.strictEqual(ctx.session.error, undefined); + assert.deepStrictEqual(ctx.session.errorDescriptions, undefined); + + }); + }); // _codeChallengeRequired + + describe('_redirectURIRequired', function () { + beforeEach(function () { + sinon.stub(Manager, '_setError'); + ctx.queryParams['redirect_uri'] = 'https://example.com/redirect'; + ctx.session.clientId = new URL('https://example.com/'); + }); + it('requires redirect_uri', function () { + delete ctx.queryParams['redirect_uri']; + Manager._redirectURIRequired(ctx); + assert(Manager._setError.called); + }); + it('requires valid redirect_uri', function () { + ctx.queryParams['redirect_uri'] = 'not a uri'; + Manager._redirectURIRequired(ctx); + assert(Manager._setError.called); + }); + it('sets redirectUri if no clientId', function () { + delete ctx.session.clientId; + Manager._redirectURIRequired(ctx); + assert(Manager._setError.notCalled); + assert(ctx.session.redirectUri instanceof URL); + }); + it('sets redirectUri if clientId matches', function () { + Manager._redirectURIRequired(ctx); + assert(Manager._setError.notCalled); + assert(ctx.session.redirectUri instanceof URL); + }); + it('rejects mis-matched', function () { + ctx.queryParams['redirect_uri'] = 'https://example.com:8080/redirect'; + Manager._redirectURIRequired(ctx); + assert(Manager._setError.called); + assert.strictEqual(ctx.session.redirectUri, undefined); + }); + it('allows client-specified alternate redirect uri', function () { + ctx.session.clientIdentifier = { + rels: { + 'redirect_uri': ['https://alternate.example.com/redirect'], + }, + }; + ctx.queryParams['redirect_uri'] = 'https://alternate.example.com/redirect'; + Manager._redirectURIRequired(ctx); + assert(Manager._setError.notCalled); + assert(ctx.session.redirectUri instanceof URL); + }); + }); // _redirectURIRequired + + describe('_scopeOptional', function () { + it('covers valid', function () { + ctx.queryParams['scope'] = 'profile email'; + manager._scopeOptional(ctx); + assert.strictEqual(ctx.session.error, undefined); + assert.deepStrictEqual(ctx.session.errorDescriptions, undefined); + assert.strictEqual(ctx.session.scope.length, 2); + }); + it('allows empty', function () { + ctx.queryParams['scope'] = undefined; + manager._scopeOptional(ctx); + assert.strictEqual(ctx.session.error, undefined); + assert.deepStrictEqual(ctx.session.errorDescriptions, undefined); + assert.strictEqual(ctx.session.scope.length, 0); + }); + it('rejects invalid scope combination', function () { + ctx.queryParams['scope'] = 'email'; + manager._scopeOptional(ctx); + assert(ctx.session.error); + assert(ctx.session.errorDescriptions.length); + }); + it('ignores invalid scope', function () { + ctx.queryParams['scope'] = 'profile email "funny_business"'; + manager._scopeOptional(ctx); + assert.strictEqual(ctx.session.error, undefined); + assert.deepStrictEqual(ctx.session.errorDescriptions, undefined); + assert.strictEqual(ctx.session.scope.length, 2); + }); + }); // _scopeOptional + + describe('_meOptional', function () { + this.beforeEach(function () { + ctx.queryParams['me'] = 'https://profile.example.com/'; + }); + it('covers valid', async function () { + await manager._meOptional(ctx); + + assert.strictEqual(ctx.session.me.href, ctx.queryParams['me']); + }); + it('ignore invalid', async function () { + ctx.queryParams['me'] = 'not a url'; + + await manager._meOptional(ctx); + + assert.strictEqual(ctx.session.me, undefined); + }); + it('allows empty', async function () { + ctx.queryParams['me'] = undefined; + + await manager._meOptional(ctx); + + assert.strictEqual(ctx.session.me, undefined); + }); + }); // _meOptional + + describe('_profileValidForIdentifier', function () { + beforeEach(function () { + ctx.session = { + profiles: ['https://profile.example.com/', 'https://example.com/profile'], + me: new URL('https://example.com/profile'), + }; + }); + it('covers valid', async function () { + + const result = await manager._profileValidForIdentifier(ctx); + + assert.strictEqual(result, true); + }); + it('covers missing me', async function () { + delete ctx.session.me; + + const result = await manager._profileValidForIdentifier(ctx); + + assert.strictEqual(result, false); + }); + }); // _profileValidForIdentifier + + describe('_parseLifespan', function () { + let field, customField; + beforeEach(function () { + field = 'lifespan'; + customField = 'lifespan-seconds'; + ctx.parsedBody['lifespan'] = undefined; + ctx.parsedBody['lifespan-seconds'] = undefined; + }); + it('returns nothing without fields', function () { + const result = manager._parseLifespan(ctx, field, customField); + assert.strictEqual(result, undefined); + }); + it('returns nothing for unrecognized field', function () { + ctx.parsedBody['lifespan'] = 'a while'; + const result = manager._parseLifespan(ctx, field, customField); + assert.strictEqual(result, undefined); + }); + it('returns recognized preset value', function () { + ctx.parsedBody['lifespan'] = '1d'; + const result = manager._parseLifespan(ctx, field, customField); + assert.strictEqual(result, 86400); + }); + it('returns valid custom value', function () { + ctx.parsedBody['lifespan'] = 'custom'; + ctx.parsedBody['lifespan-seconds'] = '123'; + const result = manager._parseLifespan(ctx, field, customField); + assert.strictEqual(result, 123); + }); + it('returns nothing for invalid custom value', function () { + ctx.parsedBody['lifespan'] = 'custom'; + ctx.parsedBody['lifespan-seconds'] = 'Not a number'; + const result = manager._parseLifespan(ctx, field, customField); + assert.strictEqual(result, undefined); + }); + it('returns nothing for invalid custom value', function () { + ctx.parsedBody['lifespan'] = 'custom'; + ctx.parsedBody['lifespan-seconds'] = '-50'; + const result = manager._parseLifespan(ctx, field, customField); + assert.strictEqual(result, undefined); + }); + }); // _parseLifespan + + describe('_parseConsentScopes', function () { + it('covers no scopes', function () { + const result = manager._parseConsentScopes(ctx); + assert.deepStrictEqual(result, []); + }); + it('filters invalid scopes', function () { + ctx.parsedBody['accepted_scopes'] = ['read', 'email']; + ctx.parsedBody['ad_hoc_scopes'] = 'bad"scope create '; + const result = manager._parseConsentScopes(ctx); + assert.deepStrictEqual(result, ['read', 'create']); + }); + }); // _parseConsentScopes + + describe('_parseConsentMe', function () { + beforeEach(function () { + ctx.session.profiles = ['https://me.example.com/']; + }); + it('covers valid', function () { + const expected = 'https://me.example.com/'; + ctx.parsedBody['me'] = expected; + const result = manager._parseConsentMe(ctx); + assert(result); + assert.strictEqual(result.href, expected); + }); + it('rejects unsupported', function () { + ctx.parsedBody['me'] = 'https://notme.example.com/'; + const result = manager._parseConsentMe(ctx); + assert(!result); + assert(ctx.session.error); + }); + it('rejects invalid', function () { + ctx.parsedBody['me'] = 'bagel'; + const result = manager._parseConsentMe(ctx); + assert(!result); + assert(ctx.session.error); + }); + }); // _parseConsentMe + + describe('_fetchConsentProfileData', function () { + let profileResponse; + beforeEach(function () { + profileResponse = { + url: 'https://profile.example.com/', + }; + manager.communication.fetchProfile.resolves(profileResponse); + }); + it('covers success', async function () { + const expected = profileResponse; + const result = await manager._fetchConsentProfileData(ctx); + assert.deepStrictEqual(result, expected); + assert(!ctx.session.error); + }); + it('covers empty response', async function () { + manager.communication.fetchProfile.resolves(); + const result = await manager._fetchConsentProfileData(ctx); + assert.deepStrictEqual(result, undefined); + assert(ctx.session.error); + }); + it('covers failure', async function () { + manager.communication.fetchProfile.rejects(); + const result = await manager._fetchConsentProfileData(ctx); + assert.deepStrictEqual(result, undefined); + assert(ctx.session.error); + }); + }); // _fetchConsentProfileData + + describe('postConsent', function () { + let oldSession; + beforeEach(function () { + sinon.stub(manager.mysteryBox, 'unpack'); + sinon.stub(manager.mysteryBox, 'pack'); + manager.communication.fetchProfile.resolves({ + url: 'https://profile.example.com/', + }); + oldSession = { + clientId: 'https://example.com/', + redirectUri: 'https://example.com/_redirect', + profiles: ['https://profile.example.com/'], + }; + manager.mysteryBox.unpack.resolves(oldSession); + ctx.parsedBody['me'] = 'https://profile.example.com/'; + ctx.parsedBody['accept'] = 'true'; + }); + it('covers valid', async function () { + await manager.postConsent(res, ctx); + assert(!ctx.session.error, ctx.session.error); + assert.strictEqual(res.statusCode, 302); + }); + it('covers valid with expiration and refresh', async function () { + ctx.parsedBody['expires'] = '1d'; + ctx.parsedBody['refresh'] = '1w'; + await manager.postConsent(res, ctx); + assert(!ctx.session.error, ctx.session.error); + assert.strictEqual(res.statusCode, 302); + }); + it('covers denial', async function () { + ctx.parsedBody['accept'] = 'false'; + await manager.postConsent(res, ctx); + assert(ctx.session.error); + assert.strictEqual(ctx.session.error, 'access_denied'); + assert.strictEqual(res.statusCode, 302); + }); + it('covers profile fetch failure', async function () { + manager.communication.fetchProfile.resolves(); + await manager.postConsent(res, ctx); + assert.strictEqual(res.statusCode, 302); + assert(ctx.session.error); + }); + it('covers bad code', async function () { + manager.mysteryBox.unpack.rejects(); + await manager.postConsent(res, ctx); + assert.strictEqual(res.statusCode, 400); + assert(ctx.session.error); + }); + it('removes email scope without profile', async function () { + ctx.parsedBody['accepted_scopes'] = ['email', 'create']; + await manager.postConsent(res, ctx); + assert(!ctx.session.acceptedScopes.includes('email')); + }); + it('merges valid ad-hoc scopes', async function () { + ctx.parsedBody['accepted_scopes'] = ['email', 'create']; + ctx.parsedBody['ad_hoc_scopes'] = ' my:scope "badScope'; + await manager.postConsent(res, ctx); + assert(ctx.session.acceptedScopes.includes('my:scope')); + }); + it('covers invalid selected me profile', async function () { + ctx.parsedBody['me'] = 'https://different.example.com/'; + await manager.postConsent(res, ctx); + assert(ctx.session.error); + }); + it('covers invalid me url', async function () { + ctx.parsedBody['me'] = 'bagel'; + await manager.postConsent(res, ctx); + assert(ctx.session.error); + }); + it('covers profile fetch error', async function () { + manager.communication.fetchProfile.rejects(expectedException); + await manager.postConsent(res, ctx); + assert.strictEqual(res.statusCode, 302); + assert(ctx.session.error); + }); + }); // postConsent + + describe('postAuthorization', function () { + let code, parsedBody; + beforeEach(function () { + sinon.stub(manager.mysteryBox, 'unpack'); + code = { + codeId: 'cffe1558-35f0-11ec-98bc-0025905f714a', + codeChallengeMethod: 'S256', + codeChallenge: 'iMnq5o6zALKXGivsnlom_0F5_WYda32GHkxlV7mq7hQ', + clientId: 'https://app.example.com/', + redirectUri: 'https://app.example.com/_redirect', + acceptedScopes: ['profile'], + minted: Date.now(), + me: 'https://client.example.com/', + identifier: 'username', + profile: { + name: 'Firsty McLastname', + email: 'f.mclastname@example.com', + }, + }; + parsedBody = { + code: 'codeCodeCode', + 'client_id': 'https://app.example.com/', + 'redirect_uri': 'https://app.example.com/_redirect', + 'grant_type': 'authorization_code', + 'code_verifier': 'verifier', + }; + }); + it('covers valid', async function () { + manager.db.redeemCode.resolves(true); + manager.mysteryBox.unpack.resolves(code); + Object.assign(ctx.parsedBody, parsedBody); + + await manager.postAuthorization(res, ctx); + assert(!ctx.session.error, ctx.session.error); + assert(!res.end.firstCall.args[0].includes('email')); + }); + it('includes email if accepted in scope', async function () { + code.acceptedScopes = ['profile', 'email']; + manager.db.redeemCode.resolves(true); + manager.mysteryBox.unpack.resolves(code); + Object.assign(ctx.parsedBody, parsedBody); + + await manager.postAuthorization(res, ctx); + assert(!ctx.session.error); + assert(res.end.firstCall.args[0].includes('email')); + }); + it('fails if already redeemed', async function () { + manager.db.redeemCode.resolves(false); + manager.mysteryBox.unpack.resolves(code); + Object.assign(ctx.parsedBody, parsedBody); + + await manager.postAuthorization(res, ctx); + assert(ctx.session.error); + }); + it('covers bad request', async function () { + manager.mysteryBox.unpack.rejects(expectedException); + Object.assign(ctx.parsedBody, parsedBody); + + await manager.postAuthorization(res, ctx); + assert(ctx.session.error); + }); + }); // postAuthorization + + describe('_ingestPostAuthorizationRequest', function () { + beforeEach(function () { + sinon.stub(manager, '_restoreSessionFromCode'); + sinon.stub(manager, '_checkSessionMatchingClientId'); + sinon.stub(manager, '_checkSessionMatchingRedirectUri'); + sinon.stub(manager, '_checkGrantType'); + sinon.stub(manager, '_checkSessionMatchingCodeVerifier'); + }); + it('covers valid', async function () { + manager._restoreSessionFromCode.callsFake((ctx) => { + ctx.session = { + me: 'https://profile.example.com/', + minted: Date.now(), + }; + }); + + await manager._ingestPostAuthorizationRequest(ctx); + assert(!ctx.session.error); + }); + it('requires data', async function () { + delete ctx.parsedBody; + await manager._ingestPostAuthorizationRequest(ctx); + assert(ctx.session.error); + }); + it('requires me field', async function () { + manager._restoreSessionFromCode.callsFake((ctx) => { + ctx.session = { + minted: Date.now(), + }; + }); + await manager._ingestPostAuthorizationRequest(ctx); + assert(ctx.session.error); + }); + it('requires minted field', async function () { + manager._restoreSessionFromCode.callsFake((ctx) => { + ctx.session = { + me: 'https://profile.example.com/', + }; + }); + await manager._ingestPostAuthorizationRequest(ctx); + assert(ctx.session.error); + }); + it('rejects expired code', async function () { + manager._restoreSessionFromCode.callsFake((ctx) => { + ctx.session = { + me: 'https://profile.example.com/', + minted: Date.now() - 86400000, + }; + }); + + await manager._ingestPostAuthorizationRequest(ctx); + assert(ctx.session.error); + }); + }); // _ingestPostAuthorizationRequest + + describe('_restoreSessionFromCode', function () { + let unpackedCode; + beforeEach(function () { + sinon.stub(manager.mysteryBox, 'unpack'); + unpackedCode = { + codeId: 'cffe1558-35f0-11ec-98bc-0025905f714a', + codeChallengeMethod: 'S256', + codeChallenge: 'iMnq5o6zALKXGivsnlom_0F5_WYda32GHkxlV7mq7hQ', + clientId: 'https://app.example.com/', + redirectUri: 'https://app.example.com/_redirect', + acceptedScopes: ['profile'], + minted: Date.now(), + me: 'https://client.example.com/', + identifier: 'username', + profile: { + name: 'Firsty McLastname', + email: 'f.mclastname@example.com', + }, + }; + }); + it('covers valid', async function () { + ctx.parsedBody['code'] = 'codeCodeCode'; + manager.mysteryBox.unpack.resolves(unpackedCode); + const expected = Object.assign({}, ctx, { + session: unpackedCode, + }); + await manager._restoreSessionFromCode(ctx); + assert.deepStrictEqual(ctx, expected); + assert(!ctx.session.error); + }); + it('requires code', async function () { + ctx.parsedBody['code'] = ''; + manager.mysteryBox.unpack.resolves({ + me: 'https://example.com/me', + }); + await manager._restoreSessionFromCode(ctx); + assert(ctx.session.error); + }); + it('covers invalid code', async function () { + ctx.parsedBody['code'] = 'codeCodeCode'; + manager.mysteryBox.unpack.rejects(); + await manager._restoreSessionFromCode(ctx); + assert(ctx.session.error); + }); + it('covers missing code fields', async function () { + ctx.parsedBody['code'] = 'codeCodeCode'; + delete unpackedCode.clientId; + manager.mysteryBox.unpack.resolves(unpackedCode); + await manager._restoreSessionFromCode(ctx); + assert(ctx.session.error); + }); + it('covers legacy non-PKCE missing fields', async function () { + ctx.parsedBody['code'] = 'codeCodeCode'; + delete unpackedCode.codeChallengeMethod; + delete unpackedCode.codeChallenge; + manager.mysteryBox.unpack.resolves(unpackedCode); + manager.options.manager.allowLegacyNonPKCE = true; + const expected = Object.assign({}, ctx, { + session: unpackedCode, + }); + await manager._restoreSessionFromCode(ctx); + assert.deepStrictEqual(ctx, expected); + assert(!ctx.session.error); + }); + }); // _restoreSessionFromCode + + describe('_checkSessionMatchingClientId', function () { + it('covers valid', async function () { + ctx.session = { + clientId: 'https://client.example.com/', + }; + ctx.parsedBody['client_id'] = 'https://client.example.com/'; + + manager._checkSessionMatchingClientId(ctx); + assert(!ctx.session.error); + }); + it('covers missing', async function () { + ctx.session = { + clientId: 'https://client.example.com/', + }; + ctx.parsedBody['client_id'] = undefined; + + manager._checkSessionMatchingClientId(ctx); + assert(ctx.session.error); + }); + it('covers un-parsable', async function () { + ctx.session = { + clientId: 'https://client.example.com/', + }; + ctx.parsedBody['client_id'] = 'not a url'; + + manager._checkSessionMatchingClientId(ctx); + assert(ctx.session.error); + }); + it('covers mismatch', async function () { + ctx.session = { + clientId: 'https://client.example.com/', + }; + ctx.parsedBody['client_id'] = 'https://otherclient.example.com/'; + + manager._checkSessionMatchingClientId(ctx); + assert(ctx.session.error); + }); + }); // _checkSessionMatchingClientId + + describe('_checkSessionMatchingRedirectUri', function () { + it('covers valid', async function () { + ctx.parsedBody['redirect_uri'] = 'https://client.example.com/_redirect'; + ctx.session.redirectUri = 'https://client.example.com/_redirect'; + + manager._checkSessionMatchingRedirectUri(ctx); + assert(!ctx.session.error); + }); + it('requires field', async function () { + ctx.parsedBody['redirect_uri'] = undefined; + ctx.session.redirectUri = 'https://client.example.com/_redirect'; + + manager._checkSessionMatchingRedirectUri(ctx); + assert(ctx.session.error); + }); + it('requires valid field', async function () { + ctx.parsedBody['redirect_uri'] = 'not a url'; + ctx.session.redirectUri = 'https://client.example.com/_redirect'; + + manager._checkSessionMatchingRedirectUri(ctx); + assert(ctx.session.error); + }); + it('requires match', async function () { + ctx.parsedBody['redirect_uri'] = 'https://client.example.com/other'; + ctx.session.redirectUri = 'https://client.example.com/_redirect'; + + manager._checkSessionMatchingRedirectUri(ctx); + assert(ctx.session.error); + }); + }); // _checkSessionMatchingRedirectUri + + describe('_checkGrantType', function () { + it('covers valid', async function () { + ctx.parsedBody['grant_type'] = 'authorization_code'; + + manager._checkGrantType(ctx); + assert(!ctx.session.error); + }); + it('allows missing, because of one client', async function () { + ctx.parsedBody['grant_type'] = undefined; + + manager._checkGrantType(ctx); + assert(!ctx.session.error); + }); + it('rejects invalid', async function () { + ctx.parsedBody['grant_type'] = 'pigeon_dance'; + + manager._checkGrantType(ctx); + assert(ctx.session.error); + }); + }); // _checkGrantType + + describe('_checkSessionMatchingCodeVerifier', function () { + it('covers valid', async function () { + ctx.parsedBody['code_verifier'] = 'verifier'; + ctx.session.codeChallengeMethod = 'S256'; + ctx.session.codeChallenge = 'iMnq5o6zALKXGivsnlom_0F5_WYda32GHkxlV7mq7hQ'; + + manager._checkSessionMatchingCodeVerifier(ctx); + assert(!ctx.session.error); + }); + it('requires field', async function () { + ctx.parsedBody['code_verifier'] = undefined; + ctx.session.codeChallengeMethod = 'S256'; + ctx.session.codeChallenge = 'iMnq5o6zALKXGivsnlom_0F5_WYda32GHkxlV7mq7hQ'; + + manager._checkSessionMatchingCodeVerifier(ctx); + assert(ctx.session.error); + }); + it('requires match', async function () { + ctx.parsedBody['code_verifier'] = 'wrongverifier'; + ctx.session.codeChallengeMethod = 'S256'; + ctx.session.codeChallenge = 'iMnq5o6zALKXGivsnlom_0F5_WYda32GHkxlV7mq7hQ'; + + manager._checkSessionMatchingCodeVerifier(ctx); + assert(ctx.session.error); + }); + it('covers legacy non-PKCE missing fields', async function () { + ctx.parsedBody['code_verifier'] = undefined; + ctx.session.codeChallengeMethod = undefined; + ctx.session.codeChallenge = undefined; + manager.options.manager.allowLegacyNonPKCE = true; + + manager._checkSessionMatchingCodeVerifier(ctx); + assert(!ctx.session.error); + }); + }); // _checkSessionMatchingCodeVerifier + + describe('postToken', function () { + let unpackedCode; + beforeEach(function () { + ctx.session.acceptedScopes = []; + unpackedCode = { + codeId: 'cffe1558-35f0-11ec-98bc-0025905f714a', + codeChallengeMethod: 'S256', + codeChallenge: 'iMnq5o6zALKXGivsnlom_0F5_WYda32GHkxlV7mq7hQ', + clientId: 'https://app.example.com/', + redirectUri: 'https://app.example.com/return', + acceptedScopes: ['profile', 'email', 'tricks'], + minted: Date.now(), + me: 'https://client.example.com/', + identifier: 'username', + profile: { + name: 'Firsty McLastname', + email: 'f.mclastname@example.com', + url: 'https://example.com/', + }, + }; + }); + describe('Revocation (legacy)', function () { + beforeEach(function () { + sinon.stub(manager, '_revokeToken'); + }); + it('covers revocation', async function () { + manager._revokeToken.resolves(); + ctx.parsedBody = { + action: 'revoke', + token: 'XXX', + }; + await manager.postToken(req, res, ctx); + assert(manager._revokeToken.called); + }); + }); // Revocation + describe('Validation (legacy)', function () { + beforeEach(function () { + sinon.stub(manager, '_validateToken'); + req.getHeader.returns({ Authorization: 'Bearer XXX' }); + }); + it('covers validation', async function () { + ctx.bearer = { isValid: true }; + await manager.postToken(req, res, ctx); + assert(manager._validateToken.called); + }); + }); // Validation + describe('Refresh', function () { + beforeEach(function () { + sinon.stub(manager, '_refreshToken'); + }); + it('covers refresh', async function () { + ctx.parsedBody['grant_type'] = 'refresh_token'; + await manager.postToken(req, res, ctx); + assert(manager._refreshToken.called); + }); + }); // Refresh + describe('Ticket Redemption', function () { + beforeEach(function () { + sinon.stub(manager, '_ticketAuthToken'); + }); + it('covers ticket', async function () { + ctx.parsedBody['grant_type'] = 'ticket'; + await manager.postToken(req, res, ctx); + assert(manager._ticketAuthToken.called); + }); + it('covers no ticket queue', async function () { + delete options.queues.amqp.url; + manager = new Manager(logger, stubDb, options); + sinon.stub(manager.communication, 'fetchProfile'); + sinon.stub(manager.communication, 'fetchClientIdentifier'); + sinon.stub(manager.communication, 'deliverTicket'); + + ctx.parsedBody['grant_type'] = 'ticket'; + await assert.rejects(() => manager.postToken(req, res, ctx), ResponseError); + }); + }); // Ticket Redemption + describe('Code Redemption', function () { + beforeEach(function () { + sinon.stub(manager.mysteryBox, 'unpack'); + sinon.spy(manager.mysteryBox, 'pack'); + manager.mysteryBox.unpack.resolves(unpackedCode); + ctx.parsedBody = { + 'redirect_uri': 'https://app.example.com/return', + 'code': 'xxx', + }; + }); + it('covers invalid code', async function () { + manager.mysteryBox.unpack.rejects(expectedException); + try { + await manager.postToken(req, res, ctx); + assert.fail(noExpectedException); + } catch (e) { + assert(e instanceof ResponseError); + } + }); + it('covers mismatched redirect', async function () { + ctx.parsedBody['redirect_uri'] = 'https://elsewhere.example.com/'; + try { + await manager.postToken(req, res, ctx); + assert.fail(noExpectedException); + } catch (e) { + assert(e instanceof ResponseError); + } + }); + it('covers success', async function () { + manager.db.redeemCode.resolves(true); + await manager.postToken(req, res, ctx); + assert(res.end.called); + assert.strictEqual(manager.mysteryBox.pack.callCount, 1); + }); + it('covers success with refresh', async function () { + manager.db.redeemCode.resolves(true); + unpackedCode.refreshLifespan = 86400; + unpackedCode.tokenLifespan = 86400; + manager.mysteryBox.unpack.resolves(unpackedCode); + await manager.postToken(req, res, ctx); + assert(res.end.called); + assert.strictEqual(manager.mysteryBox.pack.callCount, 2); + }); + it('covers redemption failure', async function () { + manager.db.redeemCode.resolves(false); + try { + await manager.postToken(req, res, ctx); + assert.fail(noExpectedException); + } catch (e) { + assert(e instanceof ResponseError); + } + }); + it('removes email from profile if not in scope', async function () { + manager.db.redeemCode.resolves(true); + unpackedCode.acceptedScopes = ['profile', 'tricks']; + manager.mysteryBox.unpack.resolves(unpackedCode); + await manager.postToken(req, res, ctx); + assert(res.end.called); + const response = JSON.parse(res.end.args[0][0]); + assert(!('email' in response.profile)); + }); + + }); // Code Redemption + describe('Invalid grant_type', function () { + it('throws response error', async function () { + ctx.parsedBody['grant_type'] = 'bad'; + try { + await manager.postToken(req, res, ctx); + assert.fail(noExpectedException); + } catch (e) { + assert(e instanceof ResponseError); + } + }); + }); // Invalid grant_type + }); // postToken + + describe('_validateToken', function () { + let dbCtx; + beforeEach(function () { + dbCtx = {}; + sinon.stub(manager, '_checkTokenValidationRequest'); + }); + it('covers valid token', async function () { + ctx.bearer = { + isValid: true, + }; + ctx.token = { + }; + await manager._validateToken(dbCtx, req, res, ctx); + assert(res.end.called); + }); + it('covers invalid token', async function () { + ctx.bearer = { + isValid: false, + }; + await assert.rejects(manager._validateToken(dbCtx, req, res, ctx), ResponseError); + }); + it('covers errors', async function () { + ctx.bearer = { + isValid: false, + }; + ctx.session.error = 'error'; + ctx.session.errorDescriptions = ['error_description']; + await assert.rejects(manager._validateToken(dbCtx, req, res, ctx), ResponseError); + }); + }); // _validateToken + + describe('_checkTokenValidationRequest', function () { + let dbCtx; + beforeEach(function () { + dbCtx = {}; + sinon.stub(manager.mysteryBox, 'unpack'); + }); + it('does nothing with no auth header', async function () { + await manager._checkTokenValidationRequest(dbCtx, req, ctx); + }); + it('does nothing with unknown auth header', async function () { + req.getHeader.returns('flarp authy woo'); + await manager._checkTokenValidationRequest(dbCtx, req, ctx); + }); + it('requires a valid auth token', async function () { + manager.mysteryBox.unpack.rejects(expectedException); + req.getHeader.returns('Bearer XXX'); + await manager._checkTokenValidationRequest(dbCtx, req, ctx); + assert(ctx.session.error); + }); + it('requires valid auth token fields', async function () { + manager.mysteryBox.unpack.resolves({}); + req.getHeader.returns('Bearer XXX'); + await manager._checkTokenValidationRequest(dbCtx, req, ctx); + assert(ctx.session.error) + }); + it('covers no token', async function () { + manager.mysteryBox.unpack.resolves({ c: 'xxx' }); + req.getHeader.returns('Bearer XXX'); + await manager._checkTokenValidationRequest(dbCtx, req, ctx); + assert(ctx.session.error) + }); + it('covers db error', async function () { + manager.mysteryBox.unpack.resolves({ c: 'xxx' }); + manager.db.tokenGetByCodeId.rejects(expectedException); + req.getHeader.returns('Bearer XXX'); + await assert.rejects(manager._checkTokenValidationRequest(dbCtx, req, ctx), expectedException); + }); + it('valid token', async function () { + manager.mysteryBox.unpack.resolves({ c: 'xxx' }); + manager.db.tokenGetByCodeId.resolves({ + isRevoked: false, + expires: new Date(Date.now() + 86400000), + }); + req.getHeader.returns('Bearer XXX'); + await manager._checkTokenValidationRequest(dbCtx, req, ctx); + assert.strictEqual(ctx.bearer.isValid, true); + }); + it('revoked token', async function () { + manager.mysteryBox.unpack.resolves({ c: 'xxx' }); + manager.db.tokenGetByCodeId.resolves({ + isRevoked: true, + expires: new Date(Date.now() + 86400000), + }); + req.getHeader.returns('Bearer XXX'); + await manager._checkTokenValidationRequest(dbCtx, req, ctx); + assert.strictEqual(ctx.bearer.isValid, false); + }); + it('expired token', async function () { + manager.mysteryBox.unpack.resolves({ c: 'xxx' }); + manager.db.tokenGetByCodeId.resolves({ + isRevoked: false, + expires: new Date(Date.now() - 86400000), + }); + req.getHeader.returns('Bearer XXX'); + await manager._checkTokenValidationRequest(dbCtx, req, ctx); + assert.strictEqual(ctx.bearer.isValid, false); + }); + }); // _checkTokenValidationRequest + + describe('postIntrospection', function () { + let inactiveToken, activeToken, dbResponse; + beforeEach(function () { + dbResponse = { + profile: 'https://profile.example.com/', + clientId: 'https://client.example.com/', + scopes: ['scope1', 'scope2'], + created: new Date(), + expires: Infinity, + }; + inactiveToken = JSON.stringify({ + active: false, + }); + activeToken = JSON.stringify({ + active: true, + me: dbResponse.profile, + 'client_id': dbResponse.clientId, + scope: dbResponse.scopes.join(' '), + iat: Math.ceil(dbResponse.created.getTime() / 1000), + }); + sinon.stub(manager.mysteryBox, 'unpack').resolves({ c: '7e9991dc-9cd5-11ec-85c4-0025905f714a' }); + manager.db.tokenGetByCodeId.resolves(dbResponse); + }); + it('covers bad token', async function () { + manager.mysteryBox.unpack.rejects(); + await manager.postIntrospection(res, ctx); + assert(res.end.called); + assert.strictEqual(res.end.args[0][0], inactiveToken); + }); + it('covers token not in db', async function () { + manager.db.tokenGetByCodeId.resolves(); + await manager.postIntrospection(res, ctx); + assert(res.end.called); + assert.strictEqual(res.end.args[0][0], inactiveToken); + }); + it('covers valid token', async function () { + await manager.postIntrospection(res, ctx); + assert(res.end.called); + assert.strictEqual(res.end.args[0][0], activeToken); + }); + it('covers expired token', async function () { + dbResponse.expires = new Date((new Date()).getTime() - 86400000); + await manager.postIntrospection(res, ctx); + assert(res.end.called); + assert.strictEqual(res.end.args[0][0], inactiveToken); + }); + it('covers expiring token', async function () { + dbResponse.expires = new Date((new Date()).getTime() + 86400000); + activeToken = JSON.stringify({ + active: true, + me: dbResponse.profile, + 'client_id': dbResponse.clientId, + scope: dbResponse.scopes.join(' '), + iat: Math.ceil(dbResponse.created.getTime() / 1000), + exp: Math.ceil(dbResponse.expires / 1000), + }); + await manager.postIntrospection(res, ctx); + assert(res.end.called); + assert.strictEqual(res.end.args[0][0], activeToken); + }); + it('covers ticket', async function () { + ctx.parsedBody['token_hint_type'] = 'ticket'; + const nowEpoch = Math.ceil(Date.now() / 1000); + manager.mysteryBox.unpack.resolves({ + c: '515172ae-5b0b-11ed-a6af-0025905f714a', + iss: nowEpoch - 86400, + exp: nowEpoch + 86400, + sub: 'https://subject.exmaple.com/', + res: 'https://profile.example.com/feed', + scope: ['read', 'role:private'], + ident: 'username', + profile: 'https://profile.example.com/', + }); + await manager.postIntrospection(res, ctx); + assert(res.end.called); + }); + }); // postIntrospection + + describe('_revokeToken', function () { + let dbCtx; + beforeEach(function () { + dbCtx = {}; + }); + it('requires token field', async function () { + await manager._revokeToken(dbCtx, res, ctx); + assert(res.end.called); + assert.strictEqual(res.statusCode, 400); + }); + it('requires parsable token', async function () { + sinon.stub(manager.mysteryBox, 'unpack').resolves({ notC: 'foop' }); + ctx.parsedBody['token'] = 'invalid token'; + ctx.parsedBody['token_type_hint'] = 'access_token'; + await manager._revokeToken(dbCtx, res, ctx); + assert(res.end.called); + assert.strictEqual(res.statusCode, 400); + }); + it('requires parsable token', async function () { + sinon.stub(manager.mysteryBox, 'unpack').resolves(); + ctx.parsedBody['token'] = 'invalid token'; + ctx.parsedBody['token_type_hint'] = 'refresh_token'; + await manager._revokeToken(dbCtx, res, ctx); + assert(res.end.called); + assert.strictEqual(res.statusCode, 400); + }); + it('succeeds', async function () { + sinon.stub(manager.mysteryBox, 'unpack').resolves({ c: '8e4aed9e-fa3e-11ec-992e-0025905f714a' }); + ctx.parsedBody['token'] = 'valid token'; + await manager._revokeToken(dbCtx, res, ctx); + assert(manager.db.tokenRevokeByCodeId.called); + assert(res.end.called); + }); + it('succeeds for refresh token', async function () { + sinon.stub(manager.mysteryBox, 'unpack').resolves({ rc: '8e4aed9e-fa3e-11ec-992e-0025905f714a' }); + ctx.parsedBody['token'] = 'valid token'; + await manager._revokeToken(dbCtx, res, ctx); + assert(manager.db.tokenRefreshRevokeByCodeId.called); + assert(res.end.called); + }); + it('covers non-revokable token', async function () { + sinon.stub(manager.mysteryBox, 'unpack').resolves({ c: '8e4aed9e-fa3e-11ec-992e-0025905f714a' }); + manager.db.tokenRevokeByCodeId.rejects(new UnexpectedResult()); + ctx.parsedBody['token'] = 'valid token'; + await manager._revokeToken(dbCtx, res, ctx); + assert.strictEqual(res.statusCode, 404); + }); + it('covers failure', async function () { + sinon.stub(manager.mysteryBox, 'unpack').resolves({ c: '8e4aed9e-fa3e-11ec-992e-0025905f714a' }); + manager.db.tokenRevokeByCodeId.rejects(expectedException); + ctx.parsedBody['token'] = 'valid token'; + ctx.parsedBody['token_type_hint'] = 'ignores_bad_hint'; + await assert.rejects(manager._revokeToken(dbCtx, res, ctx), expectedException, noExpectedException); + }); + }); // _revokeToken + + describe('_scopeDifference', function () { + let previousScopes, requestedScopes; + beforeEach(function () { + previousScopes = ['a', 'b', 'c']; + requestedScopes = ['b', 'c', 'd']; + }); + it('covers', function () { + const expected = ['a']; + const result = Manager._scopeDifference(previousScopes, requestedScopes); + assert.deepStrictEqual(result, expected); + }); + }); // _scopeDifference + + describe('_refreshToken', function () { + let dbCtx; + beforeEach(function () { + dbCtx = {}; + ctx.parsedBody['client_id'] = 'https://client.example.com/'; + const nowEpoch = Math.ceil(Date.now() / 1000); + sinon.stub(manager.mysteryBox, 'unpack').resolves({ + rc: '03bb8ab0-1dc7-11ed-99f2-0025905f714a', + ts: nowEpoch - 86400, + exp: nowEpoch + 86400, + }); + sinon.stub(manager.mysteryBox, 'pack').resolves('newToken'); + const futureDate = new Date(Date.now() + 86400000); + manager.db.tokenGetByCodeId.resolves({ + refreshExpires: futureDate, + duration: 86400, + clientId: 'https://client.example.com/', + scopes: ['profile', 'create'], + }); + manager.db.refreshCode.resolves({ + expires: futureDate, + refreshExpires: futureDate, + }); + }); + it('requires a token', async function () { + manager.mysteryBox.unpack.rejects(); + await assert.rejects(() => manager._refreshToken(dbCtx, req, res, ctx), ResponseError); + }); + it('requires token to have refresh field', async function () { + manager.mysteryBox.unpack.resolves(); + await assert.rejects(() => manager._refreshToken(dbCtx, req, res, ctx), ResponseError); + }); + it('requires token to exist in db', async function () { + manager.db.tokenGetByCodeId.resolves(); + await assert.rejects(() => manager._refreshToken(dbCtx, req, res, ctx), ResponseError); + }); + it('requires token be refreshable', async function () { + manager.db.tokenGetByCodeId.resolves({ + refreshExpires: undefined, + }); + await assert.rejects(() => manager._refreshToken(dbCtx, req, res, ctx), ResponseError); + }); + it('requires refresh of token not be expired', async function () { + manager.db.tokenGetByCodeId.resolves({ + refreshExpires: 1000, + }); + await assert.rejects(() => manager._refreshToken(dbCtx, req, res, ctx), ResponseError); + }); + it('requires token not to have been already refreshed', async function () { + const nowEpoch = Math.ceil(Date.now() / 1000); + manager.mysteryBox.unpack.resolves({ + rc: '03bb8ab0-1dc7-11ed-99f2-0025905f714a', + ts: nowEpoch - 864000, + exp: nowEpoch - 86400, + }); + await assert.rejects(() => manager._refreshToken(dbCtx, req, res, ctx), ResponseError); + }); + it('requires client_id requesting refresh match', async function () { + ctx.parsedBody['client_id'] = 'https://wrong.example.com/'; + await assert.rejects(() => manager._refreshToken(dbCtx, req, res, ctx), ResponseError); + }); + it('succeeds', async function () { + await manager._refreshToken(dbCtx, req, res, ctx); + assert(res.end.called); + }); + it('covers non-expiring', async function () { + manager.db.tokenGetByCodeId.resolves({ + refreshExpires: new Date(Date.now() + 86400000), + duration: 86400, + clientId: 'https://client.example.com/', + scopes: ['profile', 'create'], + }); + await manager._refreshToken(dbCtx, req, res, ctx); + assert(res.end.called); + }); + it('covers profile and email', async function () { + manager.db.tokenGetByCodeId.resolves({ + refreshExpires: new Date(Date.now() + 86400000), + duration: 86400, + clientId: 'https://client.example.com/', + scopes: ['profile', 'email', 'create'], + }); + await manager._refreshToken(dbCtx, req, res, ctx); + assert(res.end.called); + }); + it('succeeds with scope reduction', async function () { + ctx.parsedBody['scope'] = 'profile fancy'; + manager.db.tokenGetByCodeId.resolves({ + refreshExpires: new Date(Date.now() + 86400000), + clientId: 'https://client.example.com/', + scopes: ['profile', 'create'], + }); + await manager._refreshToken(dbCtx, req, res, ctx); + assert(res.end.called); + }); + it('covers refresh failed', async function () { + manager.db.refreshCode.resolves(); + await assert.rejects(() => manager._refreshToken(dbCtx, req, res, ctx), ResponseError); + }); + }); // _refreshToken + + describe('_mintTicket', function () { + let dbCtx, payload; + beforeEach(function () { + dbCtx = {}; + payload = { + subject: 'https://third-party.example.com/', + resource: 'https://private.example.com/feed', + scopes: ['read'], + identifier: 'account', + profile: 'https://profile.example.com/', + ticketLifespanSeconds: 86400, + }; + }); + it('covers', async function () { + const expected = 'xxx'; + sinon.stub(manager.mysteryBox, 'pack').resolves(expected); + const result = await manager._mintTicket(dbCtx, payload); + assert.strictEqual(result, expected); + }); + }); // _mintTicket + + describe('_ticketAuthToken', function () { + let dbCtx, ticketPayload, nowEpoch; + beforeEach(function () { + dbCtx = {}; + nowEpoch = Math.ceil(Date.now() / 1000); + ticketPayload = { + c: '5ec17f78-5576-11ed-b444-0025905f714a', + iss: nowEpoch - 86400, + exp: nowEpoch + 86400, + sub: 'https://third-party.example.com/', + res: 'https://private.example.com/feed', + scope: ['read', 'flap'], + ident: 'account', + profile: 'https://profile.example.com/', + }; + sinon.stub(manager.mysteryBox, 'unpack').resolves(ticketPayload); + sinon.stub(manager.mysteryBox, 'pack').resolves('ticket'); + }); + it('covers invalid ticket', async function () { + manager.mysteryBox.unpack.resolves(); + await assert.rejects(() => manager._ticketAuthToken(dbCtx, req, res, ctx), ResponseError); + }); + it('covers expired ticket', async function () { + manager.mysteryBox.unpack.resolves({ + c: '5ec17f78-5576-11ed-b444-0025905f714a', + iss: nowEpoch - 172800, + exp: nowEpoch - 86400, + sub: 'https://third-party.example.com/', + res: 'https://private.example.com/feed', + scope: ['read', 'flap'], + ident: 'account', + profile: 'https://profile.example.com/', + }); + await assert.rejects(() => manager._ticketAuthToken(dbCtx, req, res, ctx), ResponseError); + }); + it('covers success', async function () { + manager.db.redeemCode.resolves(true); + await manager._ticketAuthToken(dbCtx, req, res, ctx); + assert(res.end.called); + }); + it('covers invalid redeem', async function () { + manager.db.redeemCode.resolves(false); + await assert.rejects(() => manager._ticketAuthToken(dbCtx, req, res, ctx), ResponseError); + }); + }); // _ticketAuthToken + + describe('postRevocation', function () { + beforeEach(function () { + sinon.stub(manager, '_revokeToken'); + }); + it('covers success', async function () { + manager._revokeToken.resolves(); + await manager.postRevocation(res, ctx); + assert(manager._revokeToken.called); + }); + it('covers failure', async function () { + manager._revokeToken.rejects(expectedException); + await assert.rejects(manager.postRevocation(res, ctx)); + }); + }); // postRevocation + + describe('postUserInfo', function () { + beforeEach(function () { + ctx.parsedBody['token'] = 'XXX'; + sinon.stub(manager.mysteryBox, 'unpack'); + }); + it('requires a token', async function () { + delete ctx.parsedBody.token; + await manager.postUserInfo(res, ctx); + assert(res.end.called); + assert.strictEqual(res.statusCode, 400); + }); + it('requires a valid token', async function () { + manager.mysteryBox.unpack.rejects(expectedException); + await manager.postUserInfo(res, ctx); + assert(res.end.called); + assert.strictEqual(res.statusCode, 401); + }); + it('requires token to have profile scope', async function () { + manager.mysteryBox.unpack.resolves({}); + manager.db.tokenGetByCodeId.resolves({ + scopes: [], + }); + await manager.postUserInfo(res, ctx); + assert(res.end.called); + assert.strictEqual(res.statusCode, 403); + }); + it('succeeds', async function () { + manager.mysteryBox.unpack.resolves({}); + manager.db.tokenGetByCodeId.resolves({ + scopes: ['profile', 'email'], + profile: { + url: 'https://example.com/', + email: 'user@example.com', + }, + }); + await manager.postUserInfo(res, ctx); + assert(res.end.called); + assert.strictEqual(res.statusCode, 200); + }); + it('succeeds, and does not include email without scope', async function () { + manager.mysteryBox.unpack.resolves({}); + manager.db.tokenGetByCodeId.resolves({ + scopes: ['profile'], + profile: { + url: 'https://example.com/', + email: 'user@example.com', + }, + }); + await manager.postUserInfo(res, ctx); + assert(res.end.called); + assert.strictEqual(res.statusCode, 200); + const response = JSON.parse(res.end.args[0][0]); + assert(!('email' in response)); + }); + }); // postUserInfo + + describe('getAdmin', function () { + beforeEach(function () { + manager.db.profilesScopesByIdentifier.resolves({ + profileScopes: { + 'https://profile.example.com/': { + 'scope': { + 'scope1': { + description: 'a scope', + profiles: ['https://profile.example.com/'], + }, + }, + }, + }, + scopeIndex: { + 'scope1': { + description: 'a scope', + profiles: ['https://profile.example.com/'], + }, + }, + profiles: ['https://profile.example.com/'], + }); + manager.db.tokensGetByIdentifier.resolves(); + }); + it('covers', async function () { + await manager.getAdmin(res, ctx); + }); + }); // getAdmin + + describe('postAdmin', function () { + beforeEach(function () { + manager.db.profilesScopesByIdentifier.resolves({ + profileScopes: { + 'https://profile.example.com/': { + 'scope': { + 'scope1': { + description: 'a scope', + profiles: ['https://profile.example.com/'], + }, + }, + }, + }, + scopeIndex: { + 'scope1': { + description: 'a scope', + profiles: ['https://profile.example.com/'], + }, + }, + profiles: ['https://profile.example.com/'], + }); + manager.db.tokensGetByIdentifier.resolves([]); + manager.db.tokenRevokeByCodeId.resolves(); + manager.db.profileIdentifierInsert.resolves(); + manager.db.profileScopesSetAll.resolves(); + manager.communication.fetchProfile.resolves({ + metadata: { + authorizationEndpoint: manager.selfAuthorizationEndpoint, + }, + }); + }); + describe('save-scopes action', function () { + beforeEach(function () { + ctx.parsedBody['action'] = 'save-scopes'; + ctx.parsedBody['scopes-https://profile/example.com/'] = ['scope1', 'scope2']; + }); + it('covers saving scopes', async function () { + await manager.postAdmin(res, ctx); + assert(ctx.notifications.length); + assert(manager.db.profileScopesSetAll.called); + }); + it('covers saving scopes error', async function () { + manager.db.profileScopesSetAll.rejects(); + await manager.postAdmin(res, ctx); + assert(ctx.errors.length); + }); + }); // save-scopes action + describe('new-profile action', function () { + beforeEach(function () { + ctx.parsedBody['action'] = 'new-profile'; + }); + it('covers new profile', async function () { + ctx.parsedBody['profile'] = 'https://profile.example.com/'; + await manager.postAdmin(res, ctx); + assert(ctx.notifications.length); + assert(manager.db.profileIdentifierInsert.called); + assert(manager.db.profileScopesSetAll.called); + }); + it('covers invalid profile', async function () { + ctx.parsedBody['action'] = 'new-profile'; + ctx.parsedBody['profile'] = 'not a url'; + await manager.postAdmin(res, ctx); + assert(ctx.errors.length); + }); + it('covers other validation failure', async function () { + sinon.stub(manager.communication, 'validateProfile').rejects(expectedException); + ctx.parsedBody['action'] = 'new-profile'; + ctx.parsedBody['profile'] = 'not a url'; + await manager.postAdmin(res, ctx); + assert(ctx.errors.length); + }); + it('covers mismatched profile', async function () { + ctx.parsedBody['action'] = 'new-profile'; + ctx.parsedBody['profile'] = 'https://profile.example.com/'; + manager.communication.fetchProfile.resolves({ + metadata: { + authorizationEndpoint: 'https://other.example.com/auth', + }, + }); + await manager.postAdmin(res, ctx); + assert(ctx.errors.length); + }); + it('covers new profile error', async function () { + ctx.parsedBody['action'] = 'new-profile'; + ctx.parsedBody['profile'] = 'https://profile.example.com/'; + manager.db.profileIdentifierInsert.rejects(); + await manager.postAdmin(res, ctx); + assert(ctx.errors.length); + }); + }); // new-profile action + describe('new-scope action', function () { + beforeEach(function () { + ctx.parsedBody['action'] = 'new-scope'; + }); + it('covers new scope', async function () { + ctx.parsedBody['scope'] = 'newscope'; + await manager.postAdmin(res, ctx); + assert(ctx.notifications.length); + assert(manager.db.scopeUpsert.called); + }); + it('covers bad scope', async function () { + ctx.parsedBody['scope'] = 'bad scope'; + await manager.postAdmin(res, ctx); + assert(ctx.errors.length); + }); + it('covers new scope error', async function () { + ctx.parsedBody['scope'] = 'newscope'; + manager.db.scopeUpsert.rejects(); + await manager.postAdmin(res, ctx); + assert(ctx.errors.length); + }); + it('covers empty scope', async function () { + delete ctx.parsedBody.scope; + await manager.postAdmin(res, ctx); + assert(!ctx.errors.length); + }); + }); // new-scope action + describe('delete-scope-* action', function () { + beforeEach(function () { + ctx.parsedBody['action'] = 'delete-scope-food%3Ayum'; + }); + it('covers delete', async function () { + manager.db.scopeDelete.resolves(true); + await manager.postAdmin(res, ctx); + assert(ctx.notifications.length); + assert(manager.db.scopeDelete.called); + }); + it('covers no delete', async function () { + manager.db.scopeDelete.resolves(false); + await manager.postAdmin(res, ctx); + assert(ctx.notifications.length); + assert(manager.db.scopeDelete.called); + }); + it('covers delete error', async function () { + manager.db.scopeDelete.rejects(); + await manager.postAdmin(res, ctx); + assert(ctx.errors.length); + assert(manager.db.scopeDelete.called); + }); + it('ignores empty scope', async function () { + ctx.parsedBody['action'] = 'delete-scope-'; + await manager.postAdmin(res, ctx); + assert(manager.db.scopeDelete.notCalled); + assert(!ctx.notifications.length); + assert(!ctx.errors.length); + }); + }); // delete-scope-* action + describe('revoke-* action', function () { + beforeEach(function () { + ctx.parsedBody['action'] = 'revoke-b1591c00-9cb7-11ec-a05c-0025905f714a'; + }); + it('covers revocation', async function () { + await manager.postAdmin(res, ctx); + assert(ctx.notifications.length); + assert(manager.db.tokenRevokeByCodeId.called); + }); + it('covers revocation error', async function () { + manager.db.tokenRevokeByCodeId.rejects(); + await manager.postAdmin(res, ctx); + assert(ctx.errors.length); + }); + it('covers no code', async function () { + ctx.parsedBody['action'] = 'revoke-'; + await manager.postAdmin(res, ctx); + assert(!ctx.notifications.length); + assert(!ctx.errors.length); + assert(manager.db.tokenRevokeByCodeId.notCalled); + }); + }); // revoke-* action + it('covers empty action', async function () { + delete ctx.parsedBody.action; + await manager.postAdmin(res, ctx); + assert(!ctx.errors.length); + }); + it('covers unknown action', async function () { + ctx.parsedBody['action'] = 'unsupported-action'; + await manager.postAdmin(res, ctx); + assert(ctx.errors.length); + }); + }); // postAdmin + + describe('getAdminTicket', function () { + it('covers', async function () { + manager.db.profilesScopesByIdentifier.resolves({ scopeIndex: {} }); + await manager.getAdminTicket(res, ctx); + assert(res.end.called); + }); + }); // getAdminTicket + + describe('postAdminTicket', function () { + beforeEach(function () { + ctx.parsedBody['action'] = 'proffer-ticket'; + ctx.parsedBody['scopes'] = ['read', 'role:private']; + ctx.parsedBody['adhoc'] = 'adhoc_scope'; + ctx.parsedBody['profile'] = 'https://profile.example.com/'; + ctx.parsedBody['resource'] = 'https://profile.example.com/feed'; + ctx.parsedBody['subject'] = 'https://subject.example.com/'; + manager.db.profilesScopesByIdentifier.resolves({ scopeIndex: {} }); + sinon.stub(manager.mysteryBox, 'pack').resolves('ticket'); + manager.communication.fetchProfile.resolves({ + metadata: { + ticketEndpoint: 'https://example.com/ticket', + }, + }); + }); + it('covers success', async function () { + await manager.postAdminTicket(res, ctx); + assert(res.end.called); + assert.strictEqual(ctx.errors.length, 0); + assert.strictEqual(ctx.notifications.length, 1); + }); + it('requires params', async function () { + delete ctx.parsedBody['adhoc']; + ctx.parsedBody['profile'] = 'bad url'; + ctx.parsedBody['resource'] = 'bad url'; + ctx.parsedBody['subject'] = 'bad url'; + ctx.parsedBody['scopes'] = ['fl"hrgl', 'email']; + await manager.postAdminTicket(res, ctx); + assert(res.end.called); + assert.strictEqual(ctx.errors.length, 5); + assert.strictEqual(ctx.notifications.length, 0); + }); + it('ignores unknown action', async function () { + ctx.parsedBody['action'] = 'prove-dough'; + await manager.postAdminTicket(res, ctx); + assert(res.end.called); + }); + it('covers delivery failure', async function () { + manager.communication.deliverTicket.rejects(expectedException); + await manager.postAdminTicket(res, ctx); + assert(res.end.called); + assert.strictEqual(ctx.errors.length, 1); + assert.strictEqual(ctx.notifications.length, 0); + }); + it('covers no ticket endpoint', async function () { + manager.communication.fetchProfile.resolves({ + metadata: { + }, + }); + await manager.postAdminTicket(res, ctx); + assert(res.end.called); + assert.strictEqual(ctx.errors.length, 1); + assert.strictEqual(ctx.notifications.length, 0); + }); + it('covers bad ticket endpoint', async function () { + manager.communication.fetchProfile.resolves({ + metadata: { + ticketEndpoint: 'not a url', + }, + }); + await manager.postAdminTicket(res, ctx); + assert(res.end.called); + assert.strictEqual(ctx.errors.length, 1); + assert.strictEqual(ctx.notifications.length, 0); + }); + }); // postAdminTicket + + describe('postTicket', function () { + beforeEach(function () { + ctx.parsedBody = { + ticket: 'ticket123', + resource: 'https://blog.example.com/', + subject: 'https://otheruser.example.com/', + }; + }); + it('accepts a ticket for a known profile', async function () { + manager.db.profileIsValid.resolves(true); + await manager.postTicket(req, res, ctx); + assert(res.end.called); + assert.strictEqual(res.statusCode, 202); + }); + it('rejects invalid resource', async function () { + ctx.parsedBody.resource = 'invalid url'; + await assert.rejects(() => manager.postTicket(req, res, ctx), ResponseError); + }); + it('rejects invalid subject', async function () { + manager.db.profileIsValid(false); + await assert.rejects(() => manager.postTicket(req, res, ctx), ResponseError); + }); + it('covers queue publish failure', async function () { + manager.db.profileIsValid.resolves(true); + manager.queuePublisher.publish.rejects(expectedException); + await assert.rejects(() => manager.postTicket(req, res, ctx), expectedException); + }); + it('covers no ticket queue', async function () { + delete options.queues.amqp.url; + manager = new Manager(logger, stubDb, options); + + await assert.rejects(() => manager.postTicket(req, res, ctx), ResponseError); + }); + + }); // postTicket + + describe('getAdminMaintenance', function () { + it('covers information', async function () { + await manager.getAdminMaintenance(res, ctx); + assert(res.end.called); + }); + it('covers tasks', async function () { + ctx.queryParams = { + [Enum.Chore.CleanTokens]: '', + }; + await manager.getAdminMaintenance(res, ctx); + assert(res.end.called); + }); + }); // getAdminMaintenance + +}); // Manager \ No newline at end of file diff --git a/test/src/service.js b/test/src/service.js new file mode 100644 index 0000000..48f0c0b --- /dev/null +++ b/test/src/service.js @@ -0,0 +1,278 @@ +/* eslint-env mocha */ +/* eslint-disable capitalized-comments */ + +'use strict'; + +const assert = require('assert'); +const sinon = require('sinon'); // eslint-disable-line node/no-unpublished-require + +const stubDb = require('../stub-db'); +const stubLogger = require('../stub-logger'); +const Service = require('../../src/service'); +const Config = require('../../config'); + + +describe('Service', function () { + let service, options; + let req, res, ctx; + + beforeEach(function () { + options = new Config('test'); + service = new Service(stubLogger, stubDb, options); + sinon.stub(service.manager); + sinon.stub(service.sessionManager); + sinon.stub(service.authenticator); + sinon.stub(service.resourceAuthenticator); + sinon.stub(service, 'setResponseType'); + sinon.stub(service, 'serveFile'); + sinon.stub(service, 'ingestBody').resolves(); + req = { + getHeader: sinon.stub(), + }; + res = { + setHeader: sinon.stub(), + write: sinon.stub(), + end: sinon.stub(), + }; + ctx = { + params: {}, + }; + }); + + afterEach(function () { + sinon.restore(); + }); + + it('instantiates', function () { + assert(service); + }); + + it('instantiates with config coverage', async function () { + options.dingus.selfBaseUrl = 'https://example.com/'; + service = new Service(stubLogger, stubDb, options); + assert(service); + }); + + it('instantiates with config coverage', async function () { + delete options.dingus.selfBaseUrl; + service = new Service(stubLogger, stubDb, options); + assert(service); + }); + + describe('initialize', function () { + it('covers', async function () { + await service.initialize(); + assert(service.manager.initialize.called); + }); + }); // initialize + + describe('preHandler', function () { + it('persists url into context', async function () { + req.url = 'https://example.com/foo'; + sinon.stub(service.__proto__.__proto__, 'preHandler').resolves(); + await service.preHandler(req, res, ctx); + assert.strictEqual(ctx.url, req.url); + }); + }); // preHandler + + describe('handlerGetAdminLogin', function () { + it('covers', async function () { + await service.handlerGetAdminLogin(req, res, ctx); + assert(service.sessionManager.getAdminLogin.called); + }); + }); // handlerGetAdminLogin + + describe('handlerPostAdminLogin', function () { + it('covers', async function () { + await service.handlerPostAdminLogin(req, res, ctx); + assert(service.sessionManager.postAdminLogin.called); + }); + }); // handlerPostAdminLogin + + describe('handlerGetAdminLogout', function () { + it('covers', async function () { + await service.handlerGetAdminLogout(req, res, ctx); + assert(service.sessionManager.getAdminLogout.called); + }); + }); // handlerGetAdminLogout + + describe('handlerGetAdmin', function () { + it('covers authenticated', async function () { + service.authenticator.sessionRequiredLocal.resolves(true); + await service.handlerGetAdmin(req, res, ctx); + assert(service.manager.getAdmin.called); + }); + it('covers unauthenticated', async function () { + service.authenticator.sessionRequiredLocal.resolves(false); + await service.handlerGetAdmin(req, res, ctx); + assert(service.manager.getAdmin.notCalled); + }); + }); // handlerGetAdmin + + describe('handlerPostAdmin', function () { + it('covers authenticated', async function () { + service.authenticator.sessionRequiredLocal.resolves(true); + await service.handlerPostAdmin(req, res, ctx); + assert(service.manager.postAdmin.called); + }); + it('covers unauthenticated', async function () { + service.authenticator.sessionRequiredLocal.resolves(false); + await service.handlerPostAdmin(req, res, ctx); + assert(service.manager.getAdmin.notCalled); + }); + }); // handlerPostAdmin + + describe('handlerGetRoot', function () { + it('covers', async function () { + await service.handlerGetRoot(req, res, ctx); + assert(service.manager.getRoot.called); + }); + }); // handlerGetRoot + + describe('handlerGetAdminTicket', function () { + it('covers authenticated', async function () { + service.authenticator.sessionRequiredLocal.resolves(true); + await service.handlerGetAdminTicket(req, res, ctx); + assert(service.manager.getAdminTicket.called); + }); + it('covers unauthenticated', async function () { + service.authenticator.sessionRequiredLocal.resolves(false); + await service.handlerGetAdminTicket(req, res, ctx); + assert(service.manager.getAdminTicket.notCalled); + }); + }); // handlerGetAdminTicket + + describe('handlerPostAdminTicket', function () { + it('covers authenticated', async function () { + service.authenticator.sessionRequiredLocal.resolves(true); + await service.handlerPostAdminTicket(req, res, ctx); + assert(service.manager.postAdminTicket.called); + }); + it('covers unauthenticated', async function () { + service.authenticator.sessionRequiredLocal.resolves(false); + await service.handlerPostAdminTicket(req, res, ctx); + assert(service.manager.postAdminTicket.notCalled); + }); + }); // handlerPostAdminTicket + + describe('handlerGetMeta', function () { + it('covers', async function () { + await service.handlerGetMeta(req, res, ctx); + assert(service.manager.getMeta.called); + }); + }); // handlerGetMeta + + describe('handlerGetHealthcheck', function () { + it('covers', async function () { + await service.handlerGetHealthcheck(req, res, ctx); + assert(service.manager.getHealthcheck.called); + }); + it('cover errors', async function () { + const expectedException = 'blah'; + service.manager.getHealthcheck.rejects(expectedException); + try { + await service.handlerGetHealthcheck(req, res, ctx); + assert.fail('did not get expected exception'); + } catch (e) { + assert.strictEqual(e.name, expectedException, 'did not get expected exception'); + } + assert(service.manager.getHealthcheck.called); + }); + }); // handlerGetHealthcheck + + describe('handlerInternalServerError', function () { + it('covers no redirect', async function () { + sinon.stub(service.__proto__.__proto__, 'handlerInternalServerError'); + await service.handlerInternalServerError(req, res, ctx); + assert(service.__proto__.__proto__.handlerInternalServerError.called); + }); + it('covers redirect', async function () { + sinon.stub(service.__proto__.__proto__, 'handlerInternalServerError'); + ctx.session = { + redirectUri: new URL('https://client.example.com/app'), + clientIdentifier: new URL('https://client.exmaple.com/'), + state: '123456', + }; + await service.handlerInternalServerError(req, res, ctx); + assert(!service.__proto__.__proto__.handlerInternalServerError.called); + assert(res.setHeader); + }); + }); // handlerInternalServerError + + describe('handlerGetAuthorization', function () { + it('covers authenticated', async function() { + service.authenticator.sessionRequiredLocal.resolves(true); + await service.handlerGetAuthorization(req, res, ctx); + assert(service.manager.getAuthorization.called); + }); + it('covers unauthenticated', async function() { + service.authenticator.sessionRequiredLocal.resolves(false); + await service.handlerGetAuthorization(req, res, ctx); + assert(service.manager.getAuthorization.notCalled); + }); + }); // handlerGetAuthorization + + describe('handlerPostAuthorization', function () { + it('covers', async function () { + await service.handlerPostAuthorization(req, res, ctx); + assert(service.manager.postAuthorization.called); + }); + }); // handlerPostAuthorization + + describe('handlerPostConsent', function () { + it('covers', async function () { + service.serveFile.resolves(); + await service.handlerPostConsent(req, res, ctx); + assert(service.manager.postConsent.called); + }); + }); // handlerPostConsent + + describe('handlerPostToken', function () { + it('covers', async function () { + await service.handlerPostToken(req, res, ctx); + assert(service.manager.postToken.called); + }); + }); // handlerPostToken + + describe('handlerPostTicket', function () { + it('covers', async function () { + await service.handlerPostTicket(req, res, ctx); + assert(service.manager.postTicket.called); + }); + }); // handlerPostTicket + + describe('handlerPostIntrospection', function () { + it('covers', async function () { + await service.handlerPostIntrospection(req, res, ctx); + assert(service.manager.postIntrospection.called); + }); + }); // handlerPostIntrospection + + describe('handlerPostRevocation', function () { + it('covers', async function () { + await service.handlerPostRevocation(req, res, ctx); + assert(service.manager.postRevocation.called); + }); + }); // handlerPostRevocation + + describe('handlerPostUserInfo', function () { + it('covers', async function () { + await service.handlerPostUserInfo(req, res, ctx); + assert(service.manager.postUserInfo.called); + }); + }); // handlerPostUserInfo + + describe('handlerGetAdminMaintenance', function () { + it('covers authenticated', async function () { + service.authenticator.sessionRequiredLocal.resolves(true); + await service.handlerGetAdminMaintenance(req, res, ctx); + assert(service.manager.getAdminMaintenance.called); + }); + it('covers unauthenticated', async function () { + service.authenticator.sessionRequiredLocal.resolves(false); + await service.handlerGetAdminMaintenance(req, res, ctx); + assert(service.manager.getAdminMaintenance.notCalled); + }); + }); // handlerGetAdminMaintenance + +}); \ No newline at end of file diff --git a/test/src/template/admin-html.js b/test/src/template/admin-html.js new file mode 100644 index 0000000..4c9e7a7 --- /dev/null +++ b/test/src/template/admin-html.js @@ -0,0 +1,112 @@ +/* eslint-env mocha */ +'use strict'; + +const assert = require('assert'); +const template = require('../../../src/template/admin-html'); +const Config = require('../../../config'); +const StubLogger = require('../../stub-logger'); +const lint = require('html-minifier-lint').lint; // eslint-disable-line node/no-unpublished-require + +const stubLogger = new StubLogger(); + +function lintHtml(html) { + const result = lint(html); + stubLogger.debug('validHtml', '', { result, html }); + assert(!result); +} + +describe('Admin HTML Template', function () { + let ctx, config; + beforeEach(function () { + ctx = { + profilesScopes: { + scopeIndex: { + 'scope': { + application: '', + description: '', + isPermanent: true, + isManuallyAdded: false, + profiles: ['https://example.com/'], + }, + 'other_scope': { + application: 'app1', + description: '', + isPermanent: false, + isManuallyAdded: true, + profiles: [], + }, + 'more_scope': { + application: 'app2', + description: '', + isPermanent: false, + isManuallyAdded: false, + profiles: [], + }, + 'scopitty_scope': { + application: 'app2', + description: '', + isPermanent: false, + isManuallyAdded: false, + profiles: [], + }, + 'last_scope': { + application: 'app1', + description: '', + isPermanent: false, + isManuallyAdded: false, + profiles: [], + }, + }, + profiles: ['https://example.com/'], + }, + tokens: [ + { + codeId: 'xxx', + clientId: 'https://client.example.com/', + profile: 'https://profile.example.com/', + created: new Date(), + expires: null, + isRevoked: false, + }, + { + codeId: 'yyy', + clientId: 'https://client.example.com/', + profile: 'https://profile.example.com/', + isToken: true, + created: new Date(Date.now() - 86400000), + refreshed: new Date(), + expires: new Date(Date.now() + 86400000), + isRevoked: true, + }, + { + codeId: 'zzz', + clientId: 'https://client.exmaple.com/', + profile: 'https://profile.example.com/', + resource: 'https://resource.example.com/', + created: new Date(), + scopes: ['read'], + }, + ], + }; + config = new Config('test'); + }); + it('renders', function () { + const result = template(ctx, config); + lintHtml(result); + assert(result); + }); + it('renders no tokens', function () { + ctx.tokens = []; + const result = template(ctx, config); + lintHtml(result); + assert(result); + }); + it('covers options', function () { + delete ctx.profilesScopes.profiles; + delete ctx.profilesScopes.scopeIndex.scope.profiles; + delete ctx.tokens; + const result = template(ctx, config); + lintHtml(result); + assert(result); + }); +}); // Admin HTML Template diff --git a/test/src/template/admin-maintenance-html.js b/test/src/template/admin-maintenance-html.js new file mode 100644 index 0000000..49d3b15 --- /dev/null +++ b/test/src/template/admin-maintenance-html.js @@ -0,0 +1,47 @@ +/* eslint-env mocha */ +'use strict'; + +const assert = require('assert'); +const template = require('../../../src/template/admin-maintenance-html'); +const Config = require('../../../config'); +const StubLogger = require('../../stub-logger'); +const lint = require('html-minifier-lint').lint; // eslint-disable-line node/no-unpublished-require + +const stubLogger = new StubLogger(); + +function lintHtml(html) { + const result = lint(html); + stubLogger.debug('validHtml', '', { result, html }); + assert(!result); +} + +describe('Admin Management HTML Template', function () { + let ctx, config; + beforeEach(function () { + ctx = { + almanac: [{ + event: 'exampleChore', + date: new Date(), + }], + chores: { + exampleChore: { + intervalMs: 86400, + nextSchedule: new Date(), + }, + }, + }; + config = new Config('test'); + }); + it('renders', function () { + const result = template(ctx, config); + lintHtml(result); + assert(result); + }); + it('covers failsafes', function () { + delete ctx.almanac; + delete ctx.chores; + const result = template(ctx, config); + lintHtml(result); + assert(result); + }); +}); // Admin Ticket HTML Template diff --git a/test/src/template/admin-ticket-html.js b/test/src/template/admin-ticket-html.js new file mode 100644 index 0000000..9622aa5 --- /dev/null +++ b/test/src/template/admin-ticket-html.js @@ -0,0 +1,87 @@ +/* eslint-env mocha */ +'use strict'; + +const assert = require('assert'); +const template = require('../../../src/template/admin-ticket-html'); +const Config = require('../../../config'); +const StubLogger = require('../../stub-logger'); +const lint = require('html-minifier-lint').lint; // eslint-disable-line node/no-unpublished-require + +const stubLogger = new StubLogger(); + +function lintHtml(html) { + const result = lint(html); + stubLogger.debug('validHtml', '', { result, html }); + assert(!result); +} + +describe('Admin Ticket HTML Template', function () { + let ctx, config; + beforeEach(function () { + ctx = { + profilesScopes: { + scopeIndex: { + 'profile': { + application: '', + description: '', + isPermanent: true, + isManuallyAdded: false, + profiles: ['https://example.com/'], + }, + 'other_scope': { + application: 'app1', + description: '', + isPermanent: false, + isManuallyAdded: true, + profiles: [], + }, + 'read': { + application: 'app2', + description: '', + isPermanent: true, + isManuallyAdded: false, + profiles: [], + }, + 'scopitty_scope': { + application: 'app2', + description: '', + isPermanent: false, + isManuallyAdded: false, + profiles: [], + }, + 'last_scope': { + application: 'app1', + description: '', + isPermanent: false, + isManuallyAdded: false, + profiles: [], + }, + }, + profileScopes: { + 'https://example.com': { + 'profile': { + application: '', + description: '', + isPermanent: true, + isManuallyAdded: false, + profiles: ['https://example.com/'], + }, + }, + }, + profiles: ['https://example.com/'], + }, + }; + config = new Config('test'); + }); + it('renders', function () { + const result = template(ctx, config); + lintHtml(result); + assert(result); + }); + it('covers branches', function () { + delete ctx.profilesScopes; + const result = template(ctx, config); + lintHtml(result); + assert(result); + }); +}); // Admin Ticket HTML Template diff --git a/test/src/template/authorization-error-html.js b/test/src/template/authorization-error-html.js new file mode 100644 index 0000000..ba92f30 --- /dev/null +++ b/test/src/template/authorization-error-html.js @@ -0,0 +1,38 @@ +/* eslint-env mocha */ +'use strict'; + +const assert = require('assert'); +const template = require('../../../src/template/authorization-error-html'); +const Config = require('../../../config'); +const StubLogger = require('../../stub-logger'); +const lint = require('html-minifier-lint').lint; // eslint-disable-line node/no-unpublished-require + +const stubLogger = new StubLogger(); + +function lintHtml(html) { + const result = lint(html); + stubLogger.debug('validHtml', '', { result, html }); + assert(!result); +} + +describe('Authorization Error HTML Template', function () { + let ctx, config; + beforeEach(function () { + ctx = {}; + config = new Config('test'); + }); + it('renders', function () { + const result = template(ctx, config); + lintHtml(result); + assert(result); + }); + it('renders errors', function () { + ctx.session = { + error: 'error_name', + errorDescriptions: ['something went wrong', 'another thing went wrong'], + } + const result = template(ctx, config); + lintHtml(result); + assert(result); + }); +}); // Authorization Error HTML Template diff --git a/test/src/template/authorization-request-html.js b/test/src/template/authorization-request-html.js new file mode 100644 index 0000000..b599df3 --- /dev/null +++ b/test/src/template/authorization-request-html.js @@ -0,0 +1,144 @@ +/* eslint-env mocha */ +'use strict'; + +const assert = require('assert'); +const template = require('../../../src/template/authorization-request-html'); +const Config = require('../../../config'); +const StubLogger = require('../../stub-logger'); +const lint = require('html-minifier-lint').lint; // eslint-disable-line node/no-unpublished-require + +const stubLogger = new StubLogger(); + +function lintHtml(html) { + const result = lint(html); + stubLogger.debug('validHtml', '', { result, html }); + assert(!result); +} + +describe('Authorization Request HTML Template', function () { + let ctx, config; + beforeEach(function () { + ctx = {}; + config = new Config('test'); + }); + it('renders', function () { + const result = template(ctx, config); + lintHtml(result); + assert(result); + }); + it('covers options', function () { + ctx.session = { + scope: ['profile', 'email'], + scopeIndex: { + 'profile': { + description: 'Profile', + }, + 'email': { + description: 'Email', + }, + 'create': { + description: 'Create', + profiles: ['https://exmaple.com/profile'], + }, + }, + me: new URL('https://example.com/profile'), + profiles: ['https://another.example.com/profile', 'https://example.com/profile'], + clientIdentifier: { + items: [{ + properties: { + url: 'https://client.example.com/app/', + summary: 'This is an app', + logo: 'https://client.example.com/app/logo.png', + name: 'Some Fancy Application', + }, + }], + }, + clientId: 'https://client.example.com/app/', + persist: 'encodedData', + redirectUri: 'https://client.example.com/app/_return', + }; + const result = template(ctx, config); + lintHtml(result); + assert(result); + }); + it('covers alternate scopes and client logo', function () { + ctx.session = { + scope: ['profile', 'email'], + scopeIndex: { + 'profile': { + description: 'Profile', + }, + 'email': { + description: 'Email', + }, + 'create': { + description: 'Create', + profiles: ['https://example.com/profile'], + }, + 'other': { + description: 'Another Scope', + profiles: ['https://example.com/profile'], + }, + }, + me: new URL('https://example.com/profile'), + profiles: ['https://another.example.com/profile', 'https://example.com/profile'], + clientIdentifier: { + items: [{ + properties: { + url: 'https://client.example.com/app/', + summary: 'This is an app', + logo: [{ + value: 'https://client.example.com/app/logo.png', + alt: 'alt', + }], + name: 'Some Fancy Application', + }, + }], + }, + clientId: 'https://client.example.com/app/', + persist: 'encodedData', + redirectUri: 'https://client.example.com/app/_return', + }; + const result = template(ctx, config); + lintHtml(result); + assert(result); + }); + it('covers partial data', function () { + ctx.session = { + scope: ['profile', 'email', 'create'], + profiles: ['https://another.example.com/profile', 'https://example.com/profile'], + clientIdentifier: { + items: [{ + properties: { + url: 'https://client.example.com/app/', + summary: 'This is an app', + logo: 'https://client.example.com/app/logo.png', + name: 'Some Fancy Application', + }, + }], + }, + clientId: 'https://client.example.com/app/', + persist: 'encodedData', + redirectUri: 'https://client.example.com/app/_return', + }; + const result = template(ctx, config); + lintHtml(result); + assert(result); + }); + it('covers partial data', function () { + ctx.session = { + scope: ['profile', 'email', 'create'], + profiles: [], + clientIdentifier: { + items: [{ + }], + }, + clientId: 'https://client.example.com/app/', + persist: 'encodedData', + redirectUri: 'https://client.example.com/app/_return', + }; + const result = template(ctx, config); + lintHtml(result); + assert(result); + }); +}); // Authorization Request HTML Template diff --git a/test/src/template/root-html.js b/test/src/template/root-html.js new file mode 100644 index 0000000..e2956df --- /dev/null +++ b/test/src/template/root-html.js @@ -0,0 +1,35 @@ +/* eslint-env mocha */ +'use strict'; + +const assert = require('assert'); +const template = require('../../../src/template/root-html'); +const Config = require('../../../config'); +const StubLogger = require('../../stub-logger'); +const lint = require('html-minifier-lint').lint; // eslint-disable-line node/no-unpublished-require + +const stubLogger = new StubLogger(); + +function lintHtml(html) { + const result = lint(html); + stubLogger.debug('validHtml', '', { result, html }); + assert(!result); +} + +describe('Root HTML Template', function () { + let ctx, config; + beforeEach(function () { + ctx = {}; + config = new Config('test'); + }); + it('renders', function () { + const result = template(ctx, config); + lintHtml(result); + assert(result); + }); + it('covers options', function () { + config.adminContactHTML = '<div>support</div>'; + const result = template(ctx, config); + lintHtml(result); + assert(result); + }); +}); // Root HTML Template diff --git a/test/src/template/template-helper.js b/test/src/template/template-helper.js new file mode 100644 index 0000000..7903dd8 --- /dev/null +++ b/test/src/template/template-helper.js @@ -0,0 +1,95 @@ +/* eslint-env mocha */ +'use strict'; + +const assert = require('assert'); +const th = require('../../../src/template/template-helper'); + +describe('Template Helper', function () { + + describe('escapeCSS', function () { + it('allows valid', function () { + const str = 'valid-identifier'; + const result = th.escapeCSS(str); + assert.strictEqual(result, str); + }); + it('escapes invalid', function () { + const str = '(invalid*identifier)'; + const expected = '\\(invalid\\*identifier\\)'; + const result = th.escapeCSS(str); + assert.strictEqual(result, expected); + }); + }); // escapeCSS + + describe('scopeCompare', function () { + let a, b; + describe('empty app', function () { + it('sorts by name, first lower', function () { + a = ['scopeA', { application: '' }]; + b = ['scopeB', { application: '' }]; + const result = th.scopeCompare(a, b); + assert.strictEqual(result, -1); + }); + it('sorts by name, first higher', function () { + a = ['scopeA', { application: '' }]; + b = ['scopeB', { application: '' }]; + const result = th.scopeCompare(b, a); + assert.strictEqual(result, 1); + }); + it('sorts by name, equal', function () { + a = ['scopeA', { application: '' }]; + b = ['scopeA', { application: '' }]; + const result = th.scopeCompare(a, b); + assert.strictEqual(result, 0); + }); + }); + + describe('equal app', function () { + it('sorts by name, first lower', function () { + a = ['scopeA', { application: 'app' }]; + b = ['scopeB', { application: 'app' }]; + const result = th.scopeCompare(a, b); + assert.strictEqual(result, -1); + }); + it('sorts by name, first higher', function () { + a = ['scopeA', { application: 'app' }]; + b = ['scopeB', { application: 'app' }]; + const result = th.scopeCompare(b, a); + assert.strictEqual(result, 1); + }); + it('sorts by name, equal', function () { + a = ['scopeA', { application: 'app' }]; + b = ['scopeA', { application: 'app' }]; + const result = th.scopeCompare(a, b); + assert.strictEqual(result, 0); + }); + }); + + describe('different app', function () { + it('sorts by app, first lower', function () { + a = ['scopeA', { application: 'appA' }]; + b = ['scopeB', { application: 'appB' }]; + const result = th.scopeCompare(a, b); + assert.strictEqual(result, -1); + }); + it('sorts by app, first higher', function () { + a = ['scopeA', { application: 'appA' }]; + b = ['scopeB', { application: 'appB' }]; + const result = th.scopeCompare(b, a); + assert.strictEqual(result, 1); + }); + it('sorts by app, empty first', function () { + a = ['scopeA', { application: '' }]; + b = ['scopeB', { application: 'app' }]; + const result = th.scopeCompare(a, b); + assert.strictEqual(result, -1); + }); + it('sorts by app, empty last', function () { + a = ['scopeA', { application: 'app' }]; + b = ['scopeB', { application: '' }]; + const result = th.scopeCompare(a, b); + assert.strictEqual(result, 1); + }); + }); + }); // scopeCompare + +}); // Template Helper diff --git a/test/stub-db.js b/test/stub-db.js new file mode 100644 index 0000000..f973b8d --- /dev/null +++ b/test/stub-db.js @@ -0,0 +1,35 @@ +/* eslint-disable security/detect-object-injection */ +'use strict'; + +const { StubDatabase: Base } = require('@squeep/test-helper'); // eslint-disable-line node/no-unpublished-require + +class StubDatabase extends Base { + get _stubFns() { + return [ + ...super._stubFns, + 'almanacGetAll', + 'authenticationGet', + 'authenticationSuccess', + 'authenticationUpsert', + 'profileIdentifierInsert', + 'profileIsValid', + 'profileScopeInsert', + 'profileScopesSetAll', + 'profilesScopesByIdentifier', + 'redeemCode', + 'refreshCode', + 'resourceGet', + 'resourceUpsert', + 'scopeCleanup', + 'scopeDelete', + 'scopeUpsert', + 'tokenCleanup', + 'tokenGetByCodeId', + 'tokenRefreshRevokeByCodeId', + 'tokenRevokeByCodeId', + 'tokensGetByIdentifier', + ]; + } +} + +module.exports = StubDatabase; \ No newline at end of file diff --git a/test/stub-logger.js b/test/stub-logger.js new file mode 100644 index 0000000..8be142f --- /dev/null +++ b/test/stub-logger.js @@ -0,0 +1,10 @@ +'use strict'; + +const { StubLogger: Base } = require('@squeep/test-helper'); // eslint-disable-line node/no-unpublished-require + + +class StubLogger extends Base { + +} + +module.exports = StubLogger; \ No newline at end of file -- 2.49.0