diff --git a/.gitignore b/.gitignore index 00b75270..fa7c2589 100644 --- a/.gitignore +++ b/.gitignore @@ -87,3 +87,9 @@ docker/nginx/conf.d/server-override/* __pycache__ /.idea/ /venv* + +# CockroachDB certificates +.cr_certs/ + +# Oathkeeper JWKS signing token +docker/kratos/oathkeeper/id_token.jwks.json diff --git a/docker-compose.yml b/docker-compose.yml index 2c0c6a5b..88047ebb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,7 +15,6 @@ networks: volumes: webapp: - kratos-sqlite: services: sia: @@ -62,7 +61,9 @@ services: - nginx nginx: - image: openresty/openresty:1.15.8.3-2-xenial + build: + context: ./docker/nginx + dockerfile: Dockerfile container_name: nginx restart: unless-stopped logging: *default-logging @@ -174,6 +175,9 @@ services: - SKYNET_DB_PORT=27017 - 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} expose: - 3000 networks: @@ -204,11 +208,11 @@ services: restart: on-failure logging: *default-logging environment: - - DSN=cockroach://root@cockroachd:26257/defaultdb?sslmode=disable&max_conns=20&max_idle_conns=4 + - DSN=cockroach://root@cockroach:26257/defaultdb?sslmode=disable&max_conns=20&max_idle_conns=4 - SQA_OPT_OUT=true volumes: - ./docker/kratos/config:/etc/config/kratos - - kratos-sqlite:/var/lib/sqlite + - ./docker/data/cockroach/sqlite:/var/lib/sqlite command: -c /etc/config/kratos/kratos.yml migrate sql -e --yes networks: shared: @@ -226,17 +230,15 @@ services: - 4433 # public - 4434 # admin environment: - - DSN=cockroach://root@cockroachd:26257/defaultdb?sslmode=disable&max_conns=20&max_idle_conns=4 + - DSN=cockroach://root@cockroach:26257/defaultdb?sslmode=disable&max_conns=20&max_idle_conns=4 - LOG_LEVEL=trace - - SERVE_PUBLIC_BASE_URL=https://siasky.xyz/secure/.ory/kratos/public/ + - SERVE_PUBLIC_BASE_URL=/.ory/kratos/public/ - SQA_OPT_OUT=true command: serve -c /etc/config/kratos/kratos.yml volumes: - ./docker/kratos/config:/etc/config/kratos - - kratos-sqlite:/var/lib/sqlite - - type: bind - source: ./.kratos.yml - target: /etc/config/kratos/kratos.yml + - ./docker/data/cockroach/sqlite:/var/lib/sqlite + - ./.kratos.yml:/etc/config/kratos/kratos.yml networks: shared: ipv4_address: 10.10.10.81 @@ -248,11 +250,20 @@ services: container_name: kratos-selfservice-ui-node restart: on-failure logging: *default-logging + volumes: + - ./docker/kratos-selfservice-ui-node/main.hbs:/usr/src/app/views/layouts/main.hbs:ro + - ./docker/kratos-selfservice-ui-node/login.hbs:/usr/src/app/views/login.hbs:ro + - ./docker/kratos-selfservice-ui-node/dashboard.hbs:/usr/src/app/views/dashboard.hbs:ro + - ./docker/kratos-selfservice-ui-node/registration.hbs:/usr/src/app/views/registration.hbs:ro + - ./docker/kratos-selfservice-ui-node/icon_logo.hbs:/usr/src/app/views/partials/icon_logo.hbs:ro + - ./docker/kratos-selfservice-ui-node/branding.css:/usr/src/app/public/branding.css:ro + - ./docker/kratos-selfservice-ui-node/favico.png:/usr/src/app/public/favico.png:ro environment: - PORT=4435 - SECURITY_MODE=jwks - - BASE_URL=https://siasky.xyz/secure/ - - KRATOS_BROWSER_URL=https://siasky.xyz/secure/.ory/kratos/public + - PROJECT_NAME=Skynet + - BASE_URL=/ + - KRATOS_BROWSER_URL=/.ory/kratos/public - JWKS_URL=http://oathkeeper:4456/.well-known/jwks.json - KRATOS_PUBLIC_URL=http://kratos:4433/ - KRATOS_ADMIN_URL=http://kratos:4434/ @@ -279,12 +290,12 @@ services: shared: ipv4_address: 10.10.10.83 - cockroachd: + cockroach: image: cockroachdb/cockroach:v20.1.10 - container_name: cockroachd + container_name: cockroach 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: - - kratos-sqlite:/cockroach/cockroach-data + - ./docker/data/cockroach/sqlite:/cockroach/cockroach-data - ./.cr_certs:/certs expose: - 8080 diff --git a/docker/caddy/Caddyfile b/docker/caddy/Caddyfile index a5a92e8a..3900cad8 100644 --- a/docker/caddy/Caddyfile +++ b/docker/caddy/Caddyfile @@ -6,7 +6,7 @@ } (siasky.net) { - siasky.net, *.siasky.net, *.hns.siasky.net { + siasky.xyz, *.siasky.xyz, *.hns.siasky.xyz { tls { dns route53 { max_retries 50 @@ -27,4 +27,4 @@ import localhost # import custom.domain -# import siasky.net +import siasky.net diff --git a/docker/kratos-selfservice-ui-node/branding.css b/docker/kratos-selfservice-ui-node/branding.css new file mode 100644 index 00000000..91fe5848 --- /dev/null +++ b/docker/kratos-selfservice-ui-node/branding.css @@ -0,0 +1,18 @@ +:root { + --base-white: #ffffff; + --base-light: #f0f0f1; + --base-text: #99999e; + --base-main: #5a5b6a; + --base-dark: #19191d; + --base-black: #000000; + --primary-light: #ecfdfe; + --primary-half: #4ea156; + --primary-main: #57b560; + --primary-dark: #2e0473; + --red-strong: #f44336; + --green-strong: #43a047; +} + +.logo { + margin: 0 auto; +} diff --git a/docker/kratos-selfservice-ui-node/dashboard.hbs b/docker/kratos-selfservice-ui-node/dashboard.hbs new file mode 100644 index 00000000..53228209 --- /dev/null +++ b/docker/kratos-selfservice-ui-node/dashboard.hbs @@ -0,0 +1,15 @@ +
+ {{> header}} +
+

Welcome back, {{session.identity.traits.email}}!

+

This will be your dashboard!

+

Right now there is nothing else here but in future, you will be able to list your pinned files, upgrade to a + premium tiers and see your usage stats.

+ +
+ +

+ Go back to siasky.xyz +

+
+
\ No newline at end of file diff --git a/docker/kratos-selfservice-ui-node/favico.png b/docker/kratos-selfservice-ui-node/favico.png new file mode 100644 index 00000000..30c2af53 Binary files /dev/null and b/docker/kratos-selfservice-ui-node/favico.png differ diff --git a/docker/kratos-selfservice-ui-node/icon_logo.hbs b/docker/kratos-selfservice-ui-node/icon_logo.hbs new file mode 100644 index 00000000..4b356286 --- /dev/null +++ b/docker/kratos-selfservice-ui-node/icon_logo.hbs @@ -0,0 +1,12 @@ + + \ No newline at end of file diff --git a/docker/kratos-selfservice-ui-node/login.hbs b/docker/kratos-selfservice-ui-node/login.hbs new file mode 100644 index 00000000..42fb184d --- /dev/null +++ b/docker/kratos-selfservice-ui-node/login.hbs @@ -0,0 +1,28 @@ +
+
+ {{> icon_logo}} +
Welcome to siasky.net!
+ + {{> messages messages=messages className="global"}} + + {{#if password}} +
+ {{> form submitLabel="Sign in" form=password}} +
+ {{/if}} + + {{#if oidc}} +
+ {{> form form=oidc}} +
+ {{/if}} + +
+ + +
+
\ No newline at end of file diff --git a/docker/kratos-selfservice-ui-node/main.hbs b/docker/kratos-selfservice-ui-node/main.hbs new file mode 100644 index 00000000..76e85ff9 --- /dev/null +++ b/docker/kratos-selfservice-ui-node/main.hbs @@ -0,0 +1,23 @@ + + + + + {{#if baseUrl}} + + {{/if}} + + + + {{projectName}} + + + + + + + + + {{{body}}} + + + \ No newline at end of file diff --git a/docker/kratos-selfservice-ui-node/registration.hbs b/docker/kratos-selfservice-ui-node/registration.hbs new file mode 100644 index 00000000..51d7cf57 --- /dev/null +++ b/docker/kratos-selfservice-ui-node/registration.hbs @@ -0,0 +1,27 @@ +
+
+ {{> icon_logo}} +
Welcome to siasky.net!
+ Use the form below to sign up:
+ + {{> messages messages=messages className="global"}} + + {{#if password}} +
+ {{> form submitLabel="Sign up" form=password}} +
+ {{/if}} + + {{#if oidc}} +
+ {{> form form=oidc}} +
+ {{/if}} + +
+ + +
+
\ No newline at end of file diff --git a/docker/kratos/config/kratos.yml b/docker/kratos/config/kratos.yml index ffc289d3..a939024b 100644 --- a/docker/kratos/config/kratos.yml +++ b/docker/kratos/config/kratos.yml @@ -4,16 +4,16 @@ dsn: memory serve: public: - base_url: https://siasky.xyz/secure/ + base_url: http://127.0.0.1/ cors: enabled: true admin: - base_url: https://siasky.xyz/admin/ + base_url: http://127.0.0.1/admin/ selfservice: - default_browser_return_url: https://siasky.xyz/secure/ + default_browser_return_url: http://127.0.0.1/ whitelisted_return_urls: - - https://siasky.xyz/secure + - http://127.0.0.1/ methods: password: @@ -21,33 +21,33 @@ selfservice: flows: error: - ui_url: https://siasky.xyz/secure/error + ui_url: http://127.0.0.1/error settings: - ui_url: https://siasky.xyz/secure/settings + ui_url: http://127.0.0.1/settings privileged_session_max_age: 15m recovery: enabled: true - ui_url: https://siasky.xyz/secure/recovery + ui_url: http://127.0.0.1/recovery verification: enabled: true - ui_url: https://siasky.xyz/secure/verify + ui_url: http://127.0.0.1/verify after: - default_browser_return_url: https://siasky.xyz/secure/ + default_browser_return_url: http://127.0.0.1/ logout: after: - default_browser_return_url: https://siasky.xyz/secure/auth/login + default_browser_return_url: http://127.0.0.1/auth/login login: - ui_url: https://siasky.xyz/secure/auth/login + ui_url: http://127.0.0.1/auth/login lifespan: 10m registration: lifespan: 10m - ui_url: https://siasky.xyz/secure/auth/registration + ui_url: http://127.0.0.1/auth/registration after: password: hooks: @@ -64,7 +64,7 @@ secrets: session: cookie: - domain: siasky.xyz + domain: secure.siasky.xyz hashers: argon2: diff --git a/docker/kratos/oathkeeper/access-rules.yml b/docker/kratos/oathkeeper/access-rules.yml index e6c5d395..5e0e03fe 100644 --- a/docker/kratos/oathkeeper/access-rules.yml +++ b/docker/kratos/oathkeeper/access-rules.yml @@ -1,5 +1,4 @@ -- - id: "ory:kratos:public" +- id: "ory:kratos:public" upstream: preserve_host: true url: "http://kratos:4433" @@ -13,15 +12,13 @@ - DELETE - PATCH authenticators: - - - handler: noop + - handler: noop authorizer: handler: allow mutators: - handler: noop -- - id: "ory:kratos-selfservice-ui-node:anonymous" +- id: "ory:kratos-selfservice-ui-node:anonymous" upstream: preserve_host: true url: "http://kratos-selfservice-ui-node:4435" @@ -30,16 +27,13 @@ methods: - GET authenticators: - - - handler: anonymous + - handler: anonymous authorizer: handler: allow mutators: - - - handler: noop + - handler: noop -- - id: "ory:kratos-selfservice-ui-node:protected" +- id: "ory:kratos-selfservice-ui-node:protected" upstream: preserve_host: true url: "http://kratos-selfservice-ui-node:4435" @@ -48,8 +42,7 @@ methods: - GET authenticators: - - - handler: cookie_session + - handler: cookie_session authorizer: handler: allow mutators: @@ -57,6 +50,21 @@ errors: - handler: redirect config: - #to: http://oathkeeper:4455/auth/login - to: https://siasky.xyz/secure/auth/login + to: http://127.0.0.1/auth/login +- id: "accounts" + upstream: + preserve_host: true + url: "http://accounts:3000" + match: + url: "http://oathkeeper<{,:4455}>/<{user,user/**}>" + methods: + - GET + authenticators: + - handler: cookie_session + authorizer: + handler: allow + mutators: + - handler: id_token + errors: + - handler: json diff --git a/docker/kratos/oathkeeper/id_token.jwks.json b/docker/kratos/oathkeeper/id_token.jwks.json deleted file mode 100644 index 719f2c7f..00000000 --- a/docker/kratos/oathkeeper/id_token.jwks.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "keys": [ - { - "use": "sig", - "kty": "RSA", - "kid": "a2aa9739-d753-4a0d-87ee-61f101050277", - "alg": "RS256", - "n": "zpjSl0ySsdk_YC4ZJYYV-cSznWkzndTo0lyvkYmeBkW60YHuHzXaviHqonY_DjFBdnZC0Vs_QTWmBlZvPzTp4Oni-eOetP-Ce3-B8jkGWpKFOjTLw7uwR3b3jm_mFNiz1dV_utWiweqx62Se0SyYaAXrgStU8-3P2Us7_kz5NnBVL1E7aEP40aB7nytLvPhXau-YhFmUfgykAcov0QrnNY0DH0eTcwL19UysvlKx6Uiu6mnbaFE1qx8X2m2xuLpErfiqj6wLCdCYMWdRTHiVsQMtTzSwuPuXfH7J06GTo3I1cEWN8Mb-RJxlosJA_q7hEd43yYisCO-8szX0lgCasw", - "e": "AQAB", - "d": "x3dfY_rna1UQTmFToBoMn6Edte47irhkra4VSNPwwaeTTvI-oN2TO51td7vo91_xD1nw-0c5FFGi4V2UfRcudBv9LD1rHt_O8EPUh7QtAUeT3_XXgjx1Xxpqu5goMZpkTyGZ-B6JzOY3L8lvWQ_Qeia1EXpvxC-oTOjJnKZeuwIPlcoNKMRU-mIYOnkRFfnUvrDm7N9UZEp3PfI3vhE9AquP1PEvz5KTUYkubsfmupqqR6FmMUm6ulGT7guhBw9A3vxIYbYGKvXLdBvn68mENrEYxXrwmu6ITMh_y208M5rC-hgEHIAIvMu1aVW6jNgyQTunsGST3UyrSbwjI0K9UQ", - "p": "77fDvnfHRFEgyi7mh0c6fAdtMEMJ05W8NwTG_D-cSwfWipfTwJJrroWoRwEgdAg5AWGq-MNUzrubTVXoJdC2T4g1o-VRZkKKYoMvav3CvOIMzCBxBs9I_GAKr5NCSk7maksMqiCTMhmkoZ5RPuMYMY_YzxKNAbjBd9qFLfaVAqs", - "q": "3KEmPA2XQkf7dvtpY1Xkp1IfMV_UBdmYk7J6dB5BYqzviQWdEFvWaSATJ_7qV1dw0JDZynOgipp8gvoL-RepfjtArhPz41wB3J2xmBYrBr1sJ-x5eqAvMkQk2bd5KTor44e79TRIkmkFYAIdUQ5JdVXPA13S8WUZfb_bAbwaCBk", - "dp": "5uyy32AJkNFKchqeLsE6INMSp0RdSftbtfCfM86fZFQno5lA_qjOnO_avJPkTILDT4ZjqoKYxxJJOEXCffNCPPltGvbE5GrDXsUbP8k2-LgWNeoml7XFjIGEqcCFQoohQ1IK4DTDN6cmRh76C0e_Pbdh15D6TydJEIlsdGuu_kM", - "dq": "aegFNYCEojFxeTzX6vIZL2RRSt8oJKK-Be__reu0EUzYMtr5-RdMhev6phFMph54LfXKRc9ZOg9MQ4cJ5klAeDKzKpyzTukkj6U20b2aa8LTvxpZec6YuTVSxxu2Ul71IGRQijTNvVIiXWLGddk409Ub6Q7JqkyQfvdwhpWnnUk", - "qi": "P68-EwgcRy9ce_PZ75c909cU7dzCiaGcTX1psJiXmQAFBcG0msWfsyHGbllOZG27pKde78ORGJDYDNk1FqTwsogZyCP87EiBmOoqXWnMvKYfJ1DOx7x42LMAGwMD3bgQj9jgRACxFJG4n3NI6uFlFruyl_CLQzwW_rQFHshLK7Q" - } - ] -} - diff --git a/docker/kratos/oathkeeper/oathkeeper.yml b/docker/kratos/oathkeeper/oathkeeper.yml index e31ef77c..1887f8e1 100644 --- a/docker/kratos/oathkeeper/oathkeeper.yml +++ b/docker/kratos/oathkeeper/oathkeeper.yml @@ -30,11 +30,9 @@ errors: redirect: enabled: true config: - #to: http://oathkeeper:4455/auth/login - to: https://siasky.xyz/secure/auth/login + to: http://127.0.0.1/auth/login when: - - - error: + - error: - unauthorized - forbidden request: @@ -81,11 +79,9 @@ mutators: id_token: enabled: true config: - #issuer_url: http://oathkeeper:4455/ - issuer_url: https://siasky.xyz/ + issuer_url: http://oathkeeper:4455/ jwks_url: file:///etc/config/oathkeeper/id_token.jwks.json claims: | { "session": {{ .Extra | toJson }} } - diff --git a/docker/nginx/Dockerfile b/docker/nginx/Dockerfile new file mode 100644 index 00000000..bba36f7b --- /dev/null +++ b/docker/nginx/Dockerfile @@ -0,0 +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 + +# 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/conf.d/client.conf b/docker/nginx/conf.d/client.conf index 451aedc6..90c6c668 100644 --- a/docker/nginx/conf.d/client.conf +++ b/docker/nginx/conf.d/client.conf @@ -57,6 +57,7 @@ server { rewrite ^/portals /skynet/portals permanent; rewrite ^/stats /skynet/stats permanent; rewrite ^/skynet/blacklist /skynet/blocklist permanent; + rewrite ^/secure/(.*) https://secure.$domain.$tld/$1 permanent; location / { # This is only safe workaround to reroute based on some conditions @@ -290,6 +291,16 @@ server { # proxy this call to siad endpoint (make sure the ip is correct) proxy_pass http://siad/skynet/skyfile/$dir1/$dir2/$dir3/$dir4$is_args$args; + + # register the upload in accounts service (cookies should contain jwt) + log_by_lua_block { + 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"] } + http.request { url = "http://accounts:3000/track/upload/" .. skylink, method = "POST", headers = headers } + end + } } location ~ "^/(([a-zA-Z0-9-_]{46}|[a-z0-9]{55})(/.*)?)$" { @@ -310,6 +321,16 @@ server { # decoded whitespaces and set will re-encode it for us before passing it to proxy_pass set $skylink $1; + # register the download in accounts service (cookies should contain jwt) + log_by_lua_block { + local skylink = ngx.var[2] + 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"] } + http.request { url = "http://accounts:3000/track/download/" .. skylink, method = "POST", headers = headers } + 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) @@ -347,16 +368,6 @@ server { proxy_pass http://127.0.0.1/$uri?attachment=true&$args; } - location /secure { - rewrite /secure/(.*) /$1 break; - proxy_pass http://oathkeeper:4455; - } - - #location /secure/self-service { - # rewrite /secure/self-service/(.*) /$1 break; - # proxy_pass http://oathkeeper:4455; - #} - # include custom locations, specific to the server include /etc/nginx/conf.d/server-override/*; } diff --git a/docker/nginx/conf.d/secure.conf b/docker/nginx/conf.d/secure.conf new file mode 100644 index 00000000..d8e996ef --- /dev/null +++ b/docker/nginx/conf.d/secure.conf @@ -0,0 +1,33 @@ +server { + listen 80; + listen [::]:80; + server_name secure.*; + + location / { + proxy_redirect http://127.0.0.1/ https://$host/; + proxy_pass http://oathkeeper:4455; + } + + location /.ory/kratos/public/self-service/login/methods/password { + proxy_redirect http://127.0.0.1/ https://$host/; + proxy_pass http://oathkeeper:4455; + + header_filter_by_lua_block { + if ngx.status >= ngx.HTTP_OK and ngx.status < ngx.HTTP_BAD_REQUEST then + local http = require("socket.http") + local sessionCookie = "" + local responseCookies = {} + for k, cookie in ipairs(ngx.header["set-cookie"]) do + local sessionCookieMatch = string.match(cookie, "(ory_kratos_session=[^;]+);") + if sessionCookieMatch then sessionCookie = sessionCookieMatch end + table.insert(responseCookies, cookie) + end + local ok, status, headers = http.request { url = "http://oathkeeper:4455/user", headers = { Cookie = sessionCookie } } + if headers["set-cookie"] then + table.insert(responseCookies, headers["set-cookie"]) + ngx.header["set-cookie"] = responseCookies + end + end + } + } +} diff --git a/packages/webapp/package.json b/packages/webapp/package.json index cc07b31d..624c28c5 100644 --- a/packages/webapp/package.json +++ b/packages/webapp/package.json @@ -20,6 +20,7 @@ "gatsby-source-filesystem": "2.4.0", "gatsby-transformer-sharp": "2.5.21", "http-status-codes": "2.1.4", + "js-cookie": "^2.2.1", "jsonp": "0.2.1", "node-sass": "4.14.1", "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..ba62c1eb 100644 --- a/packages/webapp/src/components/HomeTop/HomeTop.js +++ b/packages/webapp/src/components/HomeTop/HomeTop.js @@ -15,6 +15,16 @@ export default function HomeTop() { The decentralized CDN and file sharing platform for devs. Skynet is the storage foundation for a Free Internet!

+

+ + 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..d3859c29 100644 --- a/packages/webapp/src/components/HomeTop/HomeTop.scss +++ b/packages/webapp/src/components/HomeTop/HomeTop.scss @@ -36,10 +36,18 @@ max-width: 560px; margin: 0 auto; + &.auth-links { + font-size: 18px; + } + @media (min-width: $largebp) { font-size: 24px; max-width: 670px; } + + & + p { + margin-top: 24px; + } } } diff --git a/yarn.lock b/yarn.lock index 460bd1c2..1237c922 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8647,6 +8647,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" @@ -8795,6 +8800,11 @@ junk@^3.1.0: resolved "https://registry.yarnpkg.com/junk/-/junk-3.1.0.tgz#31499098d902b7e98c5d9b9c80f43457a88abfa1" integrity sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ== +jwt-decode@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-3.1.2.tgz#3fb319f3675a2df0c2895c8f5e9fa4b67b04ed59" + integrity sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A== + keyv@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373"