diff --git a/Dockerfile b/Dockerfile index 1970735..44439a1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,21 @@ -FROM node:14-alpine +FROM node:15-alpine -WORKDIR /codebase +RUN apk update +RUN apk upgrade -COPY package.json /codebase/ -COPY package-lock.json /codebase/ +# setup run user +RUN apk add libcap +RUN setcap 'cap_net_bind_service=+ep' /usr/local/bin/node +RUN adduser appuser -D +USER appuser +WORKDIR /home/appuser + +COPY --chown=appuser package.json /home/appuser +COPY --chown=appuser package-lock.json /home/appuser RUN npm install --production -COPY . /codebase +COPY --chown=appuser . /home/appuser ENV NODE_ENV production ENTRYPOINT ["./bin/server.js"] diff --git a/README.md b/README.md index 3d04e45..6558b2a 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ -# mytunnel-server +# fusetunnel-server -mytunnel exposes your localhost to the world for easy testing and sharing! No need to mess with DNS or deploy just to have others test out your changes. +Fusetunnel exposes your localhost to the world for easy testing and sharing! No need to mess with DNS or deploy just to have others test out your changes. -This repo is the server component. If you are just looking for the CLI mytunnel app, see (https://github.com/StyleT/mytunnel). +This repo is the server component. If you are just looking for the CLI fusetunnel app, see (https://github.com/fusebit/tunnel). ## Overview -You can easily set up and run your own server. In order to run your own mytunnel server you must ensure that your server can meet the following requirements: +You can easily set up and run your own server. In order to run your own fusetunnel server you must ensure that your server can meet the following requirements: * You can set up DNS entries for your `domain.tld` and `*.domain.tld` (or `sub.domain.tld` and `*.sub.domain.tld`). * The server can accept incoming TCP connections for any non-root TCP port (i.e. ports over 1000). @@ -17,24 +17,24 @@ The above are important as the client will ask the server for a subdomain under ```shell # pick a place where the files will live -git clone git://github.com/StyleT/mytunnel-server.git -cd mytunnel-server +git clone git://github.com/fusebit/tunnel-server.git +cd tunnel-server npm install # server set to run on port 1234 bin/server.js --port 1234 ``` -The mytunnel server is now running and waiting for client requests on port 1234. You will most likely want to set up a reverse proxy to listen on port 80 (or start mytunnel on port 80 directly). +The fusetunnel server is now running and waiting for client requests on port 1234. You will most likely want to set up a reverse proxy to listen on port 80 (or start fusetunnel on port 80 directly). -**NOTE** By default, mytunnel will use subdomains for clients, if you plan to host your mytunnel server itself on a subdomain you will need to use the _--domain_ option and specify the domain name behind which you are hosting mytunnel. (i.e. my-tunnel-server.example.com) +**NOTE** By default, fusetunnel will use subdomains for clients, if you plan to host your fusetunnel server itself on a subdomain you will need to use the _--domain_ option and specify the domain name behind which you are hosting fusetunnel. (i.e. my-tunnel-server.example.com) ### Systemd config Sample systemd config file: ``` [Unit] -Description=MyTunnel service +Description=FuseTunnel service After=network.target StartLimitIntervalSec=0 @@ -53,18 +53,47 @@ WantedBy=multi-user.target Setup flow: ```bash sudo setcap CAP_NET_BIND_SERVICE=+eip /usr/bin/node # allow non root access to bind below port number 1024 -sudo vi /etc/systemd/system/mytunnel.service -sudo systemctl start mytunnel -sudo systemctl enable mytunnel # Add to autoload -journalctl -f -u mytunnel # See logs +sudo vi /etc/systemd/system/fusetunnel.service +sudo systemctl start fusetunnel +sudo systemctl enable fusetunnel # Add to autoload +journalctl -f -u fusetunnel # See logs ``` +## Enable TLS + +You can enable TLS support for both API plane and data plane natively + +To enable data plane TLS, enable these flags on fusetunnel-server + +`--tunnel-ssl-cert` (the SSL certificate of the tunnel) + +`--tunnel-ssl-key` (the SSL key of the tunnel) + +`--tunnel-ssl-ca` (optional: the certificate authority/full chain certificate of the tunnel) + +`--auto-generate-cert` (optional: automatically generate self signed certificate and key for tunnel data plane) + +To enable control plane TLS, enable these flags in fusetunnel-server + +`--web-cert` (the SSL cert of the API server) + +`--web-key` (the SSL key of the API server) + +`--web-ca` (the certificate authority/full chain certificate of the tunnel) + +## Use behind reverse proxy/load balancer + +If you need to override the IP sockets connect to for fuse-tunnel, enable these flags on fusetunnel-server + +`--override-tunnel-ip` (optional: override the IP fusetunnel return to client) + +`--auto-discover-tunnel-ip` (optional: automatically discover the public ip of the fusetunnel server through AWS' public API) ## Use your server You can now use your domain with the `--host` flag for the `lt` client. ```shell -npx mytunnel --host http://tunnel.example.com --port 9000 +npx fusetunnel --host http://tunnel.example.com --port 9000 ``` You will be assigned a URL similar to `http://heavy-puma-9.tunnel.example.com`. @@ -75,7 +104,7 @@ If your server is acting as a reverse proxy (i.e. nginx) and is able to listen o ### POST /api/tunnels -Create a new tunnel. A MyTunnel client posts to this enpoint to request a new tunnel with a specific name or a randomly assigned name. +Create a new tunnel. A FuseTunnel client posts to this enpoint to request a new tunnel with a specific name or a randomly assigned name. ### GET /api/status @@ -83,16 +112,17 @@ General server information. ## Deploy -You can deploy your own mytunnel server using the prebuilt docker image. +You can deploy your own fusetunnel server using the prebuilt docker image. -**Note** This assumes that you have a proxy in front of the server to handle the http(s) requests and forward them to the mytunnel server on port 3000. You can use our [localtunnel-nginx](https://github.com/localtunnel/nginx) to accomplish this. +**Note** This assumes that you have a proxy in front of the server to handle the http(s) requests and forward them to the fusetunnel server on port 3000. You can use our [localtunnel-nginx](https://github.com/localtunnel/nginx) to accomplish this. If you do not want ssl support for your own tunnel (not recommended), then you can just run the below with `--port 80` instead. + ``` docker run -d \ --restart always \ - --name mytunnel \ + --name fusetunnel \ --net host \ defunctzombie/localtunnel-server:latest --port 3000 ``` diff --git a/bin/server.js b/bin/server.js index c221ae6..d3e5a31 100755 --- a/bin/server.js +++ b/bin/server.js @@ -5,10 +5,11 @@ import optimist from 'optimist'; import log from 'book'; import Debug from 'debug'; - +import pemPromise from 'pem-promise'; import CreateServer from '../server.js'; - -const debug = Debug('mytunnel'); +import fs from 'fs'; +import axios from 'axios'; +const debug = Debug('fusetunnel'); const argv = optimist .usage('Usage: $0 --port [num]') @@ -31,17 +32,78 @@ const argv = optimist default: 10, describe: 'maximum number of tcp sockets each client is allowed to establish at one time (the tunnels)' }) + .options('tunnel-ssl-cert', { + describe: 'the ssl cert for encrypting the tunnel' + }) + .options('tunnel-ssl-key', { + describe: 'the ssl key for encrypting the tunnel' + }) + .options('tunnel-ssl-ca', { + describe: 'the certificate authority chain for the ssl cert that is used to encrypt the tunnel' + }) + .options('enable-tunnel-ssl', { + describe: 'tells the tunnel to enable SSL' + }) + .options('web-cert', { + describe: 'the ssl cert for the main web page' + }) + .options('web-key', { + describe: 'the ssl key for the main web page' + }) + .options('web-ca', { + describe: 'the ssl ca for the main web page' + }) + .options('auto-generate-cert', { + describe: 'enabling this flag will automatically generate the server certs for you' + }) + .options('override-tunnel-ip', { + describe: 'override the ip to connect to when establishing sockets, usually meant to be used if you are using a external load balancer' + }) + .options('auto-discover-tunnel-ip', { + describe: 'automatically descover the tunnel public ip via the AWS checkip endpoint' + }) + .options("secret", { + describe: + "the secret that clients need to pass to open a tunnel connection with the server", + }) .argv; if (argv.help) { optimist.showHelp(); process.exit(); } +if (!argv['auto-generate-cert'] && argv['enable-tunnel-ssl']) { + argv['tunnel-ssl-key'] = fs.readFileSync(argv['tunnel-ssl-key']) + argv['tunnel-ssl-cert'] = fs.readFileSync(argv['tunnel-ssl-cert']) + argv['tunnel-ssl-ca'] = fs.readFileSync(argv['tunnel-ssl-ca']) +} +if (argv['auto-generate-cert']) { + await pemPromise.createCertificate().then((keys) => { + argv['tunnel-ssl-key'] = keys.serviceKey + argv['tunnel-ssl-cert'] = keys.certificate + argv['tunnel-ssl-ca'] = keys.certificate + } + ); +} +if (argv['auto-discover-tunnel-ip']) { + await axios.get("http://checkip.amazonaws.com") + .then((response) => { + argv['override-tunnel-ip'] = response.data.split("\n")[0] + }) +} const server = CreateServer({ max_tcp_sockets: argv['max-sockets'], secure: argv.secure, domain: argv.domain, + key: argv['tunnel-ssl-key'], + cert: argv['tunnel-ssl-cert'], + ca: argv['tunnel-ssl-ca'], + webcert: argv['web-cert'], + webkey: argv['web-key'], + webca: argv['web-ca'], + OverrideTunnelIp: argv['override-tunnel-ip'], + secret: argv.secret, }); server.listen(argv.port, argv.address, () => { diff --git a/keys/test.crt b/keys/test.crt new file mode 100644 index 0000000..a2509f5 --- /dev/null +++ b/keys/test.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDETCCAfkCFEh5+sIJi3pEG2H3ycSK30r3LUlkMA0GCSqGSIb3DQEBCwUAMEUx +CzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl +cm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMjEwMzIyMDMzMjQ3WhcNMjEwNDIxMDMz +MjQ3WjBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UE +CgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAxO5pBm6kNOVwQrnfJonNsdEBI6q2nomQ2mA4hticJ33jG+Pm +4Mj1UHx+sL/FcEVRgtfuTEc2D3YIyDQTg7bBrS2U3FmAgHBpfn0kYR4OG3kfquCK +bcjouzwIg+suqp/j90ASLl1+s/qLOhOgmNgEQAwv7z+DOQ6ISRgVz5LtBr4BWRGH +5jOwm+6JezBSRC+JyYMSciDrZz3SXz9cl5xmfA1gt9AFrZXYxTb+B0KMPVNiUNnl +oOmQ8S0IEO1lEtp99GoTUVp8fl4edAkqRG1KXrB3fOJ7UTAln9tQRi+ajgJdn1eM +YBEhLs3tFY5I8NwX2t7LQpzN7dDh5CBZd8G1UwIDAQABMA0GCSqGSIb3DQEBCwUA +A4IBAQCq2IeKsd7MG7mdZVbZfXuamn5QzOwJOk3D6x1IFc2YDAwd+Kx1nYNiqfqB +OiyRP04e81AYDue59rgifVtV5BGRraAHO1d2u6ZemHTO9U2XVIswQDD+XQDZCKmq +7tvKXiCY9h3t1L6k1AQHzPZv7m8ZAcnPjupbGXyjhcljkL4hkM5YeMgmYOgwuHAQ +XQM/jFIFipCwhLcFFInIOwwppeW1Ui7ySg1LS5kr2hJK4x1qksYSQ769tG/uVfhJ +2RHIix6JJrVfIHuB1znkpBT4PGZu5nM6yKmIc3vM8+X0z2vzC1SBbQsBPtCEA7nK +8kE+3yg6Sz6Dh+oNFH7ipgMe9DDg +-----END CERTIFICATE----- diff --git a/keys/test.csr b/keys/test.csr new file mode 100644 index 0000000..bff3727 --- /dev/null +++ b/keys/test.csr @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICijCCAXICAQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx +ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAMTuaQZupDTlcEK53yaJzbHRASOqtp6JkNpgOIbY +nCd94xvj5uDI9VB8frC/xXBFUYLX7kxHNg92CMg0E4O2wa0tlNxZgIBwaX59JGEe +Dht5H6rgim3I6Ls8CIPrLqqf4/dAEi5dfrP6izoToJjYBEAML+8/gzkOiEkYFc+S +7Qa+AVkRh+YzsJvuiXswUkQvicmDEnIg62c90l8/XJecZnwNYLfQBa2V2MU2/gdC +jD1TYlDZ5aDpkPEtCBDtZRLaffRqE1FafH5eHnQJKkRtSl6wd3zie1EwJZ/bUEYv +mo4CXZ9XjGARIS7N7RWOSPDcF9rey0Kcze3Q4eQgWXfBtVMCAwEAAaAAMA0GCSqG +SIb3DQEBCwUAA4IBAQCXJcZjImSryMYlvtiGJ5Xr2JH+yyhLYIgci6dolAoaDQDm +5QqByounrNC8goHA5pbTpxeL6KonjeY8cPJiVeSTMWGp372mSOFJKkDA2CkOiAlG ++pUOPo7+JxDZ4g179vzTBrkbEhNweEqp2QGJp+qTRj1KCMnyxsoqXhxAr+gXU7tr +vIhkBXgH9zvftxXFYl6juhaT3bfaed8klWfkuDaYpbEp+dRWZLUCqI3B2qYCTVNw +7dE2XrMoh9ZjwXG3bdbv/h1UAUCx6joPyEVQ38iFA9hfKrL+7HvRjqZal6A5vA5G +FE9xHiJi210a+L7anZ531JqkPcidg+wduulwgoBz +-----END CERTIFICATE REQUEST----- diff --git a/keys/test.key b/keys/test.key new file mode 100644 index 0000000..e428b36 --- /dev/null +++ b/keys/test.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAxO5pBm6kNOVwQrnfJonNsdEBI6q2nomQ2mA4hticJ33jG+Pm +4Mj1UHx+sL/FcEVRgtfuTEc2D3YIyDQTg7bBrS2U3FmAgHBpfn0kYR4OG3kfquCK +bcjouzwIg+suqp/j90ASLl1+s/qLOhOgmNgEQAwv7z+DOQ6ISRgVz5LtBr4BWRGH +5jOwm+6JezBSRC+JyYMSciDrZz3SXz9cl5xmfA1gt9AFrZXYxTb+B0KMPVNiUNnl +oOmQ8S0IEO1lEtp99GoTUVp8fl4edAkqRG1KXrB3fOJ7UTAln9tQRi+ajgJdn1eM +YBEhLs3tFY5I8NwX2t7LQpzN7dDh5CBZd8G1UwIDAQABAoIBAFULWFOsyEEHrHlE +Z7fu3uOhjMpoWMESS3ni/8ZMGPN9C+zpeLUuU7JUcSnHR256oP7OXVyXjCMVKCm9 +Q4goDm/JNXYLONE+unAjfuhp4FHA9woGOgG7N7ZT8KF3mQmaTwphovhe6+6xjhqg +i0Q2VW+LU9AQL40eV4CpZBHmM3IrLaCVlgPsMD4aIT0JH+blGLXuwHKX2Qq4Sshc +D8m7z3+iO3ZI5JilY/ffmKtlo2BDCWXd2iZ1Z+tBUZujPZRM1KZdVeRgTutIclyO +oHKyREaYY3ndMKrx+WVypYG4VfS0PJ3jMqHLaUlNd7vEcySRrFnXlBshbAr4595n +tMt2CKECgYEA7Cc25h1VdCzJA9ODZor8hyF3qNkHfxPz5zodIMpvoPasQPsql3Xn +MqtLmFnZtBmw0UYS/lcty6+mo/cbGM6kFKW4LZVxOYsG0Ql/KHndKYWNsja4K5mc +9x+ECf8Y+ia2yEitHF2Jsmfe1Kzg1Ke6KEcqxQUw2IBJI1Y7a8i2GzkCgYEA1XtY +Wy52ig7rWUSpkMgmsbpWyuUq5ubunquTTGkVUKSIqPxNxg0wAlVxBwlX2aji+N+6 +Zxhi5/dAey0CByofSHGuqCgAK6vxdKCjnTtVUzkCjPSt4SVqSzdhk9jKnOJvqYIo +QL+OqMBAcHsXlWHa4sFPbEz3PuPjcB6kFLZ0eOsCgYEAxj/dfK1fkdoPHuEwTKOd +gCv+codQHcS4W4OT9HU95VlwHlU82k4mu4jGO64ib2mp4OX9B/xT+80IDlpiKx8+ +6/57cfklRnOKU26vi2FS44q0+8moLyIUffm9NU8svsRFajpo6Yk1EcrVbKF9VclB +JJMqOqAy824u+DVqSQAEsTECgYEAj3knJ5ixaBWgzEzeHQS3JKkUHaYo0CgR5Kdx +BmB1R85cXh2680j3pAniPZVk6k6bxCEweIsmJbnBJ0dXXpNLlPd6J19Cxhb33qb7 +bvdqX9Unxq3GklL//e8JcEC54vg3jVeBUAqtiPI0HKRNdELgxZaflyye2jB0MW0W +XylEW+MCgYEA30QKHxzWxB1+7JroBNJXgf3e0ERCW4i3KV6WiLtQ0Kr2spGuXaTm +8C7dR0Jucd1k3wQMC2v2sXEjT6q0Qpu04OdSvBrOvsXzfFOlrZ21SNJ/YYpq7N+8 +PurZmp9Hwidr/RtHDKe1hRYzrgv0I//IxomABIx2EMeSFpQPp8ZEDmY= +-----END RSA PRIVATE KEY----- diff --git a/lib/Client.js b/lib/Client.js index 496dd91..3ded22e 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -14,7 +14,7 @@ class Client extends EventEmitter { const agent = this.agent = options.agent; const id = this.id = options.id; - this.debug = Debug(`mytunnel:Client[${this.id}]`); + this.debug = Debug(`fusetunnel:Client[${this.id}]`); // client is given a grace period in which they can connect before they are _removed_ this.graceTimeout = setTimeout(() => { @@ -57,22 +57,18 @@ class Client extends EventEmitter { handleRequest(req, res) { this.debug('> %s', req.url); - const opt = { + const clientReq = http.request({ path: req.url, agent: this.agent, method: req.method, - headers: req.headers - }; - - const clientReq = http.request(opt, (clientRes) => { + headers: req.headers, + }, (clientRes) => { this.debug('< %s', req.url); // write response code and headers res.writeHead(clientRes.statusCode, clientRes.headers); - // using pump is deliberate - see the pump docs for why pump(clientRes, res); }); - // this can happen when underlying agent produces an error // in our case we 504 gateway error this? // if we have already sent headers? diff --git a/lib/ClientManager.js b/lib/ClientManager.js index 1dd5d72..5687d6e 100644 --- a/lib/ClientManager.js +++ b/lib/ClientManager.js @@ -19,7 +19,7 @@ class ClientManager { tunnels: 0 }; - this.debug = Debug('mytunnel:ClientManager'); + this.debug = Debug('fusetunnel:ClientManager'); } // create a new tunnel with `id` @@ -35,6 +35,9 @@ class ClientManager { const agent = new TunnelAgent({ clientId: id, maxSockets: 10, + key: this.opt.key, + cert: this.opt.cert, + ca: this.opt.ca }); const client = new Client({ @@ -57,6 +60,9 @@ class ClientManager { return { id: id, port: info.port, + isTls: this.opt.cert ? true: false, + OverrideTunnelIp: this.opt.OverrideTunnelIp, + certificate: this.opt.cert, max_conn_count: maxSockets, }; } diff --git a/lib/TunnelAgent.js b/lib/TunnelAgent.js index 7988508..f7a9513 100644 --- a/lib/TunnelAgent.js +++ b/lib/TunnelAgent.js @@ -1,8 +1,9 @@ import { Agent } from 'http'; -import net from 'net'; +import tls from 'tls'; import log from 'book'; import Debug from 'debug'; - +import fs from 'fs'; +import net from 'net'; const DEFAULT_MAX_SOCKETS = 10; const DEFAULT_SOCKET_TIMEOUT = 10 * 60 * 1000; @@ -17,7 +18,7 @@ class TunnelAgent extends Agent { // this prevents it from holding on to all the sockets so they can be used for upgrades maxFreeSockets: 1, }); - + this.options = options // sockets we can hand out via createConnection this.availableSockets = []; @@ -25,15 +26,24 @@ class TunnelAgent extends Agent { // once a socket is available it is handed out to the next callback this.waitingCreateConn = []; - this.debug = Debug(`mytunnel:TunnelAgent[${options.clientId}]`); + this.debug = Debug(`fusetunnel:TunnelAgent[${options.clientId}]`); // track maximum allowed sockets this.connectedSockets = 0; - this.maxTcpSockets = options.maxTcpSockets || DEFAULT_MAX_SOCKETS; - + // new tcp server to service requests for this client - this.server = net.createServer(); - + + if (options.cert) { + this.server = tls.createServer({ + key: options.key, + cert: options.cert, + ca: options.ca, + minVersion: 'TLSv1.3', + }); + } else { + this.server = net.createServer() + } + this._socketTimeout = options.socketTimeout || DEFAULT_SOCKET_TIMEOUT; // flag to avoid double starts @@ -54,7 +64,7 @@ class TunnelAgent extends Agent { this.started = true; this.server.on('close', this._onClose.bind(this)); - this.server.on('connection', this._onConnection.bind(this)); + this.server.on(this.options.cert ? 'secureConnection': 'connection', this._onConnection.bind(this)); this.server.on('error', (err) => { // These errors happen from killed connections, we don't worry about them if (err.code == 'ECONNRESET' || err.code == 'ETIMEDOUT') { @@ -119,7 +129,8 @@ class TunnelAgent extends Agent { }); // close will be emitted after this - socket.once('error', () => { + socket.once('error', (err) => { + console.log(err) // we do not log these errors, sessions can drop from clients for many reasons // these are not actionable errors for our server socket.destroy(); diff --git a/package-lock.json b/package-lock.json index 446323b..beb3c8c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { - "name": "mytunnel-server", - "version": "1.0.0", + "name": "@fusebit/tunnel-server", + "version": "1.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -41,46 +41,12 @@ } }, "ansi-align": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", - "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", "dev": true, "requires": { - "string-width": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } + "string-width": "^4.1.0" } }, "ansi-colors": { @@ -90,11 +56,20 @@ "dev": true }, "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", @@ -116,17 +91,31 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "requires": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + }, + "dependencies": { + "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" + } + } + } }, "balanced-match": { "version": "1.0.0", @@ -166,8 +155,7 @@ "dependencies": { "ansi-regex": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "resolved": "", "dev": true }, "ansi-styles": { @@ -310,6 +298,38 @@ } } }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "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" + }, + "dependencies": { + "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" + } + } + } + }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" + }, "chokidar": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", @@ -347,40 +367,6 @@ "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "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==", - "dev": true - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } } }, "clone-response": { @@ -397,11 +383,25 @@ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" }, + "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==", + "dev": 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==", + "dev": 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==", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -471,6 +471,11 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" + }, "crypto-random-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", @@ -485,6 +490,12 @@ "ms": "2.0.0" } }, + "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 + }, "decompress-response": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", @@ -514,8 +525,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "delegates": { "version": "1.0.0", @@ -585,6 +595,16 @@ "stackframe": "^0.3.1" } }, + "es6-promise": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", + "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=" + }, + "es6-promisify": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-6.1.1.tgz", + "integrity": "sha512-HBL8I3mIki5C1Cc9QjKUenHtnG0A5/xA8Q/AllRcfiwl2CZFXGK7ddBiCoRwAix4i2KxcQfjtIVcrVbB3vbmwg==" + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -602,10 +622,16 @@ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, + "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 + }, "esm": { - "version": "3.0.34", - "resolved": "https://registry.npmjs.org/esm/-/esm-3.0.34.tgz", - "integrity": "sha512-napl1sk7uu4ULhGVWVGIleN2G1TpURvfq5+ALLSc1V4jXcbftCtV8RIOkHw46UnLtzw3xIZgMES39f6N75JhtA==" + "version": "3.2.25", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", + "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==" }, "extend": { "version": "3.0.2", @@ -622,12 +648,27 @@ "to-regex-range": "^5.0.1" } }, + "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 }, + "follow-redirects": { + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", + "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" + }, "form-data": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", @@ -679,9 +720,9 @@ } }, "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -735,10 +776,10 @@ "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "dev": true }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "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-yarn": { @@ -857,6 +898,11 @@ "binary-extensions": "^2.0.0" } }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, "is-ci": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", @@ -872,12 +918,6 @@ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, "is-generator-function": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz", @@ -938,6 +978,12 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "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-yarn-global": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", @@ -952,13 +998,12 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "js-yaml": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", - "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "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" @@ -1099,63 +1144,13 @@ } }, "log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "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.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "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==", - "dev": 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==", - "dev": true - }, - "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 - }, - "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" - } - } + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" } }, "lowercase-keys": { @@ -1181,6 +1176,16 @@ } } }, + "md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "requires": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -1226,47 +1231,80 @@ } }, "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true }, "mocha": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.3.0.tgz", - "integrity": "sha512-TQqyC89V1J/Vxx0DhJIXlq9gbbL9XFNdeLQ1+JsnZsVaSOV1z3tWfw0qZmQJGQRIfkvZcs7snQnZnOCKoldq1Q==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz", + "integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==", "dev": true, "requires": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.5.1", - "debug": "4.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.1.6", - "growl": "1.10.5", + "glob": "7.2.0", "he": "1.2.0", - "js-yaml": "4.0.0", - "log-symbols": "4.0.0", - "minimatch": "3.0.4", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", "ms": "2.1.3", - "nanoid": "3.1.20", - "serialize-javascript": "5.0.1", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", - "which": "2.0.2", - "wide-align": "1.1.3", - "workerpool": "6.1.0", + "workerpool": "6.2.1", "yargs": "16.2.0", "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" }, "dependencies": { + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "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" + } + }, + "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" + } + }, "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -1280,20 +1318,22 @@ } } }, - "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 + "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" + } }, - "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==", + "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": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" + "brace-expansion": "^2.0.1" } }, "ms": { @@ -1302,19 +1342,13 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "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==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "requires": { - "isexe": "^2.0.0" + "picomatch": "^2.2.1" } } } @@ -1325,9 +1359,9 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "nanoid": { - "version": "3.1.20", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", - "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", "dev": true }, "negotiator": { @@ -1401,9 +1435,9 @@ "dev": true }, "normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", "dev": true }, "on-finished": { @@ -1428,14 +1462,18 @@ "integrity": "sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q=" }, "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.5.2.tgz", + "integrity": "sha1-hcjBRUszFeSniUfoV7HfAzRQv7w=", "requires": { - "minimist": "~0.0.1", "wordwrap": "~0.0.2" } }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, "p-cancelable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", @@ -1485,6 +1523,12 @@ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, + "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==", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -1499,6 +1543,36 @@ "isarray": "0.0.1" } }, + "pem": { + "version": "1.14.4", + "resolved": "https://registry.npmjs.org/pem/-/pem-1.14.4.tgz", + "integrity": "sha512-v8lH3NpirgiEmbOqhx0vwQTxwi0ExsiWBGYh0jYNq7K6mQuO4gI6UEFlr6fLAdv9TPXRt6GqiwE37puQdIDS8g==", + "requires": { + "es6-promisify": "^6.0.0", + "md5": "^2.2.1", + "os-tmpdir": "^1.0.1", + "which": "^2.0.2" + } + }, + "pem-promise": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pem-promise/-/pem-promise-1.0.0.tgz", + "integrity": "sha1-ejaayVljcTD54zpSrGge+ztZzE8=", + "requires": { + "es6-promisify": "^4.1.0", + "pem": "^1.8.3" + }, + "dependencies": { + "es6-promisify": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-4.1.0.tgz", + "integrity": "sha1-28waPpP9uOnnCXRBgrfSCAwD/bM=", + "requires": { + "es6-promise": "^3.2.1" + } + } + } + }, "picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", @@ -1573,12 +1647,6 @@ "strip-json-comments": "~2.0.1" }, "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -1681,9 +1749,9 @@ } }, "serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "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" @@ -1711,13 +1779,22 @@ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "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==", + "dev": true + } } }, "string_decoder": { @@ -1730,12 +1807,12 @@ } }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^5.0.1" } }, "strip-json-comments": { @@ -1779,14 +1856,6 @@ "dev": true, "requires": { "has-flag": "^4.0.0" - }, - "dependencies": { - "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 - } } }, "term-size": { @@ -1958,9 +2027,9 @@ } }, "urijs": { - "version": "1.19.6", - "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.6.tgz", - "integrity": "sha512-eSXsXZ2jLvGWeLYlQA3Gh36BcjF+0amo92+wHPyN1mdR8Nxf75fuEuYTd9c0a+m/vhCjRK0ESlE9YNLW+E1VEw==" + "version": "1.19.11", + "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz", + "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==" }, "url-parse-lax": { "version": "3.0.0", @@ -1982,13 +2051,12 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "requires": { - "string-width": "^1.0.2 || 2" + "isexe": "^2.0.0" } }, "widest-line": { @@ -2002,8 +2070,7 @@ "dependencies": { "ansi-regex": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "resolved": "", "dev": true }, "is-fullwidth-code-point": { @@ -2040,9 +2107,9 @@ "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" }, "workerpool": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", - "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", "dev": true }, "wrap-ansi": { @@ -2054,64 +2121,6 @@ "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "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==", - "dev": 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==", - "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==", - "dev": true - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } } }, "wrappy": { @@ -2132,13 +2141,10 @@ } }, "ws": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-5.1.1.tgz", - "integrity": "sha512-bOusvpCb09TOBLbpMKszd45WKC2KPtxiyiHanv+H2DE3Az+1db5a/L7sVJZVDPUC1Br8f0SKRr1KjLpD1U/IAw==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.6.0.tgz", + "integrity": "sha512-AzmM3aH3gk0aX7/rZLYvjdvZooofDu3fFOzGqcSnQ1tOcTWwhM/o+q++E8mAyVVIyUdajrkzWUGftaVSDLn1bw==", + "dev": true }, "xdg-basedir": { "version": "4.0.0", @@ -2147,9 +2153,9 @@ "dev": true }, "y18n": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", - "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yargs": { @@ -2165,40 +2171,6 @@ "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "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==", - "dev": true - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } } }, "yargs-parser": { @@ -2217,20 +2189,6 @@ "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" - }, - "dependencies": { - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "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": { diff --git a/package.json b/package.json index 454e34b..1527647 100644 --- a/package.json +++ b/package.json @@ -1,38 +1,45 @@ { "type": "module", - "author": "Vladlen Fedosov ", - "name": "mytunnel-server", + "author": "Fusebit", + "name": "@fusebit/tunnel-server", "description": "Expose localhost to the world", - "version": "1.0.0", + "version": "1.1.0", "license": "MIT", "engines": { "node": ">=14" }, "repository": { "type": "git", - "url": "git://github.com/StyleT/mytunnel-server.git" + "url": "git://github.com/fusebit/tunnel-server.git" }, "dependencies": { + "axios": "0.27.2", "book": "1.3.3", "debug": "3.1.0", - "esm": "3.0.34", + "esm": "3.2.25", "human-readable-ids": "1.0.3", "koa": "2.5.1", "koa-router": "7.4.0", "localenv": "0.2.2", - "optimist": "0.6.1", + "optimist": "0.5.2", + "pem": "1.14.4", + "pem-promise": "1.0.0", "pump": "3.0.0", "tldjs": "2.3.1" }, "devDependencies": { - "mocha": "^8.3.0", + "mocha": "10.0.0", "nodemon": "2.0.7", "supertest": "3.1.0", - "ws": "5.1.1" + "ws": "8.6.0" + }, + "bin": { + "ft-server": "bin/server.js" }, "scripts": { "test": "mocha --check-leaks **/*.test.js", "start": "./bin/server.js", - "dev": "DEBUG=mytunnel* nodemon bin/server.js --port 3000" - } + "dev": "DEBUG=fusetunnel* nodemon bin/server.js --port 3000" + }, + "private": false } diff --git a/server.js b/server.js index 3cc767f..b1cb16d 100644 --- a/server.js +++ b/server.js @@ -2,16 +2,16 @@ import Koa from 'koa'; import tldjs from 'tldjs'; import Debug from 'debug'; import http from 'http'; +import https from 'https'; import { hri } from 'human-readable-ids'; import Router from 'koa-router'; import ClientManager from './lib/ClientManager.js'; - +import fs from 'fs'; const debug = Debug('mytunnel:server'); export default function(opt) { opt = opt || {}; - const validHosts = (opt.domain) ? [opt.domain] : undefined; const myTldjs = tldjs.fromUserSettings({ validHosts }); @@ -27,6 +27,9 @@ export default function(opt) { const router = new Router(); router.get('/api/status', async (ctx, next) => { + if (opt.secret && ctx.headers.authorization !== opt.secret) { + ctx.throw(401); + } ctx.body = { tunnelsCount: manager.stats.tunnels, tunnels: manager.getClients(), @@ -35,6 +38,9 @@ export default function(opt) { }); router.get('/api/tunnels/:id/status', async (ctx, next) => { + if (opt.secret && ctx.headers.authorization !== opt.secret) { + ctx.throw(401); + } const clientId = ctx.params.id; const client = manager.getClient(clientId); if (!client) { @@ -63,6 +69,9 @@ export default function(opt) { const isNewClientRequest = ctx.query['new'] !== undefined; if (isNewClientRequest) { + if (opt.secret && ctx.headers.authorization !== opt.secret) { + ctx.throw(401); + } const reqId = hri.random(); debug('making new client with id %s', reqId); const info = await manager.newClient(reqId); @@ -107,13 +116,13 @@ export default function(opt) { const info = await manager.newClient(reqId); const url = schema + '://' + info.id + '.' + ctx.request.host; - info.url = url; + info.url = url; + console.log(info) + info.OverrideTunnelIp = opt.OverrideTunnelIp; ctx.body = info; return; }); - - const server = http.createServer(); - + let server = !opt.webcert ? http.createServer(): https.createServer({cert: fs.readFileSync(opt.webcert), key: fs.readFileSync(opt.webkey), ca: fs.readFileSync(opt.webca), minVersion: 'TLSv1.2'}) const appCallback = app.callback(); server.on('request', (req, res) => {