From fede204c6b0e957c23ded3eb76f36427e8e81a95 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karol=20Wypch=C5=82o?=
Date: Thu, 1 Apr 2021 15:15:37 +0200
Subject: [PATCH] Accounts (#554)
* stripe env
* stripe env
* stripe env
* allow post
* accounts/**
* accounts/**
* accounts/**
* accounts/**
* accounts/**
* accounts/**
* accounts/**
* accounts/**
* accounts/**
* accounts/**
* accounts/**
* accounts/**
* accounts/**
* accounts/**
* accounts/**
* accounts/**
* accounts/**
* favicon
* foo
* foo
* foo
* foo
* foo
* foo
* title
* fix dashboard timestamp
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* prices
* Revert "prices"
This reverts commit 7071ed4ef4641bc7a7247f2b56ba1159c9606112.
* Make sure we don't accidentally commit `kratos.yml`.
* Add Oathkeeper access rules for Stripe.
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* Add `max_breaches` to Kratos's sample config file.
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* payments
* cache .next folder
* Use own fork of Kratos's `master` in order to get the fix for the migrations issue.
* Don't retry running Kratos migrations.
* payments
* restart: no
* no
* no
* no
* no
* no
* no
* no
* no
* no
* payments
* accounts
* accounts
* accounts
* accounts
* accounts
* accounts
* accounts
* accounts
* accounts
* accounts
* accounts
* accounts
* accounts
* accounts
* accounts
* accounts
* accounts
* accounts
* limits
* limits
* nginx depends on accounts and kratos-migrate depends on cockroach.
* upload limit rate
* upload limit rate - 2
* upload limit rate - 3
* upload limit rate - 4
* upload limit rate - 5
* upload limit rate - 6
* upload limit rate - 7
* upload limit rate - 8
* upload limit rate - 9
* forgotten password link
* use header for skylink
* use header for skylink
* use header for skylink
* use header for skylink
* use header for skylink
* use header for skylink
* use header for skylink
* use header for skylink
* copy to clipboard
* fix ratelimit issue
* Allow access to the stripe webhook.
* enable allow_promotion_codes
* Allow POST on webhook.
* Add all env vars accounts need to docker-compose.
* Don't use custom port for accounts.
* print recovery
* recovery sign up link
* refactor cors header response
* refactor cors header response
* do not log unauthorized
* fix registration link
* settings logging
* update node and tailwindcss
* move webapp from volume
* host 0.0.0.0
* refactor dockerfile
* enable accounts
* cache public
* uncache public
* remove cache control
* no-cache
* no cache
* Do not use the person's name for registration.
* add verify route
* add verify route
* add verify route
* Go back to using the stock kratos image.
* add verify route
* fix settings link
* clean up verify flow
* refactor Dockerfile
* Remove first and last name from used traits.
* Remove account verification via email.
* Allow additional properties.
* Cookies and tokens last for 30 days now.
* Rename secure.siasky.net to account.siasky.net.
* redirect secure to account
Co-authored-by: Ivaylo Novakov
Co-authored-by: Ivaylo Novakov
---
.gitignore | 11 +
.prettierignore | 2 +
README.md | 152 +-
docker-compose.accounts.yml | 167 ++
docker-compose.uploads.yml | 12 +
docker-compose.yml | 27 +-
docker/accounts/Dockerfile | 20 +
docker/accounts/nginx.account.conf | 20 +
docker/cockroach/certs/README.md | 2 +
docker/handshake/Dockerfile | 4 +-
docker/kratos/config/identity.schema.json | 31 +
docker/kratos/config/kratos.yml.sample | 86 +
.../config/oidc/identity.traits.schema.json | 37 +
docker/kratos/config/oidc/oidc.github.jsonnet | 17 +
docker/kratos/cr_certs/README.md | 7 +
docker/kratos/oathkeeper/access-rules.yml | 116 ++
docker/kratos/oathkeeper/oathkeeper.yml | 94 +
docker/nginx/Dockerfile | 2 +-
docker/nginx/Dockerfile.bionic | 185 ++
docker/nginx/conf.d/client.conf | 125 +-
docker/nginx/nginx.conf | 2 +
docker/nginx/nginx.vh.default.conf | 58 +
package.json | 6 +-
packages/dashboard/.env | 4 +
packages/dashboard/.gitignore | 38 +
packages/dashboard/.prettierignore | 3 +
packages/dashboard/.prettierrc | 3 +
packages/dashboard/Dockerfile | 16 +
packages/dashboard/README.md | 34 +
packages/dashboard/package.json | 43 +
packages/dashboard/postcss.config.js | 6 +
packages/dashboard/public/favicon.ico | Bin 0 -> 2118 bytes
.../dashboard/src/components/Form/Message.js | 62 +
.../src/components/Form/SelfServiceForm.js | 104 ++
.../components/Form/SelfServiceMessages.js | 45 +
packages/dashboard/src/components/Layout.js | 327 ++++
packages/dashboard/src/components/Table.js | 128 ++
packages/dashboard/src/config.js | 14 +
packages/dashboard/src/pages/_app.js | 21 +
.../dashboard/src/pages/api/accounts/login.js | 19 +
.../dashboard/src/pages/api/square/cards.js | 58 +
.../src/pages/api/square/invoices.js | 45 +
.../src/pages/api/square/subscription.js | 46 +
.../pages/api/square/subscription/cancel.js | 55 +
.../pages/api/square/subscription/restore.js | 58 +
.../dashboard/src/pages/api/stripe/billing.js | 28 +
.../src/pages/api/stripe/checkout.js | 59 +
.../src/pages/api/stripe/subscription.js | 23 +
.../src/pages/api/stubs/stripe/prices.js | 37 +
.../dashboard/src/pages/api/stubs/user.js | 5 +
.../dashboard/src/pages/api/stubs/user.json | 12 +
.../src/pages/api/stubs/user/downloads.js | 8 +
.../src/pages/api/stubs/user/downloads.json | 44 +
.../src/pages/api/stubs/user/stats.js | 5 +
.../src/pages/api/stubs/user/stats.json | 13 +
.../src/pages/api/stubs/user/uploads.js | 8 +
.../src/pages/api/stubs/user/uploads.json | 44 +
packages/dashboard/src/pages/auth/login.js | 96 ++
.../dashboard/src/pages/auth/registration.js | 113 ++
packages/dashboard/src/pages/downloads.js | 44 +
packages/dashboard/src/pages/error.js | 68 +
packages/dashboard/src/pages/index.js | 276 +++
packages/dashboard/src/pages/payments.js | 193 +++
packages/dashboard/src/pages/plans.js | 389 +++++
packages/dashboard/src/pages/recovery.js | 95 ++
packages/dashboard/src/pages/settings.js | 83 +
packages/dashboard/src/pages/uploads.js | 44 +
packages/dashboard/src/pages/verify.js | 103 ++
.../src/services/authServerSideProps.js | 27 +
.../src/services/longestCommonSequence.js | 65 +
packages/dashboard/src/services/tiers.js | 2 +
.../dashboard/src/services/useAccountsApi.js | 15 +
packages/dashboard/stubs/login.json | 45 +
packages/dashboard/stubs/recovery.json | 31 +
packages/dashboard/stubs/registration.json | 58 +
packages/dashboard/stubs/settings.json | 49 +
packages/dashboard/styles/Home.module.css | 122 ++
packages/dashboard/styles/globals.css | 16 +
packages/dashboard/tailwind.config.js | 18 +
packages/handshake-api/Dockerfile | 2 +-
packages/health-check/Dockerfile | 2 +-
packages/webapp/Dockerfile | 21 +-
packages/webapp/package.json | 2 +
.../webapp/src/components/HomeTop/HomeTop.js | 13 +
.../src/components/HomeTop/HomeTop.scss | 12 +
scripts/crdb_backup.sh | 21 +
scripts/crdb_restore.sh | 25 +
scripts/mongo_backup.sh | 32 +
scripts/mongo_restore.sh | 40 +
setup-scripts/README.md | 13 +
setup-scripts/setup-docker-services.sh | 16 +-
setup-scripts/setup-server.sh | 2 +-
yarn.lock | 1516 ++++++++++++++++-
93 files changed, 6140 insertions(+), 127 deletions(-)
create mode 100644 .prettierignore
create mode 100644 docker-compose.accounts.yml
create mode 100644 docker-compose.uploads.yml
create mode 100644 docker/accounts/Dockerfile
create mode 100644 docker/accounts/nginx.account.conf
create mode 100644 docker/cockroach/certs/README.md
create mode 100644 docker/kratos/config/identity.schema.json
create mode 100644 docker/kratos/config/kratos.yml.sample
create mode 100644 docker/kratos/config/oidc/identity.traits.schema.json
create mode 100644 docker/kratos/config/oidc/oidc.github.jsonnet
create mode 100644 docker/kratos/cr_certs/README.md
create mode 100644 docker/kratos/oathkeeper/access-rules.yml
create mode 100644 docker/kratos/oathkeeper/oathkeeper.yml
create mode 100644 docker/nginx/Dockerfile.bionic
create mode 100644 docker/nginx/nginx.vh.default.conf
create mode 100644 packages/dashboard/.env
create mode 100644 packages/dashboard/.gitignore
create mode 100644 packages/dashboard/.prettierignore
create mode 100644 packages/dashboard/.prettierrc
create mode 100644 packages/dashboard/Dockerfile
create mode 100644 packages/dashboard/README.md
create mode 100644 packages/dashboard/package.json
create mode 100644 packages/dashboard/postcss.config.js
create mode 100644 packages/dashboard/public/favicon.ico
create mode 100644 packages/dashboard/src/components/Form/Message.js
create mode 100644 packages/dashboard/src/components/Form/SelfServiceForm.js
create mode 100644 packages/dashboard/src/components/Form/SelfServiceMessages.js
create mode 100644 packages/dashboard/src/components/Layout.js
create mode 100644 packages/dashboard/src/components/Table.js
create mode 100644 packages/dashboard/src/config.js
create mode 100644 packages/dashboard/src/pages/_app.js
create mode 100644 packages/dashboard/src/pages/api/accounts/login.js
create mode 100644 packages/dashboard/src/pages/api/square/cards.js
create mode 100644 packages/dashboard/src/pages/api/square/invoices.js
create mode 100644 packages/dashboard/src/pages/api/square/subscription.js
create mode 100644 packages/dashboard/src/pages/api/square/subscription/cancel.js
create mode 100644 packages/dashboard/src/pages/api/square/subscription/restore.js
create mode 100644 packages/dashboard/src/pages/api/stripe/billing.js
create mode 100644 packages/dashboard/src/pages/api/stripe/checkout.js
create mode 100644 packages/dashboard/src/pages/api/stripe/subscription.js
create mode 100644 packages/dashboard/src/pages/api/stubs/stripe/prices.js
create mode 100644 packages/dashboard/src/pages/api/stubs/user.js
create mode 100644 packages/dashboard/src/pages/api/stubs/user.json
create mode 100644 packages/dashboard/src/pages/api/stubs/user/downloads.js
create mode 100644 packages/dashboard/src/pages/api/stubs/user/downloads.json
create mode 100644 packages/dashboard/src/pages/api/stubs/user/stats.js
create mode 100644 packages/dashboard/src/pages/api/stubs/user/stats.json
create mode 100644 packages/dashboard/src/pages/api/stubs/user/uploads.js
create mode 100644 packages/dashboard/src/pages/api/stubs/user/uploads.json
create mode 100644 packages/dashboard/src/pages/auth/login.js
create mode 100644 packages/dashboard/src/pages/auth/registration.js
create mode 100644 packages/dashboard/src/pages/downloads.js
create mode 100644 packages/dashboard/src/pages/error.js
create mode 100644 packages/dashboard/src/pages/index.js
create mode 100644 packages/dashboard/src/pages/payments.js
create mode 100644 packages/dashboard/src/pages/plans.js
create mode 100644 packages/dashboard/src/pages/recovery.js
create mode 100644 packages/dashboard/src/pages/settings.js
create mode 100644 packages/dashboard/src/pages/uploads.js
create mode 100644 packages/dashboard/src/pages/verify.js
create mode 100644 packages/dashboard/src/services/authServerSideProps.js
create mode 100644 packages/dashboard/src/services/longestCommonSequence.js
create mode 100644 packages/dashboard/src/services/tiers.js
create mode 100644 packages/dashboard/src/services/useAccountsApi.js
create mode 100644 packages/dashboard/stubs/login.json
create mode 100644 packages/dashboard/stubs/recovery.json
create mode 100644 packages/dashboard/stubs/registration.json
create mode 100644 packages/dashboard/stubs/settings.json
create mode 100644 packages/dashboard/styles/Home.module.css
create mode 100644 packages/dashboard/styles/globals.css
create mode 100644 packages/dashboard/tailwind.config.js
create mode 100644 scripts/crdb_backup.sh
create mode 100644 scripts/crdb_restore.sh
create mode 100644 scripts/mongo_backup.sh
create mode 100644 scripts/mongo_restore.sh
diff --git a/.gitignore b/.gitignore
index e2f92125..d1821376 100644
--- a/.gitignore
+++ b/.gitignore
@@ -53,6 +53,7 @@ typings/
# dotenv environment variable files
.env*
+./docker/kratos/config/kratos.yml
# Mac files
.DS_Store
@@ -82,3 +83,13 @@ docker/nginx/conf.d/server-override/*
__pycache__
/.idea/
/venv*
+
+# CockroachDB certificates
+docker/cockroach/certs/*.crt
+docker/cockroach/certs/*.key
+docker/kratos/cr_certs/*.crt
+docker/kratos/cr_certs/*.key
+
+# Oathkeeper JWKS signing token
+docker/kratos/oathkeeper/id_token.jwks.json
+/docker/kratos/config/kratos.yml
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 00000000..6ec8e548
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,2 @@
+/package.json
+/package-lock.json
\ No newline at end of file
diff --git a/README.md b/README.md
index 8cd84d05..59c2e5df 100644
--- a/README.md
+++ b/README.md
@@ -26,12 +26,160 @@ following Siacoin address:
`fb6c9320bc7e01fbb9cd8d8c3caaa371386928793c736837832e634aaaa484650a3177d6714a`
+### MongoDB Setup
+
+Mongo needs a couple of extra steps in order to start a secure cluster.
+
+- Open port 27017 on all nodes that will take part in the cluster. Ideally, you would only open the port for the other
+ nodes in the cluster.
+- Manually run an initialisation `docker run` with extra environment variables that will initialise the admin user with
+ a password (example below).
+- Manually add a `mgkey` file under `./docker/data/mongo` with the respective secret (
+ see [Mongo's keyfile access control](https://docs.mongodb.com/manual/tutorial/enforce-keyfile-access-control-in-existing-replica-set/)
+ for details).
+- During the initialisation run mentioned above, we need to make two extra steps within the container:
+ - Change the ownership of `mgkey` to `mongodb:mongodb`
+ - Change its permissions to 400
+- After these steps are done we can open a mongo shell on the master node and run `rs.add()` in order to add the new
+ node to the cluster.
+
+Example initialisation docker run command:
+
+```
+docker run \
+ --rm \
+ --name mg \
+ -p 27017:27017 \
+ -e MONGO_INITDB_ROOT_USERNAME= \
+ -e MONGO_INITDB_ROOT_PASSWORD= \
+ -v /home/user/skynet-webportal/docker/data/mongo/db:/data/db \
+ -v /home/user/skynet-webportal/docker/data/mongo/mgkey:/data/mgkey \
+ mongo --keyFile=/data/mgkey --replSet=skynet
+```
+
+Regular docker run command:
+
+```
+docker run \
+ --rm \
+ --name mg \
+ -p 27017:27017 \
+ -v /home/user/skynet-webportal/docker/data/mongo/db:/data/db \
+ -v /home/user/skynet-webportal/docker/data/mongo/mgkey:/data/mgkey \
+ mongo --keyFile=/data/mgkey --replSet=skynet
+```
+
+Cluster initialisation mongo command:
+
+```
+rs.initiate(
+ {
+ _id : "skynet",
+ members: [
+ { _id : 0, host : "mongo:27017" }
+ ]
+ }
+)
+```
+
+Add more nodes when they are ready:
+
+```
+rs.add("second.node.net:27017")
+```
+
+### Kratos & Oathkeeper Setup
+
+[Kratos](https://www.ory.sh/kratos) is our user management system of choice and
+[Oathkeeper](https://www.ory.sh/oathkeeper) is the identity and access proxy.
+
+Most of the needed config is already under `docker/kratos`. The only two things that need to be changed are the config
+for Kratos that might contain you email server password, and the JWKS Oathkeeper uses to sign its JWT tokens.
+
+Make sure to create your own`docker/kratos/config/kratos.yml` by copying the `kratos.yml.sample` in the same directory.
+Also make sure to never add that file to source control because it will most probably contain your email password in
+plain text!
+
+To override the JWKS you will need to directly edit
+`docker/kratos/oathkeeper/id_token.jwks.json` and replace it with your generated key set. If you don't know how to
+generate a key set you can use this code:
+
+```go
+package main
+
+import (
+ "encoding/json"
+ "log"
+ "os"
+
+ "github.com/ory/hydra/jwk"
+)
+
+func main() {
+ gen := jwk.RS256Generator{
+ KeyLength: 2048,
+ }
+ jwks, err := gen.Generate("", "sig")
+ if err != nil {
+ log.Fatal(err)
+ }
+ jsonbuf, err := json.MarshalIndent(jwks, "", " ")
+ if err != nil {
+ log.Fatal("failed to generate JSON: %s", err)
+ }
+ os.Stdout.Write(jsonbuf)
+}
+```
+
+While you can directly put the output of this programme into the file mentioned above, you can also remove the public
+key from the set and change the `kid` of the private key to not include the prefix `private:`.
+
+### CockroachDB Setup
+
+Kratos uses CockroachDB to store its data. For that data to be shared across all nodes that comprise your portal cluster
+setup, we need to set up a CockroachDB cluster, complete with secure communication.
+
+#### Generate the certificates for secure communication
+
+For a detailed walk-through, please check [this guide](https://www.cockroachlabs.com/docs/v20.2/secure-a-cluster.html)
+out.
+
+Steps:
+
+1. Start a local cockroach docker instance:
+ `docker run -d -v ":/cockroach/cockroach-secure" --name=crdb cockroachdb/cockroach start --insecure`
+1. Get a shall into that instance: `docker exec -it crdb /bin/bash`
+1. Go to the directory we which we mapped to a local dir: `cd /cockroach/cockroach-secure`
+1. Create the subdirectories in which to create certificates and keys: `mkdir certs my-safe-directory`
+1. Create the CA (Certificate Authority) certificate and key
+ pair: `cockroach cert create-ca --certs-dir=certs --ca-key=my-safe-directory/ca.key`
+1. Create a client certificate and key pair for the root
+ user: `cockroach cert create-client root --certs-dir=certs --ca-key=my-safe-directory/ca.key`
+1. Create the certificate and key pair for your
+ nodes: `cockroach cert create-node cockroach mynode.siasky.net --certs-dir=certs --ca-key=my-safe-directory/ca.key`.
+ Don't forget the `cockroach` node name - it's needed by our docker-compose setup. If you want to create certificates
+ for more nodes, just delete the `node.*` files (after you've finished the next steps for this node!) and re-run the
+ above command with the new node name.
+1. Put the contents of the `certs` folder under `docker/cockroach/certs/*` under your portal's root dir and store the
+ content of `my-safe-directory` somewhere safe.
+1. Put _another copy_ of those certificates under `docker/kratos/cr_certs` and change permissions of the `*.key` files,
+ so they can be read by anyone (644).
+
+#### Configure your CockroachDB node
+
+There is some configuration that needs to be added to your `.env`file, namely:
+
+1. CR_NODE - the name of your node
+1. CR_IP - the public IP of your node
+1. CR_CLUSTER_NODES - a list of IPs and ports which make up your cluster, e.g.
+ `95.216.13.185:26257,147.135.37.21:26257,144.76.136.122:26257`. This will be the list of nodes that will make up your
+ cluster, so make sure those are accurate.
+
## Contributing
### Testing Your Code
-Before pushing your code you should verify that it will pass our online test
-suite.
+Before pushing your code, you should verify that it will pass our online test suite.
**Cypress Tests**
Verify the Cypress test suite by doing the following:
diff --git a/docker-compose.accounts.yml b/docker-compose.accounts.yml
new file mode 100644
index 00000000..22d24541
--- /dev/null
+++ b/docker-compose.accounts.yml
@@ -0,0 +1,167 @@
+version: "3.7"
+
+x-logging: &default-logging
+ driver: json-file
+ options:
+ max-size: "10m"
+ max-file: "3"
+
+services:
+ webapp:
+ build:
+ args:
+ WITH_ACCOUNTS: 1 # enable accounts frontend
+
+ nginx:
+ environment:
+ - ACCOUNTS_ENABLED=1
+ volumes:
+ - ./docker/accounts/nginx.account.conf:/etc/nginx/conf.extra.d/nginx.account.conf:ro
+ depends_on:
+ - accounts
+
+ accounts:
+ build:
+ context: ./docker/accounts
+ dockerfile: Dockerfile
+ container_name: accounts
+ restart: unless-stopped
+ logging: *default-logging
+ env_file:
+ - .env
+ environment:
+ - SKYNET_DB_HOST=${SKYNET_DB_HOST}
+ - SKYNET_DB_PORT=${SKYNET_DB_PORT}
+ - SKYNET_DB_USER=${SKYNET_DB_USER}
+ - SKYNET_DB_PASS=${SKYNET_DB_PASS}
+ - COOKIE_DOMAIN=${COOKIE_DOMAIN}
+ - COOKIE_HASH_KEY=${COOKIE_HASH_KEY}
+ - COOKIE_ENC_KEY=${COOKIE_ENC_KEY}
+ - STRIPE_API_KEY=${STRIPE_API_KEY}
+ - STRIPE_WEBHOOK_SECRET=${STRIPE_WEBHOOK_SECRET}
+ - SKYNET_ACCOUNTS_LOG_LEVEL=${SKYNET_ACCOUNTS_LOG_LEVEL}
+ - KRATOS_ADDR=${KRATOS_ADDR}
+ - OATHKEEPER_ADDR=${OATHKEEPER_ADDR}
+ expose:
+ - 3000
+ networks:
+ shared:
+ ipv4_address: 10.10.10.70
+ depends_on:
+ - mongo
+ - oathkeeper
+
+ mongo:
+ image: mongo:4.4.1
+ command: --keyFile=/data/mgkey --replSet=skynet
+ container_name: mongo
+ restart: unless-stopped
+ logging: *default-logging
+ volumes:
+ - ./docker/data/mongo/db:/data/db
+ - ./docker/data/mongo/mgkey:/data/mgkey:rw
+ networks:
+ shared:
+ ipv4_address: 10.10.10.71
+ ports:
+ - "27017:27017"
+
+ kratos-migrate:
+ image: oryd/kratos:v0.5.5-alpha.1
+ container_name: kratos-migrate
+ restart: "no"
+ logging: *default-logging
+ environment:
+ - DSN=cockroach://root@cockroach:26257/defaultdb?max_conns=20&max_idle_conns=4&sslmode=verify-full&sslcert=/certs/node.crt&sslkey=/certs/node.key&sslrootcert=/certs/ca.crt
+ - SQA_OPT_OUT=true
+ volumes:
+ - ./docker/kratos/config:/etc/config/kratos
+ - ./docker/data/cockroach/sqlite:/var/lib/sqlite
+ - ./docker/kratos/cr_certs:/certs
+ command: -c /etc/config/kratos/kratos.yml migrate sql -e --yes
+ networks:
+ shared:
+ ipv4_address: 10.10.10.80
+ depends_on:
+ - cockroach
+
+ kratos:
+ image: oryd/kratos:v0.5.5-alpha.1
+ container_name: kratos
+ restart: unless-stopped
+ logging: *default-logging
+ expose:
+ - 4433 # public
+ - 4434 # admin
+ environment:
+ - DSN=cockroach://root@cockroach:26257/defaultdb?max_conns=20&max_idle_conns=4&sslmode=verify-full&sslcert=/certs/node.crt&sslkey=/certs/node.key&sslrootcert=/certs/ca.crt
+ - LOG_LEVEL=trace
+ - SERVE_PUBLIC_BASE_URL=${SKYNET_DASHBOARD_URL}/.ory/kratos/public/
+ - SQA_OPT_OUT=true
+ command: serve -c /etc/config/kratos/kratos.yml
+ volumes:
+ - ./docker/kratos/config:/etc/config/kratos
+ - ./docker/data/cockroach/sqlite:/var/lib/sqlite
+ - ./docker/kratos/cr_certs:/certs
+ networks:
+ shared:
+ ipv4_address: 10.10.10.81
+ depends_on:
+ - kratos-migrate
+
+ dashboard:
+ build:
+ context: ./packages/dashboard
+ dockerfile: Dockerfile
+ container_name: dashboard
+ restart: unless-stopped
+ logging: *default-logging
+ env_file:
+ - .env
+ environment:
+ - NEXT_PUBLIC_SKYNET_PORTAL_API=${SKYNET_PORTAL_API}
+ - NEXT_PUBLIC_SKYNET_DASHBOARD_URL=${SKYNET_DASHBOARD_URL}
+ - NEXT_PUBLIC_KRATOS_BROWSER_URL=${SKYNET_DASHBOARD_URL}/.ory/kratos/public
+ - NEXT_PUBLIC_KRATOS_PUBLIC_URL=${SKYNET_DASHBOARD_URL}/.ory/kratos/public
+ - NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=${STRIPE_PUBLISHABLE_KEY}
+ volumes:
+ - ./docker/data/dashboard/.next:/usr/app/.next
+ networks:
+ shared:
+ ipv4_address: 10.10.10.85
+ expose:
+ - 3000
+
+ oathkeeper:
+ image: oryd/oathkeeper:v0.38
+ container_name: oathkeeper
+ expose:
+ - 4455
+ - 4456
+ command: serve proxy -c "/etc/config/oathkeeper/oathkeeper.yml"
+ environment:
+ - LOG_LEVEL=debug
+ volumes:
+ - ./docker/kratos/oathkeeper:/etc/config/oathkeeper
+ restart: on-failure
+ networks:
+ shared:
+ ipv4_address: 10.10.10.83
+ depends_on:
+ - kratos
+
+ cockroach:
+ image: cockroachdb/cockroach:v20.2.3
+ container_name: cockroach
+ env_file:
+ - .env
+ command: start --advertise-addr=${CR_IP} --join=${CR_CLUSTER_NODES} --certs-dir=/certs --listen-addr=0.0.0.0:26257 --http-addr=0.0.0.0:8080
+ volumes:
+ - ./docker/data/cockroach/sqlite:/cockroach/cockroach-data
+ - ./docker/cockroach/certs:/certs
+ ports:
+ - "4080:8080"
+ - "26257:26257"
+ networks:
+ shared:
+ ipv4_address: 10.10.10.84
diff --git a/docker-compose.uploads.yml b/docker-compose.uploads.yml
new file mode 100644
index 00000000..c7d3043a
--- /dev/null
+++ b/docker-compose.uploads.yml
@@ -0,0 +1,12 @@
+version: "3.7"
+
+services:
+ nginx:
+ build:
+ context: ./docker/nginx
+ dockerfile: Dockerfile.bionic
+ args:
+ RESTY_ADD_PACKAGE_BUILDDEPS: git
+ RESTY_EVAL_PRE_CONFIGURE: git clone https://github.com/fdintino/nginx-upload-module /tmp/nginx-upload-module
+ RESTY_CONFIG_OPTIONS_MORE: --add-module=/tmp/nginx-upload-module
+ RESTY_EVAL_POST_MAKE: /usr/local/openresty/luajit/bin/luarocks install luasocket
diff --git a/docker-compose.yml b/docker-compose.yml
index 12597890..5671efad 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -13,9 +13,6 @@ networks:
config:
- subnet: 10.10.10.0/24
-volumes:
- webapp:
-
services:
sia:
build:
@@ -76,7 +73,6 @@ services:
- ./docker/data/nginx/logs:/usr/local/openresty/nginx/logs
- ./docker/data/nginx/skynet:/data/nginx/skynet:ro
- ./docker/data/sia/apipassword:/data/sia/apipassword:ro
- - webapp:/var/www/webportal:ro
networks:
shared:
ipv4_address: 10.10.10.30
@@ -94,9 +90,13 @@ services:
container_name: webapp
restart: unless-stopped
logging: *default-logging
- tty: true
volumes:
- - webapp:/usr/app/public
+ - ./docker/data/webapp/.cache:/usr/app/.cache
+ networks:
+ shared:
+ ipv4_address: 10.10.10.35
+ expose:
+ - 9000
handshake:
build:
@@ -163,18 +163,3 @@ services:
depends_on:
- handshake
- handshake-api
-
- mongo:
- image: mongo:4.4.1
- command: --keyFile=/data/mgkey --replSet=skynet
- container_name: mongo
- restart: unless-stopped
- logging: *default-logging
- volumes:
- - ./docker/data/mongo/db:/data/db
- - ./docker/data/mongo/mgkey:/data/mgkey:rw
- networks:
- shared:
- ipv4_address: 10.10.10.70
- ports:
- - "27017:27017"
diff --git a/docker/accounts/Dockerfile b/docker/accounts/Dockerfile
new file mode 100644
index 00000000..8be44370
--- /dev/null
+++ b/docker/accounts/Dockerfile
@@ -0,0 +1,20 @@
+FROM golang:1.15
+LABEL maintainer="NebulousLabs "
+
+ENV GOOS linux
+ENV GOARCH amd64
+
+WORKDIR /root
+
+RUN git clone --single-branch --branch main https://github.com/NebulousLabs/skynet-accounts.git && \
+ cd skynet-accounts && \
+ go mod download && \
+ make release
+
+ENV SKYNET_DB_HOST="localhost"
+ENV SKYNET_DB_PORT="27017"
+ENV SKYNET_DB_USER="username"
+ENV SKYNET_DB_PASS="password"
+ENV SKYNET_ACCOUNTS_PORT=3000
+
+ENTRYPOINT ["skynet-accounts"]
diff --git a/docker/accounts/nginx.account.conf b/docker/accounts/nginx.account.conf
new file mode 100644
index 00000000..f3705200
--- /dev/null
+++ b/docker/accounts/nginx.account.conf
@@ -0,0 +1,20 @@
+server {
+ listen 80;
+ listen [::]:80;
+ server_name account.*;
+
+ location / {
+ proxy_redirect http://127.0.0.1/ https://$host/;
+ proxy_pass http://oathkeeper:4455;
+ }
+}
+
+server {
+ listen 80;
+ listen [::]:80;
+ server_name secure.*;
+
+ if ($host ~ secure.(.*)) {
+ return 301 $scheme://account.$1$request_uri;
+ }
+}
diff --git a/docker/cockroach/certs/README.md b/docker/cockroach/certs/README.md
new file mode 100644
index 00000000..fd957133
--- /dev/null
+++ b/docker/cockroach/certs/README.md
@@ -0,0 +1,2 @@
+This directory needs to contain all certificates needed by this cockroachdb node. Those can be generated by the steps
+outlined in the README in the root directory, under "Setting up CockroachDB".
diff --git a/docker/handshake/Dockerfile b/docker/handshake/Dockerfile
index 09525735..39ca14f2 100644
--- a/docker/handshake/Dockerfile
+++ b/docker/handshake/Dockerfile
@@ -1,8 +1,8 @@
-FROM node:15.8.0-alpine
+FROM node:15.12.0-alpine
WORKDIR /opt/hsd
-RUN apk add --no-cache bash unbound-dev gmp-dev g++ gcc make python2 git
+RUN apk update && apk add bash unbound-dev gmp-dev g++ gcc make python2 git
RUN git clone https://github.com/handshake-org/hsd.git /opt/hsd
RUN npm install --production
diff --git a/docker/kratos/config/identity.schema.json b/docker/kratos/config/identity.schema.json
new file mode 100644
index 00000000..781fc761
--- /dev/null
+++ b/docker/kratos/config/identity.schema.json
@@ -0,0 +1,31 @@
+{
+ "$id": "https://schemas.ory.sh/presets/kratos/quickstart/email-password/identity.schema.json",
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "Person",
+ "type": "object",
+ "properties": {
+ "traits": {
+ "type": "object",
+ "properties": {
+ "email": {
+ "type": "string",
+ "format": "email",
+ "title": "E-Mail",
+ "minLength": 3,
+ "ory.sh/kratos": {
+ "credentials": {
+ "password": {
+ "identifier": true
+ }
+ },
+ "recovery": {
+ "via": "email"
+ }
+ }
+ }
+ },
+ "required": ["email"],
+ "additionalProperties": true
+ }
+ }
+}
diff --git a/docker/kratos/config/kratos.yml.sample b/docker/kratos/config/kratos.yml.sample
new file mode 100644
index 00000000..15442f0f
--- /dev/null
+++ b/docker/kratos/config/kratos.yml.sample
@@ -0,0 +1,86 @@
+version: v0.5.5-alpha.1
+
+dsn: memory
+
+serve:
+ public:
+ base_url: http://127.0.0.1/
+ cors:
+ enabled: true
+ admin:
+ base_url: http://127.0.0.1/admin/
+
+selfservice:
+ default_browser_return_url: http://127.0.0.1/
+ whitelisted_return_urls:
+ - http://127.0.0.1/
+
+ methods:
+ password:
+ enabled: true
+
+ flows:
+ error:
+ ui_url: http://127.0.0.1/error
+
+ settings:
+ ui_url: http://127.0.0.1/settings
+ privileged_session_max_age: 15m
+
+ recovery:
+ enabled: true
+ ui_url: http://127.0.0.1/recovery
+
+ verification:
+ enabled: true
+ ui_url: http://127.0.0.1/verify
+ after:
+ default_browser_return_url: http://127.0.0.1/
+
+ logout:
+ after:
+ default_browser_return_url: http://127.0.0.1/auth/login
+
+ login:
+ ui_url: http://127.0.0.1/auth/login
+ lifespan: 10m
+
+ registration:
+ lifespan: 10m
+ ui_url: http://127.0.0.1/auth/registration
+ after:
+ password:
+ hooks:
+ - hook: session
+
+log:
+ level: debug
+ format: text
+ leak_sensitive_values: true
+
+password:
+ max_breaches: 100
+
+secrets:
+ cookie:
+ - PLEASE-CHANGE-ME-I-AM-VERY-INSECURE
+
+session:
+ cookie:
+ domain: account.siasky.net
+ lifespan: "720h"
+
+hashers:
+ argon2:
+ parallelism: 1
+ memory: 131072
+ iterations: 2
+ salt_length: 16
+ key_length: 16
+
+identity:
+ default_schema_url: file:///etc/config/kratos/identity.schema.json
+
+courier:
+ smtp:
+ connection_uri: smtps://test:test@mailslurper:1025/?skip_ssl_verify=true
diff --git a/docker/kratos/config/oidc/identity.traits.schema.json b/docker/kratos/config/oidc/identity.traits.schema.json
new file mode 100644
index 00000000..62de3d1b
--- /dev/null
+++ b/docker/kratos/config/oidc/identity.traits.schema.json
@@ -0,0 +1,37 @@
+{
+ "$id": "https://schemas.ory.sh/presets/kratos/quickstart/email-password/identity.schema.json",
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "Person",
+ "type": "object",
+ "properties": {
+ "traits": {
+ "type": "object",
+ "properties": {
+ "email": {
+ "type": "string",
+ "format": "email",
+ "title": "E-Mail",
+ "minLength": 3,
+ "ory.sh/kratos": {
+ "credentials": {
+ "password": {
+ "identifier": true
+ }
+ },
+ "verification": {
+ "via": "email"
+ },
+ "recovery": {
+ "via": "email"
+ }
+ }
+ },
+ "website": {
+ "type": "object"
+ }
+ },
+ "required": ["website", "email"],
+ "additionalProperties": false
+ }
+ }
+}
diff --git a/docker/kratos/config/oidc/oidc.github.jsonnet b/docker/kratos/config/oidc/oidc.github.jsonnet
new file mode 100644
index 00000000..06b92bf9
--- /dev/null
+++ b/docker/kratos/config/oidc/oidc.github.jsonnet
@@ -0,0 +1,17 @@
+local claims = {
+ email_verified: false
+} + std.extVar('claims');
+
+{
+ identity: {
+ traits: {
+ // Allowing unverified email addresses enables account
+ // enumeration attacks, especially if the value is used for
+ // e.g. verification or as a password login identifier.
+ //
+ // Therefore we only return the email if it (a) exists and (b) is marked verified
+ // by GitHub.
+ [if "email" in claims && claims.email_verified then "email" else null]: claims.email,
+ },
+ },
+}
diff --git a/docker/kratos/cr_certs/README.md b/docker/kratos/cr_certs/README.md
new file mode 100644
index 00000000..47c143eb
--- /dev/null
+++ b/docker/kratos/cr_certs/README.md
@@ -0,0 +1,7 @@
+This directory needs to contain all certificates needed by this cockroachdb node. Those can be generated by the steps
+outlined in the README in the root directory, under "Setting up CockroachDB".
+
+The only difference between the files here and those under
+`docker/cockroach/certs` is that the files here need to be readable by anyone, while the files under `cockroach` need to
+have their original access rights
+(all *.key files should be 600 instead of 644 there).
diff --git a/docker/kratos/oathkeeper/access-rules.yml b/docker/kratos/oathkeeper/access-rules.yml
new file mode 100644
index 00000000..020b6a27
--- /dev/null
+++ b/docker/kratos/oathkeeper/access-rules.yml
@@ -0,0 +1,116 @@
+- id: "ory:kratos:public"
+ upstream:
+ preserve_host: true
+ url: "http://kratos:4433"
+ strip_path: /.ory/kratos/public
+ match:
+ url: "http://oathkeeper:4455/.ory/kratos/public/<**>"
+ methods:
+ - GET
+ - POST
+ - PUT
+ - DELETE
+ - PATCH
+ authenticators:
+ - handler: noop
+ authorizer:
+ handler: allow
+ mutators:
+ - handler: noop
+
+- id: "dashboard:anonymous"
+ upstream:
+ preserve_host: true
+ url: "http://dashboard:3000"
+ match:
+ url: "http://oathkeeper:4455/<{_next/*,auth/*,recovery,verify,error,favicon.ico}{/,}>"
+ methods:
+ - GET
+ authenticators:
+ - handler: anonymous
+ authorizer:
+ handler: allow
+ mutators:
+ - handler: noop
+
+- id: "dashboard:protected"
+ upstream:
+ preserve_host: true
+ url: "http://dashboard:3000"
+ match:
+ url: "http://oathkeeper:4455/<{,api/*,settings,uploads,downloads,payments}>"
+ methods:
+ - GET
+ - POST
+ - PUT
+ - DELETE
+ - PATCH
+ authenticators:
+ - handler: cookie_session
+ authorizer:
+ handler: allow
+ mutators:
+ - handler: id_token
+ - handler: header
+ config:
+ headers:
+ X-User: "{{ print .Subject }}"
+ errors:
+ - handler: redirect
+ config:
+ to: http://127.0.0.1/auth/login
+
+- id: "accounts:anonymous"
+ upstream:
+ preserve_host: true
+ url: "http://accounts:3000"
+ match:
+ url: "http://oathkeeper<{,:4455}>/<{stripe/prices,stripe/webhook}>"
+ methods:
+ - GET
+ - POST
+ authenticators:
+ - handler: anonymous
+ authorizer:
+ handler: allow
+ mutators:
+ - handler: noop
+
+- id: "accounts:public"
+ upstream:
+ preserve_host: true
+ url: "http://accounts:3000"
+ match:
+ url: "http://oathkeeper<{,:4455}>/<{user/limits}>"
+ methods:
+ - GET
+ authenticators:
+ - handler: cookie_session
+ - handler: noop
+ authorizer:
+ handler: allow
+ mutators:
+ - handler: id_token
+
+- id: "accounts:protected"
+ upstream:
+ preserve_host: true
+ url: "http://accounts:3000"
+ match:
+ url: "http://oathkeeper<{,:4455}>/<{login,logout,user,user/uploads,user/downloads,user/stats}>"
+ methods:
+ - GET
+ - POST
+ - PUT
+ - DELETE
+ - PATCH
+ authenticators:
+ - handler: cookie_session
+ authorizer:
+ handler: allow
+ mutators:
+ - handler: id_token
+ errors:
+ - handler: redirect
+ config:
+ to: http://127.0.0.1/auth/login
diff --git a/docker/kratos/oathkeeper/oathkeeper.yml b/docker/kratos/oathkeeper/oathkeeper.yml
new file mode 100644
index 00000000..6436c2ee
--- /dev/null
+++ b/docker/kratos/oathkeeper/oathkeeper.yml
@@ -0,0 +1,94 @@
+log:
+ level: debug
+ format: json
+
+serve:
+ proxy:
+ cors:
+ enabled: true
+ allowed_origins:
+ - "*"
+ allowed_methods:
+ - POST
+ - GET
+ - PUT
+ - PATCH
+ - DELETE
+ allowed_headers:
+ - Authorization
+ - Content-Type
+ exposed_headers:
+ - Content-Type
+ allow_credentials: true
+ debug: true
+
+errors:
+ fallback:
+ - json
+
+ handlers:
+ redirect:
+ enabled: true
+ config:
+ to: http://127.0.0.1/auth/login
+ when:
+ - error:
+ - unauthorized
+ - forbidden
+ request:
+ header:
+ accept:
+ - text/html
+ json:
+ enabled: true
+ config:
+ verbose: true
+
+access_rules:
+ matching_strategy: glob
+ repositories:
+ - file:///etc/config/oathkeeper/access-rules.yml
+
+authenticators:
+ anonymous:
+ enabled: true
+ config:
+ subject: guest
+
+ cookie_session:
+ enabled: true
+ config:
+ check_session_url: http://kratos:4433/sessions/whoami
+ preserve_path: true
+ extra_from: "@this"
+ subject_from: "identity.id"
+ only:
+ - ory_kratos_session
+
+ noop:
+ enabled: true
+
+authorizers:
+ allow:
+ enabled: true
+
+mutators:
+ noop:
+ enabled: true
+
+ header:
+ enabled: true
+ config:
+ headers:
+ X-User: "{{ print .Subject }}"
+
+ id_token:
+ enabled: true
+ config:
+ issuer_url: http://oathkeeper:4455/
+ jwks_url: file:///etc/config/oathkeeper/id_token.jwks.json
+ ttl: 720h
+ claims: |
+ {
+ "session": {{ .Extra | toJson }}
+ }
diff --git a/docker/nginx/Dockerfile b/docker/nginx/Dockerfile
index 71e45a70..bba36f7b 100644
--- a/docker/nginx/Dockerfile
+++ b/docker/nginx/Dockerfile
@@ -1,7 +1,7 @@
FROM openresty/openresty:1.19.3.1-2-bionic
# RUN apt-get update -qq && apt-get install cron logrotate -qq
-# RUN luarocks install luasocket
+RUN luarocks install luasocket
# CMD ["sh", "-c", "service cron start;", "/usr/local/openresty/bin/openresty -g daemon off;"]
CMD ["/usr/local/openresty/bin/openresty", "-g", "daemon off;"]
diff --git a/docker/nginx/Dockerfile.bionic b/docker/nginx/Dockerfile.bionic
new file mode 100644
index 00000000..d51e4c8a
--- /dev/null
+++ b/docker/nginx/Dockerfile.bionic
@@ -0,0 +1,185 @@
+# Dockerfile - Ubuntu Bionic
+# https://github.com/openresty/docker-openresty
+
+ARG RESTY_IMAGE_BASE="ubuntu"
+ARG RESTY_IMAGE_TAG="bionic"
+
+FROM ${RESTY_IMAGE_BASE}:${RESTY_IMAGE_TAG}
+
+LABEL maintainer="Evan Wies "
+
+# Docker Build Arguments
+ARG RESTY_IMAGE_BASE="ubuntu"
+ARG RESTY_IMAGE_TAG="bionic"
+ARG RESTY_VERSION="1.19.3.1"
+ARG RESTY_LUAROCKS_VERSION="3.5.0"
+ARG RESTY_OPENSSL_VERSION="1.1.1i"
+ARG RESTY_OPENSSL_PATCH_VERSION="1.1.1f"
+ARG RESTY_OPENSSL_URL_BASE="https://www.openssl.org/source"
+ARG RESTY_PCRE_VERSION="8.44"
+ARG RESTY_J="1"
+ARG RESTY_CONFIG_OPTIONS="\
+ --with-compat \
+ --with-file-aio \
+ --with-http_addition_module \
+ --with-http_auth_request_module \
+ --with-http_dav_module \
+ --with-http_flv_module \
+ --with-http_geoip_module=dynamic \
+ --with-http_gunzip_module \
+ --with-http_gzip_static_module \
+ --with-http_image_filter_module=dynamic \
+ --with-http_mp4_module \
+ --with-http_random_index_module \
+ --with-http_realip_module \
+ --with-http_secure_link_module \
+ --with-http_slice_module \
+ --with-http_ssl_module \
+ --with-http_stub_status_module \
+ --with-http_sub_module \
+ --with-http_v2_module \
+ --with-http_xslt_module=dynamic \
+ --with-ipv6 \
+ --with-mail \
+ --with-mail_ssl_module \
+ --with-md5-asm \
+ --with-pcre-jit \
+ --with-sha1-asm \
+ --with-stream \
+ --with-stream_ssl_module \
+ --with-threads \
+ "
+ARG RESTY_CONFIG_OPTIONS_MORE=""
+ARG RESTY_LUAJIT_OPTIONS="--with-luajit-xcflags='-DLUAJIT_NUMMODE=2 -DLUAJIT_ENABLE_LUA52COMPAT'"
+
+ARG RESTY_ADD_PACKAGE_BUILDDEPS=""
+ARG RESTY_ADD_PACKAGE_RUNDEPS=""
+ARG RESTY_EVAL_PRE_CONFIGURE=""
+ARG RESTY_EVAL_POST_MAKE=""
+
+# These are not intended to be user-specified
+ARG _RESTY_CONFIG_DEPS="--with-pcre \
+ --with-cc-opt='-DNGX_LUA_ABORT_AT_PANIC -I/usr/local/openresty/pcre/include -I/usr/local/openresty/openssl/include' \
+ --with-ld-opt='-L/usr/local/openresty/pcre/lib -L/usr/local/openresty/openssl/lib -Wl,-rpath,/usr/local/openresty/pcre/lib:/usr/local/openresty/openssl/lib' \
+ "
+
+LABEL resty_image_base="${RESTY_IMAGE_BASE}"
+LABEL resty_image_tag="${RESTY_IMAGE_TAG}"
+LABEL resty_version="${RESTY_VERSION}"
+LABEL resty_luarocks_version="${RESTY_LUAROCKS_VERSION}"
+LABEL resty_openssl_version="${RESTY_OPENSSL_VERSION}"
+LABEL resty_openssl_patch_version="${RESTY_OPENSSL_PATCH_VERSION}"
+LABEL resty_openssl_url_base="${RESTY_OPENSSL_URL_BASE}"
+LABEL resty_pcre_version="${RESTY_PCRE_VERSION}"
+LABEL resty_config_options="${RESTY_CONFIG_OPTIONS}"
+LABEL resty_config_options_more="${RESTY_CONFIG_OPTIONS_MORE}"
+LABEL resty_config_deps="${_RESTY_CONFIG_DEPS}"
+LABEL resty_add_package_builddeps="${RESTY_ADD_PACKAGE_BUILDDEPS}"
+LABEL resty_add_package_rundeps="${RESTY_ADD_PACKAGE_RUNDEPS}"
+LABEL resty_eval_pre_configure="${RESTY_EVAL_PRE_CONFIGURE}"
+LABEL resty_eval_post_make="${RESTY_EVAL_POST_MAKE}"
+
+
+RUN DEBIAN_FRONTEND=noninteractive apt-get update \
+ && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
+ build-essential \
+ ca-certificates \
+ curl \
+ gettext-base \
+ libgd-dev \
+ libgeoip-dev \
+ libncurses5-dev \
+ libperl-dev \
+ libreadline-dev \
+ libxslt1-dev \
+ make \
+ perl \
+ unzip \
+ zlib1g-dev \
+ ${RESTY_ADD_PACKAGE_BUILDDEPS} \
+ ${RESTY_ADD_PACKAGE_RUNDEPS} \
+ && cd /tmp \
+ && if [ -n "${RESTY_EVAL_PRE_CONFIGURE}" ]; then eval $(echo ${RESTY_EVAL_PRE_CONFIGURE}); fi \
+ && curl -fSL "${RESTY_OPENSSL_URL_BASE}/openssl-${RESTY_OPENSSL_VERSION}.tar.gz" -o openssl-${RESTY_OPENSSL_VERSION}.tar.gz \
+ && tar xzf openssl-${RESTY_OPENSSL_VERSION}.tar.gz \
+ && cd openssl-${RESTY_OPENSSL_VERSION} \
+ && if [ $(echo ${RESTY_OPENSSL_VERSION} | cut -c 1-5) = "1.1.1" ] ; then \
+ echo 'patching OpenSSL 1.1.1 for OpenResty' \
+ && curl -s https://raw.githubusercontent.com/openresty/openresty/master/patches/openssl-${RESTY_OPENSSL_PATCH_VERSION}-sess_set_get_cb_yield.patch | patch -p1 ; \
+ fi \
+ && if [ $(echo ${RESTY_OPENSSL_VERSION} | cut -c 1-5) = "1.1.0" ] ; then \
+ echo 'patching OpenSSL 1.1.0 for OpenResty' \
+ && curl -s https://raw.githubusercontent.com/openresty/openresty/ed328977028c3ec3033bc25873ee360056e247cd/patches/openssl-1.1.0j-parallel_build_fix.patch | patch -p1 \
+ && curl -s https://raw.githubusercontent.com/openresty/openresty/master/patches/openssl-${RESTY_OPENSSL_PATCH_VERSION}-sess_set_get_cb_yield.patch | patch -p1 ; \
+ fi \
+ && ./config \
+ no-threads shared zlib -g \
+ enable-ssl3 enable-ssl3-method \
+ --prefix=/usr/local/openresty/openssl \
+ --libdir=lib \
+ -Wl,-rpath,/usr/local/openresty/openssl/lib \
+ && make -j${RESTY_J} \
+ && make -j${RESTY_J} install_sw \
+ && cd /tmp \
+ && curl -fSL https://ftp.pcre.org/pub/pcre/pcre-${RESTY_PCRE_VERSION}.tar.gz -o pcre-${RESTY_PCRE_VERSION}.tar.gz \
+ && tar xzf pcre-${RESTY_PCRE_VERSION}.tar.gz \
+ && cd /tmp/pcre-${RESTY_PCRE_VERSION} \
+ && ./configure \
+ --prefix=/usr/local/openresty/pcre \
+ --disable-cpp \
+ --enable-jit \
+ --enable-utf \
+ --enable-unicode-properties \
+ && make -j${RESTY_J} \
+ && make -j${RESTY_J} install \
+ && cd /tmp \
+ && curl -fSL https://openresty.org/download/openresty-${RESTY_VERSION}.tar.gz -o openresty-${RESTY_VERSION}.tar.gz \
+ && tar xzf openresty-${RESTY_VERSION}.tar.gz \
+ && cd /tmp/openresty-${RESTY_VERSION} \
+ && eval ./configure -j${RESTY_J} ${_RESTY_CONFIG_DEPS} ${RESTY_CONFIG_OPTIONS} ${RESTY_CONFIG_OPTIONS_MORE} ${RESTY_LUAJIT_OPTIONS} \
+ && make -j${RESTY_J} \
+ && make -j${RESTY_J} install \
+ && cd /tmp \
+ && rm -rf \
+ openssl-${RESTY_OPENSSL_VERSION}.tar.gz openssl-${RESTY_OPENSSL_VERSION} \
+ pcre-${RESTY_PCRE_VERSION}.tar.gz pcre-${RESTY_PCRE_VERSION} \
+ openresty-${RESTY_VERSION}.tar.gz openresty-${RESTY_VERSION} \
+ && curl -fSL https://luarocks.github.io/luarocks/releases/luarocks-${RESTY_LUAROCKS_VERSION}.tar.gz -o luarocks-${RESTY_LUAROCKS_VERSION}.tar.gz \
+ && tar xzf luarocks-${RESTY_LUAROCKS_VERSION}.tar.gz \
+ && cd luarocks-${RESTY_LUAROCKS_VERSION} \
+ && ./configure \
+ --prefix=/usr/local/openresty/luajit \
+ --with-lua=/usr/local/openresty/luajit \
+ --lua-suffix=jit-2.1.0-beta3 \
+ --with-lua-include=/usr/local/openresty/luajit/include/luajit-2.1 \
+ && make build \
+ && make install \
+ && cd /tmp \
+ && if [ -n "${RESTY_EVAL_POST_MAKE}" ]; then eval $(echo ${RESTY_EVAL_POST_MAKE}); fi \
+ && rm -rf luarocks-${RESTY_LUAROCKS_VERSION} luarocks-${RESTY_LUAROCKS_VERSION}.tar.gz \
+ && if [ -n "${RESTY_ADD_PACKAGE_BUILDDEPS}" ]; then DEBIAN_FRONTEND=noninteractive apt-get remove -y --purge ${RESTY_ADD_PACKAGE_BUILDDEPS} ; fi \
+ && DEBIAN_FRONTEND=noninteractive apt-get autoremove -y \
+ && mkdir -p /var/run/openresty \
+ && ln -sf /dev/stdout /usr/local/openresty/nginx/logs/access.log \
+ && ln -sf /dev/stderr /usr/local/openresty/nginx/logs/error.log
+
+# Add additional binaries into PATH for convenience
+ENV PATH=$PATH:/usr/local/openresty/luajit/bin:/usr/local/openresty/nginx/sbin:/usr/local/openresty/bin
+
+# Add LuaRocks paths
+# If OpenResty changes, these may need updating:
+# /usr/local/openresty/bin/resty -e 'print(package.path)'
+# /usr/local/openresty/bin/resty -e 'print(package.cpath)'
+ENV LUA_PATH="/usr/local/openresty/site/lualib/?.ljbc;/usr/local/openresty/site/lualib/?/init.ljbc;/usr/local/openresty/lualib/?.ljbc;/usr/local/openresty/lualib/?/init.ljbc;/usr/local/openresty/site/lualib/?.lua;/usr/local/openresty/site/lualib/?/init.lua;/usr/local/openresty/lualib/?.lua;/usr/local/openresty/lualib/?/init.lua;./?.lua;/usr/local/openresty/luajit/share/luajit-2.1.0-beta3/?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/openresty/luajit/share/lua/5.1/?.lua;/usr/local/openresty/luajit/share/lua/5.1/?/init.lua"
+
+ENV LUA_CPATH="/usr/local/openresty/site/lualib/?.so;/usr/local/openresty/lualib/?.so;./?.so;/usr/local/lib/lua/5.1/?.so;/usr/local/openresty/luajit/lib/lua/5.1/?.so;/usr/local/lib/lua/5.1/loadall.so;/usr/local/openresty/luajit/lib/lua/5.1/?.so"
+
+# Copy nginx configuration files
+COPY nginx.conf /usr/local/openresty/nginx/conf/nginx.conf
+COPY nginx.vh.default.conf /etc/nginx/conf.d/default.conf
+
+CMD ["/usr/local/openresty/bin/openresty", "-g", "daemon off;"]
+
+# Use SIGQUIT instead of default SIGTERM to cleanly drain requests
+# See https://github.com/openresty/docker-openresty/blob/master/README.md#tips--pitfalls
+STOPSIGNAL SIGQUIT
\ No newline at end of file
diff --git a/docker/nginx/conf.d/client.conf b/docker/nginx/conf.d/client.conf
index ca3fc9ce..fd28971f 100644
--- a/docker/nginx/conf.d/client.conf
+++ b/docker/nginx/conf.d/client.conf
@@ -24,8 +24,8 @@ limit_conn_zone $binary_remote_addr zone=downloads_by_ip:10m;
limit_req_status 429;
limit_conn_status 429;
-# since we are proxying request to nginx from caddy, access logs will contain caddy's ip address
-# as the request address so we need to use real_ip_header module to use ip address from
+# since we are proxying request to nginx from caddy, access logs will contain caddy's ip address
+# as the request address so we need to use real_ip_header module to use ip address from
# X-Forwarded-For header as a real ip address of the request
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 127.0.0.1/32;
@@ -57,6 +57,7 @@ server {
rewrite ^/portals /skynet/portals permanent;
rewrite ^/stats /skynet/stats permanent;
rewrite ^/skynet/blacklist /skynet/blocklist permanent;
+ rewrite ^/account/(.*) https://account.$domain.$tld/$1 permanent;
location / {
# This is only safe workaround to reroute based on some conditions
@@ -77,7 +78,7 @@ server {
include /etc/nginx/conf.d/include/cors;
- root /var/www/webportal;
+ proxy_pass http://webapp:9000;
}
location /docs {
@@ -113,11 +114,11 @@ server {
local file_exists = io.open("/data/nginx/skynet/prevstats.lua")
if file_exists then
file_exists.close()
-
+
-- because response data is chunked, we need to concat ngx.arg[1] until
-- last chunk is received (when ngx.arg[2] is set to true)
ngx.var.response_body = ngx.var.response_body .. ngx.arg[1]
-
+
if ngx.arg[2] then
local json = require('cjson')
local prevstats = require('/data/nginx/skynet/prevstats')
@@ -153,11 +154,11 @@ server {
# variable definititions - we need to define a variable to be able to access it in lua by ngx.var.something
set $skylink ''; # placeholder for the raw 46 bit skylink
set $rest ''; # placeholder for the rest of the url that gets appended to skylink (path and args)
-
+
# resolve handshake domain by requesting to /hnsres endpoint and assign correct values to $skylink and $rest
access_by_lua_block {
local json = require('cjson')
-
+
-- match the request_uri and extract the hns domain and anything that is passed in the uri after it
-- example: /hns/something/foo/bar?baz=1 matches:
-- > hns_domain_name: something
@@ -222,9 +223,6 @@ server {
end
}
- # overwrite the Cache-Control header to only cache for 60s in case the domain gets updated
- more_set_headers 'Cache-Control: public, max-age=60';
-
# we proxy to another nginx location rather than directly to siad because we don't want to deal with caching here
proxy_pass http://127.0.0.1/$skylink$rest;
@@ -255,7 +253,7 @@ server {
# and we are using it currently for caching registry resolutions from /hns calls
location /skynet/registry/cached {
internal; # internal endpoint only
- access_log off; # do not log traffic
+ access_log off; # do not log traffic
proxy_cache skynet;
proxy_cache_key publickey=$arg_publickey&datakey=$arg_datakey; # cache based on publickey and datakey
@@ -276,6 +274,40 @@ server {
proxy_set_header User-Agent: Sia-Agent;
proxy_read_timeout 600; # siad should timeout with 404 after 5 minutes
proxy_pass http://siad/skynet/registry;
+
+ access_by_lua_block {
+ -- this block runs only when accounts are enabled
+ if os.getenv("ACCOUNTS_ENABLED", "0") == "0" then return end
+
+ local res = ngx.location.capture("/accounts/user/limits", { copy_all_vars = true })
+ if res.status == ngx.HTTP_OK then
+ local json = require('cjson')
+ local limits = json.decode(res.body)
+ if limits.registry > 0 then
+ ngx.sleep(limits.registry / 1000)
+ end
+ end
+ }
+
+ # register the registry access in accounts service (cookies should contain jwt)
+ log_by_lua_block {
+ -- this block runs only when accounts are enabled
+ if os.getenv("ACCOUNTS_ENABLED", "0") == "0" then return end
+
+ if ngx.status == ngx.HTTP_OK or ngx.status == ngx.HTTP_NOT_FOUND then
+ local http = require("socket.http")
+ local headers = { Cookie = ngx.req.get_headers()["Cookie"] }
+ local method = ngx.req.get_method() == ngx.HTTP_GET and "read" or "write"
+ local ok, statusCode, headers, statusText = http.request {
+ url = "http://accounts:3000/track/registry/" .. method,
+ method = "POST",
+ headers = headers
+ }
+ if statusCode ~= ngx.HTTP_NO_CONTENT and statusCode ~= ngx.HTTP_UNAUTHORIZED then
+ ngx.log(ngx.ERR, "accounts endpoint /track/registry/" .. method .. " failed with error " .. statusCode)
+ end
+ end
+ }
}
location /skynet/skyfile {
@@ -306,8 +338,37 @@ server {
set $dir3 $3;
}
+ # access_by_lua_block {
+ # -- this block runs only when accounts are enabled
+ # if os.getenv("ACCOUNTS_ENABLED", "0") == "0" then return end
+
+ # ngx.var.upload_limit_rate = 5 * 1024 * 1024
+ # local res = ngx.location.capture("/accounts/user", { copy_all_vars = true })
+ # if res.status == ngx.HTTP_OK then
+ # local json = require('cjson')
+ # local user = json.decode(res.body)
+ # ngx.var.upload_limit_rate = ngx.var.upload_limit_rate * (user.tier + 1)
+ # end
+ # }
+
# proxy this call to siad endpoint (make sure the ip is correct)
proxy_pass http://siad/skynet/skyfile/$dir1/$dir2/$dir3$is_args$args;
+
+ # register the upload in accounts service (cookies should contain jwt)
+ log_by_lua_block {
+ -- this block runs only when accounts are enabled
+ if os.getenv("ACCOUNTS_ENABLED", "0") == "0" then return end
+
+ local skylink = ngx.header["Skynet-Skylink"]
+ if skylink and ngx.status >= ngx.HTTP_OK and ngx.status < ngx.HTTP_SPECIAL_RESPONSE then
+ local http = require("socket.http")
+ local headers = { Cookie = ngx.req.get_headers()["Cookie"] }
+ local ok, statusCode, headers, statusText = http.request { url = "http://accounts:3000/track/upload/" .. skylink, method = "POST", headers = headers }
+ if statusCode ~= ngx.HTTP_NO_CONTENT and statusCode ~= ngx.HTTP_UNAUTHORIZED then
+ ngx.log(ngx.ERR, "accounts endpoint /track/upload/" .. skylink .. " failed with error " .. statusCode)
+ end
+ end
+ }
}
location ~ "^/(([a-zA-Z0-9-_]{46}|[a-z0-9]{55})(/.*)?)$" {
@@ -322,12 +383,44 @@ server {
}
limit_conn downloads_by_ip 100; # ddos protection: max 100 downloads at a time
- add_header Cache-Control "public, max-age=86400"; # allow consumer to cache response
# we need to explicitly use set directive here because $1 will contain the skylink with
# decoded whitespaces and set will re-encode it for us before passing it to proxy_pass
set $skylink $1;
+ access_by_lua_block {
+ -- this block runs only when accounts are enabled
+ if os.getenv("ACCOUNTS_ENABLED", "0") == "0" then return end
+
+ local res = ngx.location.capture("/accounts/user/limits", { copy_all_vars = true })
+ if res.status == ngx.HTTP_OK then
+ local json = require('cjson')
+ local limits = json.decode(res.body)
+ ngx.var.limit_rate = limits.download
+ end
+ }
+
+ # register the download in accounts service (cookies should contain jwt)
+ log_by_lua_block {
+ -- this block runs only when accounts are enabled
+ if os.getenv("ACCOUNTS_ENABLED", "0") == "0" then return end
+
+ local skylink = ngx.header["Skynet-Skylink"]
+ if skylink and ngx.status >= ngx.HTTP_OK and ngx.status < ngx.HTTP_SPECIAL_RESPONSE then
+ local http = require("socket.http")
+ local headers = { Cookie = ngx.req.get_headers()["Cookie"] }
+ local query = table.concat({ "status=" .. ngx.status, "bytes=" .. ngx.var.body_bytes_sent }, "&")
+ local ok, statusCode, headers, statusText = http.request {
+ url = "http://accounts:3000/track/download/" .. skylink .. "?" .. query,
+ method = "POST",
+ headers = headers
+ }
+ if statusCode ~= ngx.HTTP_NO_CONTENT and statusCode ~= ngx.HTTP_UNAUTHORIZED then
+ ngx.log(ngx.ERR, "accounts endpoint /track/download/" .. skylink .. " failed with error " .. statusCode)
+ end
+ end
+ }
+
proxy_read_timeout 600;
proxy_set_header User-Agent: Sia-Agent;
# proxy this call to siad /skynet/skylink/ endpoint (make sure the ip is correct)
@@ -365,6 +458,14 @@ server {
proxy_pass http://127.0.0.1/$uri?attachment=true&$args;
}
+ location /accounts {
+ internal; # internal endpoint only
+ access_log off; # do not log traffic
+
+ rewrite /accounts(.*) $1 break; # drop the /accounts prefix from uri
+ proxy_pass http://accounts:3000;
+ }
+
# include custom locations, specific to the server
include /etc/nginx/conf.d/server-override/*;
}
diff --git a/docker/nginx/nginx.conf b/docker/nginx/nginx.conf
index 3a5b885e..4fcea569 100644
--- a/docker/nginx/nginx.conf
+++ b/docker/nginx/nginx.conf
@@ -26,6 +26,7 @@ worker_processes 1;
#pid logs/nginx.pid;
env SKYNET_PORTAL_API; # declare env variable to use it in config
+env ACCOUNTS_ENABLED; # declare env variable to use it in config
events {
worker_connections 1024;
@@ -67,4 +68,5 @@ http {
header_filter_by_lua 'ngx.header["Skynet-Portal-Api"] = os.getenv("SKYNET_PORTAL_API")';
include /etc/nginx/conf.d/*.conf;
+ include /etc/nginx/conf.extra.d/*.conf;
}
diff --git a/docker/nginx/nginx.vh.default.conf b/docker/nginx/nginx.vh.default.conf
new file mode 100644
index 00000000..d4aa8d5a
--- /dev/null
+++ b/docker/nginx/nginx.vh.default.conf
@@ -0,0 +1,58 @@
+# nginx.vh.default.conf -- docker-openresty
+#
+# This file is installed to:
+# `/etc/nginx/conf.d/default.conf`
+#
+# It tracks the `server` section of the upstream OpenResty's `nginx.conf`.
+#
+# This config (and any other configs in `etc/nginx/conf.d/`) is loaded by
+# default by the `include` directive in `/usr/local/openresty/nginx/conf/nginx.conf`.
+#
+# See https://github.com/openresty/docker-openresty/blob/master/README.md#nginx-config-files
+#
+
+
+server {
+ listen 80;
+ server_name localhost;
+
+ #charset koi8-r;
+ #access_log /var/log/nginx/host.access.log main;
+
+ location / {
+ root /usr/local/openresty/nginx/html;
+ index index.html index.htm;
+ }
+
+ #error_page 404 /404.html;
+
+ # redirect server error pages to the static page /50x.html
+ #
+ error_page 500 502 503 504 /50x.html;
+ location = /50x.html {
+ root /usr/local/openresty/nginx/html;
+ }
+
+ # proxy the PHP scripts to Apache listening on 127.0.0.1:80
+ #
+ #location ~ \.php$ {
+ # proxy_pass http://127.0.0.1;
+ #}
+
+ # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
+ #
+ #location ~ \.php$ {
+ # root /usr/local/openresty/nginx/html;
+ # fastcgi_pass 127.0.0.1:9000;
+ # fastcgi_index index.php;
+ # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
+ # include fastcgi_params;
+ #}
+
+ # deny access to .htaccess files, if Apache's document root
+ # concurs with nginx's one
+ #
+ #location ~ /\.ht {
+ # deny all;
+ #}
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index 06108e34..71155372 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,10 @@
"packages/*"
],
"dependencies": {
- "sharp": "^0.27.2"
+ "@tailwindcss/forms": "^0.2.1",
+ "autoprefixer": "^10.2.4",
+ "postcss": "^8.2.6",
+ "sharp": "^0.27.2",
+ "tailwindcss": "^2.0.4"
}
}
diff --git a/packages/dashboard/.env b/packages/dashboard/.env
new file mode 100644
index 00000000..bb640cd8
--- /dev/null
+++ b/packages/dashboard/.env
@@ -0,0 +1,4 @@
+NEXT_PUBLIC_SKYNET_PORTAL_API=https://siasky.net
+NEXT_PUBLIC_SKYNET_DASHBOARD_URL=https://account.siasky.net
+NEXT_PUBLIC_KRATOS_BROWSER_URL=https://account.siasky.net/.ory/kratos/public
+NEXT_PUBLIC_KRATOS_PUBLIC_URL=https://account.siasky.net/.ory/kratos/public
diff --git a/packages/dashboard/.gitignore b/packages/dashboard/.gitignore
new file mode 100644
index 00000000..ea47d16a
--- /dev/null
+++ b/packages/dashboard/.gitignore
@@ -0,0 +1,38 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# env defaults
+!.env
+
+# local env files
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+# vercel
+.vercel
+.next
diff --git a/packages/dashboard/.prettierignore b/packages/dashboard/.prettierignore
new file mode 100644
index 00000000..571a2ec1
--- /dev/null
+++ b/packages/dashboard/.prettierignore
@@ -0,0 +1,3 @@
+.next
+package.json
+package-lock.json
diff --git a/packages/dashboard/.prettierrc b/packages/dashboard/.prettierrc
new file mode 100644
index 00000000..963354f2
--- /dev/null
+++ b/packages/dashboard/.prettierrc
@@ -0,0 +1,3 @@
+{
+ "printWidth": 120
+}
diff --git a/packages/dashboard/Dockerfile b/packages/dashboard/Dockerfile
new file mode 100644
index 00000000..d5dd31eb
--- /dev/null
+++ b/packages/dashboard/Dockerfile
@@ -0,0 +1,16 @@
+FROM node:15.12.0-alpine
+
+WORKDIR /usr/app
+
+COPY package.json .
+
+ENV NEXT_TELEMETRY_DISABLED 1
+RUN yarn --no-lockfile
+
+COPY public ./public
+COPY src ./src
+COPY styles ./styles
+COPY postcss.config.js .
+COPY tailwind.config.js .
+
+CMD ["sh", "-c", "env | grep -E 'NEXT_PUBLIC|KRATOS|STRIPE' > .env.local && yarn build && yarn start"]
diff --git a/packages/dashboard/README.md b/packages/dashboard/README.md
new file mode 100644
index 00000000..4b412a3c
--- /dev/null
+++ b/packages/dashboard/README.md
@@ -0,0 +1,34 @@
+This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
+
+## Getting Started
+
+First, run the development server:
+
+```bash
+npm run dev
+# or
+yarn dev
+```
+
+Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
+
+You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
+
+[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
+
+The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
+
+## Learn More
+
+To learn more about Next.js, take a look at the following resources:
+
+- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
+- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
+
+You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
+
+## Deploy on Vercel
+
+The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/import?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
+
+Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
diff --git a/packages/dashboard/package.json b/packages/dashboard/package.json
new file mode 100644
index 00000000..38f0fd0e
--- /dev/null
+++ b/packages/dashboard/package.json
@@ -0,0 +1,43 @@
+{
+ "name": "dashboard",
+ "version": "0.1.0",
+ "private": true,
+ "scripts": {
+ "dev": "next dev",
+ "build": "next build",
+ "start": "next start"
+ },
+ "dependencies": {
+ "@fontsource/metropolis": "^4.1.0",
+ "@ory/kratos-client": "^0.5.4-alpha.1",
+ "@stripe/react-stripe-js": "^1.4.0",
+ "@stripe/stripe-js": "^1.13.0",
+ "@tailwindcss/forms": "^0.2.1",
+ "autoprefixer": "^10.2.5",
+ "classnames": "^2.2.6",
+ "clipboardy": "^2.3.0",
+ "dayjs": "^1.10.4",
+ "express-jwt": "^6.0.0",
+ "fast-levenshtein": "^3.0.0",
+ "formik": "^2.2.6",
+ "http-status-codes": "^2.1.4",
+ "jwks-rsa": "^1.12.2",
+ "ky": "0.25.1",
+ "next": "^10.0.8",
+ "postcss": "^8.2.8",
+ "prettier": "^2.2.1",
+ "pretty-bytes": "^5.5.0",
+ "react": "17.0.1",
+ "react-dom": "17.0.1",
+ "skynet-js": "^3.0.0",
+ "square": "^9.0.0",
+ "stripe": "^8.137.0",
+ "superagent": "^6.1.0",
+ "swr": "^0.5.0",
+ "tailwindcss": "^2.0.3",
+ "yup": "^0.32.9"
+ },
+ "devDependencies": {
+ "@tailwindcss/forms": "^0.2.1"
+ }
+}
diff --git a/packages/dashboard/postcss.config.js b/packages/dashboard/postcss.config.js
new file mode 100644
index 00000000..12a703d9
--- /dev/null
+++ b/packages/dashboard/postcss.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+};
diff --git a/packages/dashboard/public/favicon.ico b/packages/dashboard/public/favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..9229fbf780c52d9d25e2183c0effe239dd2728dd
GIT binary patch
literal 2118
zcmV-M2)Xx(P)RT(~arVF-3X?a8o@+eOO1vEksNT^L4i?pS?
zGjpFa_ntF5TNVgSR!EH+O{o}6G@z1bNRVez0u;Kt_nv!ax2u$A6CgkW0YZ2+L`XDR
z1#DW{()IiQb7pobr6JWx{@i=coOAyFeE;`9t`LXuTbZsA!xQ~t-Jh2TFH3}{6DQEJ
z6zHVn=d$E!>4ZfC^CXFAOg6;-{0rK#2(l(bi6EE4Cxy8zUvSIUSxJyd0Rx1evq8d3
zha9Xa(>gb=iy)OEOqCGRhoRgjg}D-58;WpffF}-SLzdsS%z?raVZb67@GTf{F2-MV
z(;;3%66v9mpUF~Vb13?^4dbll7gOv$>{{hgcsXEBn}Asfe+!Jr!P=_3OLR`PC=u47m}Isz}7LsTJhYKlCX6
zBrpm{_G9fwFm8vh)jxegBJUdaX<*jugv4$kh1*sRUB<(^s6k0J8xl1@Q`Ifu62!Wz
z+yV4rnwc|67!;s5J#&f^`FEE?D^M;J+P
z;%n0lV?YH4c$so)2pvDO1^^yEi{W=B-2JRDm%Hq(_dtH+>c$*)kzLPGfJosn$QKta
zdXmew2L_S72C-xyFa#|NKOLOcpAXIQu&HjCTdHZ^SoVznTV2RCE8l@Qznmh#O=J3h
z78I6XfMX0$4v)2*l}sob3GuObZu4h&@jgg+93dg9d26nxo0q_V3qw69jAg11h#;Qj
zDR}?8_2qtS+zU2;*M?vpB_R1gT_ocp*w^H!af_x%#v;V~H0>t?U?2=j)mQNTdY7PD
zZXhCJQB%m#rURBP$K+3N@Hbh3=G!-{-;CwC{F!BN-%?!>mGOpHxy46*@Pyi|a1O0SL$oa(Oxy+yS{A3FTxaVkXbQxJ`r$#~X7z
z9fPQnAa>SWcDz`7_lT%XxTM6vdWYOb$_E}95$<@4!#JM08fQ1lVbNqhSso#BHJ{WcsMGC+s#y>%;d%dC-$XAo6C?u463wTSt8Zevs@3$fuj%5eDahUm$bsR1c?k;$bnU{Q6G
z%e5hDFGq%yXJFl#IBPZxFwkdI8<>z~c0H(G+CkpL$0@rrh6
z!b;0^Hrf0IDAoPZmRK~kif*_X;|+K=K;SP^z5r6+!1y}IjgWpAu)v^VWaa$>qR}3v
zGas{V*m7Xe(PRkxXg2%`;~!Ar2(tJz&iRIrFF>whcV)?!F!w{qpRoSdE^(;fig+sT
z)pDGaKyHFu>ZNk7Z#Xh)4S3=J0}u%!EL15d*q8U%n?De0HMc&=a~u3_7^$sr*=Z5=#{DWog{4r;P%E_h
zCCAPZsfPA)*!UqQk7VpavYAR>lqbtMjYx2N<{jkw26<%#wZXJgG+
z*N|LpM^^j=o(nl5vj6G{7H?h8Y>jY>(6n6>)&N^XP*^gaKLT)S=|n$IDgsqZlJ*-%E4s_CX$-kA59MkIQa@fv`6?8@k
zw^$U8So06Ne!n&3U&N(q*60gNWKkFOY>#U${)_>uw%0_Zh=dv&7HaewVf{yk?y^PX
zX*3dZO~zAYCT&K^hMG}%GUjzB)AbYvw~dZ-5;
z!<>{o530&fZU3Nf`+3q7K-7m>-d9&P+7gDpAywt9R6xgS?w{vDC|LpBIEbSh$nHyP0=?P
zw;tMn89qqS+)N~k&F7e|6B6ir;v;d3??cJ&F#iP?H%Mm!b#eF8VSrZkti
zGFk(^_;+E!A%^ce)A_=Ha+r79E$ViFRx$_Ca4go%YaylE-qQ4i87Y>Id~#4Me|QZS
zy~FwqZM;@g@x?SS6;hRRY?lL)suBzkoldE#L;6}S+wRy2CSwue3)wHE_`m)L)*x*d
wcr!_T1R3R2QHrnKyh^M|E8>b`?IF+j55uL_p0enzz5oCK07*qoM6N<$f=9md3IG5A
literal 0
HcmV?d00001
diff --git a/packages/dashboard/src/components/Form/Message.js b/packages/dashboard/src/components/Form/Message.js
new file mode 100644
index 00000000..e8ebb7e8
--- /dev/null
+++ b/packages/dashboard/src/components/Form/Message.js
@@ -0,0 +1,62 @@
+const types = {
+ error: {
+ backgroundColor: "bg-red-50",
+ titleColor: "text-red-800",
+ detailsColor: "text-red-700",
+ iconColor: "text-red-400",
+ icon: (
+
+ ),
+ },
+ info: {
+ backgroundColor: "bg-blue-50",
+ titleColor: "text-blue-800",
+ detailsColor: "text-blue-700",
+ iconColor: "text-blue-400",
+ icon: (
+
+ ),
+ },
+};
+
+export default function Message({ type = "info", title, items = [] }) {
+ const { backgroundColor, titleColor, detailsColor, iconColor, icon } = types[type];
+
+ return (
+
+
+
+
+
+
+ {title &&
{title}
}
+ {items.length > 0 && (
+
+
1 ? "list-disc pl-5 space-y-1" : ""}`}>
+ {items.map((item, index) => (
+ - {item}
+ ))}
+
+
+ )}
+
+
+
+ );
+}
diff --git a/packages/dashboard/src/components/Form/SelfServiceForm.js b/packages/dashboard/src/components/Form/SelfServiceForm.js
new file mode 100644
index 00000000..e00f27ac
--- /dev/null
+++ b/packages/dashboard/src/components/Form/SelfServiceForm.js
@@ -0,0 +1,104 @@
+import { useFormik, getIn, setIn } from "formik";
+import classnames from "classnames";
+import SelfServiceMessages from "./SelfServiceMessages";
+
+export default function SelfServiceForm({ flow, config, fieldsConfig, title, button = "Submit" }) {
+ const fields = config.fields
+ .map((field) => ({ ...field, ...fieldsConfig[field.name] }))
+ .sort((a, b) => (a.position < b.position ? -1 : 1));
+ const formik = useFormik({
+ initialValues: fields.reduce((acc, field) => setIn(acc, field.name, field.value ?? ""), {}),
+ });
+
+ return (
+
+ );
+}
diff --git a/packages/dashboard/src/components/Form/SelfServiceMessages.js b/packages/dashboard/src/components/Form/SelfServiceMessages.js
new file mode 100644
index 00000000..9395e227
--- /dev/null
+++ b/packages/dashboard/src/components/Form/SelfServiceMessages.js
@@ -0,0 +1,45 @@
+import classnames from "classnames";
+
+// const types = {
+// error: {
+// backgroundColor: "bg-red-50",
+// titleColor: "text-red-800",
+// detailsColor: "text-red-700",
+// iconColor: "text-red-400",
+// icon: (
+//
+// ),
+// },
+// info: {
+// backgroundColor: "bg-blue-50",
+// titleColor: "text-blue-800",
+// detailsColor: "text-blue-700",
+// iconColor: "text-blue-400",
+// icon: (
+//
+// ),
+// },
+// };
+
+export default function SelfServiceMessages({ messages = [] }) {
+ if (!messages) return null; // make sure we don't throw on invalid data
+
+ return messages.map(({ text, type }) => (
+
+ {text}
+
+ ));
+}
diff --git a/packages/dashboard/src/components/Layout.js b/packages/dashboard/src/components/Layout.js
new file mode 100644
index 00000000..1d7fe6c2
--- /dev/null
+++ b/packages/dashboard/src/components/Layout.js
@@ -0,0 +1,327 @@
+import Link from "next/link";
+import { useRouter } from "next/router";
+import Head from "next/head";
+import ky from "ky/umd";
+import { useState } from "react";
+import config from "../../src/config";
+
+export default function Layout({ title, children }) {
+ const [menuOpen, openMenu] = useState(false);
+ const [avatarDropdownOpen, openAvatarDropdown] = useState(false);
+ const router = useRouter();
+ const handleSignOut = async (e) => {
+ e.preventDefault();
+
+ try {
+ await ky.post("/logout");
+
+ window.location = `${config.kratos.browser}/self-service/browser/flows/logout`;
+ } catch (error) {
+ console.log(error); // todo: handle errors with a message
+ }
+ };
+
+ return (
+
+
+
Skynet - {title}
+
+
+
+
+
+
+
+
+ {children || (
+
+ )}
+
+
+
+
+
+ );
+}
diff --git a/packages/dashboard/src/components/Table.js b/packages/dashboard/src/components/Table.js
new file mode 100644
index 00000000..e3ae6d5e
--- /dev/null
+++ b/packages/dashboard/src/components/Table.js
@@ -0,0 +1,128 @@
+import { useEffect } from "react";
+import classnames from "classnames";
+
+function Button({ children, disabled, className, ...props }) {
+ return (
+
+ );
+}
+
+export default function Table({ items, count, headers, actions, offset, setOffset, pageSize = 10 }) {
+ useEffect(() => {
+ if (offset < 0) setOffset(0);
+ else if (offset >= count && count > 0) setOffset(Math.floor(count / pageSize - 1) * pageSize);
+ else if (offset % pageSize) setOffset(offset - (offset % pageSize));
+ }, [offset, pageSize, setOffset]);
+
+ return (
+
+
+
+
+
+
+
+ {headers.map(({ key, name }) => (
+
+ {name}
+ |
+ ))}
+ {actions.map(({ key, name }) => (
+
+ {name}
+ |
+ ))}
+
+
+
+ {items && items.length ? (
+ items.map((row, index) => (
+
+ {headers.map(({ key, formatter, href, nowrap = true }) => (
+
+ {(formatter ? (
+ formatter(row, key)
+ ) : href ? (
+
+ {row[key]}
+
+ ) : (
+ row[key]
+ )) || <>—>}
+ |
+ ))}
+ {actions.map(({ key, name, action }) => (
+
+
+ {name}
+
+ |
+ ))}
+
+ ))
+ ) : (
+
+
+ no entries
+ |
+
+ )}
+
+
+ {/* This example requires Tailwind CSS v2.0+ */}
+
+
+
+
+
+ );
+}
diff --git a/packages/dashboard/src/config.js b/packages/dashboard/src/config.js
new file mode 100644
index 00000000..326ec4e9
--- /dev/null
+++ b/packages/dashboard/src/config.js
@@ -0,0 +1,14 @@
+export default {
+ // https://github.com/ory/kratos-selfservice-ui-node#configuration
+ kratos: {
+ // The URL where ORY Kratos's Public API is located at. If this app and ORY Kratos are running in the same
+ // private network, this should be the private network address (e.g. kratos-public.svc.cluster.local)
+ public: process.env.NEXT_PUBLIC_KRATOS_PUBLIC_URL.replace(/\/+$/, ""),
+ // The URL where ORY Kratos's public API is located, when accessible from the public internet via ORY Oathkeeper.
+ // This could be for example http://kratos.my-app.com/.
+ browser: process.env.NEXT_PUBLIC_KRATOS_BROWSER_URL.replace(/\/+$/, ""),
+ },
+ tiers: {
+ starter: { id: "starter", tier: 1, name: "Free", description: "Pin up to 100GB" },
+ },
+};
diff --git a/packages/dashboard/src/pages/_app.js b/packages/dashboard/src/pages/_app.js
new file mode 100644
index 00000000..5be206d2
--- /dev/null
+++ b/packages/dashboard/src/pages/_app.js
@@ -0,0 +1,21 @@
+import { Elements } from "@stripe/react-stripe-js";
+import { loadStripe } from "@stripe/stripe-js";
+import Head from "next/head";
+import "tailwindcss/tailwind.css";
+import "@fontsource/metropolis/all.css";
+
+const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY);
+
+function MyApp({ Component, pageProps }) {
+ return (
+
+
+
+ Skynet
+
+
+
+ );
+}
+
+export default MyApp;
diff --git a/packages/dashboard/src/pages/api/accounts/login.js b/packages/dashboard/src/pages/api/accounts/login.js
new file mode 100644
index 00000000..4890d52b
--- /dev/null
+++ b/packages/dashboard/src/pages/api/accounts/login.js
@@ -0,0 +1,19 @@
+import superagent from "superagent";
+
+export default async (req, res) => {
+ if (req.cookies.ory_kratos_session) {
+ try {
+ const { header } = await superagent
+ .post("http://oathkeeper:4455/login")
+ .set("cookie", `ory_kratos_session=${req.cookies.ory_kratos_session}`);
+
+ res.setHeader("Set-Cookie", header["set-cookie"]);
+ res.redirect(req.query.return_to ?? "/");
+ } catch (error) {
+ // credentials were correct but accounts service failed
+ res.redirect("/.ory/kratos/public/self-service/browser/flows/logout");
+ }
+ } else {
+ res.redirect("/auth/login"); // redirect to login page if kratos session is missing
+ }
+};
diff --git a/packages/dashboard/src/pages/api/square/cards.js b/packages/dashboard/src/pages/api/square/cards.js
new file mode 100644
index 00000000..603da8f4
--- /dev/null
+++ b/packages/dashboard/src/pages/api/square/cards.js
@@ -0,0 +1,58 @@
+import { Client, Environment } from "square";
+import { StatusCodes } from "http-status-codes";
+
+const client = new Client({
+ environment: Environment.Sandbox,
+ accessToken: process.env.SQUARE_ACCESS_TOKEN,
+});
+
+const api = {
+ GET: async (req, res) => {
+ const user = "R7R0NY1Z8WT11D43564EEFKTYR"; // req.headers["x-user"];
+
+ try {
+ const { result: customerResult } = await client.customersApi.retrieveCustomer(user);
+ const { customer } = customerResult;
+
+ res.json(customer.cards);
+ } catch (error) {
+ res.json([]);
+ }
+ },
+ // POST: async (req, res) => {
+ // const user = req.headers["x-user"];
+ // const card = {
+ // cardNonce: "YOUR_CARD_NONCE",
+ // cardholderName: "Amelia Earhart",
+ // billingAddress: {},
+ // verificationToken: "verification_token0",
+ // };
+
+ // card.bodyBillingAddress.addressLine1 = "500 Electric Ave";
+ // card.bodyBillingAddress.addressLine2 = "Suite 600";
+ // card.bodyBillingAddress.addressLine3 = "address_line_38";
+ // card.bodyBillingAddress.locality = "New York";
+ // card.bodyBillingAddress.sublocality = "sublocality2";
+ // card.bodyBillingAddress.administrativeDistrictLevel1 = "NY";
+ // card.bodyBillingAddress.postalCode = "10003";
+ // card.bodyBillingAddress.country = "US";
+
+ // try {
+ // const { result } = await client.customersApi.createCustomerCard(user, card);
+
+ // res.status(StatusCodes.NO_CONTENT);
+ // } catch (error) {
+ // console.log(Object.keys(error));
+
+ // res.status(StatusCodes.BAD_REQUEST);
+ // }
+ // },
+};
+
+export default (req, res) => {
+ if (req.method in api) {
+ api[req.method](req, res);
+ } else {
+ res.status(StatusCodes.NOT_FOUND);
+ }
+};
diff --git a/packages/dashboard/src/pages/api/square/invoices.js b/packages/dashboard/src/pages/api/square/invoices.js
new file mode 100644
index 00000000..1ad8471a
--- /dev/null
+++ b/packages/dashboard/src/pages/api/square/invoices.js
@@ -0,0 +1,45 @@
+import { Client, Environment } from "square";
+import { StatusCodes } from "http-status-codes";
+
+const client = new Client({
+ environment: Environment.Sandbox,
+ accessToken: process.env.SQUARE_ACCESS_TOKEN,
+});
+
+const api = {
+ GET: async (req, res) => {
+ const user = "NBE7TRXZPGZXNBD64JB6DR5AGR"; // req.headers["x-user"];
+
+ try {
+ // get locations for invoices search query
+ const { result: locationsResponse } = await client.locationsApi.listLocations();
+ const { locations } = locationsResponse;
+
+ // create invoices serach query
+ const locationIds = locations.map(({ id }) => id);
+ const customerIds = [user];
+ const filter = { locationIds, customerIds };
+ const sort = { field: "INVOICE_SORT_DATE", order: "DESC" };
+ const query = { filter, sort };
+
+ // query invoices with given search criteria
+ const { result: invoicesResponse } = await client.invoicesApi.searchInvoices({ query, limit: 10 });
+ const { invoices } = invoicesResponse;
+
+ res.json(invoices);
+ } catch (error) {
+ console.log(error);
+ console.log(error?.errors);
+
+ res.json([]); // todo: error handling
+ }
+ },
+};
+
+export default (req, res) => {
+ if (req.method in api) {
+ return api[req.method](req, res);
+ }
+
+ return res.status(StatusCodes.NOT_FOUND);
+};
diff --git a/packages/dashboard/src/pages/api/square/subscription.js b/packages/dashboard/src/pages/api/square/subscription.js
new file mode 100644
index 00000000..5ece9e68
--- /dev/null
+++ b/packages/dashboard/src/pages/api/square/subscription.js
@@ -0,0 +1,46 @@
+import { Client, Environment } from "square";
+import { StatusCodes } from "http-status-codes";
+
+const client = new Client({
+ environment: Environment.Sandbox,
+ accessToken: process.env.SQUARE_ACCESS_TOKEN,
+});
+
+const api = {
+ GET: async (req, res) => {
+ try {
+ const user = "NBE7TRXZPGZXNBD64JB6DR5AGR"; // req.headers["x-user"];
+
+ // create subscriptions search query
+ const query = { filter: { customerIds: [user] } };
+
+ // query subscriptions with given search criteria
+ const { result: subscriptionsResponse } = await client.subscriptionsApi.searchSubscriptions({ query });
+ const { subscriptions } = subscriptionsResponse;
+
+ // get active subscription
+ const subscription = subscriptions.find(({ status }) => status === "ACTIVE");
+
+ if (!subscription) {
+ return res.status(StatusCodes.NO_CONTENT).end(); // no active subscription found
+ }
+
+ console.log("....", subscription);
+
+ return res.json(subscription);
+ } catch (error) {
+ console.log(error);
+ console.log(error?.errors);
+
+ return res.status(StatusCodes.BAD_REQUEST).end(); // todo: error handling
+ }
+ },
+};
+
+export default (req, res) => {
+ if (req.method in api) {
+ return api[req.method](req, res);
+ }
+
+ return res.status(StatusCodes.NOT_FOUND).end();
+};
diff --git a/packages/dashboard/src/pages/api/square/subscription/cancel.js b/packages/dashboard/src/pages/api/square/subscription/cancel.js
new file mode 100644
index 00000000..9b2f017c
--- /dev/null
+++ b/packages/dashboard/src/pages/api/square/subscription/cancel.js
@@ -0,0 +1,55 @@
+import { Client, Environment } from "square";
+import { StatusCodes } from "http-status-codes";
+
+const client = new Client({
+ environment: Environment.Sandbox,
+ accessToken: process.env.SQUARE_ACCESS_TOKEN,
+});
+
+const cancelSubscription = async (id) => {
+ const { result: subscriptionsResponse } = await client.subscriptionsApi.cancelSubscription(id);
+ const { subscription } = subscriptionsResponse;
+
+ return subscription;
+};
+
+const getActiveSubscription = async (customerId) => {
+ // create subscriptions search query
+ const query = { filter: { customerIds: [customerId] } };
+
+ // query subscriptions with given search criteria
+ const { result: subscriptionsResponse } = await client.subscriptionsApi.searchSubscriptions({ query });
+ const { subscriptions } = subscriptionsResponse;
+
+ // get active subscription with a set cancellation date
+ return subscriptions.find(({ status, canceledDate }) => status === "ACTIVE" && !canceledDate);
+};
+
+const api = {
+ POST: async (req, res) => {
+ try {
+ const user = "NBE7TRXZPGZXNBD64JB6DR5AGR"; // req.headers["x-user"];
+ const subscription = await getActiveSubscription(user);
+
+ if (!subscription) {
+ return res.status(StatusCodes.BAD_REQUEST).end(); // no active subscription found
+ }
+
+ const canceledSubscription = await cancelSubscription(subscription.id);
+
+ return res.json(canceledSubscription);
+ } catch (error) {
+ console.log(error.errors);
+
+ return res.status(StatusCodes.BAD_REQUEST).end(); // todo: error handling
+ }
+ },
+};
+
+export default (req, res) => {
+ if (req.method in api) {
+ return api[req.method](req, res);
+ }
+
+ return res.status(StatusCodes.NOT_FOUND).end();
+};
diff --git a/packages/dashboard/src/pages/api/square/subscription/restore.js b/packages/dashboard/src/pages/api/square/subscription/restore.js
new file mode 100644
index 00000000..8cac9dfc
--- /dev/null
+++ b/packages/dashboard/src/pages/api/square/subscription/restore.js
@@ -0,0 +1,58 @@
+import { Client, Environment } from "square";
+import { StatusCodes } from "http-status-codes";
+
+const client = new Client({
+ environment: Environment.Sandbox,
+ accessToken: process.env.SQUARE_ACCESS_TOKEN,
+});
+
+const updateSubscription = async (id, body) => {
+ const { result: subscriptionsResponse } = await client.subscriptionsApi.updateSubscription(id, body);
+ const { subscription } = subscriptionsResponse;
+
+ return subscription;
+};
+
+const getActiveCanceledSubscription = async (customerId) => {
+ // create subscriptions search query
+ const query = { filter: { customerIds: [customerId] } };
+
+ // query subscriptions with given search criteria
+ const { result: subscriptionsResponse } = await client.subscriptionsApi.searchSubscriptions({ query });
+ const { subscriptions } = subscriptionsResponse;
+
+ // get active subscription with a set cancellation date
+ return subscriptions.find(({ status, canceledDate }) => status === "ACTIVE" && canceledDate);
+};
+
+const api = {
+ POST: async (req, res) => {
+ try {
+ const user = "NBE7TRXZPGZXNBD64JB6DR5AGR"; // req.headers["x-user"];
+ const subscription = await getActiveCanceledSubscription(user);
+
+ if (!subscription) {
+ return res.status(StatusCodes.BAD_REQUEST).end(); // no active subscription with cancel date found
+ }
+
+ // update the subscription setting empty canceledDate
+ const updatedSubscription = await updateSubscription(subscription.id, {
+ subscription: { ...subscription, canceledDate: "" },
+ });
+
+ return res.json(updatedSubscription);
+ } catch (error) {
+ console.log(error.errors);
+
+ return res.status(StatusCodes.BAD_REQUEST).end(); // todo: error handling
+ }
+ },
+};
+
+export default (req, res) => {
+ if (req.method in api) {
+ return api[req.method](req, res);
+ }
+
+ return res.status(StatusCodes.NOT_FOUND).end();
+};
diff --git a/packages/dashboard/src/pages/api/stripe/billing.js b/packages/dashboard/src/pages/api/stripe/billing.js
new file mode 100644
index 00000000..0c855ec4
--- /dev/null
+++ b/packages/dashboard/src/pages/api/stripe/billing.js
@@ -0,0 +1,28 @@
+import ky from "ky/umd";
+import Stripe from "stripe";
+import { StatusCodes } from "http-status-codes";
+
+const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
+
+const getStripeCustomer = (stripeCustomerId = null) => {
+ if (stripeCustomerId) {
+ return stripe.customers.retrieve(stripeCustomerId);
+ }
+ return stripe.customers.create();
+};
+
+export default async (req, res) => {
+ try {
+ const authorization = req.headers.authorization; // authorization header from request
+ const { stripeCustomerId } = await ky("http://accounts:3000/user", { headers: { authorization } }).json();
+ const customer = await getStripeCustomer(stripeCustomerId);
+ const session = await stripe.billingPortal.sessions.create({
+ customer: customer.id,
+ return_url: `${process.env.SKYNET_DASHBOARD_URL}/payments`,
+ });
+
+ res.redirect(session.url);
+ } catch ({ message }) {
+ res.status(StatusCodes.BAD_REQUEST).json({ error: { message } });
+ }
+};
diff --git a/packages/dashboard/src/pages/api/stripe/checkout.js b/packages/dashboard/src/pages/api/stripe/checkout.js
new file mode 100644
index 00000000..4ddf17a9
--- /dev/null
+++ b/packages/dashboard/src/pages/api/stripe/checkout.js
@@ -0,0 +1,59 @@
+import ky from "ky/umd";
+import Stripe from "stripe";
+import { StatusCodes } from "http-status-codes";
+import { isPaidTier } from "../../../services/tiers";
+
+const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
+
+const getStripeCustomer = async (user, authorization) => {
+ if (user.stripeCustomerId) {
+ return stripe.customers.retrieve(user.stripeCustomerId);
+ }
+
+ const customer = await stripe.customers.create();
+
+ // update user instance and include the customer id once created
+ await ky.put(`http://accounts:3000/user`, { headers: { authorization }, json: { stripeCustomerId: customer.id } });
+
+ return customer;
+};
+
+export default async (req, res) => {
+ if (req.method !== "POST") {
+ return res.status(StatusCodes.NOT_FOUND).end();
+ }
+
+ const { price } = req.body;
+
+ if (!price) {
+ return res.status(StatusCodes.BAD_REQUEST).json({ error: { message: "Missing 'price' attribute" } });
+ }
+
+ try {
+ const authorization = req.headers.authorization; // authorization header from request
+ const user = await ky("http://accounts:3000/user", { headers: { authorization } }).json();
+
+ if (isPaidTier(user.tier)) {
+ const message = `Customer can have only one active subscription at a time, use Stripe Customer Portal to manage active subscription`;
+
+ return res.status(StatusCodes.BAD_REQUEST).json({ error: { message } });
+ }
+
+ const customer = await getStripeCustomer(user, authorization);
+ const session = await stripe.checkout.sessions.create({
+ mode: "subscription",
+ payment_method_types: ["card"],
+ line_items: [{ price, quantity: 1 }],
+ customer: customer.id,
+ client_reference_id: user.sub,
+ allow_promotion_codes: true,
+ success_url: `${process.env.SKYNET_DASHBOARD_URL}/payments?session_id={CHECKOUT_SESSION_ID}`,
+ cancel_url: `${process.env.SKYNET_DASHBOARD_URL}/payments`,
+ });
+
+ res.json({ sessionId: session.id });
+ } catch (error) {
+ console.log(error);
+ res.status(StatusCodes.BAD_REQUEST).json({ error: { message: error.message } });
+ }
+};
diff --git a/packages/dashboard/src/pages/api/stripe/subscription.js b/packages/dashboard/src/pages/api/stripe/subscription.js
new file mode 100644
index 00000000..3526d5ac
--- /dev/null
+++ b/packages/dashboard/src/pages/api/stripe/subscription.js
@@ -0,0 +1,23 @@
+import ky from "ky/umd";
+import Stripe from "stripe";
+import { StatusCodes } from "http-status-codes";
+
+const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
+
+export default async (req, res) => {
+ try {
+ const authorization = req.headers.authorization; // authorization header from request
+ const { stripeCustomerId } = await ky("http://accounts:3000/user", { headers: { authorization } }).json();
+ const stripeCustomer = await stripe.customers.retrieve(stripeCustomerId, { expand: ["subscriptions"] });
+ const { subscriptions } = stripeCustomer;
+
+ // todo: find a better way to get current subscription
+ if (subscriptions.total_count) {
+ return res.json(subscriptions.data[0]);
+ }
+
+ res.status(StatusCodes.NO_CONTENT).end();
+ } catch ({ message }) {
+ res.status(StatusCodes.BAD_REQUEST).json({ error: { message } });
+ }
+};
diff --git a/packages/dashboard/src/pages/api/stubs/stripe/prices.js b/packages/dashboard/src/pages/api/stubs/stripe/prices.js
new file mode 100644
index 00000000..ebf013a3
--- /dev/null
+++ b/packages/dashboard/src/pages/api/stubs/stripe/prices.js
@@ -0,0 +1,37 @@
+export default (req, res) => {
+ res.json([
+ {
+ id: "price_1IReYFIzjULiPWN6DqN2DwjN",
+ name: "Skynet Extreme",
+ description: "Skynet Extreme description",
+ tier: 4,
+ price: 80,
+ currency: "usd",
+ stripe: "price_1IReYFIzjULiPWN6DqN2DwjN",
+ productId: "prod_J3m6IuVyh3XOc5",
+ livemode: false,
+ },
+ {
+ id: "price_1IReY5IzjULiPWN6AxPytHEG",
+ name: "Skynet Pro",
+ description: "Skynet Pro description",
+ tier: 3,
+ price: 20,
+ currency: "usd",
+ stripe: "price_1IReY5IzjULiPWN6AxPytHEG",
+ productId: "prod_J3m6ioQg90kZj5",
+ livemode: false,
+ },
+ {
+ id: "price_1IReXpIzjULiPWN66PvsxHL4",
+ name: "Skynet Plus",
+ description: "Skynet Plus description",
+ tier: 2,
+ price: 5,
+ currency: "usd",
+ stripe: "price_1IReXpIzjULiPWN66PvsxHL4",
+ productId: "prod_J3m6xMfDiz2LGE",
+ livemode: false,
+ },
+ ]);
+};
diff --git a/packages/dashboard/src/pages/api/stubs/user.js b/packages/dashboard/src/pages/api/stubs/user.js
new file mode 100644
index 00000000..409bf333
--- /dev/null
+++ b/packages/dashboard/src/pages/api/stubs/user.js
@@ -0,0 +1,5 @@
+import user from "./user.json";
+
+export default (req, res) => {
+ res.json(user);
+};
diff --git a/packages/dashboard/src/pages/api/stubs/user.json b/packages/dashboard/src/pages/api/stubs/user.json
new file mode 100644
index 00000000..f41dab0e
--- /dev/null
+++ b/packages/dashboard/src/pages/api/stubs/user.json
@@ -0,0 +1,12 @@
+{
+ "firstName": "John",
+ "lastName": "Doe",
+ "email": "john@example.com",
+ "sub": "ab776d6d-f324-4fa7-4k21-7587d5215481",
+ "tier": 1,
+ "subscribedUntil": "0001-01-01T00:00:00Z",
+ "subscriptionStatus": "active",
+ "subscriptionCancelAt": "2021-04-21T00:00:00Z",
+ "subscriptionCancelAtPeriodEnd": true,
+ "stripeCustomerId": "cus_J0iYnAp6LRgsTI"
+}
diff --git a/packages/dashboard/src/pages/api/stubs/user/downloads.js b/packages/dashboard/src/pages/api/stubs/user/downloads.js
new file mode 100644
index 00000000..c4a24c03
--- /dev/null
+++ b/packages/dashboard/src/pages/api/stubs/user/downloads.js
@@ -0,0 +1,8 @@
+import items from "./downloads.json";
+
+export default (req, res) => {
+ const offset = parseInt(req.query?.offset ?? 0, 10);
+ const pageSize = parseInt(req.query?.pageSize ?? 10, 10);
+
+ res.json({ items: items.slice(offset, offset + pageSize), count: items.length, pageSize, offset });
+};
diff --git a/packages/dashboard/src/pages/api/stubs/user/downloads.json b/packages/dashboard/src/pages/api/stubs/user/downloads.json
new file mode 100644
index 00000000..edf6ff0d
--- /dev/null
+++ b/packages/dashboard/src/pages/api/stubs/user/downloads.json
@@ -0,0 +1,44 @@
+[
+ {
+ "id": 1111,
+ "skylink": "PAL0w4SdA5rFCDGEutgpeQ50Om-YkBabtXVOJAkmedslKw",
+ "name": "ugabuga.pdf",
+ "size": 123123,
+ "downloadedOn": "2020-04-02T08:02:17-05:00"
+ },
+ {
+ "id": 2222,
+ "skylink": "XABvi7JtJbQSMAcDwnUnmp2FKDPjg8_tTTFP4BwMSxVdEg",
+ "name": "ugabuga.pdf",
+ "size": 8912739812,
+ "downloadedOn": "2020-04-02T08:02:17-05:00"
+ },
+ {
+ "id": 3333,
+ "skylink": "IADUs8d9CQjUO34LmdaaNPK_STuZo24rpKVfYW3wPPM2uQ",
+ "name": "ugabuga.pdf",
+ "size": 123123,
+ "downloadedOn": "2020-04-02T08:02:17-05:00"
+ },
+ {
+ "id": 4444,
+ "skylink": "_A2zt5SKoqwnnZU4cBF8uBycSKULXMyeg1c5ZISBr2Q3dA",
+ "name": "ugabuga.pdf",
+ "size": 83943,
+ "downloadedOn": "2020-04-02T08:02:17-05:00"
+ },
+ {
+ "id": 5555,
+ "skylink": "AAC0uO43g64ULpyrW0zO3bjEknSFbAhm8c-RFP21EQlmSQ",
+ "name": "ugabuga.pdf",
+ "size": 3290489120,
+ "downloadedOn": "2020-04-02T08:02:17-05:00"
+ },
+ {
+ "id": 6666,
+ "skylink": "CACqf4NlIMlA0CCCieYGjpViPGyfyJ4v1x3bmuCKZX8FKA",
+ "name": "ugabuga.pdf",
+ "size": 1290389,
+ "downloadedOn": "2020-04-02T08:02:17-05:00"
+ }
+]
diff --git a/packages/dashboard/src/pages/api/stubs/user/stats.js b/packages/dashboard/src/pages/api/stubs/user/stats.js
new file mode 100644
index 00000000..81a65545
--- /dev/null
+++ b/packages/dashboard/src/pages/api/stubs/user/stats.js
@@ -0,0 +1,5 @@
+import stats from "./stats.json";
+
+export default (req, res) => {
+ res.json(stats);
+};
diff --git a/packages/dashboard/src/pages/api/stubs/user/stats.json b/packages/dashboard/src/pages/api/stubs/user/stats.json
new file mode 100644
index 00000000..29696ca2
--- /dev/null
+++ b/packages/dashboard/src/pages/api/stubs/user/stats.json
@@ -0,0 +1,13 @@
+{
+ "storageUsed": 809500672,
+ "numRegReads": 0,
+ "numRegWrites": 0,
+ "numUploads": 13,
+ "numDownloads": 78,
+ "totalUploadsSize": 618649028,
+ "totalDownloadsSize": 32307956843,
+ "bwUploads": 2810183680,
+ "bwDownloads": 32323934976,
+ "bwRegReads": 0,
+ "bwRegWrites": 0
+}
diff --git a/packages/dashboard/src/pages/api/stubs/user/uploads.js b/packages/dashboard/src/pages/api/stubs/user/uploads.js
new file mode 100644
index 00000000..ad8b3d20
--- /dev/null
+++ b/packages/dashboard/src/pages/api/stubs/user/uploads.js
@@ -0,0 +1,8 @@
+import items from "./uploads.json";
+
+export default (req, res) => {
+ const offset = parseInt(req.query?.offset ?? 0, 10);
+ const pageSize = parseInt(req.query?.pageSize ?? 10, 10);
+
+ res.json({ items: items.slice(offset, offset + pageSize), count: items.length, pageSize, offset });
+};
diff --git a/packages/dashboard/src/pages/api/stubs/user/uploads.json b/packages/dashboard/src/pages/api/stubs/user/uploads.json
new file mode 100644
index 00000000..efc42359
--- /dev/null
+++ b/packages/dashboard/src/pages/api/stubs/user/uploads.json
@@ -0,0 +1,44 @@
+[
+ {
+ "id": 1111,
+ "skylink": "PAL0w4SdA5rFCDGEutgpeQ50Om-YkBabtXVOJAkmedslKw",
+ "name": "ugabuga.pdf",
+ "size": 123123,
+ "uploadedOn": "2020-04-02T08:02:17-05:00"
+ },
+ {
+ "id": 2222,
+ "skylink": "XABvi7JtJbQSMAcDwnUnmp2FKDPjg8_tTTFP4BwMSxVdEg",
+ "name": "ugabuga.pdf",
+ "size": 8912739812,
+ "uploadedOn": "2020-04-02T08:02:17-05:00"
+ },
+ {
+ "id": 3333,
+ "skylink": "IADUs8d9CQjUO34LmdaaNPK_STuZo24rpKVfYW3wPPM2uQ",
+ "name": "ugabuga.pdf",
+ "size": 123123,
+ "uploadedOn": "2020-04-02T08:02:17-05:00"
+ },
+ {
+ "id": 4444,
+ "skylink": "_A2zt5SKoqwnnZU4cBF8uBycSKULXMyeg1c5ZISBr2Q3dA",
+ "name": "ugabuga.pdf",
+ "size": 83943,
+ "uploadedOn": "2020-04-02T08:02:17-05:00"
+ },
+ {
+ "id": 5555,
+ "skylink": "AAC0uO43g64ULpyrW0zO3bjEknSFbAhm8c-RFP21EQlmSQ",
+ "name": "ugabuga.pdf",
+ "size": 3290489120,
+ "uploadedOn": "2020-04-02T08:02:17-05:00"
+ },
+ {
+ "id": 6666,
+ "skylink": "CACqf4NlIMlA0CCCieYGjpViPGyfyJ4v1x3bmuCKZX8FKA",
+ "name": "ugabuga.pdf",
+ "size": 1290389,
+ "uploadedOn": "2020-04-02T08:02:17-05:00"
+ }
+]
diff --git a/packages/dashboard/src/pages/auth/login.js b/packages/dashboard/src/pages/auth/login.js
new file mode 100644
index 00000000..481f8d44
--- /dev/null
+++ b/packages/dashboard/src/pages/auth/login.js
@@ -0,0 +1,96 @@
+import Link from "next/link";
+import { Configuration, PublicApi } from "@ory/kratos-client";
+import config from "../../config";
+import SelfServiceForm from "../../components/Form/SelfServiceForm";
+
+const kratos = new PublicApi(new Configuration({ basePath: config.kratos.public }));
+
+export async function getServerSideProps(context) {
+ const flow = context.query.flow;
+ const redirect = encodeURIComponent(`/api/accounts/login?return_to=${context.query.return_to ?? "/"}`);
+
+ if (process.env.NODE_ENV === "development") {
+ return { props: { flow: require("../../../stubs/login.json") } };
+ }
+
+ // The flow is used to identify the login and registration flow and
+ // return data like the csrf_token and so on.
+ if (!flow || typeof flow !== "string") {
+ // No flow ID found in URL, initializing login flow.
+ return {
+ redirect: {
+ permanent: false,
+ destination: `${config.kratos.browser}/self-service/login/browser?return_to=${redirect}`,
+ },
+ };
+ }
+
+ try {
+ const { status, data } = await kratos.getSelfServiceLoginFlow(flow);
+
+ if (status === 200) return { props: { flow: data } };
+
+ throw new Error(`Failed to retrieve flow ${flow} with code ${status}`);
+ } catch (error) {
+ return {
+ redirect: {
+ permanent: false,
+ destination: `${config.kratos.browser}/self-service/login/browser?return_to=${redirect}`,
+ },
+ };
+ }
+}
+
+const fieldsConfig = {
+ identifier: {
+ label: "Email address",
+ autoComplete: "email",
+ position: 0,
+ },
+ password: {
+ label: "Password",
+ autoComplete: "current-password",
+ position: 1,
+ },
+ csrf_token: {
+ position: 99,
+ },
+};
+
+export default function Login({ flow }) {
+ return (
+
+
+
+
Sign in to your account
+
+ or{" "}
+
+ sign up
+ {" "}
+ if you don't have one yet
+
+
+
+
+
+
+
+ );
+}
diff --git a/packages/dashboard/src/pages/auth/registration.js b/packages/dashboard/src/pages/auth/registration.js
new file mode 100644
index 00000000..33230c54
--- /dev/null
+++ b/packages/dashboard/src/pages/auth/registration.js
@@ -0,0 +1,113 @@
+import Link from "next/link";
+import { Configuration, PublicApi } from "@ory/kratos-client";
+import { getIn } from "formik";
+import config from "../../config";
+import levenshtein from "fast-levenshtein";
+import lcs from "../../services/longestCommonSequence";
+import SelfServiceForm from "../../components/Form/SelfServiceForm";
+
+const kratos = new PublicApi(new Configuration({ basePath: config.kratos.public }));
+
+export async function getServerSideProps(context) {
+ const flow = context.query.flow;
+ const redirect = encodeURIComponent(`/api/accounts/login?return_to=${context.query.return_to ?? "/"}`);
+
+ if (process.env.NODE_ENV === "development") {
+ return { props: { flow: require("../../../stubs/registration.json") } };
+ }
+
+ // The flow is used to identify the login and registration flow and
+ // return data like the csrf_token and so on.
+ if (!flow || typeof flow !== "string") {
+ // No flow ID found in URL, initializing registration flow.
+ return {
+ redirect: {
+ permanent: false,
+ destination: `${config.kratos.browser}/self-service/registration/browser?return_to=${redirect}`,
+ },
+ };
+ }
+
+ try {
+ const { status, data } = await kratos.getSelfServiceRegistrationFlow(flow);
+
+ if (status === 200) return { props: { flow: data } };
+
+ throw new Error(`Failed to retrieve flow ${flow} with code ${status}`);
+ } catch (error) {
+ return {
+ redirect: {
+ permanent: false,
+ destination: `${config.kratos.browser}/self-service/registration/browser?return_to=${redirect}`,
+ },
+ };
+ }
+}
+
+const fieldsConfig = {
+ "traits.email": {
+ label: "Email address",
+ autoComplete: "email",
+ position: 0,
+ },
+ password: {
+ label: "Password",
+ autoComplete: "new-password",
+ position: 1,
+ checks: [
+ {
+ label: "At least 6 characters long",
+ validate: (values, field) => {
+ const value = getIn(values, field);
+
+ return value && value.length > 5;
+ },
+ },
+ {
+ label: "Significantly different from the email",
+ validate: (values, field) => {
+ const value = getIn(values, field);
+ const email = getIn(values, "traits.email");
+
+ // levenshtein distance higher than 5 and longest common sequence shorter than half of the password
+ return value && email && levenshtein.get(value, email) > 5 && lcs(value, email).length / value.length <= 0.5;
+ },
+ },
+ ],
+ },
+ csrf_token: {
+ position: 99,
+ },
+};
+
+export default function Registration({ flow }) {
+ return (
+
+
+
+
Sign up for a new account
+
+ or{" "}
+
+ sign in
+ {" "}
+ if you already have one
+
+
+
+
+
+ );
+}
diff --git a/packages/dashboard/src/pages/downloads.js b/packages/dashboard/src/pages/downloads.js
new file mode 100644
index 00000000..942efd11
--- /dev/null
+++ b/packages/dashboard/src/pages/downloads.js
@@ -0,0 +1,44 @@
+import dayjs from "dayjs";
+import prettyBytes from "pretty-bytes";
+import { useState } from "react";
+import Layout from "../components/Layout";
+import Table from "../components/Table";
+import authServerSideProps from "../services/authServerSideProps";
+import { SkynetClient } from "skynet-js";
+import useAccountsApi from "../services/useAccountsApi";
+
+const skynetClient = new SkynetClient(process.env.NEXT_PUBLIC_SKYNET_PORTAL_API);
+const apiPrefix = process.env.NODE_ENV === "development" ? "/api/stubs" : "";
+const getSkylinkLink = ({ skylink }) => skynetClient.getSkylinkUrl(skylink);
+const getRelativeDate = ({ downloadedOn }) => dayjs(downloadedOn).format("YYYY-MM-DD HH:mm:ss");
+const headers = [
+ { key: "name", name: "Name", nowrap: false, href: getSkylinkLink },
+ { key: "skylink", name: "Skylink" },
+ { key: "size", name: "Size", formatter: ({ size }) => prettyBytes(size) },
+ { key: "downloadedOn", name: "Accessed on", formatter: getRelativeDate },
+];
+const actions = [];
+
+export const getServerSideProps = authServerSideProps(async (context, api) => {
+ const initialData = await api.get("user/downloads?pageSize=10&offset=0").json();
+
+ return { props: { initialData } };
+});
+
+export default function Downloads({ initialData }) {
+ const [offset, setOffset] = useState(0);
+ const { data } = useAccountsApi(`${apiPrefix}/user/downloads?pageSize=10&offset=${offset}`, {
+ initialData: offset === 0 ? initialData : undefined,
+ revalidateOnMount: true,
+ });
+
+ // preload next page if it exists (based on the response from the current page query)
+ const nextPageOffset = data && data.offset + data.pageSize < data.count ? data.offset + data.pageSize : offset;
+ useAccountsApi(`${apiPrefix}/user/downloads?pageSize=10&offset=${nextPageOffset}`);
+
+ return (
+
+
+
+ );
+}
diff --git a/packages/dashboard/src/pages/error.js b/packages/dashboard/src/pages/error.js
new file mode 100644
index 00000000..19a1e7b1
--- /dev/null
+++ b/packages/dashboard/src/pages/error.js
@@ -0,0 +1,68 @@
+import Link from "next/link";
+import { Configuration, PublicApi } from "@ory/kratos-client";
+import config from "../config";
+
+const kratos = new PublicApi(new Configuration({ basePath: config.kratos.public }));
+
+export async function getServerSideProps(context) {
+ const error = context.query.error;
+
+ // No error was send, redirecting back to home.
+ if (!error || typeof error !== "string") {
+ console.log("No error ID found in URL, redirecting to homepage.");
+
+ return { redirect: { permanent: false, destination: "/" } };
+ }
+
+ try {
+ const { status, data } = await kratos.getSelfServiceError(error);
+
+ if ("errors" in data) return { props: { errors: data.errors } };
+
+ throw new Error(`Expected error ${error} to contain "errors" but got ${JSON.stringify(data)}`);
+ } catch (error) {
+ return { redirect: { permanent: false, destination: "/" } };
+ }
+}
+
+export default function Error({ errors }) {
+ return (
+
+
+
+
An error occurred
+
+
+
+ {errors.map((error, index) => (
+
1 ? "mt-3 sm:mt-5" : ""} text-center`}>
+
+ {error.code} - {error.message}
+
+
+
+ ))}
+
+
+
+
+ );
+}
diff --git a/packages/dashboard/src/pages/index.js b/packages/dashboard/src/pages/index.js
new file mode 100644
index 00000000..696ece24
--- /dev/null
+++ b/packages/dashboard/src/pages/index.js
@@ -0,0 +1,276 @@
+import dayjs from "dayjs";
+import relativeTime from "dayjs/plugin/relativeTime";
+import prettyBytes from "pretty-bytes";
+import Link from "next/link";
+import Layout from "../components/Layout";
+import authServerSideProps from "../services/authServerSideProps";
+import { SkynetClient } from "skynet-js";
+import config from "../config";
+import useAccountsApi from "../services/useAccountsApi";
+import { isFreeTier } from "../services/tiers";
+import { write } from "clipboardy";
+
+dayjs.extend(relativeTime);
+
+const skynetClient = new SkynetClient(process.env.NEXT_PUBLIC_SKYNET_PORTAL_API);
+const apiPrefix = process.env.NODE_ENV === "development" ? "/api/stubs" : "";
+
+export const getServerSideProps = authServerSideProps(async (context, api) => {
+ const stripe = await api.get("stripe/prices").json();
+ const plans = [config.tiers.starter, ...stripe].sort((a, b) => a.tier - b.tier);
+
+ return { props: { plans } };
+});
+
+function SkylinkList({ items = [], timestamp }) {
+ return (
+
+ {items.slice(0, 3).map((item) => (
+ -
+
+
+
+
+
+
+ {prettyBytes(item.size)}
+
+
+
+
+
+ {item[timestamp] &&
}
+
+
+
+
+ ))}
+
+ {!items.length && (
+ -
+
+
+ )}
+
+ );
+}
+
+export default function Home({ plans }) {
+ const { data: user } = useAccountsApi(`${apiPrefix}/user`);
+ const { data: stats } = useAccountsApi(`${apiPrefix}/user/stats`);
+ const { data: downloads } = useAccountsApi(`${apiPrefix}/user/downloads?pageSize=3&offset=0`);
+ const { data: uploads } = useAccountsApi(`${apiPrefix}/user/uploads?pageSize=3&offset=0`);
+
+ const activePlan = plans.find(({ tier }) => (user ? user.tier === tier : isFreeTier(tier)));
+
+ return (
+
+
+
+
+
+
+
+ {/* Heroicon name: outline/users */}
+
+
+
+
- Current plan
+
-
+
{activePlan.name}
+
+
+
+
+
+
+
+
+
+
+
+
- Storage used
+
-
+
{prettyBytes(stats?.storageUsed ?? 0)}
+
+
+
+
+
+
+ {/*
+
+
+
+
+
- Bandwidth used
+
-
+
{prettyBytes(stats?.bwDownloads ?? 0)}
+
+
+
+
+
+
*/}
+
+
+ {/* ============ */}
+
+
+
+
Recent downloads
+
+ {/* This example requires Tailwind CSS v2.0+ */}
+
+
+
+
+
+
Recent uploads
+
+ {/* This example requires Tailwind CSS v2.0+ */}
+
+
+
+
+
+
+
+ );
+}
diff --git a/packages/dashboard/src/pages/payments.js b/packages/dashboard/src/pages/payments.js
new file mode 100644
index 00000000..c36fe039
--- /dev/null
+++ b/packages/dashboard/src/pages/payments.js
@@ -0,0 +1,193 @@
+import dayjs from "dayjs";
+import Layout from "../components/Layout";
+import ky from "ky/umd";
+import { useEffect, useState } from "react";
+import authServerSideProps from "../services/authServerSideProps";
+import classnames from "classnames";
+import prettyBytes from "pretty-bytes";
+import config from "../config";
+import useAccountsApi from "../services/useAccountsApi";
+import { isFreeTier, isPaidTier } from "../services/tiers";
+
+const apiPrefix = process.env.NODE_ENV === "development" ? "/api/stubs" : "";
+
+const ActiveBadge = () => {
+ return (
+
+ active
+
+ );
+};
+
+export const getServerSideProps = authServerSideProps(async (context, api) => {
+ const [user, stats, stripe] = await Promise.all([
+ api.get("user").json(),
+ api.get("user/stats").json(),
+ api.get("stripe/prices").json(),
+ ]);
+ const plans = [config.tiers.starter, ...stripe].sort((a, b) => a.tier - b.tier);
+
+ return { props: { plans, user, stats } };
+});
+
+export default function Payments({ plans, user: initialUserData, stats: initialStatsData }) {
+ const { data: user } = useAccountsApi(`${apiPrefix}/user`, { initialData: initialUserData });
+ const { data: stats } = useAccountsApi(`${apiPrefix}/user/stats`, { initialData: initialStatsData });
+ const [selectedPlan, setSelectedPlan] = useState(plans.find(({ tier }) => isFreeTier(tier)));
+ const activePlan = plans.find(({ tier }) => (user ? user.tier === tier : isFreeTier(tier)));
+ const handleSubscribe = async () => {
+ try {
+ const price = selectedPlan.stripe;
+ const { sessionId } = await ky.post("/api/stripe/checkout", { json: { price } }).json();
+ const stripe = new Stripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY);
+ await stripe.redirectToCheckout({ sessionId });
+ } catch (error) {
+ console.log(error); // todo: handle error
+ }
+ };
+
+ useEffect(() => {
+ if (activePlan && isPaidTier(activePlan.tier)) {
+ setSelectedPlan(activePlan);
+ }
+ }, [activePlan, selectedPlan, setSelectedPlan]);
+
+ return (
+
+
+
+
+
+
+
- Current plan
+ - {activePlan?.name || "—"}
+
+
+
+
+
+
- Subscription status
+ -
+ {isFreeTier(activePlan?.tier) ? "—" : user?.subscriptionStatus}
+
+
+ {user?.subscriptionCancelAtPeriodEnd && (
+
+
+ Your plan will be cancelled on {dayjs(user.subscriptionCancelAt).format("D MMM YYYY")}.
+
+
+ )}
+
+
+
+
+
- Storage used
+ - {prettyBytes(stats.storageUsed)}
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/packages/dashboard/src/pages/plans.js b/packages/dashboard/src/pages/plans.js
new file mode 100644
index 00000000..ee319e69
--- /dev/null
+++ b/packages/dashboard/src/pages/plans.js
@@ -0,0 +1,389 @@
+import Layout from "../components/Layout";
+
+export default function Payments() {
+ return (
+
+ {/* This example requires Tailwind CSS v2.0+ */}
+
+
+
+
+ Start using for free, then add a plan to improve the experience. Account plans unlock additional features.
+
+
+
+
+
+
+
+
+
+
Free
+
All the basics for starting a new business
+
+ no cost
+
+
+ Active
+
+
+
+
What's included
+
+ -
+ {/* Heroicon name: solid/check */}
+
+ Potenti felis, in cras at at ligula nunc.
+
+ -
+ {/* Heroicon name: solid/check */}
+
+ Orci neque eget pellentesque.
+
+
+
+
+
+
+
Skynet Plus
+
All the basics for starting a new business
+
+ $5
+ /mo
+
+
+ Buy Skynet Plus
+
+
+
+
What's included
+
+ -
+ {/* Heroicon name: solid/check */}
+
+ Potenti felis, in cras at at ligula nunc.
+
+ -
+ {/* Heroicon name: solid/check */}
+
+ Orci neque eget pellentesque.
+
+ -
+ {/* Heroicon name: solid/check */}
+
+ Donec mauris sit in eu tincidunt etiam.
+
+
+
+
+
+
+
Skynet Pro
+
All the basics for starting a new business
+
+ $20
+ /mo
+
+
+ Buy Skynet Pro
+
+
+
+
What's included
+
+ -
+ {/* Heroicon name: solid/check */}
+
+ Potenti felis, in cras at at ligula nunc.
+
+ -
+ {/* Heroicon name: solid/check */}
+
+ Orci neque eget pellentesque.
+
+ -
+ {/* Heroicon name: solid/check */}
+
+ Donec mauris sit in eu tincidunt etiam.
+
+ -
+ {/* Heroicon name: solid/check */}
+
+ Faucibus volutpat magna.
+
+
+
+
+
+
+
+
What's included
+
+ -
+ {/* Heroicon name: solid/check */}
+
+ Potenti felis, in cras at at ligula nunc.
+
+ -
+ {/* Heroicon name: solid/check */}
+
+ Orci neque eget pellentesque.
+
+ -
+ {/* Heroicon name: solid/check */}
+
+ Donec mauris sit in eu tincidunt etiam.
+
+ -
+ {/* Heroicon name: solid/check */}
+
+ Faucibus volutpat magna.
+
+ -
+ {/* Heroicon name: solid/check */}
+
+ Id sed tellus in varius quisque.
+
+ -
+ {/* Heroicon name: solid/check */}
+
+ Risus egestas faucibus.
+
+ -
+ {/* Heroicon name: solid/check */}
+
+ Risus cursus ullamcorper.
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/packages/dashboard/src/pages/recovery.js b/packages/dashboard/src/pages/recovery.js
new file mode 100644
index 00000000..e64a4213
--- /dev/null
+++ b/packages/dashboard/src/pages/recovery.js
@@ -0,0 +1,95 @@
+import Link from "next/link";
+import { Configuration, PublicApi } from "@ory/kratos-client";
+import config from "../config";
+import SelfServiceForm from "../components/Form/SelfServiceForm";
+
+const kratos = new PublicApi(new Configuration({ basePath: config.kratos.public }));
+
+export async function getServerSideProps(context) {
+ const flow = context.query.flow;
+
+ if (process.env.NODE_ENV === "development") {
+ return { props: { flow: require("../../stubs/recovery.json") } };
+ }
+
+ // The flow is used to identify the login and registration flow and
+ // return data like the csrf_token and so on.
+ if (!flow || typeof flow !== "string") {
+ // No flow ID found in URL, initializing recovery flow.
+ return {
+ redirect: {
+ permanent: false,
+ destination: `${config.kratos.browser}/self-service/recovery/browser`,
+ },
+ };
+ }
+
+ try {
+ const { status, data } = await kratos.getSelfServiceRecoveryFlow(flow);
+
+ if (status === 200) return { props: { flow: data } };
+
+ throw new Error(`Failed to retrieve flow ${flow} with code ${status}`);
+ } catch (error) {
+ return {
+ redirect: {
+ permanent: false,
+ destination: `${config.kratos.browser}/self-service/recovery/browser`,
+ },
+ };
+ }
+}
+
+const fieldsConfig = {
+ email: {
+ label: "Your email",
+ autoComplete: "email",
+ position: 0,
+ },
+ csrf_token: {
+ position: 99,
+ },
+};
+
+export default function Recovery({ flow }) {
+ return (
+
+
+
+
Recover your account
+
+
+ sign in
+ {" "}
+ if you suddenly remembered your password
+
+
+ or{" "}
+
+ sign up
+ {" "}
+ for a new account
+
+
+
+
+
+ );
+}
diff --git a/packages/dashboard/src/pages/settings.js b/packages/dashboard/src/pages/settings.js
new file mode 100644
index 00000000..6f314ca5
--- /dev/null
+++ b/packages/dashboard/src/pages/settings.js
@@ -0,0 +1,83 @@
+import { Configuration, PublicApi } from "@ory/kratos-client";
+import Layout from "../components/Layout";
+import config from "../config";
+import SelfServiceForm from "../components/Form/SelfServiceForm";
+import authServerSideProps from "../services/authServerSideProps";
+
+const kratos = new PublicApi(new Configuration({ basePath: config.kratos.public }));
+
+export const getServerSideProps = authServerSideProps(async (context) => {
+ const flow = context.query.flow;
+
+ if (process.env.NODE_ENV === "development") {
+ return { props: { flow: require("../../stubs/settings.json") } };
+ }
+
+ // The flow is used to identify the login and registration flow and
+ // return data like the csrf_token and so on.
+ if (!flow || typeof flow !== "string") {
+ // No flow ID found in URL, initializing settings flow.
+ return {
+ redirect: {
+ permanent: false,
+ destination: `${config.kratos.browser}/self-service/settings/browser`,
+ },
+ };
+ }
+
+ try {
+ const { status, data } = await kratos.getSelfServiceSettingsFlow(flow, {
+ headers: { cookie: context.req.headers.cookie },
+ });
+
+ console.log(flow, status, data);
+
+ if (status === 200) return { props: { flow: data } };
+
+ throw new Error(`Failed to retrieve flow ${flow} with code ${status}`);
+ } catch (error) {
+ console.log(error);
+
+ return {
+ redirect: {
+ permanent: false,
+ destination: `${config.kratos.browser}/self-service/settings/browser`,
+ },
+ };
+ }
+});
+
+const fieldsConfig = {
+ "traits.email": {
+ label: "Email address",
+ autoComplete: "email",
+ position: 0,
+ },
+ password: {
+ label: "Password",
+ autoComplete: "new-password",
+ position: 1,
+ },
+ csrf_token: {
+ position: 99,
+ },
+};
+
+export default function Settings({ flow }) {
+ const profileConfig = flow.methods.profile.config;
+ const passwordConfig = flow.methods.password.config;
+
+ return (
+
+
+
+
+
+
+ );
+}
diff --git a/packages/dashboard/src/pages/uploads.js b/packages/dashboard/src/pages/uploads.js
new file mode 100644
index 00000000..d78288f7
--- /dev/null
+++ b/packages/dashboard/src/pages/uploads.js
@@ -0,0 +1,44 @@
+import dayjs from "dayjs";
+import prettyBytes from "pretty-bytes";
+import { useState } from "react";
+import Layout from "../components/Layout";
+import Table from "../components/Table";
+import authServerSideProps from "../services/authServerSideProps";
+import { SkynetClient } from "skynet-js";
+import useAccountsApi from "../services/useAccountsApi";
+
+const skynetClient = new SkynetClient(process.env.NEXT_PUBLIC_SKYNET_PORTAL_API);
+const apiPrefix = process.env.NODE_ENV === "development" ? "/api/stubs" : "";
+const getSkylinkLink = ({ skylink }) => skynetClient.getSkylinkUrl(skylink);
+const getRelativeDate = ({ uploadedOn }) => dayjs(uploadedOn).format("YYYY-MM-DD HH:mm:ss");
+const headers = [
+ { key: "name", name: "Name", nowrap: false, href: getSkylinkLink },
+ { key: "skylink", name: "Skylink" },
+ { key: "size", name: "Size", formatter: ({ size }) => prettyBytes(size) },
+ { key: "uploadedOn", name: "Uploaded on", formatter: getRelativeDate },
+];
+const actions = [];
+
+export const getServerSideProps = authServerSideProps(async (context, api) => {
+ const initialData = await api.get("user/uploads?pageSize=10&offset=0").json();
+
+ return { props: { initialData } };
+});
+
+export default function Uploads({ initialData }) {
+ const [offset, setOffset] = useState(0);
+ const { data } = useAccountsApi(`${apiPrefix}/user/uploads?pageSize=10&offset=${offset}`, {
+ initialData: offset === 0 ? initialData : undefined,
+ revalidateOnMount: true,
+ });
+
+ // preload next page if it exists (based on the response from the current page query)
+ const nextPageOffset = data && data.offset + data.pageSize < data.count ? data.offset + data.pageSize : offset;
+ useAccountsApi(`${apiPrefix}/user/uploads?pageSize=10&offset=${nextPageOffset}`);
+
+ return (
+
+
+
+ );
+}
diff --git a/packages/dashboard/src/pages/verify.js b/packages/dashboard/src/pages/verify.js
new file mode 100644
index 00000000..adcde201
--- /dev/null
+++ b/packages/dashboard/src/pages/verify.js
@@ -0,0 +1,103 @@
+import Link from "next/link";
+import { Configuration, PublicApi } from "@ory/kratos-client";
+import config from "../config";
+import SelfServiceForm from "../components/Form/SelfServiceForm";
+import { useEffect } from "react";
+
+const kratos = new PublicApi(new Configuration({ basePath: config.kratos.public }));
+
+export async function getServerSideProps(context) {
+ const flow = context.query.flow;
+
+ // if (process.env.NODE_ENV === "development") {
+ // return { props: { flow: require("../../stubs/recovery.json") } };
+ // }
+
+ if (!flow || typeof flow !== "string") {
+ return {
+ redirect: {
+ permanent: false,
+ destination: `${config.kratos.browser}/self-service/verification/browser`,
+ },
+ };
+ }
+
+ try {
+ const { status, data } = await kratos.getSelfServiceVerificationFlow(flow);
+
+ if (status === 200) return { props: { flow: data } };
+
+ throw new Error(`Failed to retrieve flow ${flow} with code ${status}`);
+ } catch (error) {
+ return {
+ redirect: {
+ permanent: false,
+ destination: `${config.kratos.browser}/self-service/verification/browser`,
+ },
+ };
+ }
+}
+
+const fieldsConfig = {
+ email: {
+ label: "Your email",
+ autoComplete: "email",
+ position: 0,
+ },
+ csrf_token: {
+ position: 99,
+ },
+};
+
+export default function Verify({ flow }) {
+ const state = flow.state;
+
+ useEffect(() => {
+ if (state === "passed_challenge") {
+ setTimeout(() => (window.location = "/"), 5000);
+ }
+ }, [state]);
+
+ return (
+
+
+
+
+ {flow.state === "passed_challenge" ? "Verification successful!" : "Account verification"}
+
+
+ {flow.state === "passed_challenge" && (
+ <>
+
You will be redirected automatically
+
+
+ go to dashboard
+
+
+ >
+ )}
+
+
+ {flow.state !== "passed_challenge" && (
+
+ )}
+
+ );
+}
diff --git a/packages/dashboard/src/services/authServerSideProps.js b/packages/dashboard/src/services/authServerSideProps.js
new file mode 100644
index 00000000..bc7bf43c
--- /dev/null
+++ b/packages/dashboard/src/services/authServerSideProps.js
@@ -0,0 +1,27 @@
+import ky from "ky/umd";
+
+const isProduction = process.env.NODE_ENV === "production";
+
+export default function authServerSideProps(getServerSideProps) {
+ return function authenticate(context) {
+ if (isProduction && (!("ory_kratos_session" in context.req.cookies) || !("skynet-jwt" in context.req.cookies))) {
+ return {
+ redirect: {
+ permanent: false,
+ destination: `/api/accounts/login?return_to=${encodeURIComponent(context.resolvedUrl)}`,
+ },
+ };
+ }
+
+ if (getServerSideProps) {
+ const api = ky.create({
+ headers: { cookie: context.req.headers.cookie },
+ prefixUrl: isProduction ? "http://oathkeeper:4455" : "http://localhost:3000/api/stubs",
+ });
+
+ return getServerSideProps(context, api);
+ }
+
+ return { props: {} };
+ };
+}
diff --git a/packages/dashboard/src/services/longestCommonSequence.js b/packages/dashboard/src/services/longestCommonSequence.js
new file mode 100644
index 00000000..5c5f5143
--- /dev/null
+++ b/packages/dashboard/src/services/longestCommonSequence.js
@@ -0,0 +1,65 @@
+// @source https://github.com/trekhleb/javascript-algorithms/blob/master/src/algorithms/sets/longest-common-subsequence/longestCommonSubsequence.js
+// @license MIT https://github.com/trekhleb/javascript-algorithms/blob/master/LICENSE
+
+/**
+ * @param {string[]} set1
+ * @param {string[]} set2
+ * @return {string[]}
+ */
+export default function longestCommonSubsequence(set1, set2) {
+ // Init LCS matrix.
+ const lcsMatrix = Array(set2.length + 1)
+ .fill(null)
+ .map(() => Array(set1.length + 1).fill(null));
+
+ // Fill first row with zeros.
+ for (let columnIndex = 0; columnIndex <= set1.length; columnIndex += 1) {
+ lcsMatrix[0][columnIndex] = 0;
+ }
+
+ // Fill first column with zeros.
+ for (let rowIndex = 0; rowIndex <= set2.length; rowIndex += 1) {
+ lcsMatrix[rowIndex][0] = 0;
+ }
+
+ // Fill rest of the column that correspond to each of two strings.
+ for (let rowIndex = 1; rowIndex <= set2.length; rowIndex += 1) {
+ for (let columnIndex = 1; columnIndex <= set1.length; columnIndex += 1) {
+ if (set1[columnIndex - 1] === set2[rowIndex - 1]) {
+ lcsMatrix[rowIndex][columnIndex] = lcsMatrix[rowIndex - 1][columnIndex - 1] + 1;
+ } else {
+ lcsMatrix[rowIndex][columnIndex] = Math.max(
+ lcsMatrix[rowIndex - 1][columnIndex],
+ lcsMatrix[rowIndex][columnIndex - 1]
+ );
+ }
+ }
+ }
+
+ // Calculate LCS based on LCS matrix.
+ if (!lcsMatrix[set2.length][set1.length]) {
+ // If the length of largest common string is zero then return empty string.
+ return [""];
+ }
+
+ const longestSequence = [];
+ let columnIndex = set1.length;
+ let rowIndex = set2.length;
+
+ while (columnIndex > 0 || rowIndex > 0) {
+ if (set1[columnIndex - 1] === set2[rowIndex - 1]) {
+ // Move by diagonal left-top.
+ longestSequence.unshift(set1[columnIndex - 1]);
+ columnIndex -= 1;
+ rowIndex -= 1;
+ } else if (lcsMatrix[rowIndex][columnIndex] === lcsMatrix[rowIndex][columnIndex - 1]) {
+ // Move left.
+ columnIndex -= 1;
+ } else {
+ // Move up.
+ rowIndex -= 1;
+ }
+ }
+
+ return longestSequence;
+}
diff --git a/packages/dashboard/src/services/tiers.js b/packages/dashboard/src/services/tiers.js
new file mode 100644
index 00000000..4e561e2b
--- /dev/null
+++ b/packages/dashboard/src/services/tiers.js
@@ -0,0 +1,2 @@
+export const isFreeTier = (tier) => tier === 1;
+export const isPaidTier = (tier) => tier > 1;
diff --git a/packages/dashboard/src/services/useAccountsApi.js b/packages/dashboard/src/services/useAccountsApi.js
new file mode 100644
index 00000000..169b12d9
--- /dev/null
+++ b/packages/dashboard/src/services/useAccountsApi.js
@@ -0,0 +1,15 @@
+import useSWR from "swr";
+import { StatusCodes } from "http-status-codes";
+
+const fetcher = (url) =>
+ fetch(url).then((res) => {
+ if (res.status === StatusCodes.UNAUTHORIZED) {
+ window.location.href = `/auth/login?return_to=${encodeURIComponent(window.location.href)}`;
+ }
+
+ return res.json();
+ });
+
+export default function useAccountsApi(key, config) {
+ return useSWR(key, fetcher, config);
+}
diff --git a/packages/dashboard/stubs/login.json b/packages/dashboard/stubs/login.json
new file mode 100644
index 00000000..bb136cd8
--- /dev/null
+++ b/packages/dashboard/stubs/login.json
@@ -0,0 +1,45 @@
+{
+ "id": "bda73c77-1e21-4bfd-b85a-322fce2e4576",
+ "expires_at": "2020-01-28T13:48:04.690715Z",
+ "issued_at": "2020-01-28T13:38:04.690732Z",
+ "request_url": "http://127.0.0.1:4455/auth/browser/login",
+ "methods": {
+ "oidc": {
+ "method": "oidc",
+ "config": {
+ "action": "http://127.0.0.1:4455/.ory/kratos/public/auth/browser/methods/oidc/auth/bda73c77-1e21-4bfd-b85a-322fce2e4576",
+ "method": "POST",
+ "fields": [
+ {
+ "name": "csrf_token",
+ "type": "hidden",
+ "required": true,
+ "value": "QJreyXtUD4oUSJfGNjA/+6ydsQyq0o/rfTL6QK86VadVFg6mwgX5x1QHVQ6uRqKxmwAcavQup3ILCSwl7ke97g=="
+ }
+ ]
+ }
+ },
+ "password": {
+ "method": "password",
+ "config": {
+ "action": "http://127.0.0.1:4455/.ory/kratos/public/auth/browser/methods/password/login?request=bda73c77-1e21-4bfd-b85a-322fce2e4576",
+ "method": "POST",
+ "fields": [
+ {
+ "name": "csrf_token",
+ "type": "hidden",
+ "required": true,
+ "value": "M1gAKA8fIhw4JOpQ/5m9mKARBAvKhzWkyhbxjtZNLG8m1NBHtk7UUXhrKJhn7yDSl4ypbZR7HT28LSfrlzDEJg=="
+ },
+ { "name": "identifier", "type": "text", "required": true, "value": "asfdasdffads" },
+ { "name": "password", "type": "password", "required": true }
+ ],
+ "errors": [
+ {
+ "message": "The provided credentials are invalid. Check for spelling mistakes in your password or username, email address, or phone number."
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/packages/dashboard/stubs/recovery.json b/packages/dashboard/stubs/recovery.json
new file mode 100644
index 00000000..28fde87a
--- /dev/null
+++ b/packages/dashboard/stubs/recovery.json
@@ -0,0 +1,31 @@
+{
+ "id": "01e21a99-8e69-41f9-b3ba-4967f714c8eb",
+ "type": "browser",
+ "expires_at": "2021-03-18T15:46:30.634635Z",
+ "issued_at": "2021-03-18T14:46:30.634635Z",
+ "request_url": "http://oathkeeper:4455/self-service/recovery/browser",
+ "messages": null,
+ "methods": {
+ "link": {
+ "method": "link",
+ "config": {
+ "action": "http://127.0.0.1:4455/.ory/kratos/public/self-service/recovery/methods/link?flow=01e21a99-8e69-41f9-b3ba-4967f714c8eb",
+ "method": "POST",
+ "fields": [
+ {
+ "name": "csrf_token",
+ "type": "hidden",
+ "required": true,
+ "value": "XvPfLJzxmcTWnr2rmLzFcED9Ef1PIkqSBQgx5t0yu0WuIp2S6ll+B9cQ0ClIcLQ=="
+ },
+ {
+ "name": "email",
+ "type": "email",
+ "required": true
+ }
+ ]
+ }
+ }
+ },
+ "state": "choose_method"
+}
diff --git a/packages/dashboard/stubs/registration.json b/packages/dashboard/stubs/registration.json
new file mode 100644
index 00000000..4fe796ae
--- /dev/null
+++ b/packages/dashboard/stubs/registration.json
@@ -0,0 +1,58 @@
+{
+ "id": "dbff7b96-8116-42c5-8624-f9fb28f1db15",
+ "expires_at": "2020-01-28T13:49:01.2274112Z",
+ "issued_at": "2020-01-28T13:39:01.2274261Z",
+ "request_url": "http://127.0.0.1:4455/auth/browser/registration",
+ "methods": {
+ "oidc": {
+ "method": "oidc",
+ "config": {
+ "action": "http://127.0.0.1:4455/.ory/kratos/public/auth/browser/methods/oidc/auth/dbff7b96-8116-42c5-8624-f9fb28f1db15",
+ "method": "POST",
+ "fields": [
+ {
+ "name": "csrf_token",
+ "type": "hidden",
+ "required": true,
+ "value": "xwb6A6iHdsguYwkAM6m3jj196E7TcmiWpAavIRxuAgXSiipsEdaAhW4sy8ir3yrECuBFKI2OQA/SPXlEXRPqTA=="
+ }
+ ]
+ }
+ },
+ "password": {
+ "method": "password",
+ "config": {
+ "errors": [
+ {
+ "message": "The provided credentials are invalid. Check for spelling mistakes in your password or username, email address, or phone number."
+ }
+ ],
+ "action": "http://127.0.0.1:4455/.ory/kratos/public/auth/browser/methods/password/registration?request=dbff7b96-8116-42c5-8624-f9fb28f1db15",
+ "method": "POST",
+ "fields": [
+ {
+ "name": "csrf_token",
+ "type": "hidden",
+ "required": true,
+ "value": "xLg4B9WnuC0Ue+j9ay5EQvleaJpOl0H9xJJ7W3+Bwv7RNOhobPZOYFQ0KjXzWNkIzsPF/BBraWSyqa0+Pvwqtw=="
+ },
+ {
+ "name": "password",
+ "type": "password",
+ "required": true,
+ "errors": [{ "message": "password: Is required" }]
+ },
+ {
+ "name": "traits.email",
+ "type": "text",
+ "value": "",
+ "errors": [
+ { "message": "traits.email: String length must be greater than or equal to 3" },
+ { "message": "traits.email: Does not match format 'email'" }
+ ]
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/packages/dashboard/stubs/settings.json b/packages/dashboard/stubs/settings.json
new file mode 100644
index 00000000..c7502b31
--- /dev/null
+++ b/packages/dashboard/stubs/settings.json
@@ -0,0 +1,49 @@
+{
+ "id": "e01f6bf9-845c-4c4b-a3ce-60691dd7a97c",
+ "type": "browser",
+ "expires_at": "2021-02-18T13:31:43.947193Z",
+ "issued_at": "2021-02-18T12:31:43.947193Z",
+ "request_url": "http://oathkeeper:4455/self-service/settings/browser",
+ "messages": null,
+ "methods": {
+ "password": {
+ "method": "password",
+ "config": {
+ "action": "https://account.siasky.xyz/.ory/kratos/public/self-service/settings/methods/password?flow=e01f6bf9-845c-4c4b-a3ce-60691dd7a97c",
+ "method": "POST",
+ "fields": [
+ { "name": "password", "type": "password", "required": true },
+ {
+ "name": "csrf_token",
+ "type": "hidden",
+ "required": true,
+ "value": "i33iydUBN6jqwrkHlLPZ3ap7Ah4uC0UrTadn7zKT0jyouDpr+DF0/1Hbkshye9t7IKwyzOcLt7i6oR/OoEVg+g=="
+ }
+ ]
+ }
+ },
+ "profile": {
+ "method": "profile",
+ "config": {
+ "action": "https://account.siasky.xyz/.ory/kratos/public/self-service/settings/methods/profile?flow=e01f6bf9-845c-4c4b-a3ce-60691dd7a97c",
+ "method": "POST",
+ "fields": [
+ {
+ "name": "csrf_token",
+ "type": "hidden",
+ "required": true,
+ "value": "i33iydUBN6jqwrkHlLPZ3ap7Ah4uC0UrTadn7zKT0jyouDpr+DF0/1Hbkshye9t7IKwyzOcLt7i6oR/OoEVg+g=="
+ },
+ { "name": "traits.email", "type": "email", "value": "karol@nebulous.tech" }
+ ]
+ }
+ }
+ },
+ "identity": {
+ "id": "ab776d6d-f324-4fa7-a728-7587d5215481",
+ "schema_id": "default",
+ "schema_url": "",
+ "traits": { "email": "karol@nebulous.tech" }
+ },
+ "state": "show_form"
+}
diff --git a/packages/dashboard/styles/Home.module.css b/packages/dashboard/styles/Home.module.css
new file mode 100644
index 00000000..80745811
--- /dev/null
+++ b/packages/dashboard/styles/Home.module.css
@@ -0,0 +1,122 @@
+.container {
+ min-height: 100vh;
+ padding: 0 0.5rem;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+}
+
+.main {
+ padding: 5rem 0;
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+}
+
+.footer {
+ width: 100%;
+ height: 100px;
+ border-top: 1px solid #eaeaea;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.footer img {
+ margin-left: 0.5rem;
+}
+
+.footer a {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.title a {
+ color: #0070f3;
+ text-decoration: none;
+}
+
+.title a:hover,
+.title a:focus,
+.title a:active {
+ text-decoration: underline;
+}
+
+.title {
+ margin: 0;
+ line-height: 1.15;
+ font-size: 4rem;
+}
+
+.title,
+.description {
+ text-align: center;
+}
+
+.description {
+ line-height: 1.5;
+ font-size: 1.5rem;
+}
+
+.code {
+ background: #fafafa;
+ border-radius: 5px;
+ padding: 0.75rem;
+ font-size: 1.1rem;
+ font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New,
+ monospace;
+}
+
+.grid {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-wrap: wrap;
+ max-width: 800px;
+ margin-top: 3rem;
+}
+
+.card {
+ margin: 1rem;
+ flex-basis: 45%;
+ padding: 1.5rem;
+ text-align: left;
+ color: inherit;
+ text-decoration: none;
+ border: 1px solid #eaeaea;
+ border-radius: 10px;
+ transition: color 0.15s ease, border-color 0.15s ease;
+}
+
+.card:hover,
+.card:focus,
+.card:active {
+ color: #0070f3;
+ border-color: #0070f3;
+}
+
+.card h3 {
+ margin: 0 0 1rem 0;
+ font-size: 1.5rem;
+}
+
+.card p {
+ margin: 0;
+ font-size: 1.25rem;
+ line-height: 1.5;
+}
+
+.logo {
+ height: 1em;
+}
+
+@media (max-width: 600px) {
+ .grid {
+ width: 100%;
+ flex-direction: column;
+ }
+}
diff --git a/packages/dashboard/styles/globals.css b/packages/dashboard/styles/globals.css
new file mode 100644
index 00000000..e2e6d0f0
--- /dev/null
+++ b/packages/dashboard/styles/globals.css
@@ -0,0 +1,16 @@
+html,
+body {
+ padding: 0;
+ margin: 0;
+ font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans,
+ Helvetica Neue, sans-serif;
+}
+
+a {
+ color: inherit;
+ text-decoration: none;
+}
+
+* {
+ box-sizing: border-box;
+}
diff --git a/packages/dashboard/tailwind.config.js b/packages/dashboard/tailwind.config.js
new file mode 100644
index 00000000..09477280
--- /dev/null
+++ b/packages/dashboard/tailwind.config.js
@@ -0,0 +1,18 @@
+module.exports = {
+ purge: ["./src/**/*.js"],
+ darkMode: false, // or 'media' or 'class'
+ theme: {
+ extend: {
+ fontFamily: {
+ sans: ["Metropolis", "Helvetica", "Arial", "Sans-Serif"],
+ },
+ },
+ },
+ variants: {
+ extend: {
+ backgroundColor: ["disabled"],
+ textColor: ["disabled"],
+ },
+ },
+ plugins: [require("@tailwindcss/forms")],
+};
diff --git a/packages/handshake-api/Dockerfile b/packages/handshake-api/Dockerfile
index 1104cb21..4903f90f 100644
--- a/packages/handshake-api/Dockerfile
+++ b/packages/handshake-api/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:15.8.0-alpine
+FROM node:15.12.0-alpine
WORKDIR /usr/app
diff --git a/packages/health-check/Dockerfile b/packages/health-check/Dockerfile
index 9ecc2f14..d543bbff 100644
--- a/packages/health-check/Dockerfile
+++ b/packages/health-check/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:15.8.0-alpine
+FROM node:15.12.0-alpine
WORKDIR /usr/app
diff --git a/packages/webapp/Dockerfile b/packages/webapp/Dockerfile
index db09d2d7..a732c64d 100644
--- a/packages/webapp/Dockerfile
+++ b/packages/webapp/Dockerfile
@@ -1,15 +1,24 @@
-FROM node:15.8.0-alpine
+FROM node:15.12.0-alpine
-RUN apk add --no-cache autoconf automake libtool gcc make g++ zlib-dev file nasm util-linux
+RUN apk update && apk add autoconf automake libtool gcc make g++ zlib-dev file nasm util-linux
WORKDIR /usr/app
+COPY package.json .
+
+ENV CYPRESS_INSTALL_BINARY 0
+
+RUN yarn --no-lockfile
+
COPY src ./src
COPY static ./static
COPY gatsby-config.js .
-COPY package.json .
-ENV CYPRESS_INSTALL_BINARY 0
+ARG WITH_ACCOUNTS=0
+
ENV GATSBY_TELEMETRY_DISABLED 1
-RUN yarn --no-lockfile
-RUN yarn build
+ENV GATSBY_WITH_ACCOUNTS $WITH_ACCOUNTS
+
+EXPOSE 9000
+
+CMD [ "sh", "-c", "yarn build && yarn serve --host 0.0.0.0" ]
diff --git a/packages/webapp/package.json b/packages/webapp/package.json
index d90f8d64..c920b110 100644
--- a/packages/webapp/package.json
+++ b/packages/webapp/package.json
@@ -6,6 +6,7 @@
"dependencies": {
"@fontsource/metropolis": "^4.2.1",
"axios": "0.21.1",
+ "boolean": "^3.0.2",
"bytes": "3.1.0",
"classnames": "2.2.6",
"gatsby": "^3.0.4",
@@ -17,6 +18,7 @@
"gatsby-plugin-sass": "^4.0.2",
"gatsby-source-filesystem": "^3.0.0",
"http-status-codes": "2.1.4",
+ "js-cookie": "^2.2.1",
"jsonp": "0.2.1",
"node-sass": "5.0.0",
"path-browserify": "1.0.1",
diff --git a/packages/webapp/src/components/HomeTop/HomeTop.js b/packages/webapp/src/components/HomeTop/HomeTop.js
index 42e53788..4d1590a3 100644
--- a/packages/webapp/src/components/HomeTop/HomeTop.js
+++ b/packages/webapp/src/components/HomeTop/HomeTop.js
@@ -1,4 +1,5 @@
import React from "react";
+import { boolean } from "boolean";
import logo from "../../images/logo.svg";
import "./HomeTop.scss";
import { Skynet, Deco1, Deco2 } from "../../svg";
@@ -15,6 +16,18 @@ export default function HomeTop() {
The decentralized CDN and file sharing platform for devs. Skynet is the storage foundation for a Free Internet!
+ {boolean(process.env.GATSBY_WITH_ACCOUNTS) && (
+
+
+ Sign up now!
+ {" "}
+ Already have an account? Go to your{" "}
+
+ dashboard
+
+
+ )}
+
diff --git a/packages/webapp/src/components/HomeTop/HomeTop.scss b/packages/webapp/src/components/HomeTop/HomeTop.scss
index 572292c3..046c636d 100644
--- a/packages/webapp/src/components/HomeTop/HomeTop.scss
+++ b/packages/webapp/src/components/HomeTop/HomeTop.scss
@@ -36,10 +36,22 @@
max-width: 560px;
margin: 0 auto;
+ &.auth-links {
+ font-size: 18px;
+
+ .link {
+ font-weight: bold;
+ }
+ }
+
@media (min-width: $largebp) {
font-size: 24px;
max-width: 670px;
}
+
+ & + p {
+ margin-top: 24px;
+ }
}
}
diff --git a/scripts/crdb_backup.sh b/scripts/crdb_backup.sh
new file mode 100644
index 00000000..a216d9db
--- /dev/null
+++ b/scripts/crdb_backup.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+# Get current working directory (pwd doesn't cut it)
+cwd=$(cd -P -- "$(dirname -- "$0")" && pwd -P)
+# Set the environment:
+set -o allexport
+source $cwd/../.env
+set +o allexport
+# Check for AWS credentials:
+if [[ $AWS_ACCESS_KEY_ID == "" || $AWS_SECRET_ACCESS_KEY == "" ]]; then
+ echo "Missing AWS credentials!"
+ exit 1
+fi
+# Take the current datetime:
+DT=`date +%Y-%m-%d`
+# Create the backup:
+docker exec cockroach \
+ cockroach sql \
+ --host cockroach:26257 \
+ --certs-dir=/certs \
+ --execute="BACKUP TO 's3://skynet-crdb-backups/backups/cockroach/$DT?AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID&AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY';"
diff --git a/scripts/crdb_restore.sh b/scripts/crdb_restore.sh
new file mode 100644
index 00000000..a316984f
--- /dev/null
+++ b/scripts/crdb_restore.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+BACKUP=$1
+if [[ $BACKUP == "" ]]; then
+ echo "No backup name given. It should look like '2020-01-29'."
+ exit 1
+fi
+
+# Get current working directory (pwd doesn't cut it)
+cwd=$(cd -P -- "$(dirname -- "$0")" && pwd -P)
+# Set the environment:
+set -o allexport
+source $cwd/../.env
+set +o allexport
+# Check for AWS credentials:
+if [[ $AWS_ACCESS_KEY_ID == "" || $AWS_SECRET_ACCESS_KEY == "" ]]; then
+ echo "Missing AWS credentials!"
+ exit 1
+fi
+# Restore the backup:
+docker exec cockroach \
+ cockroach sql \
+ --host cockroach:26257 \
+ --certs-dir=/certs \
+ --execute="RESTORE DATABASE defaultdb FROM 's3://skynet-crdb-backups/backups/cockroach/$DT?AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID&AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY';"
diff --git a/scripts/mongo_backup.sh b/scripts/mongo_backup.sh
new file mode 100644
index 00000000..9867bbc3
--- /dev/null
+++ b/scripts/mongo_backup.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+# Get current working directory (pwd doesn't cut it)
+cwd=$(cd -P -- "$(dirname -- "$0")" && pwd -P)
+# Set the environment:
+set -o allexport
+source $cwd/../.env
+set +o allexport
+# Check for AWS credentials:
+if [[ $AWS_ACCESS_KEY_ID == "" || $AWS_SECRET_ACCESS_KEY == "" ]]; then
+ echo "Missing AWS credentials!"
+ exit 1
+fi
+# Take the current datetime:
+DT=`date +%Y-%m-%d`
+# Check if a backup already exists:
+totalFoundObjects=$(aws s3 ls s3://skynet-crdb-backups/backups/mongo/ --recursive --summarize | grep "$DT.tgz" | wc -l)
+if [ "$totalFoundObjects" -eq "1" ]; then
+ echo "Backup already exists for today. Exiting."
+ exit 0
+fi
+# Create the backup:
+docker exec mongo \
+ mongodump \
+ -o /data/db/backups/$DT \
+ mongodb://$SKYNET_DB_USER:$SKYNET_DB_PASS@$SKYNET_DB_HOST:$SKYNET_DB_PORT
+# Compress the backup:
+cd $cwd/../docker/data/mongo/db/backups/ && tar -czf $DT.tgz $DT && cd -
+# Upload the backup to S3:
+aws s3 cp $DT.tgz s3://skynet-crdb-backups/backups/mongo/
+# Clean up
+rm -rf $DT.tgz $cwd/../docker/data/mongo/db/backups/$DT
diff --git a/scripts/mongo_restore.sh b/scripts/mongo_restore.sh
new file mode 100644
index 00000000..f9f4396c
--- /dev/null
+++ b/scripts/mongo_restore.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+BACKUP=$1
+if [[ $BACKUP == "" ]]; then
+ echo "No backup name given. It should look like '2020-01-29'."
+ exit 1
+fi
+
+# Get current working directory (pwd doesn't cut it)
+cwd=$(cd -P -- "$(dirname -- "$0")" && pwd -P)
+# Set the environment:
+set -o allexport
+source $cwd/../.env
+set +o allexport
+# Check for AWS credentials:
+if [[ $AWS_ACCESS_KEY_ID == "" || $AWS_SECRET_ACCESS_KEY == "" ]]; then
+ echo "Missing AWS credentials!"
+ exit 1
+fi
+# Check if the backup exists:
+totalFoundObjects=$(aws s3 ls s3://skynet-crdb-backups/backups/mongo/ --recursive --summarize | grep "$DT.tgz" | wc -l)
+if [ "$totalFoundObjects" -eq "0" ]; then
+ echo "This backup doesn't exist!"
+ exit 1
+fi
+# Get the backup from S3:
+aws s3 cp s3://skynet-crdb-backups/backups/mongo/$BACKUP.tgz $BACKUP.tgz
+# Prepare a clean `to_restore` dir:
+rm -rf $cwd/../docker/data/mongo/db/backups/to_restore
+mkdir -p $cwd/../docker/data/mongo/db/backups/to_restore
+# Decompress the backup:
+tar -xzf $BACKUP.tgz -C $cwd/../docker/data/mongo/db/backups/to_restore
+rm $BACKUP.tgz
+# Restore the backup:
+docker exec mongo \
+ mongorestore \
+ mongodb://$SKYNET_DB_USER:$SKYNET_DB_PASS@$SKYNET_DB_HOST:$SKYNET_DB_PORT \
+ /data/db/backups/to_restore/$BACKUP
+# Clean up:
+rm -rf $cwd/../docker/data/mongo/db/backups/to_restore
diff --git a/setup-scripts/README.md b/setup-scripts/README.md
index 7d047421..c6407c61 100644
--- a/setup-scripts/README.md
+++ b/setup-scripts/README.md
@@ -19,6 +19,8 @@ You may want to fork this repository and replace ssh keys in
- [handshake](https://handshake.org) ([github](https://github.com/handshake-org/hsd)): full handshake node
- [handshake-api](https://github.com/NebulousLabs/skynet-webportal/tree/master/packages/handshake-api): simple API talking to the handshake node - [read more](https://github.com/NebulousLabs/skynet-webportal/blob/master/packages/handshake-api/README.md)
- [webapp](https://github.com/NebulousLabs/skynet-webportal/tree/master/packages/webapp): portal frontend application - [read more](https://github.com/NebulousLabs/skynet-webportal/blob/master/packages/webapp/README.md)
+ - [kratos](https://www.ory.sh/kratos/): user account management system
+ - [oathkeeper](https://www.ory.sh/oathkeeper/): identity and access proxy
- discord integration
- [funds-checker](funds-checker.py): script that checks wallet balance and sends status messages to discord periodically
- [health-checker](health-checker.py): script that monitors health-check service for server health issues and reports them to discord periodically
@@ -83,10 +85,21 @@ At this point we have almost everything running, we just need to set up your wal
- `CLOUDFLARE_AUTH_TOKEN` (optional) if using cloudflare as dns loadbalancer (need to change it in Caddyfile too)
- `AWS_ACCESS_KEY_ID` (optional) if using route53 as a dns loadbalancer
- `AWS_SECRET_ACCESS_KEY` (optional) if using route53 as a dns loadbalancer
+ - `PORTAL_NAME` (optional) e.g. `siasky.xyz`
+ - `DISCORD_BOT_TOKEN` (optional) if you're using Discord notifications for health checks and such
+ - `SKYNET_DB_USER` (optional) if using `accounts` this is the MongoDB username
+ - `SKYNET_DB_PASS` (optional) if using `accounts` this is the MongoDB password
+ - `SKYNET_DB_HOST` (optional) if using `accounts` this is the MongoDB address or container name
+ - `SKYNET_DB_PORT` (optional) if using `accounts` this is the MongoDB port
+ - `COOKIE_DOMAIN` (optional) if using `accounts` this is the domain to which your cookies will be issued
+ - `COOKIE_HASH_KEY` (optional) if using `accounts` hashing secret, at least 32 bytes
+ - `COOKIE_ENC_KEY` (optional) if using `accounts` encryption key, at least 32 bytes
+
1. if you have a custom domain and you configured it in `DOMAIN_NAME`, edit `/home/user/skynet-webportal/docker/caddy/Caddyfile` and uncomment `import custom.domain`
1. only for siasky.net domain instances: edit `/home/user/skynet-webportal/docker/caddy/Caddyfile`, uncomment `import siasky.net`
1. `docker-compose up -d` to restart the services so they pick up new env variables
1. `docker exec caddy caddy reload --config /etc/caddy/Caddyfile` to reload Caddyfile configuration
+1. add your custom Kratos configuration to `/home/user/skynet-webportal/docker/kratos/config/kratos.yml` (in particular, the credentials for your mail server should be here, rather than in your source control). For a starting point you can take `docker/kratos/config/kratos.yml.sample`.
## Subdomains
diff --git a/setup-scripts/setup-docker-services.sh b/setup-scripts/setup-docker-services.sh
index c9aecebd..44728e02 100755
--- a/setup-scripts/setup-docker-services.sh
+++ b/setup-scripts/setup-docker-services.sh
@@ -23,17 +23,27 @@ docker-compose --version # sanity check
# Create dummy .env file for docker-compose usage with variables
# * DOMAIN_NAME - the domain name your server is using ie. example.com
# * SKYNET_PORTAL_API - absolute url to the portal api ie. https://example.com
+# * SKYNET_DASHBOARD_URL - (optional) absolute url to the portal dashboard ie. https://account.example.com
# * EMAIL_ADDRESS - this is the administrator contact email you need to supply for communication regarding SSL certification
# * HSD_API_KEY - this is auto generated secure key for your handshake service integration
-# * CLOUDFLARE_AUTH_TOKEN` - (optional) if using cloudflare as dns loadbalancer (need to change it in Caddyfile too)
+# * CLOUDFLARE_AUTH_TOKEN - (optional) if using cloudflare as dns loadbalancer (need to change it in Caddyfile too)
# * AWS_ACCESS_KEY_ID - (optional) if using route53 as a dns loadbalancer
# * AWS_SECRET_ACCESS_KEY - (optional) if using route53 as a dns loadbalancer
# * API_PORT - (optional) the port on which siad is listening, defaults to 9980
# * PORTAL_NAME - the name of the portal, required by the discord bot
-# * DISCORD_BOT_TOKEN - required by the discord bot
+# * DISCORD_BOT_TOKEN - (optional) only required if you're using the discord notifications integration
+# * SKYNET_DB_USER - (optional) if using `accounts` this is the MongoDB username
+# * SKYNET_DB_PASS - (optional) if using `accounts` this is the MongoDB password
+# * SKYNET_DB_HOST - (optional) if using `accounts` this is the MongoDB address or container name
+# * SKYNET_DB_PORT - (optional) if using `accounts` this is the MongoDB port
+# * COOKIE_DOMAIN - (optional) if using `accounts` this is the domain to which your cookies will be issued
+# * COOKIE_HASH_KEY - (optional) if using `accounts` hashing secret, at least 32 bytes
+# * COOKIE_ENC_KEY - (optional) if using `accounts` encryption key, at least 32 bytes
+# * CR_IP - (optional) if using `accounts` the public IP/domain of your server, e.g. `helsinki.siasky.net`
+# * CR_CLUSTER_NODES - (optional) if using `accounts` the list of servers (with ports) which make up your CockroachDB cluster, e.g. `helsinki.siasky.net:26257,germany.siasky.net:26257,us-east.siasky.net:26257`
if ! [ -f /home/user/skynet-webportal/.env ]; then
HSD_API_KEY=$(openssl rand -base64 32) # generate safe random key for handshake
- printf "DOMAIN_NAME=example.com\nSKYNET_PORTAL_API=https://example.com\nEMAIL_ADDRESS=email@example.com\nSIA_WALLET_PASSWORD=\nHSD_API_KEY=${HSD_API_KEY}\nCLOUDFLARE_AUTH_TOKEN=\nAWS_ACCESS_KEY_ID=\nAWS_SECRET_ACCESS_KEY=\nPORTAL_NAME=\nDISCORD_BOT_TOKEN=\n" > /home/user/skynet-webportal/.env
+ printf "DOMAIN_NAME=example.com\nSKYNET_PORTAL_API=https://example.com\nSKYNET_DASHBOARD_URL=https://account.example.com\nEMAIL_ADDRESS=email@example.com\nSIA_WALLET_PASSWORD=\nHSD_API_KEY=${HSD_API_KEY}\nCLOUDFLARE_AUTH_TOKEN=\nAWS_ACCESS_KEY_ID=\nAWS_SECRET_ACCESS_KEY=\nPORTAL_NAME=\nDISCORD_BOT_TOKEN=\n" > /home/user/skynet-webportal/.env
fi
# Start docker container with nginx and client
diff --git a/setup-scripts/setup-server.sh b/setup-scripts/setup-server.sh
index aaaa97f3..e9e865fe 100755
--- a/setup-scripts/setup-server.sh
+++ b/setup-scripts/setup-server.sh
@@ -14,7 +14,7 @@ mkdir -p /home/user/.ssh
# Install apt packages
sudo apt-get update
-sudo apt-get -y install ufw tmux ranger htop nload gcc g++ make git vim unzip curl
+sudo apt-get -y install ufw tmux ranger htop nload gcc g++ make git vim unzip curl awscli
# Setup GIT credentials (so commands like git stash would work)
git config --global user.email "devs@nebulous.tech"
diff --git a/yarn.lock b/yarn.lock
index d81afcb2..3b09c020 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,6 +2,13 @@
# yarn lockfile v1
+"@apimatic/schema@^0.5.1":
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/@apimatic/schema/-/schema-0.5.1.tgz#673aa4ddcf31311ba9dfbf0e514cb35ab3b3b9f9"
+ integrity sha512-ZtAtLOjDEqxot017qRGK+gvNbZv5tNNDmYiYOpBhFiZwulTZUHT9NwJG+V5nIhdEqIpy5E8ty1C4tTzangfNoQ==
+ dependencies:
+ lodash.flatten "^4.4.0"
+
"@ardatan/aggregate-error@0.0.6":
version "0.0.6"
resolved "https://registry.yarnpkg.com/@ardatan/aggregate-error/-/aggregate-error-0.0.6.tgz#fe6924771ea40fc98dc7a7045c2e872dc8527609"
@@ -953,7 +960,14 @@
core-js-pure "^3.0.0"
regenerator-runtime "^0.13.4"
-"@babel/runtime@^7.10.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4":
+"@babel/runtime@7.12.5":
+ version "7.12.5"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e"
+ integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==
+ dependencies:
+ regenerator-runtime "^0.13.4"
+
+"@babel/runtime@^7.10.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4":
version "7.13.10"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d"
integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==
@@ -989,6 +1003,15 @@
globals "^11.1.0"
lodash "^4.17.19"
+"@babel/types@7.8.3":
+ version "7.8.3"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c"
+ integrity sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==
+ dependencies:
+ esutils "^2.0.2"
+ lodash "^4.17.13"
+ to-fast-properties "^2.0.0"
+
"@babel/types@^7.0.0-beta.49", "@babel/types@^7.10.5", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.12.17", "@babel/types@^7.12.6", "@babel/types@^7.13.0", "@babel/types@^7.4.4":
version "7.13.0"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.0.tgz#74424d2816f0171b4100f0ab34e9a374efdf7f80"
@@ -1067,11 +1090,18 @@
minimatch "^3.0.4"
strip-json-comments "^3.1.1"
-"@fontsource/metropolis@^4.2.1":
+"@fontsource/metropolis@^4.1.0", "@fontsource/metropolis@^4.2.1":
version "4.2.1"
resolved "https://registry.yarnpkg.com/@fontsource/metropolis/-/metropolis-4.2.1.tgz#49b69c0e3ff940bf2d94ee45627fa1fe3528f59f"
integrity sha512-PhXqIWHqD+HyTkZr1XT7irKhaObRmHLz+d0js/NuoI30md0X4LXMxkolCL5EbmSDXNXW36nT+A1HCKW71oyd6w==
+"@fullhuman/postcss-purgecss@^3.1.3":
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/@fullhuman/postcss-purgecss/-/postcss-purgecss-3.1.3.tgz#47af7b87c9bfb3de4bc94a38f875b928fffdf339"
+ integrity sha512-kwOXw8fZ0Lt1QmeOOrd+o4Ibvp4UTEBFQbzvWldjlKv5n+G9sXfIPn1hh63IQIL8K8vbvv1oYMJiIUbuy9bGaA==
+ dependencies:
+ purgecss "^3.1.3"
+
"@gatsbyjs/reach-router@^1.3.6":
version "1.3.6"
resolved "https://registry.yarnpkg.com/@gatsbyjs/reach-router/-/reach-router-1.3.6.tgz#4e8225836959be247890b66f21a3198a0589e34d"
@@ -1223,11 +1253,26 @@
is-promise "4.0.0"
tslib "~2.0.1"
+"@hapi/accept@5.0.1":
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/@hapi/accept/-/accept-5.0.1.tgz#068553e867f0f63225a506ed74e899441af53e10"
+ integrity sha512-fMr4d7zLzsAXo28PRRQPXR1o2Wmu+6z+VY1UzDp0iFo13Twj8WePakwXBiqn3E1aAlTpSNzCXdnnQXFhst8h8Q==
+ dependencies:
+ "@hapi/boom" "9.x.x"
+ "@hapi/hoek" "9.x.x"
+
"@hapi/address@2.x.x":
version "2.1.4"
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
integrity sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==
+"@hapi/boom@9.x.x":
+ version "9.1.1"
+ resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-9.1.1.tgz#89e6f0e01637c2a4228da0d113e8157c93677b04"
+ integrity sha512-VNR8eDbBrOxBgbkddRYIe7+8DZ+vSbV6qlmaN2x7eWjsUjy2VmQgChkOKcVZIeupEZYj+I0dqNg430OhwzagjA==
+ dependencies:
+ "@hapi/hoek" "9.x.x"
+
"@hapi/bourne@1.x.x":
version "1.3.2"
resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-1.3.2.tgz#0a7095adea067243ce3283e1b56b8a8f453b242a"
@@ -1238,7 +1283,7 @@
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.5.1.tgz#fde96064ca446dec8c55a8c2f130957b070c6e06"
integrity sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==
-"@hapi/hoek@^9.0.0":
+"@hapi/hoek@9.x.x", "@hapi/hoek@^9.0.0":
version "9.1.1"
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.1.1.tgz#9daf5745156fd84b8e9889a2dc721f0c58e894aa"
integrity sha512-CAEbWH7OIur6jEOzaai83jq3FmKmv4PmX1JYfs9IrYcGEVI/lyL1EXJGCj7eFVJ0bg5QR8LMxBlEtA+xKiLpFw==
@@ -1292,6 +1337,38 @@
resolved "https://registry.yarnpkg.com/@mikaelkristiansson/domready/-/domready-1.0.11.tgz#6a4b5891dccb6402ff4e944de843036ee1ffd4f5"
integrity sha512-nEBLOa0JgtqahmPrnJZ18epLiFBzxhdKgo4uhN3TaBFRmM30pEVrS9FAEV4tg92d8PTdU+dYQx2lnpPyFMgMcg==
+"@next/env@10.0.8":
+ version "10.0.8"
+ resolved "https://registry.yarnpkg.com/@next/env/-/env-10.0.8.tgz#3306c9de20ef187438affbafce0ef966c9e43c3b"
+ integrity sha512-vWdxAHD6gJn52tN5bxj1VoRgu5lNtRPc/HyYf7V014k2GZ9eKhqoFQGSSMNGHB7WgdUxLVw75+o9Ek9ClOOAjw==
+
+"@next/polyfill-module@10.0.8":
+ version "10.0.8"
+ resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-10.0.8.tgz#1d033f390389591f227499e286911e3db14c484b"
+ integrity sha512-JCUGB4/SKQ4LXniv7LKGrpW+W2DGH/CLkrgXgSo/Ze+EJdMDLxC/VFhiuW+TgAaAWLE4gryoswlZBNyHtkPGQA==
+
+"@next/react-dev-overlay@10.0.8":
+ version "10.0.8"
+ resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-10.0.8.tgz#a8e841647b74f9720cc60d3e3bd3da225ad12533"
+ integrity sha512-ygVsvkzYTYIuME+dUUSjCxbNjrJ+Up9Y+CrWEmSSk6HuxajUvrB9vN6RT+PeAzEOQ5er1sWxmVHVdPknQPVWyQ==
+ dependencies:
+ "@babel/code-frame" "7.12.11"
+ anser "1.4.9"
+ chalk "4.0.0"
+ classnames "2.2.6"
+ css.escape "1.5.1"
+ data-uri-to-buffer "3.0.1"
+ platform "1.3.6"
+ shell-quote "1.7.2"
+ source-map "0.8.0-beta.0"
+ stacktrace-parser "0.1.10"
+ strip-ansi "6.0.0"
+
+"@next/react-refresh-utils@10.0.8":
+ version "10.0.8"
+ resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-10.0.8.tgz#6129d633e2c0a9b5760de002e998932f08c8baae"
+ integrity sha512-ZMO77Xs2ioGV/nZB4GRDHgsNT2jhOp+cZIh6c7wf0xw9o/1KoTWN8nxWzwU/laAtkoSS+E6YdhuR4Mw3Ar3CSg==
+
"@nodelib/fs.scandir@2.1.4":
version "2.1.4"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69"
@@ -1321,6 +1398,25 @@
mkdirp "^1.0.4"
rimraf "^3.0.2"
+"@opentelemetry/api@0.14.0":
+ version "0.14.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-0.14.0.tgz#4e17d8d2f1da72b19374efa7b6526aa001267cae"
+ integrity sha512-L7RMuZr5LzMmZiQSQDy9O1jo0q+DaLy6XpYJfIGfYSfoJA5qzYwUP3sP1uMIQ549DvxAgM3ng85EaPTM/hUHwQ==
+ dependencies:
+ "@opentelemetry/context-base" "^0.14.0"
+
+"@opentelemetry/context-base@^0.14.0":
+ version "0.14.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/context-base/-/context-base-0.14.0.tgz#c67fc20a4d891447ca1a855d7d70fa79a3533001"
+ integrity sha512-sDOAZcYwynHFTbLo6n8kIbLiVF3a3BLkrmehJUyEbT9F+Smbi47kLGS2gG2g0fjBLR/Lr1InPD7kXL7FaTqEkw==
+
+"@ory/kratos-client@^0.5.4-alpha.1":
+ version "0.5.4-alpha.1"
+ resolved "https://registry.yarnpkg.com/@ory/kratos-client/-/kratos-client-0.5.4-alpha.1.tgz#6a87a90fd858fc4cb792253b109ea53884098107"
+ integrity sha512-koqwcEtEtGoHdX/WU3O4u6UmbMzbmbA06t5qIZv9S4YauxHZIVZM3VMws1ZK5ObgAMI6O5dCs4WYJrJq+QN48g==
+ dependencies:
+ axios "^0.19.2"
+
"@pmmmwh/react-refresh-webpack-plugin@^0.4.3":
version "0.4.3"
resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.4.3.tgz#1eec460596d200c0236bf195b078a5d1df89b766"
@@ -1383,6 +1479,18 @@
escape-string-regexp "^2.0.0"
lodash.deburr "^4.1.0"
+"@stripe/react-stripe-js@^1.4.0":
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/@stripe/react-stripe-js/-/react-stripe-js-1.4.0.tgz#a67e72202297fc409dc2c8c4f3fb98e0b61fa06d"
+ integrity sha512-Pz5QmG8PgJ3pi8gOWxlngk+ns63p2L1Ds192fn55ykZNRKfGz3G6sfssUVThHn/NAt2Hp1eCEsy/hvlKnXJI6g==
+ dependencies:
+ prop-types "^15.7.2"
+
+"@stripe/stripe-js@^1.13.0":
+ version "1.13.1"
+ resolved "https://registry.yarnpkg.com/@stripe/stripe-js/-/stripe-js-1.13.1.tgz#71384666dbd575f154bcdf923f5aa0f7be22d31c"
+ integrity sha512-mmW+38/RJiWP0B7jmekL+MTDpkDMi34ygZ3j0NIoGa/h6eAXlGDA4lOqqg6aMH9Jd2RzDUndKxvSPPQnFnpdqw==
+
"@szmarczak/http-timer@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
@@ -1390,11 +1498,23 @@
dependencies:
defer-to-connect "^1.0.1"
+"@tailwindcss/forms@^0.2.1":
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/forms/-/forms-0.2.1.tgz#3244b185854fae1a7cbe8d2456314d8b2d98cf43"
+ integrity sha512-czfvEdY+J2Ogfd6RUSr/ZSUmDxTujr34M++YLnp2cCPC3oJ4kFvFMaRXA6cEXKw7F1hJuapdjXRjsXIEXGgORg==
+ dependencies:
+ mini-svg-data-uri "^1.2.3"
+
"@tokenizer/token@^0.1.1":
version "0.1.1"
resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.1.1.tgz#f0d92c12f87079ddfd1b29f614758b9696bc29e3"
integrity sha512-XO6INPbZCxdprl+9qa/AAbFFOMzzwqYxpjPgLICrMD6C2FCw6qfJOPcBk6JqqPLSaZ/Qx87qn4rpPmPMwaAK6w==
+"@tootallnate/once@1":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
+ integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==
+
"@turist/fetch@^7.1.7":
version "7.1.7"
resolved "https://registry.yarnpkg.com/@turist/fetch/-/fetch-7.1.7.tgz#a2b1f7ec0265e6fe0946c51eef34bad9b9efc865"
@@ -1407,6 +1527,14 @@
resolved "https://registry.yarnpkg.com/@turist/time/-/time-0.0.1.tgz#57637d2a7d1860adb9f9cecbdcc966ce4f551d63"
integrity sha512-M2BiThcbxMxSKX8W4z5u9jKZn6datnM3+FpEU+eYw0//l31E2xhqi7vTAuJ/Sf0P3yhp66SDJgPu3bRRpvrdQQ==
+"@types/body-parser@*":
+ version "1.19.0"
+ resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f"
+ integrity sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==
+ dependencies:
+ "@types/connect" "*"
+ "@types/node" "*"
+
"@types/common-tags@^1.8.0":
version "1.8.0"
resolved "https://registry.yarnpkg.com/@types/common-tags/-/common-tags-1.8.0.tgz#79d55e748d730b997be5b7fce4b74488d8b26a6b"
@@ -1422,6 +1550,13 @@
resolved "https://registry.yarnpkg.com/@types/configstore/-/configstore-2.1.1.tgz#cd1e8553633ad3185c3f2f239ecff5d2643e92b6"
integrity sha1-zR6FU2M60xhcPy8jns/10mQ+krY=
+"@types/connect@*":
+ version "3.4.34"
+ resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.34.tgz#170a40223a6d666006d93ca128af2beb1d9b1901"
+ integrity sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==
+ dependencies:
+ "@types/node" "*"
+
"@types/cookie@^0.4.0":
version "0.4.0"
resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.0.tgz#14f854c0f93d326e39da6e3b6f34f7d37513d108"
@@ -1468,6 +1603,40 @@
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==
+"@types/express-jwt@0.0.42":
+ version "0.0.42"
+ resolved "https://registry.yarnpkg.com/@types/express-jwt/-/express-jwt-0.0.42.tgz#4f04e1fadf9d18725950dc041808a4a4adf7f5ae"
+ integrity sha512-WszgUddvM1t5dPpJ3LhWNH8kfNN8GPIBrAGxgIYXVCEGx6Bx4A036aAuf/r5WH9DIEdlmp7gHOYvSM6U87B0ag==
+ dependencies:
+ "@types/express" "*"
+ "@types/express-unless" "*"
+
+"@types/express-serve-static-core@^4.17.18":
+ version "4.17.18"
+ resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.18.tgz#8371e260f40e0e1ca0c116a9afcd9426fa094c40"
+ integrity sha512-m4JTwx5RUBNZvky/JJ8swEJPKFd8si08pPF2PfizYjGZOKr/svUWPcoUmLow6MmPzhasphB7gSTINY67xn3JNA==
+ dependencies:
+ "@types/node" "*"
+ "@types/qs" "*"
+ "@types/range-parser" "*"
+
+"@types/express-unless@*":
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/@types/express-unless/-/express-unless-0.5.1.tgz#4f440b905e42bbf53382b8207bc337dc5ff9fd1f"
+ integrity sha512-5fuvg7C69lemNgl0+v+CUxDYWVPSfXHhJPst4yTLcqi4zKJpORCxnDrnnilk3k0DTq/WrAUdvXFs01+vUqUZHw==
+ dependencies:
+ "@types/express" "*"
+
+"@types/express@*":
+ version "4.17.11"
+ resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.11.tgz#debe3caa6f8e5fcda96b47bd54e2f40c4ee59545"
+ integrity sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg==
+ dependencies:
+ "@types/body-parser" "*"
+ "@types/express-serve-static-core" "^4.17.18"
+ "@types/qs" "*"
+ "@types/serve-static" "*"
+
"@types/get-port@^3.2.0":
version "3.2.0"
resolved "https://registry.yarnpkg.com/@types/get-port/-/get-port-3.2.0.tgz#f9e0a11443cc21336470185eae3dfba4495d29bc"
@@ -1534,11 +1703,16 @@
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
-"@types/lodash@^4.14.92":
+"@types/lodash@^4.14.165", "@types/lodash@^4.14.92":
version "4.14.168"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.168.tgz#fe24632e79b7ade3f132891afff86caa5e5ce008"
integrity sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==
+"@types/mime@^1":
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a"
+ integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==
+
"@types/minimatch@*":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
@@ -1564,7 +1738,7 @@
"@types/node" "*"
form-data "^3.0.0"
-"@types/node@*", "@types/node@^14.14.10":
+"@types/node@*", "@types/node@>=8.1.0", "@types/node@^14.14.10", "@types/node@^14.14.30":
version "14.14.33"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.33.tgz#9e4f8c64345522e4e8ce77b334a8aaa64e2b6c78"
integrity sha512-oJqcTrgPUF29oUP8AsUqbXGJNuPutsetaa9kTQAQce5Lx5dTYWV02ScBiT/k1BX/Z7pKeqedmvp39Wu4zR7N7g==
@@ -1599,6 +1773,16 @@
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24"
integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==
+"@types/qs@*":
+ version "6.9.6"
+ resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.6.tgz#df9c3c8b31a247ec315e6996566be3171df4b3b1"
+ integrity sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==
+
+"@types/range-parser@*":
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c"
+ integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==
+
"@types/reach__router@^1.3.7":
version "1.3.7"
resolved "https://registry.yarnpkg.com/@types/reach__router/-/reach__router-1.3.7.tgz#de8ab374259ae7f7499fc1373b9697a5f3cd6428"
@@ -1636,6 +1820,14 @@
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275"
integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==
+"@types/serve-static@*":
+ version "1.13.9"
+ resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.9.tgz#aacf28a85a05ee29a11fb7c3ead935ac56f33e4e"
+ integrity sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==
+ dependencies:
+ "@types/mime" "^1"
+ "@types/node" "*"
+
"@types/sinonjs__fake-timers@^6.0.1":
version "6.0.2"
resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.2.tgz#3a84cf5ec3249439015e14049bd3161419bf9eae"
@@ -1899,7 +2091,21 @@ acorn-jsx@^5.3.1:
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b"
integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==
-acorn@^7.4.0:
+acorn-node@^1.6.1:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.8.2.tgz#114c95d64539e53dede23de8b9d96df7c7ae2af8"
+ integrity sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==
+ dependencies:
+ acorn "^7.0.0"
+ acorn-walk "^7.0.0"
+ xtend "^4.0.2"
+
+acorn-walk@^7.0.0:
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc"
+ integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==
+
+acorn@^7.0.0, acorn@^7.4.0:
version "7.4.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
@@ -1922,6 +2128,13 @@ adjust-sourcemap-loader@3.0.0:
loader-utils "^2.0.0"
regex-parser "^2.2.11"
+agent-base@6:
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
+ integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==
+ dependencies:
+ debug "4"
+
aggregate-error@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a"
@@ -1970,6 +2183,11 @@ amdefine@>=0.0.4:
resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=
+anser@1.4.9:
+ version "1.4.9"
+ resolved "https://registry.yarnpkg.com/anser/-/anser-1.4.9.tgz#1f85423a5dcf8da4631a341665ff675b96845760"
+ integrity sha512-AI+BjTeGt2+WFk4eWcqbQ7snZpDBt8SaLlj0RT2h5xfdWaiy51OjYvqwMrNzJLGy8iOAL6nKDITWO+rd4MkYEA==
+
anser@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/anser/-/anser-2.0.1.tgz#8d9069291fee18306ffaf2e364a690dcc8ed78ad"
@@ -2214,6 +2432,16 @@ arrify@^2.0.1:
resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa"
integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==
+asn1.js@^5.2.0:
+ version "5.4.1"
+ resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07"
+ integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==
+ dependencies:
+ bn.js "^4.0.0"
+ inherits "^2.0.1"
+ minimalistic-assert "^1.0.0"
+ safer-buffer "^2.1.0"
+
asn1@~0.2.3:
version "0.2.4"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
@@ -2226,6 +2454,14 @@ assert-plus@1.0.0, assert-plus@^1.0.0:
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
+assert@^1.1.1:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb"
+ integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==
+ dependencies:
+ object-assign "^4.1.1"
+ util "0.10.3"
+
assign-symbols@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
@@ -2236,6 +2472,11 @@ ast-types-flow@^0.0.7:
resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0=
+ast-types@0.13.2:
+ version "0.13.2"
+ resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.2.tgz#df39b677a911a83f3a049644fb74fdded23cea48"
+ integrity sha512-uWMHxJxtfj/1oZClOxDEV1sQ1HCDkA4MG8Gr69KKeBjEVH0R84WlejZ0y2DcwyBlpAEMltmVYkVgqfLFb2oyiA==
+
astral-regex@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"
@@ -2268,7 +2509,7 @@ async-retry-ng@^2.0.1:
resolved "https://registry.yarnpkg.com/async-retry-ng/-/async-retry-ng-2.0.1.tgz#f5285ec1c52654a2ba6a505d0c18b1eadfaebd41"
integrity sha512-iitlc2murdQ3/A5Re3CcplQBEf7vOmFrFQ6RFn3+/+zZUyIHYkZnnEziMSa6YIb2Bs2EJEPZWReTxjHqvQbDbw==
-async@1.5.2:
+async@1.5.2, async@^1.5.0:
version "1.5.2"
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=
@@ -2305,7 +2546,7 @@ attr-accept@^2.2.1:
resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.2.2.tgz#646613809660110749e92f2c10833b70968d929b"
integrity sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==
-autoprefixer@^10.2.4:
+autoprefixer@^10.2.4, autoprefixer@^10.2.5:
version "10.2.5"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.2.5.tgz#096a0337dbc96c0873526d7fef5de4428d05382d"
integrity sha512-7H4AJZXvSsn62SqZyJCP+1AWwOuoYpUfK6ot9vm0e87XD6mT8lDywc9D9OTJPMULyGcvmIxzTAMeG2Cc+YX+fA==
@@ -2339,6 +2580,13 @@ axios@0.21.1, axios@^0.21.0, axios@^0.21.1:
dependencies:
follow-redirects "^1.10.0"
+axios@^0.19.2:
+ version "0.19.2"
+ resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
+ integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==
+ dependencies:
+ follow-redirects "1.5.10"
+
axobject-query@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be"
@@ -2415,6 +2663,11 @@ babel-plugin-remove-graphql-queries@^3.0.0:
resolved "https://registry.yarnpkg.com/babel-plugin-remove-graphql-queries/-/babel-plugin-remove-graphql-queries-3.0.0.tgz#b5c4e5e29b3bd2110b55a36d5b9076da15b5805e"
integrity sha512-eKyztf9FDm4U+aEojPXKlYbE0VM4L2fxU+xHAn21lx13ZR7jT+N5qQNeZk+wR7I/NzwFBy1nuHFui4oXa/Kr0A==
+babel-plugin-syntax-jsx@6.18.0:
+ version "6.18.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
+ integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=
+
babel-plugin-transform-react-remove-prop-types@^0.4.24:
version "0.4.24"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz#f2edaf9b4c6a5fbe5c1d678bfb531078c1555f3a"
@@ -2466,7 +2719,7 @@ base64-arraybuffer@0.1.4:
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz#9818c79e059b1355f97e0428a017c838e90ba812"
integrity sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=
-base64-js@^1.3.1:
+base64-js@^1.0.2, base64-js@^1.3.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
@@ -2543,6 +2796,11 @@ big.js@^5.2.2:
resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==
+bignumber.js@^9.0.0:
+ version "9.0.1"
+ resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.1.tgz#8d7ba124c882bfd8e43260c67475518d0689e4e5"
+ integrity sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==
+
binary-extensions@^1.0.0:
version "1.13.1"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65"
@@ -2584,6 +2842,16 @@ bluebird@^3.7.2:
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
+bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9:
+ version "4.12.0"
+ resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
+ integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
+
+bn.js@^5.0.0, bn.js@^5.1.1:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002"
+ integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==
+
body-parser@1.19.0, body-parser@^1.19.0:
version "1.19.0"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
@@ -2617,6 +2885,11 @@ boolbase@^1.0.0, boolbase@~1.0.0:
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
+boolean@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.0.2.tgz#df1baa18b6a2b0e70840475e1d93ec8fe75b2570"
+ integrity sha512-RwywHlpCRc3/Wh81MiCKun4ydaIFyW5Ea6JbL6sRCVx5q5irDw7pMXBUFYF/jArQ6YrG36q0kpovc9P/Kd3I4g==
+
boxen@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64"
@@ -2676,6 +2949,72 @@ braces@^3.0.1, braces@~3.0.2:
dependencies:
fill-range "^7.0.1"
+brorand@^1.0.1, brorand@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
+ integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
+
+browserify-aes@^1.0.0, browserify-aes@^1.0.4:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48"
+ integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==
+ dependencies:
+ buffer-xor "^1.0.3"
+ cipher-base "^1.0.0"
+ create-hash "^1.1.0"
+ evp_bytestokey "^1.0.3"
+ inherits "^2.0.1"
+ safe-buffer "^5.0.1"
+
+browserify-cipher@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0"
+ integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==
+ dependencies:
+ browserify-aes "^1.0.4"
+ browserify-des "^1.0.0"
+ evp_bytestokey "^1.0.0"
+
+browserify-des@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c"
+ integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==
+ dependencies:
+ cipher-base "^1.0.1"
+ des.js "^1.0.0"
+ inherits "^2.0.1"
+ safe-buffer "^5.1.2"
+
+browserify-rsa@^4.0.0, browserify-rsa@^4.0.1:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d"
+ integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==
+ dependencies:
+ bn.js "^5.0.0"
+ randombytes "^2.0.1"
+
+browserify-sign@^4.0.0:
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3"
+ integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==
+ dependencies:
+ bn.js "^5.1.1"
+ browserify-rsa "^4.0.1"
+ create-hash "^1.2.0"
+ create-hmac "^1.1.7"
+ elliptic "^6.5.3"
+ inherits "^2.0.4"
+ parse-asn1 "^5.1.5"
+ readable-stream "^3.6.0"
+ safe-buffer "^5.2.0"
+
+browserify-zlib@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f"
+ integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==
+ dependencies:
+ pako "~1.0.5"
+
browserslist@4.14.2:
version "4.14.2"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.2.tgz#1b3cec458a1ba87588cc5e9be62f19b6d48813ce"
@@ -2686,6 +3025,17 @@ browserslist@4.14.2:
escalade "^3.0.2"
node-releases "^1.1.61"
+browserslist@4.16.1:
+ version "4.16.1"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.1.tgz#bf757a2da376b3447b800a16f0f1c96358138766"
+ integrity sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA==
+ dependencies:
+ caniuse-lite "^1.0.30001173"
+ colorette "^1.2.1"
+ electron-to-chromium "^1.3.634"
+ escalade "^3.1.1"
+ node-releases "^1.1.69"
+
browserslist@^4.0.0, browserslist@^4.12.2, browserslist@^4.14.5, browserslist@^4.16.3:
version "4.16.3"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.3.tgz#340aa46940d7db878748567c5dea24a48ddf3717"
@@ -2721,6 +3071,11 @@ buffer-crc32@~0.2.3:
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=
+buffer-equal-constant-time@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
+ integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=
+
buffer-from@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
@@ -2731,6 +3086,28 @@ buffer-indexof@^1.0.0:
resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c"
integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==
+buffer-xor@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
+ integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=
+
+buffer@5.6.0:
+ version "5.6.0"
+ resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786"
+ integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==
+ dependencies:
+ base64-js "^1.0.2"
+ ieee754 "^1.1.4"
+
+buffer@^4.3.0:
+ version "4.9.2"
+ resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8"
+ integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==
+ dependencies:
+ base64-js "^1.0.2"
+ ieee754 "^1.1.4"
+ isarray "^1.0.0"
+
buffer@^5.5.0, buffer@^5.7.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
@@ -2747,6 +3124,11 @@ buffer@^6.0.1:
base64-js "^1.3.1"
ieee754 "^1.2.1"
+builtin-status-codes@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
+ integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=
+
busboy@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.3.1.tgz#170899274c5bf38aae27d5c62b71268cd585fd1b"
@@ -2759,7 +3141,7 @@ bytes@3.0.0:
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=
-bytes@3.1.0:
+bytes@3.1.0, bytes@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6"
integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==
@@ -2890,6 +3272,11 @@ camel-case@4.1.2:
pascal-case "^3.1.2"
tslib "^2.0.3"
+camelcase-css@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5"
+ integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==
+
camelcase-keys@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7"
@@ -2932,7 +3319,7 @@ caniuse-api@^3.0.0:
lodash.memoize "^4.1.2"
lodash.uniq "^4.5.0"
-caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001181, caniuse-lite@^1.0.30001196:
+caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001173, caniuse-lite@^1.0.30001179, caniuse-lite@^1.0.30001181, caniuse-lite@^1.0.30001196:
version "1.0.30001198"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001198.tgz#ed2d9b5f060322ba2efa42afdc56dee3255473f4"
integrity sha512-r5GGgESqOPZzwvdLVER374FpQu2WluCF1Z2DSiFJ89KSmGjT0LVKjgv4NcAqHmGWF9ihNpqRI9KXO9Ex4sKsgA==
@@ -2956,6 +3343,14 @@ chalk@2.4.2, chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
+chalk@4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.0.0.tgz#6e98081ed2d17faab615eb52ac66ec1fe6209e72"
+ integrity sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==
+ dependencies:
+ ansi-styles "^4.1.0"
+ supports-color "^7.1.0"
+
chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
@@ -3013,6 +3408,21 @@ check-more-types@^2.24.0:
resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600"
integrity sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=
+chokidar@3.5.1, chokidar@^3.4.2, chokidar@^3.4.3, chokidar@^3.5.1:
+ version "3.5.1"
+ resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a"
+ integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==
+ dependencies:
+ anymatch "~3.1.1"
+ braces "~3.0.2"
+ glob-parent "~5.1.0"
+ is-binary-path "~2.1.0"
+ is-glob "~4.0.1"
+ normalize-path "~3.0.0"
+ readdirp "~3.5.0"
+ optionalDependencies:
+ fsevents "~2.3.1"
+
chokidar@^2.1.8:
version "2.1.8"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917"
@@ -3032,21 +3442,6 @@ chokidar@^2.1.8:
optionalDependencies:
fsevents "^1.2.7"
-chokidar@^3.4.2, chokidar@^3.4.3, chokidar@^3.5.1:
- version "3.5.1"
- resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a"
- integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==
- dependencies:
- anymatch "~3.1.1"
- braces "~3.0.2"
- glob-parent "~5.1.0"
- is-binary-path "~2.1.0"
- is-glob "~4.0.1"
- normalize-path "~3.0.0"
- readdirp "~3.5.0"
- optionalDependencies:
- fsevents "~2.3.1"
-
chownr@^1.1.1:
version "1.1.4"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
@@ -3069,6 +3464,14 @@ ci-info@2.0.0, ci-info@^2.0.0:
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==
+cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de"
+ integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==
+ dependencies:
+ inherits "^2.0.1"
+ safe-buffer "^5.0.1"
+
class-utils@^0.3.5:
version "0.3.6"
resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463"
@@ -3079,7 +3482,7 @@ class-utils@^0.3.5:
isobject "^3.0.0"
static-extend "^0.1.1"
-classnames@2.2.6:
+classnames@2.2.6, classnames@^2.2.6:
version "2.2.6"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
@@ -3316,7 +3719,7 @@ commander@^5.1.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==
-commander@^6.2.0:
+commander@^6.0.0, commander@^6.2.0:
version "6.2.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c"
integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==
@@ -3405,11 +3808,21 @@ connect-history-api-fallback@^1.6.0:
resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc"
integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==
+console-browserify@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336"
+ integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==
+
console-control-strings@^1.0.0, console-control-strings@~1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=
+constants-browserify@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
+ integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=
+
contains-path@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a"
@@ -3576,11 +3989,42 @@ countup.js@^1.9.3:
resolved "https://registry.yarnpkg.com/countup.js/-/countup.js-1.9.3.tgz#ce3e50cd7160441e478f07da31895edcc0f1c9dd"
integrity sha1-zj5QzXFgRB5HjwfaMYle3MDxyd0=
+create-ecdh@^4.0.0:
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e"
+ integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==
+ dependencies:
+ bn.js "^4.1.0"
+ elliptic "^6.5.3"
+
create-gatsby@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/create-gatsby/-/create-gatsby-1.0.0.tgz#f977ffcf5e005c9885f6a89efcf6a9bbdd92ac17"
integrity sha512-eDa6rpm6sNrqrnzZDBRsbiCvEvUibAswliYcwqEP1ibgljQ88TXZP4FLnX6//Epj4zTwpUPVYALWVluOgBNGCA==
+create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196"
+ integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==
+ dependencies:
+ cipher-base "^1.0.1"
+ inherits "^2.0.1"
+ md5.js "^1.3.4"
+ ripemd160 "^2.0.1"
+ sha.js "^2.4.0"
+
+create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7:
+ version "1.1.7"
+ resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff"
+ integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==
+ dependencies:
+ cipher-base "^1.0.3"
+ create-hash "^1.1.0"
+ inherits "^2.0.1"
+ ripemd160 "^2.0.0"
+ safe-buffer "^5.0.1"
+ sha.js "^2.4.8"
+
create-require@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
@@ -3613,6 +4057,23 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5:
shebang-command "^1.2.0"
which "^1.2.9"
+crypto-browserify@3.12.0, crypto-browserify@^3.11.0:
+ version "3.12.0"
+ resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
+ integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==
+ dependencies:
+ browserify-cipher "^1.0.0"
+ browserify-sign "^4.0.0"
+ create-ecdh "^4.0.0"
+ create-hash "^1.1.0"
+ create-hmac "^1.1.0"
+ diffie-hellman "^5.0.0"
+ inherits "^2.0.1"
+ pbkdf2 "^3.0.3"
+ public-encrypt "^4.0.0"
+ randombytes "^2.0.0"
+ randomfill "^1.0.3"
+
crypto-random-string@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5"
@@ -3695,12 +4156,17 @@ css-tree@^1.1.2:
mdn-data "2.0.14"
source-map "^0.6.1"
+css-unit-converter@^1.1.1:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.2.tgz#4c77f5a1954e6dbff60695ecb214e3270436ab21"
+ integrity sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==
+
css-what@^3.2.1:
version "3.4.2"
resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4"
integrity sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==
-css.escape@^1.5.1:
+css.escape@1.5.1, css.escape@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb"
integrity sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=
@@ -3761,6 +4227,22 @@ cssnano-preset-default@^4.0.7:
postcss-svgo "^4.0.2"
postcss-unique-selectors "^4.0.1"
+cssnano-preset-simple@1.2.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/cssnano-preset-simple/-/cssnano-preset-simple-1.2.2.tgz#c631bf79ffec7fdfc4069e2f2da3ca67d99d8413"
+ integrity sha512-gtvrcRSGtP3hA/wS8mFVinFnQdEsEpm3v4I/s/KmNjpdWaThV/4E5EojAzFXxyT5OCSRPLlHR9iQexAqKHlhGQ==
+ dependencies:
+ caniuse-lite "^1.0.30001179"
+ postcss "^7.0.32"
+
+cssnano-simple@1.2.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/cssnano-simple/-/cssnano-simple-1.2.2.tgz#72c2c3970e67123c3b4130894a30dc1050267007"
+ integrity sha512-4slyYc1w4JhSbhVX5xi9G0aQ42JnRyPg+7l7cqoNyoIDzfWx40Rq3JQZnoAWDu60A4AvKVp9ln/YSUOdhDX68g==
+ dependencies:
+ cssnano-preset-simple "1.2.2"
+ postcss "^7.0.32"
+
cssnano-util-get-arguments@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz#ed3a08299f21d75741b20f3b81f194ed49cc150f"
@@ -3885,6 +4367,11 @@ dashdash@^1.12.0:
dependencies:
assert-plus "^1.0.0"
+data-uri-to-buffer@3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636"
+ integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==
+
dataloader@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-2.0.0.tgz#41eaf123db115987e21ca93c005cd7753c55fe6f"
@@ -3900,18 +4387,25 @@ date-fns@^2.14.0:
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.19.0.tgz#65193348635a28d5d916c43ec7ce6fbd145059e1"
integrity sha512-X3bf2iTPgCAQp9wvjOQytnf5vO5rESYRXlPIVcgSbtT5OTScPcsf9eZU+B/YIkKAtYr5WeCii58BgATrNitlWg==
-dayjs@^1.9.3:
+dayjs@^1.10.4, dayjs@^1.9.3:
version "1.10.4"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.4.tgz#8e544a9b8683f61783f570980a8a80eaf54ab1e2"
integrity sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw==
-debug@2.6.9, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9:
+debug@2, debug@2.6.9, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
dependencies:
ms "2.0.0"
+debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@~4.3.1:
+ version "4.3.1"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
+ integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
+ dependencies:
+ ms "2.1.2"
+
debug@4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b"
@@ -3919,6 +4413,13 @@ debug@4.3.2:
dependencies:
ms "2.1.2"
+debug@=3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
+ integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
+ dependencies:
+ ms "2.0.0"
+
debug@^3.0.0, debug@^3.1.0, debug@^3.1.1, debug@^3.2.6, debug@^3.2.7:
version "3.2.7"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
@@ -3926,13 +4427,6 @@ debug@^3.0.0, debug@^3.1.0, debug@^3.1.1, debug@^3.2.6, debug@^3.2.7:
dependencies:
ms "^2.1.1"
-debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@~4.3.1:
- version "4.3.1"
- resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
- integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
- dependencies:
- ms "2.1.2"
-
decamelize-keys@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9"
@@ -4004,6 +4498,11 @@ deep-object-diff@^1.1.0:
resolved "https://registry.yarnpkg.com/deep-object-diff/-/deep-object-diff-1.1.0.tgz#d6fabf476c2ed1751fc94d5ca693d2ed8c18bc5a"
integrity sha512-b+QLs5vHgS+IoSNcUE4n9HP2NwcHj7aqnJWsjPtuG75Rh5TOaGt0OjAYInh77d5T16V5cRDC+Pw/6ZZZiETBGw==
+deepmerge@^2.1.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170"
+ integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==
+
default-gateway@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b"
@@ -4046,6 +4545,11 @@ define-property@^2.0.2:
is-descriptor "^1.0.2"
isobject "^3.0.1"
+defined@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
+ integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=
+
del@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4"
@@ -4093,6 +4597,14 @@ depd@~1.1.2:
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
+des.js@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843"
+ integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==
+ dependencies:
+ inherits "^2.0.1"
+ minimalistic-assert "^1.0.0"
+
destroy@~1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
@@ -4132,6 +4644,15 @@ detect-port@^1.3.0:
address "^1.0.1"
debug "^2.6.0"
+detective@^5.2.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/detective/-/detective-5.2.0.tgz#feb2a77e85b904ecdea459ad897cc90a99bd2a7b"
+ integrity sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==
+ dependencies:
+ acorn-node "^1.6.1"
+ defined "^1.0.0"
+ minimist "^1.1.1"
+
devcert@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/devcert/-/devcert-1.1.3.tgz#ff8119efae52ebf2449531b7482ae0f7211542e9"
@@ -4167,6 +4688,11 @@ dicer@0.3.0:
dependencies:
streamsearch "0.1.2"
+didyoumean@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.1.tgz#e92edfdada6537d484d73c0172fd1eba0c4976ff"
+ integrity sha1-6S7f2tplN9SE1zwBcv0eugxJdv8=
+
diff-sequences@^25.2.6:
version "25.2.6"
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd"
@@ -4177,6 +4703,15 @@ diff@^4.0.1:
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
+diffie-hellman@^5.0.0:
+ version "5.0.3"
+ resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
+ integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==
+ dependencies:
+ bn.js "^4.1.0"
+ miller-rabin "^4.0.0"
+ randombytes "^2.0.0"
+
dir-glob@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
@@ -4241,6 +4776,11 @@ dom-serializer@0:
domelementtype "^2.0.1"
entities "^2.0.0"
+domain-browser@^1.1.1:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
+ integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==
+
domelementtype@1, domelementtype@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f"
@@ -4296,12 +4836,19 @@ ecc-jsbn@~0.1.1:
jsbn "~0.1.0"
safer-buffer "^2.1.0"
+ecdsa-sig-formatter@1.0.11:
+ version "1.0.11"
+ resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf"
+ integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==
+ dependencies:
+ safe-buffer "^5.0.1"
+
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
-electron-to-chromium@^1.3.564, electron-to-chromium@^1.3.649:
+electron-to-chromium@^1.3.564, electron-to-chromium@^1.3.634, electron-to-chromium@^1.3.649:
version "1.3.685"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.685.tgz#f636d17c9c232c925f8bbfbff4f86303da091ff9"
integrity sha512-C3oFZNkJ8lz85ADqr3hzpjBc2ciejMRN2SCd/D0hwcqpr6MGxfdN/j89VN6l+ERTuCUvhg0VYsf40Q4qTz4bhQ==
@@ -4311,6 +4858,19 @@ elegant-spinner@^1.0.1:
resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e"
integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=
+elliptic@^6.5.3:
+ version "6.5.4"
+ resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
+ integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==
+ dependencies:
+ bn.js "^4.11.9"
+ brorand "^1.1.0"
+ hash.js "^1.0.0"
+ hmac-drbg "^1.0.1"
+ inherits "^2.0.4"
+ minimalistic-assert "^1.0.1"
+ minimalistic-crypto-utils "^1.0.1"
+
emoji-regex@^7.0.1:
version "7.0.3"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
@@ -4788,7 +5348,7 @@ esutils@^2.0.2:
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
-etag@~1.8.1:
+etag@1.8.1, etag@~1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
@@ -4816,7 +5376,7 @@ eventemitter3@^4.0.0:
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
-events@^3.2.0:
+events@^3.0.0, events@^3.2.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
@@ -4828,6 +5388,14 @@ eventsource@1.0.7, eventsource@^1.0.7:
dependencies:
original "^1.0.0"
+evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02"
+ integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==
+ dependencies:
+ md5.js "^1.3.4"
+ safe-buffer "^5.1.1"
+
execa@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8"
@@ -4912,6 +5480,21 @@ express-graphql@^0.9.0:
http-errors "^1.7.3"
raw-body "^2.4.1"
+express-jwt@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/express-jwt/-/express-jwt-6.0.0.tgz#20886c730983ffb1c706a4383235df86eff349b8"
+ integrity sha512-C26y9myRjx7CyhZ+BAT3p+gQyRCoDZ7qo8plCvLDaRT6je6ALIAQknT6XLVQGFKwIy/Ux7lvM2MNap5dt0T7gA==
+ dependencies:
+ async "^1.5.0"
+ express-unless "^0.3.0"
+ jsonwebtoken "^8.1.0"
+ lodash.set "^4.0.0"
+
+express-unless@^0.3.0:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/express-unless/-/express-unless-0.3.1.tgz#2557c146e75beb903e2d247f9b5ba01452696e20"
+ integrity sha1-JVfBRudb65A+LSR/m1ugFFJpbiA=
+
express@^4.17.1:
version "4.17.1"
resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134"
@@ -5055,12 +5638,19 @@ fast-levenshtein@^2.0.6:
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
+fast-levenshtein@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz#37b899ae47e1090e40e3fd2318e4d5f0142ca912"
+ integrity sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==
+ dependencies:
+ fastest-levenshtein "^1.0.7"
+
fast-safe-stringify@^2.0.7:
version "2.0.7"
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743"
integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==
-fastest-levenshtein@^1.0.12:
+fastest-levenshtein@^1.0.12, fastest-levenshtein@^1.0.7:
version "1.0.12"
resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2"
integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==
@@ -5197,7 +5787,7 @@ finalhandler@~1.1.2:
statuses "~1.5.0"
unpipe "~1.0.0"
-find-cache-dir@^3.3.1:
+find-cache-dir@3.3.1, find-cache-dir@^3.3.1:
version "3.3.1"
resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880"
integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==
@@ -5264,6 +5854,13 @@ flatted@^3.1.0:
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469"
integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==
+follow-redirects@1.5.10:
+ version "1.5.10"
+ resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
+ integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
+ dependencies:
+ debug "=3.1.0"
+
follow-redirects@^1.0.0, follow-redirects@^1.10.0:
version "1.13.3"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.3.tgz#e5598ad50174c1bc4e872301e82ac2cd97f90267"
@@ -5336,6 +5933,19 @@ formidable@^1.2.2:
resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.2.tgz#bf69aea2972982675f00865342b982986f6b8dd9"
integrity sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==
+formik@^2.2.6:
+ version "2.2.6"
+ resolved "https://registry.yarnpkg.com/formik/-/formik-2.2.6.tgz#378a4bafe4b95caf6acf6db01f81f3fe5147559d"
+ integrity sha512-Kxk2zQRafy56zhLmrzcbryUpMBvT0tal5IvcifK5+4YNGelKsnrODFJ0sZQRMQboblWNym4lAW3bt+tf2vApSA==
+ dependencies:
+ deepmerge "^2.1.1"
+ hoist-non-react-statics "^3.3.0"
+ lodash "^4.17.14"
+ lodash-es "^4.17.14"
+ react-fast-compare "^2.0.1"
+ tiny-warning "^1.0.2"
+ tslib "^1.10.0"
+
forwarded@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
@@ -5390,7 +6000,7 @@ fs-extra@^8.1.0:
jsonfile "^4.0.0"
universalify "^0.1.0"
-fs-extra@^9.0.0, fs-extra@^9.0.1:
+fs-extra@^9.0.0, fs-extra@^9.0.1, fs-extra@^9.1.0:
version "9.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d"
integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==
@@ -5934,6 +6544,13 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
has "^1.0.3"
has-symbols "^1.0.1"
+get-orientation@1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/get-orientation/-/get-orientation-1.1.2.tgz#20507928951814f8a91ded0a0e67b29dfab98947"
+ integrity sha512-/pViTfifW+gBbh/RnlFYHINvELT9Znt+SYyDKAUL6uV6By019AK/s+i9XP4jSwq7lwP38Fd8HVeTxym3+hkwmQ==
+ dependencies:
+ stream-parser "^0.3.1"
+
get-own-enumerable-property-symbols@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664"
@@ -6380,6 +6997,23 @@ has@^1.0.0, has@^1.0.3:
dependencies:
function-bind "^1.1.1"
+hash-base@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33"
+ integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==
+ dependencies:
+ inherits "^2.0.4"
+ readable-stream "^3.6.0"
+ safe-buffer "^5.2.0"
+
+hash.js@^1.0.0, hash.js@^1.0.3:
+ version "1.1.7"
+ resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42"
+ integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==
+ dependencies:
+ inherits "^2.0.3"
+ minimalistic-assert "^1.0.1"
+
hasha@^5.2.0:
version "5.2.2"
resolved "https://registry.yarnpkg.com/hasha/-/hasha-5.2.2.tgz#a48477989b3b327aea3c04f53096d816d97522a1"
@@ -6404,6 +7038,11 @@ hastscript@^6.0.0:
property-information "^5.0.0"
space-separated-tokens "^1.0.0"
+he@1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
+ integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
+
hex-color-regex@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
@@ -6422,6 +7061,22 @@ highlight.js@^10.4.1, highlight.js@~10.6.0:
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.6.0.tgz#0073aa71d566906965ba6e1b7be7b2682f5e18b6"
integrity sha512-8mlRcn5vk/r4+QcqerapwBYTe+iPL5ih6xrNylxrnBdHQiijDETfXX7VIxC3UiCRiINBJfANBAsPzAvRQj8RpQ==
+hmac-drbg@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
+ integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=
+ dependencies:
+ hash.js "^1.0.3"
+ minimalistic-assert "^1.0.0"
+ minimalistic-crypto-utils "^1.0.1"
+
+hoist-non-react-statics@^3.3.0:
+ version "3.3.2"
+ resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
+ integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
+ dependencies:
+ react-is "^16.7.0"
+
hosted-git-info@^2.1.4:
version "2.8.8"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
@@ -6478,6 +7133,11 @@ html-entities@^2.1.0:
resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.1.0.tgz#f5de1f8d5e1f16859a74aa73a90f0db502ca723a"
integrity sha512-u+OHVGMH5P1HlaTFp3M4HolRnWepgx5rAnYBo+7/TrBZahuJjgQ4TMv2GjQ4IouGDzkgXYeOI/NQuF95VOUOsQ==
+html-tags@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140"
+ integrity sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==
+
htmlparser2@^3.10.1:
version "3.10.1"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f"
@@ -6553,6 +7213,15 @@ http-parser-js@>=0.5.1:
resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9"
integrity sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==
+http-proxy-agent@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a"
+ integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==
+ dependencies:
+ "@tootallnate/once" "1"
+ agent-base "6"
+ debug "4"
+
http-proxy-middleware@0.19.1:
version "0.19.1"
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a"
@@ -6581,11 +7250,24 @@ http-signature@~1.2.0:
jsprim "^1.2.2"
sshpk "^1.7.0"
-http-status-codes@2.1.4, http-status-codes@^2.1.2:
+http-status-codes@2.1.4, http-status-codes@^2.1.2, http-status-codes@^2.1.4:
version "2.1.4"
resolved "https://registry.yarnpkg.com/http-status-codes/-/http-status-codes-2.1.4.tgz#453d99b4bd9424254c4f6a9a3a03715923052798"
integrity sha512-MZVIsLKGVOVE1KEnldppe6Ij+vmemMuApDfjhVSLzyYP+td0bREEYyAoIw9yFePoBXManCuBqmiNP5FqJS5Xkg==
+https-browserify@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
+ integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
+
+https-proxy-agent@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2"
+ integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==
+ dependencies:
+ agent-base "6"
+ debug "4"
+
human-signals@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
@@ -6619,7 +7301,7 @@ icss-utils@^5.0.0, icss-utils@^5.1.0:
resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae"
integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==
-ieee754@^1.1.13, ieee754@^1.2.1:
+ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
@@ -6715,11 +7397,16 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
-inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3:
+inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
+inherits@2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
+ integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=
+
inherits@2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
@@ -7396,7 +8083,7 @@ jest-get-type@^25.2.6:
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877"
integrity sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==
-jest-worker@^24.9.0:
+jest-worker@24.9.0, jest-worker@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5"
integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==
@@ -7429,6 +8116,11 @@ js-base64@^2.1.8:
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.6.4.tgz#f4e686c5de1ea1f867dbcad3d46d969428df98c4"
integrity sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==
+js-cookie@^2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8"
+ integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==
+
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@@ -7457,6 +8149,13 @@ jsesc@~0.5.0:
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=
+json-bigint@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1"
+ integrity sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==
+ dependencies:
+ bignumber.js "^9.0.0"
+
json-buffer@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
@@ -7544,6 +8243,22 @@ jsonp@0.2.1, jsonp@^0.2.1:
dependencies:
debug "^2.1.3"
+jsonwebtoken@^8.1.0, jsonwebtoken@^8.5.1:
+ version "8.5.1"
+ resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d"
+ integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==
+ dependencies:
+ jws "^3.2.2"
+ lodash.includes "^4.3.0"
+ lodash.isboolean "^3.0.3"
+ lodash.isinteger "^4.0.4"
+ lodash.isnumber "^3.0.3"
+ lodash.isplainobject "^4.0.6"
+ lodash.isstring "^4.0.1"
+ lodash.once "^4.0.0"
+ ms "^2.1.1"
+ semver "^5.6.0"
+
jsprim@^1.2.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
@@ -7562,6 +8277,39 @@ jsprim@^1.2.2:
array-includes "^3.1.2"
object.assign "^4.1.2"
+jwa@^1.4.1:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a"
+ integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==
+ dependencies:
+ buffer-equal-constant-time "1.0.1"
+ ecdsa-sig-formatter "1.0.11"
+ safe-buffer "^5.0.1"
+
+jwks-rsa@^1.12.2:
+ version "1.12.3"
+ resolved "https://registry.yarnpkg.com/jwks-rsa/-/jwks-rsa-1.12.3.tgz#40232f85d16734cb82837f38bb3e350a34435400"
+ integrity sha512-cFipFDeYYaO9FhhYJcZWX/IyZgc0+g316rcHnDpT2dNRNIE/lMOmWKKqp09TkJoYlNFzrEVODsR4GgXJMgWhnA==
+ dependencies:
+ "@types/express-jwt" "0.0.42"
+ axios "^0.21.1"
+ debug "^4.1.0"
+ http-proxy-agent "^4.0.1"
+ https-proxy-agent "^5.0.0"
+ jsonwebtoken "^8.5.1"
+ limiter "^1.1.5"
+ lru-memoizer "^2.1.2"
+ ms "^2.1.2"
+ proxy-from-env "^1.1.0"
+
+jws@^3.2.2:
+ version "3.2.2"
+ resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304"
+ integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==
+ dependencies:
+ jwa "^1.4.1"
+ safe-buffer "^5.0.1"
+
keyv@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373"
@@ -7615,6 +8363,11 @@ klona@^2.0.4:
resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0"
integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==
+ky@0.25.1:
+ version "0.25.1"
+ resolved "https://registry.yarnpkg.com/ky/-/ky-0.25.1.tgz#0df0bd872a9cc57e31acd5dbc1443547c881bfbc"
+ integrity sha512-PjpCEWlIU7VpiMVrTwssahkYXX1by6NCT0fhTUX34F3DTinARlgMpriuroolugFPcMgpPWrOW4mTb984Qm1RXA==
+
language-subtag-registry@~0.3.2:
version "0.3.21"
resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz#04ac218bea46f04cb039084602c6da9e788dd45a"
@@ -7647,6 +8400,19 @@ levn@^0.4.1:
prelude-ls "^1.2.1"
type-check "~0.4.0"
+limiter@^1.1.5:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/limiter/-/limiter-1.1.5.tgz#8f92a25b3b16c6131293a0cc834b4a838a2aa7c2"
+ integrity sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==
+
+line-column@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/line-column/-/line-column-1.0.2.tgz#d25af2936b6f4849172b312e4792d1d987bc34a2"
+ integrity sha1-0lryk2tvSEkXKzEuR5LR2Ye8NKI=
+ dependencies:
+ isarray "^1.0.0"
+ isobject "^2.0.0"
+
lines-and-columns@^1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
@@ -7820,7 +8586,12 @@ lock@^1.0.0:
resolved "https://registry.yarnpkg.com/lock/-/lock-1.1.0.tgz#53157499d1653b136ca66451071fca615703fa55"
integrity sha1-UxV0mdFlOxNspmRRBx/KYVcD+lU=
-lodash.clonedeep@4.5.0:
+lodash-es@^4.17.14, lodash-es@^4.17.15:
+ version "4.17.21"
+ resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
+ integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
+
+lodash.clonedeep@4.5.0, lodash.clonedeep@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
@@ -7840,6 +8611,11 @@ lodash.every@^4.6.0:
resolved "https://registry.yarnpkg.com/lodash.every/-/lodash.every-4.6.0.tgz#eb89984bebc4364279bb3aefbbd1ca19bfa6c6a7"
integrity sha1-64mYS+vENkJ5uzrvu9HKGb+mxqc=
+lodash.flatmap@^4.5.0:
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/lodash.flatmap/-/lodash.flatmap-4.5.0.tgz#ef8cbf408f6e48268663345305c6acc0b778702e"
+ integrity sha1-74y/QI9uSCaGYzRTBcaswLd4cC4=
+
lodash.flatten@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
@@ -7860,11 +8636,36 @@ lodash.get@^4:
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
+lodash.includes@^4.3.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
+ integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=
+
+lodash.isboolean@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
+ integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=
+
+lodash.isinteger@^4.0.4:
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
+ integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=
+
+lodash.isnumber@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc"
+ integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=
+
lodash.isplainobject@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
+lodash.isstring@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
+ integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=
+
lodash.map@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3"
@@ -7880,11 +8681,26 @@ lodash.memoize@^4.1.2:
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
-lodash.once@^4.1.1:
+lodash.once@^4.0.0, lodash.once@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
+lodash.set@^4.0.0:
+ version "4.3.2"
+ resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23"
+ integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=
+
+lodash.sortby@^4.7.0:
+ version "4.7.0"
+ resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
+ integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
+
+lodash.toarray@^4.4.0:
+ version "4.4.0"
+ resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561"
+ integrity sha1-JMS/zWsvuji/0FlNsRedjptlZWE=
+
lodash.uniq@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
@@ -7895,7 +8711,7 @@ lodash.without@^4.4.0:
resolved "https://registry.yarnpkg.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac"
integrity sha1-PNRXSgC2e643OpS3SHcmQFB7eqw=
-lodash@4, lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@~4.17.10:
+lodash@4, lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@~4.17.10:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -8022,6 +8838,22 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
+lru-cache@~4.0.0:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e"
+ integrity sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=
+ dependencies:
+ pseudomap "^1.0.1"
+ yallist "^2.0.0"
+
+lru-memoizer@^2.1.2:
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/lru-memoizer/-/lru-memoizer-2.1.4.tgz#b864d92b557f00b1eeb322156a0409cb06dafac6"
+ integrity sha512-IXAq50s4qwrOBrXJklY+KhgZF+5y98PDaNo0gi/v2KQBFLyWr+JyFvijZXkGKjQj/h9c0OwoE+JZbwUXce76hQ==
+ dependencies:
+ lodash.clonedeep "^4.5.0"
+ lru-cache "~4.0.0"
+
lru-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3"
@@ -8087,6 +8919,15 @@ md5-file@^5.0.0:
resolved "https://registry.yarnpkg.com/md5-file/-/md5-file-5.0.0.tgz#e519f631feca9c39e7f9ea1780b63c4745012e20"
integrity sha512-xbEFXCYVWrSx/gEKS1VPlg84h/4L20znVIulKw6kMfmBUAZNAnF00eczz9ICMl+/hjQGo5KSXRxbL/47X3rmMw==
+md5.js@^1.3.4:
+ version "1.3.5"
+ resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
+ integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==
+ dependencies:
+ hash-base "^3.0.0"
+ inherits "^2.0.1"
+ safe-buffer "^5.1.2"
+
mdast-util-compact@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/mdast-util-compact/-/mdast-util-compact-2.0.1.tgz#cabc69a2f43103628326f35b1acf735d55c99490"
@@ -8236,6 +9077,14 @@ micromatch@^4.0.2:
braces "^3.0.1"
picomatch "^2.0.5"
+miller-rabin@^4.0.0:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
+ integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==
+ dependencies:
+ bn.js "^4.0.0"
+ brorand "^1.0.1"
+
mime-db@1.46.0, "mime-db@>= 1.43.0 < 2", mime-db@^1.45.0:
version "1.46.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.46.0.tgz#6267748a7f799594de3cbc8cde91def349661cee"
@@ -8302,11 +9151,21 @@ mini-css-extract-plugin@1.3.9:
schema-utils "^3.0.0"
webpack-sources "^1.1.0"
-minimalistic-assert@^1.0.0:
+mini-svg-data-uri@^1.2.3:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/mini-svg-data-uri/-/mini-svg-data-uri-1.2.3.tgz#e16baa92ad55ddaa1c2c135759129f41910bc39f"
+ integrity sha512-zd6KCAyXgmq6FV1mR10oKXYtvmA9vRoB6xPSTUJTbFApCtkefDnYueVR1gkof3KcdLZo1Y8mjF2DFmQMIxsHNQ==
+
+minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
+minimalistic-crypto-utils@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
+ integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
+
minimatch@3.0.4, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
@@ -8323,7 +9182,7 @@ minimist-options@4.1.0:
is-plain-obj "^1.1.0"
kind-of "^6.0.3"
-minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5:
+minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
@@ -8394,6 +9253,11 @@ mkdirp@^1.0.3, mkdirp@^1.0.4:
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
+modern-normalize@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/modern-normalize/-/modern-normalize-1.0.0.tgz#539d84a1e141338b01b346f3e27396d0ed17601e"
+ integrity sha512-1lM+BMLGuDfsdwf3rsgBSrxJwAZHFIrQ8YR61xIqdHo0uNKI9M52wNpHSrliZATJp51On6JD0AfRxd4YGSU0lw==
+
moment@^2.27.0, moment@^2.29.1:
version "2.29.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
@@ -8414,7 +9278,7 @@ ms@2.1.2:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
-ms@^2.1.1:
+ms@^2.1.1, ms@^2.1.2:
version "2.1.3"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
@@ -8447,7 +9311,12 @@ nan@^2.12.1, nan@^2.13.2:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19"
integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==
-nanoid@^3.1.20:
+nanoclone@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/nanoclone/-/nanoclone-0.2.1.tgz#dd4090f8f1a110d26bb32c49ed2f5b9235209ed4"
+ integrity sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==
+
+nanoid@^3.1.16, nanoid@^3.1.20:
version "3.1.20"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788"
integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==
@@ -8474,6 +9343,13 @@ napi-build-utils@^1.0.1:
resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806"
integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==
+native-url@0.3.4:
+ version "0.3.4"
+ resolved "https://registry.yarnpkg.com/native-url/-/native-url-0.3.4.tgz#29c943172aed86c63cee62c8c04db7f5756661f8"
+ integrity sha512-6iM8R99ze45ivyH8vybJ7X0yekIcPf5GgLV5K0ENCbmRcaRIDoj37BC8iLEmaaBfqqb8enuZ5p0uhY+lVAbAcA==
+ dependencies:
+ querystring "^0.2.0"
+
native-url@^0.2.6:
version "0.2.6"
resolved "https://registry.yarnpkg.com/native-url/-/native-url-0.2.6.tgz#ca1258f5ace169c716ff44eccbddb674e10399ae"
@@ -8506,6 +9382,49 @@ next-tick@~1.0.0:
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
integrity sha1-yobR/ogoFpsBICCOPchCS524NCw=
+next@^10.0.8:
+ version "10.0.8"
+ resolved "https://registry.yarnpkg.com/next/-/next-10.0.8.tgz#a2232c11ffad974d67f3d572b8db2acaa5ddedd7"
+ integrity sha512-iDY65ce4Prn/9EnQpJGFMb5QJvtGWzZPk6KQqT7vDNu4D+jkivkk9NaAs/k1hR73pXdJHmhHer1s0YxLSghAKQ==
+ dependencies:
+ "@babel/runtime" "7.12.5"
+ "@hapi/accept" "5.0.1"
+ "@next/env" "10.0.8"
+ "@next/polyfill-module" "10.0.8"
+ "@next/react-dev-overlay" "10.0.8"
+ "@next/react-refresh-utils" "10.0.8"
+ "@opentelemetry/api" "0.14.0"
+ ast-types "0.13.2"
+ browserslist "4.16.1"
+ buffer "5.6.0"
+ caniuse-lite "^1.0.30001179"
+ chalk "2.4.2"
+ chokidar "3.5.1"
+ crypto-browserify "3.12.0"
+ cssnano-simple "1.2.2"
+ etag "1.8.1"
+ find-cache-dir "3.3.1"
+ get-orientation "1.1.2"
+ jest-worker "24.9.0"
+ native-url "0.3.4"
+ node-fetch "2.6.1"
+ node-html-parser "1.4.9"
+ node-libs-browser "^2.2.1"
+ p-limit "3.1.0"
+ path-browserify "1.0.1"
+ pnp-webpack-plugin "1.6.4"
+ postcss "8.1.7"
+ process "0.11.10"
+ prop-types "15.7.2"
+ raw-body "2.4.1"
+ react-is "16.13.1"
+ react-refresh "0.8.3"
+ stream-browserify "3.0.0"
+ styled-jsx "3.3.2"
+ use-subscription "1.5.1"
+ vm-browserify "1.1.2"
+ watchpack "2.1.1"
+
nice-try@^1.0.4:
version "1.0.5"
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
@@ -8538,6 +9457,13 @@ node-cache@^5.1.2:
dependencies:
clone "2.x"
+node-emoji@^1.8.1:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da"
+ integrity sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==
+ dependencies:
+ lodash.toarray "^4.4.0"
+
node-eta@^0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/node-eta/-/node-eta-0.9.0.tgz#9fb0b099bcd2a021940e603c64254dc003d9a7a8"
@@ -8569,12 +9495,48 @@ node-gyp@^7.1.0:
tar "^6.0.2"
which "^2.0.2"
+node-html-parser@1.4.9:
+ version "1.4.9"
+ resolved "https://registry.yarnpkg.com/node-html-parser/-/node-html-parser-1.4.9.tgz#3c8f6cac46479fae5800725edb532e9ae8fd816c"
+ integrity sha512-UVcirFD1Bn0O+TSmloHeHqZZCxHjvtIeGdVdGMhyZ8/PWlEiZaZ5iJzR189yKZr8p0FXN58BUeC7RHRkf/KYGw==
+ dependencies:
+ he "1.2.0"
+
+node-libs-browser@^2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425"
+ integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==
+ dependencies:
+ assert "^1.1.1"
+ browserify-zlib "^0.2.0"
+ buffer "^4.3.0"
+ console-browserify "^1.1.0"
+ constants-browserify "^1.0.0"
+ crypto-browserify "^3.11.0"
+ domain-browser "^1.1.1"
+ events "^3.0.0"
+ https-browserify "^1.0.0"
+ os-browserify "^0.3.0"
+ path-browserify "0.0.1"
+ process "^0.11.10"
+ punycode "^1.2.4"
+ querystring-es3 "^0.2.0"
+ readable-stream "^2.3.3"
+ stream-browserify "^2.0.1"
+ stream-http "^2.7.2"
+ string_decoder "^1.0.0"
+ timers-browserify "^2.0.4"
+ tty-browserify "0.0.0"
+ url "^0.11.0"
+ util "^0.11.0"
+ vm-browserify "^1.0.1"
+
node-object-hash@^2.0.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/node-object-hash/-/node-object-hash-2.3.1.tgz#5e4a6ac7f932cec4f90aff2fbdb953cb83344416"
integrity sha512-ab7pm34jqISawXpJ+fHjj2E9CmzDtm2fTTdurgzbWXIrdTEk2q2cSZRzoeGrwa0cvq6Sqezq6S9bhOBYPHRzuQ==
-node-releases@^1.1.61, node-releases@^1.1.70:
+node-releases@^1.1.61, node-releases@^1.1.69, node-releases@^1.1.70:
version "1.1.71"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb"
integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==
@@ -8908,6 +9870,11 @@ original@^1.0.0:
dependencies:
url-parse "^1.4.3"
+os-browserify@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
+ integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=
+
os-tmpdir@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
@@ -9055,6 +10022,11 @@ package-json@^6.3.0:
registry-url "^5.0.0"
semver "^6.2.0"
+pako@~1.0.5:
+ version "1.0.11"
+ resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
+ integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==
+
parent-module@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
@@ -9062,6 +10034,17 @@ parent-module@^1.0.0:
dependencies:
callsites "^3.0.0"
+parse-asn1@^5.0.0, parse-asn1@^5.1.5:
+ version "5.1.6"
+ resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4"
+ integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==
+ dependencies:
+ asn1.js "^5.2.0"
+ browserify-aes "^1.0.0"
+ evp_bytestokey "^1.0.0"
+ pbkdf2 "^3.0.3"
+ safe-buffer "^5.1.1"
+
parse-entities@^1.1.0:
version "1.2.2"
resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.2.2.tgz#c31bf0f653b6661354f8973559cb86dd1d5edf50"
@@ -9167,6 +10150,11 @@ password-prompt@^1.0.4:
ansi-escapes "^3.1.0"
cross-spawn "^6.0.5"
+path-browserify@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a"
+ integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==
+
path-browserify@1.0.1, path-browserify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd"
@@ -9245,6 +10233,17 @@ path-type@^4.0.0:
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
+pbkdf2@^3.0.3:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94"
+ integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==
+ dependencies:
+ create-hash "^1.1.2"
+ create-hmac "^1.1.4"
+ ripemd160 "^2.0.1"
+ safe-buffer "^5.0.1"
+ sha.js "^2.4.8"
+
peek-readable@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-3.1.3.tgz#932480d46cf6aa553c46c68566c4fb69a82cd2b1"
@@ -9332,7 +10331,7 @@ pkg-up@3.1.0:
dependencies:
find-up "^3.0.0"
-platform@^1.3.6:
+platform@1.3.6, platform@^1.3.6:
version "1.3.6"
resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.6.tgz#48b4ce983164b209c2d45a107adb31f473a6e7a7"
integrity sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==
@@ -9344,7 +10343,7 @@ please-upgrade-node@^3.2.0:
dependencies:
semver-compare "^1.0.0"
-pnp-webpack-plugin@^1.6.4:
+pnp-webpack-plugin@1.6.4, pnp-webpack-plugin@^1.6.4:
version "1.6.4"
resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149"
integrity sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==
@@ -9426,6 +10425,24 @@ postcss-flexbugs-fixes@^5.0.2:
resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz#2028e145313074fc9abe276cb7ca14e5401eb49d"
integrity sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==
+postcss-functions@^3:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/postcss-functions/-/postcss-functions-3.0.0.tgz#0e94d01444700a481de20de4d55fb2640564250e"
+ integrity sha1-DpTQFERwCkgd4g3k1V+yZAVkJQ4=
+ dependencies:
+ glob "^7.1.2"
+ object-assign "^4.1.1"
+ postcss "^6.0.9"
+ postcss-value-parser "^3.3.0"
+
+postcss-js@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-3.0.3.tgz#2f0bd370a2e8599d45439f6970403b5873abda33"
+ integrity sha512-gWnoWQXKFw65Hk/mi2+WTQTHdPD5UJdDXZmX073EY/B3BWnYjO4F4t0VneTCnCGQ5E5GsCdMkzPaTXwl3r5dJw==
+ dependencies:
+ camelcase-css "^2.0.1"
+ postcss "^8.1.6"
+
postcss-loader@^5.0.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-5.1.0.tgz#8a36f18b8989bee94172626b25f2b9cc6160fb43"
@@ -9525,6 +10542,13 @@ postcss-modules-values@^4.0.0:
dependencies:
icss-utils "^5.0.0"
+postcss-nested@^5.0.1:
+ version "5.0.5"
+ resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-5.0.5.tgz#f0a107d33a9fab11d7637205f5321e27223e3603"
+ integrity sha512-GSRXYz5bccobpTzLQZXOnSOfKl6TwVr5CyAQJUPub4nuRJSOECK5AqurxVgmtxP48p0Kc/ndY/YyS1yqldX0Ew==
+ dependencies:
+ postcss-selector-parser "^6.0.4"
+
postcss-normalize-charset@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz#8b35add3aee83a136b0471e0d59be58a50285dd4"
@@ -9673,7 +10697,7 @@ postcss-unique-selectors@^4.0.1:
postcss "^7.0.0"
uniqs "^2.0.0"
-postcss-value-parser@^3.0.0:
+postcss-value-parser@^3.0.0, postcss-value-parser@^3.3.0:
version "3.3.1"
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281"
integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==
@@ -9692,6 +10716,16 @@ postcss@7.0.21:
source-map "^0.6.1"
supports-color "^6.1.0"
+postcss@8.1.7:
+ version "8.1.7"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.1.7.tgz#ff6a82691bd861f3354fd9b17b2332f88171233f"
+ integrity sha512-llCQW1Pz4MOPwbZLmOddGM9eIJ8Bh7SZ2Oj5sxZva77uVaotYDsYTch1WBTNu7fUY0fpWp0fdt7uW40D4sRiiQ==
+ dependencies:
+ colorette "^1.2.1"
+ line-column "^1.0.2"
+ nanoid "^3.1.16"
+ source-map "^0.6.1"
+
postcss@8.2.6:
version "8.2.6"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.6.tgz#5d69a974543b45f87e464bc4c3e392a97d6be9fe"
@@ -9701,7 +10735,16 @@ postcss@8.2.6:
nanoid "^3.1.20"
source-map "^0.6.1"
-postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.27:
+postcss@^6.0.9:
+ version "6.0.23"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324"
+ integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==
+ dependencies:
+ chalk "^2.4.1"
+ source-map "^0.6.1"
+ supports-color "^5.4.0"
+
+postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.27, postcss@^7.0.32:
version "7.0.35"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.35.tgz#d2be00b998f7f211d8a276974079f2e92b970e24"
integrity sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==
@@ -9710,7 +10753,7 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.27:
source-map "^0.6.1"
supports-color "^6.1.0"
-postcss@^8.2.8:
+postcss@^8.1.6, postcss@^8.2.1, postcss@^8.2.6, postcss@^8.2.8:
version "8.2.8"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.8.tgz#0b90f9382efda424c4f0f69a2ead6f6830d08ece"
integrity sha512-1F0Xb2T21xET7oQV9eKuctbM9S7BC0fetoHCc4H13z0PT6haiRLP4T0ZY4XWh7iLP0usgqykT6p9B2RtOf4FPw==
@@ -9755,7 +10798,7 @@ prettier@2.2.1, prettier@^2.0.5, prettier@^2.2.1:
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5"
integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==
-pretty-bytes@^5.4.1:
+pretty-bytes@^5.4.1, pretty-bytes@^5.5.0:
version "5.6.0"
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb"
integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==
@@ -9778,6 +10821,11 @@ pretty-format@^25.5.0:
ansi-styles "^4.0.0"
react-is "^16.12.0"
+pretty-hrtime@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1"
+ integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=
+
prismjs@^1.22.0, prismjs@~1.23.0:
version "1.23.0"
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.23.0.tgz#d3b3967f7d72440690497652a9d40ff046067f33"
@@ -9790,6 +10838,11 @@ process-nextick-args@~2.0.0:
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
+process@0.11.10, process@^0.11.10:
+ version "0.11.10"
+ resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
+ integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
+
progress@^2.0.0, progress@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
@@ -9826,6 +10879,11 @@ proper-lockfile@^4.1.1:
retry "^0.12.0"
signal-exit "^3.0.2"
+property-expr@^2.0.4:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.4.tgz#37b925478e58965031bb612ec5b3260f8241e910"
+ integrity sha512-sFPkHQjVKheDNnPvotjQmm3KD3uk1fWKUN7CrpdbwmUx3CrG3QiM8QpTSimvig5vTXmTvjz7+TDvXOI9+4rkcg==
+
property-information@^5.0.0:
version "5.6.0"
resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.6.0.tgz#61675545fb23002f245c6540ec46077d4da3ed69"
@@ -9846,6 +10904,11 @@ proxy-addr@~2.0.5:
forwarded "~0.1.2"
ipaddr.js "1.9.1"
+proxy-from-env@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
+ integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
+
prr@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
@@ -9861,6 +10924,18 @@ psl@^1.1.28:
resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==
+public-encrypt@^4.0.0:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0"
+ integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==
+ dependencies:
+ bn.js "^4.1.0"
+ browserify-rsa "^4.0.0"
+ create-hash "^1.1.0"
+ parse-asn1 "^5.0.0"
+ randombytes "^2.0.1"
+ safe-buffer "^5.1.2"
+
pump@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
@@ -9874,6 +10949,11 @@ punycode@1.3.2:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=
+punycode@^1.2.4:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
+ integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
+
punycode@^2.1.0, punycode@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
@@ -9886,6 +10966,16 @@ pupa@^2.1.1:
dependencies:
escape-goat "^2.0.0"
+purgecss@^3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/purgecss/-/purgecss-3.1.3.tgz#26987ec09d12eeadc318e22f6e5a9eb0be094f41"
+ integrity sha512-hRSLN9mguJ2lzlIQtW4qmPS2kh6oMnA9RxdIYK8sz18QYqd6ePp4GNDl18oWHA1f2v2NEQIh51CO8s/E3YGckQ==
+ dependencies:
+ commander "^6.0.0"
+ glob "^7.0.0"
+ postcss "^8.2.1"
+ postcss-selector-parser "^6.0.2"
+
q@^1.1.2:
version "1.5.1"
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
@@ -9896,7 +10986,7 @@ qs@6.7.0:
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==
-qs@^6.9.4:
+qs@^6.6.0, qs@^6.9.4:
version "6.9.6"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee"
integrity sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==
@@ -9925,6 +11015,11 @@ query-string@^6.13.1, query-string@^6.13.8:
split-on-first "^1.0.0"
strict-uri-encode "^2.0.0"
+querystring-es3@^0.2.0:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
+ integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=
+
querystring@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
@@ -9955,13 +11050,21 @@ ramda@~0.27.1:
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.27.1.tgz#66fc2df3ef873874ffc2da6aa8984658abacf5c9"
integrity sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==
-randombytes@^2.1.0:
+randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
dependencies:
safe-buffer "^5.1.0"
+randomfill@^1.0.3:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458"
+ integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==
+ dependencies:
+ randombytes "^2.0.5"
+ safe-buffer "^5.1.0"
+
range-parser@^1.2.1, range-parser@~1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
@@ -9977,7 +11080,7 @@ raw-body@2.4.0:
iconv-lite "0.4.24"
unpipe "1.0.0"
-raw-body@^2.4.1:
+raw-body@2.4.1, raw-body@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c"
integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==
@@ -10067,6 +11170,11 @@ react-error-overlay@^6.0.9:
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a"
integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==
+react-fast-compare@^2.0.1:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"
+ integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==
+
react-fast-compare@^3.1.1:
version "3.2.0"
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
@@ -10082,7 +11190,7 @@ react-helmet@6.1.0:
react-fast-compare "^3.1.1"
react-side-effect "^2.1.0"
-react-is@^16.12.0, react-is@^16.8.1:
+react-is@16.13.1, react-is@^16.12.0, react-is@^16.7.0, react-is@^16.8.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
@@ -10108,6 +11216,11 @@ react-mailchimp-subscribe@^2.1.3:
prop-types "^15.5.10"
to-querystring "^1.0.4"
+react-refresh@0.8.3:
+ version "0.8.3"
+ resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
+ integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==
+
react-refresh@^0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.9.0.tgz#71863337adc3e5c2f8a6bfddd12ae3bfe32aafbf"
@@ -10204,7 +11317,7 @@ read@^1.0.7:
dependencies:
mute-stream "~0.0.4"
-readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@~2.3.6:
+readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6:
version "2.3.7"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
@@ -10217,7 +11330,7 @@ readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
-readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0:
+readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
@@ -10283,6 +11396,14 @@ redent@^3.0.0:
indent-string "^4.0.0"
strip-indent "^3.0.0"
+reduce-css-calc@^2.1.8:
+ version "2.1.8"
+ resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz#7ef8761a28d614980dc0c982f772c93f7a99de03"
+ integrity sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg==
+ dependencies:
+ css-unit-converter "^1.1.1"
+ postcss-value-parser "^3.3.0"
+
redux-thunk@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622"
@@ -10597,7 +11718,7 @@ resolve-url@^0.2.1:
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
-resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.3.2:
+resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.19.0, resolve@^1.3.2:
version "1.20.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
@@ -10688,6 +11809,14 @@ rimraf@^3.0.0, rimraf@^3.0.2:
dependencies:
glob "^7.1.3"
+ripemd160@^2.0.0, ripemd160@^2.0.1:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c"
+ integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==
+ dependencies:
+ hash-base "^3.0.0"
+ inherits "^2.0.1"
+
run-async@^2.4.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455"
@@ -10707,7 +11836,7 @@ rxjs@^6.3.3, rxjs@^6.6.0, rxjs@^6.6.6:
dependencies:
tslib "^1.9.0"
-safe-buffer@*, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0:
+safe-buffer@*, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
@@ -10918,6 +12047,11 @@ set-value@^2.0.0, set-value@^2.0.1:
is-plain-object "^2.0.3"
split-string "^3.0.1"
+setimmediate@^1.0.4:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
+ integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
+
setprototypeof@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
@@ -10933,6 +12067,14 @@ setprototypeof@1.2.0:
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
+sha.js@^2.4.0, sha.js@^2.4.8:
+ version "2.4.11"
+ resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7"
+ integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==
+ dependencies:
+ inherits "^2.0.1"
+ safe-buffer "^5.0.1"
+
shallow-clone@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3"
@@ -11046,7 +12188,7 @@ sisteransi@^1.0.5:
resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed"
integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==
-skynet-js@3.0.0:
+skynet-js@3.0.0, skynet-js@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/skynet-js/-/skynet-js-3.0.0.tgz#5d4caa55bf540fe91f6ec1d10bde1bb4c0eb3821"
integrity sha512-lRQK+vnNWhlC2OyiWiLrQoJ6EKudxvAeetUlB7GmuRSbArOlN8B5lLvy/DtnXVr+oaNX7oXV555wVe7csrXz4g==
@@ -11236,6 +12378,13 @@ source-map@0.7.3, source-map@^0.7.3, source-map@~0.7.2:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
+source-map@0.8.0-beta.0:
+ version "0.8.0-beta.0"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11"
+ integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==
+ dependencies:
+ whatwg-url "^7.0.0"
+
source-map@^0.4.2:
version "0.4.4"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b"
@@ -11319,6 +12468,20 @@ sprintf-js@~1.0.2:
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
+square@^9.0.0:
+ version "9.0.0"
+ resolved "https://registry.yarnpkg.com/square/-/square-9.0.0.tgz#41cb05539c5a28bde85329c89c64fa00058ffc2b"
+ integrity sha512-nHstJi+45Ea0RsOkO1Og47vvWO2I8BVg6675o0ZXtv543rT3kGGVop5rXxMRzXYCThwkrF5t0i6X1U57tfB9Sg==
+ dependencies:
+ "@apimatic/schema" "^0.5.1"
+ "@types/node" "^14.14.30"
+ axios "^0.21.1"
+ detect-node "^2.0.4"
+ form-data "^3.0.0"
+ json-bigint "^1.0.0"
+ lodash.flatmap "^4.5.0"
+ tiny-warning "^1.0.3"
+
sse-z@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/sse-z/-/sse-z-0.3.0.tgz#e215db7c303d6c4a4199d80cb63811cc28fa55b9"
@@ -11374,6 +12537,13 @@ stackframe@^1.1.1:
resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.0.tgz#52429492d63c62eb989804c11552e3d22e779303"
integrity sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==
+stacktrace-parser@0.1.10:
+ version "0.1.10"
+ resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a"
+ integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==
+ dependencies:
+ type-fest "^0.7.1"
+
state-toggle@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe"
@@ -11406,6 +12576,40 @@ steno@^0.4.1:
dependencies:
graceful-fs "^4.1.3"
+stream-browserify@3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f"
+ integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==
+ dependencies:
+ inherits "~2.0.4"
+ readable-stream "^3.5.0"
+
+stream-browserify@^2.0.1:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b"
+ integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==
+ dependencies:
+ inherits "~2.0.1"
+ readable-stream "^2.0.2"
+
+stream-http@^2.7.2:
+ version "2.8.3"
+ resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc"
+ integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==
+ dependencies:
+ builtin-status-codes "^3.0.0"
+ inherits "^2.0.1"
+ readable-stream "^2.3.6"
+ to-arraybuffer "^1.0.0"
+ xtend "^4.0.0"
+
+stream-parser@^0.3.1:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/stream-parser/-/stream-parser-0.3.1.tgz#1618548694420021a1182ff0af1911c129761773"
+ integrity sha1-FhhUhpRCACGhGC/wrxkRwSl2F3M=
+ dependencies:
+ debug "2"
+
streamsearch@0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a"
@@ -11431,6 +12635,11 @@ string-env-interpolation@1.0.1:
resolved "https://registry.yarnpkg.com/string-env-interpolation/-/string-env-interpolation-1.0.1.tgz#ad4397ae4ac53fe6c91d1402ad6f6a52862c7152"
integrity sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg==
+string-hash@1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b"
+ integrity sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=
+
string-natural-compare@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4"
@@ -11511,7 +12720,7 @@ string.prototype.trimstart@^1.0.4:
call-bind "^1.0.2"
define-properties "^1.1.3"
-string_decoder@^1.1.1:
+string_decoder@^1.0.0, string_decoder@^1.1.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
@@ -11622,6 +12831,14 @@ strip-json-comments@~2.0.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
+stripe@^8.137.0:
+ version "8.138.0"
+ resolved "https://registry.yarnpkg.com/stripe/-/stripe-8.138.0.tgz#032ad239cda2058ab0cc391874b4d40e449cafdb"
+ integrity sha512-Cr+jzcacXOlL1Wrd7xxcE9nk9OBF0l73Z/oCAlBHXldtRr2FRflg/2h4g4Na3LTlcLRYtx+jnKs64/WPOqmpsA==
+ dependencies:
+ "@types/node" ">=8.1.0"
+ qs "^6.6.0"
+
strtok3@^6.0.3:
version "6.0.8"
resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.0.8.tgz#c839157f615c10ba0f4ae35067dad9959eeca346"
@@ -11646,6 +12863,20 @@ style-to-object@^0.3.0:
dependencies:
inline-style-parser "0.1.1"
+styled-jsx@3.3.2:
+ version "3.3.2"
+ resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-3.3.2.tgz#2474601a26670a6049fb4d3f94bd91695b3ce018"
+ integrity sha512-daAkGd5mqhbBhLd6jYAjYBa9LpxYCzsgo/f6qzPdFxVB8yoGbhxvzQgkC0pfmCVvW3JuAEBn0UzFLBfkHVZG1g==
+ dependencies:
+ "@babel/types" "7.8.3"
+ babel-plugin-syntax-jsx "6.18.0"
+ convert-source-map "1.7.0"
+ loader-utils "1.2.3"
+ source-map "0.7.3"
+ string-hash "1.1.3"
+ stylis "3.5.4"
+ stylis-rule-sheet "0.0.10"
+
stylehacks@^4.0.0:
version "4.0.3"
resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5"
@@ -11655,12 +12886,22 @@ stylehacks@^4.0.0:
postcss "^7.0.0"
postcss-selector-parser "^3.0.0"
+stylis-rule-sheet@0.0.10:
+ version "0.0.10"
+ resolved "https://registry.yarnpkg.com/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz#44e64a2b076643f4b52e5ff71efc04d8c3c4a430"
+ integrity sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw==
+
+stylis@3.5.4:
+ version "3.5.4"
+ resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe"
+ integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==
+
sudo-prompt@^8.2.0:
version "8.2.5"
resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-8.2.5.tgz#cc5ef3769a134bb94b24a631cc09628d4d53603e"
integrity sha512-rlBo3HU/1zAJUrkY6jNxDOC9eVYliG6nS4JA8u8KAshITd07tafMc/Br7xQwCSseXwJ2iCcHCE8SNWX3q8Z+kw==
-superagent@^6.0.0:
+superagent@^6.0.0, superagent@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/superagent/-/superagent-6.1.0.tgz#09f08807bc41108ef164cfb4be293cebd480f4a6"
integrity sha512-OUDHEssirmplo3F+1HWKUrUjvnQuA+nZI6i/JJBdXb5eq9IyEQwPyPpqND+SSsxf6TygpBEkUjISVRN4/VOpeg==
@@ -11682,7 +12923,7 @@ supports-color@^2.0.0:
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
-supports-color@^5.3.0:
+supports-color@^5.3.0, supports-color@^5.4.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
@@ -11722,6 +12963,11 @@ svgo@^1.0.0:
unquote "~1.1.1"
util.promisify "~1.0.0"
+swr@^0.5.0:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/swr/-/swr-0.5.2.tgz#b7b32c3b10237ca0b4b167accfa7ce37dda356f8"
+ integrity sha512-uHCk7XmA8EGJOv9m2NRQLaiCo+JTsSdlSXc0dqyuLRKG3gzep0iOTwyz7XKL+3iC8ZyUjq+w6Kl/SneqIL1ncA==
+
symbol-observable@^1.1.0, symbol-observable@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
@@ -11745,6 +12991,32 @@ table@^6.0.4:
slice-ansi "^4.0.0"
string-width "^4.2.0"
+tailwindcss@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-2.0.3.tgz#f8d07797d1f89dc4b171673c26237b58783c2c86"
+ integrity sha512-s8NEqdLBiVbbdL0a5XwTb8jKmIonOuI4RMENEcKLR61jw6SdKvBss7NWZzwCaD+ZIjlgmesv8tmrjXEp7C0eAQ==
+ dependencies:
+ "@fullhuman/postcss-purgecss" "^3.1.3"
+ bytes "^3.0.0"
+ chalk "^4.1.0"
+ color "^3.1.3"
+ detective "^5.2.0"
+ didyoumean "^1.2.1"
+ fs-extra "^9.1.0"
+ html-tags "^3.1.0"
+ lodash "^4.17.20"
+ modern-normalize "^1.0.0"
+ node-emoji "^1.8.1"
+ object-hash "^2.1.1"
+ postcss-functions "^3"
+ postcss-js "^3.0.3"
+ postcss-nested "^5.0.1"
+ postcss-selector-parser "^6.0.4"
+ postcss-value-parser "^4.1.0"
+ pretty-hrtime "^1.0.3"
+ reduce-css-calc "^2.1.8"
+ resolve "^1.19.0"
+
tapable@^1.0.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
@@ -11847,6 +13119,13 @@ timed-out@^4.0.1:
resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"
integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=
+timers-browserify@^2.0.4:
+ version "2.0.12"
+ resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee"
+ integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==
+ dependencies:
+ setimmediate "^1.0.4"
+
timers-ext@^0.1.7:
version "0.1.7"
resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6"
@@ -11865,6 +13144,11 @@ tiny-emitter@^2.0.0:
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
+tiny-warning@^1.0.2, tiny-warning@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
+ integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
+
tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
@@ -11879,6 +13163,11 @@ tmp@^0.2.1, tmp@~0.2.1:
dependencies:
rimraf "^3.0.0"
+to-arraybuffer@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
+ integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=
+
to-fast-properties@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
@@ -11939,6 +13228,11 @@ token-types@^2.0.0:
"@tokenizer/token" "^0.1.1"
ieee754 "^1.2.1"
+toposort@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330"
+ integrity sha1-riF2gXXRVZ1IvvNUILL0li8JwzA=
+
tough-cookie@~2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
@@ -11947,6 +13241,13 @@ tough-cookie@~2.5.0:
psl "^1.1.28"
punycode "^2.1.1"
+tr46@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09"
+ integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=
+ dependencies:
+ punycode "^2.1.0"
+
trim-newlines@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613"
@@ -12033,6 +13334,11 @@ tsutils@^3.17.1:
dependencies:
tslib "^1.8.1"
+tty-browserify@0.0.0:
+ version "0.0.0"
+ resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
+ integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=
+
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
@@ -12072,6 +13378,11 @@ type-fest@^0.6.0:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b"
integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==
+type-fest@^0.7.1:
+ version "0.7.1"
+ resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48"
+ integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==
+
type-fest@^0.8.0, type-fest@^0.8.1:
version "0.8.1"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
@@ -12391,6 +13702,13 @@ url@^0.11.0:
punycode "1.3.2"
querystring "0.2.0"
+use-subscription@1.5.1:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/use-subscription/-/use-subscription-1.5.1.tgz#73501107f02fad84c6dd57965beb0b75c68c42d1"
+ integrity sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==
+ dependencies:
+ object-assign "^4.1.1"
+
use@^3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
@@ -12422,6 +13740,20 @@ util.promisify@~1.0.0:
has-symbols "^1.0.1"
object.getownpropertydescriptors "^2.1.0"
+util@0.10.3:
+ version "0.10.3"
+ resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
+ integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk=
+ dependencies:
+ inherits "2.0.1"
+
+util@^0.11.0:
+ version "0.11.1"
+ resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61"
+ integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==
+ dependencies:
+ inherits "2.0.3"
+
utila@~0.4:
version "0.4.0"
resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c"
@@ -12497,6 +13829,11 @@ vfile@^4.0.0:
unist-util-stringify-position "^2.0.0"
vfile-message "^2.0.0"
+vm-browserify@1.1.2, vm-browserify@^1.0.1:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
+ integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
+
warning@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3"
@@ -12504,7 +13841,7 @@ warning@^4.0.3:
dependencies:
loose-envify "^1.0.0"
-watchpack@^2.0.0:
+watchpack@2.1.1, watchpack@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.1.1.tgz#e99630550fca07df9f90a06056987baa40a689c7"
integrity sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==
@@ -12519,6 +13856,11 @@ wbuf@^1.1.0, wbuf@^1.7.3:
dependencies:
minimalistic-assert "^1.0.0"
+webidl-conversions@^4.0.2:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
+ integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==
+
webpack-dev-middleware@^3.7.2:
version "3.7.3"
resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz#0639372b143262e2b84ab95d3b91a7597061c2c5"
@@ -12668,6 +14010,15 @@ websocket-extensions@>=0.1.1:
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42"
integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==
+whatwg-url@^7.0.0:
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06"
+ integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==
+ dependencies:
+ lodash.sortby "^4.7.0"
+ tr46 "^1.0.1"
+ webidl-conversions "^4.0.2"
+
which-boxed-primitive@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6"
@@ -12824,7 +14175,7 @@ xstate@^4.11.0, xstate@^4.14.0, xstate@^4.9.1:
resolved "https://registry.yarnpkg.com/xstate/-/xstate-4.16.2.tgz#d6b973b1253b8c85f50f68601837287d59d4bf34"
integrity sha512-EY39NNZnwM4tRYNmQAi1c2qHuZ1lJmuDpEo1jxiRcfS+1jPtKRAjGRLNx3fYKcK0ohW6mL41Wze3mdCF0SqavA==
-xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1:
+xtend@^4.0.0, xtend@^4.0.1, xtend@^4.0.2, xtend@~4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
@@ -12959,6 +14310,19 @@ yoga-layout-prebuilt@^1.9.6:
dependencies:
"@types/yoga-layout" "1.9.2"
+yup@^0.32.9:
+ version "0.32.9"
+ resolved "https://registry.yarnpkg.com/yup/-/yup-0.32.9.tgz#9367bec6b1b0e39211ecbca598702e106019d872"
+ integrity sha512-Ci1qN+i2H0XpY7syDQ0k5zKQ/DoxO0LzPg8PAR/X4Mpj6DqaeCoIYEEjDJwhArh3Fa7GWbQQVDZKeXYlSH4JMg==
+ dependencies:
+ "@babel/runtime" "^7.10.5"
+ "@types/lodash" "^4.14.165"
+ lodash "^4.17.20"
+ lodash-es "^4.17.15"
+ nanoclone "^0.2.1"
+ property-expr "^2.0.4"
+ toposort "^2.0.2"
+
yurnalist@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/yurnalist/-/yurnalist-2.1.0.tgz#44cf7ea5a33a8fab4968cc8c2970489f93760902"