From 6189ec161717b923da43558a45a04770dd1ae85d Mon Sep 17 00:00:00 2001 From: Karol Wypchlo Date: Wed, 9 Mar 2022 14:27:27 +0100 Subject: [PATCH 01/14] improve user communication on subscription required portal --- docker/nginx/libs/skynet/account.lua | 3 +- .../src/components/Uploader/Uploader.js | 48 ++++++++++++++++--- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/docker/nginx/libs/skynet/account.lua b/docker/nginx/libs/skynet/account.lua index 7be6013f..e7ff9033 100644 --- a/docker/nginx/libs/skynet/account.lua +++ b/docker/nginx/libs/skynet/account.lua @@ -78,7 +78,8 @@ function _M.has_subscription() end function _M.is_auth_required() - return os.getenv("ACCOUNTS_LIMIT_ACCESS") == "authenticated" + -- authentication is required if mode is set to "authenticated" or "subscription" + return os.getenv("ACCOUNTS_LIMIT_ACCESS") == "authenticated" or _M.is_subscription_required() end function _M.is_subscription_required() diff --git a/packages/website/src/components/Uploader/Uploader.js b/packages/website/src/components/Uploader/Uploader.js index 40ecb19a..5a48a811 100644 --- a/packages/website/src/components/Uploader/Uploader.js +++ b/packages/website/src/components/Uploader/Uploader.js @@ -47,15 +47,37 @@ const LogInLink = () => { ); }; +const SubscribeLink = () => { + const createAccountsUrl = useAccountsUrl(); + + return ( + + available plans + + ); +}; + const Uploader = () => { const [mode, setMode] = React.useState("file"); const [uploads, setUploads] = React.useState([]); const { data: accounts } = useAccounts(); - const showAccountFeatures = - accounts && accounts.enabled !== false && !accounts?.auth_required && !accounts?.authenticated; - const disabledComponent = - accounts && accounts.enabled !== false && accounts?.auth_required && !accounts?.authenticated; + + // variables extracted from useAccounts response + const isAccountsEnabled = accounts?.enabled === true; + const isSubscriptionRequired = accounts?.subscription_required === true; + const isAuthRequired = isSubscriptionRequired || accounts?.auth_required === true; + const isAuthenticated = accounts?.authenticated === true; + const hasSubscription = accounts?.subscription === true; + + // derive current app state and extract it into variables + const showAccountFeatures = isAccountsEnabled && !isAuthRequired && !isAuthenticated; + const showAuthenticationRequired = isAccountsEnabled && isAuthRequired && !isAuthenticated; + const showSubscriptionRequired = isAccountsEnabled && isAuthenticated && isSubscriptionRequired && !hasSubscription; + const isComponentDisabled = showAuthenticationRequired || showSubscriptionRequired; const onUploadStateChange = React.useCallback((id, state) => { setUploads((uploads) => { @@ -104,7 +126,7 @@ const Uploader = () => { }, [inputElement, mode]); return ( -
+
- {!disabledComponent && ( + {!isComponentDisabled && (
@@ -204,7 +226,7 @@ const Uploader = () => {
)} - {disabledComponent && ( + {showAuthenticationRequired && (
@@ -215,6 +237,18 @@ const Uploader = () => {
)} + + {showSubscriptionRequired && ( +
+
+
+

+ Active subscription required - +

+
+
+
+ )}
); }; From 2db648b0adeea9e2c101e985fd7645f260fff859 Mon Sep 17 00:00:00 2001 From: Ivaylo Novakov Date: Thu, 10 Mar 2022 18:11:37 +0100 Subject: [PATCH 02/14] Nginx passes Skynet-Api-Key and Authorization headers at all spots where it passes the Cookie header. --- docker/nginx/conf.d/include/track-download | 6 +++++- docker/nginx/conf.d/include/track-registry | 10 +++++++--- docker/nginx/conf.d/include/track-upload | 6 +++++- docker/nginx/conf.d/server/server.api | 10 +++++++--- docker/nginx/libs/skynet/account.lua | 10 +++++++--- 5 files changed, 31 insertions(+), 11 deletions(-) diff --git a/docker/nginx/conf.d/include/track-download b/docker/nginx/conf.d/include/track-download index 606c98ad..0bd74dad 100644 --- a/docker/nginx/conf.d/include/track-download +++ b/docker/nginx/conf.d/include/track-download @@ -11,7 +11,11 @@ log_by_lua_block { -- 10.10.10.70 points to accounts service (alias not available when using resty-http) local res, err = httpc:request_uri("http://10.10.10.70:3000/track/download/" .. skylink .. "?" .. query, { method = "POST", - headers = { ["Cookie"] = "skynet-jwt=" .. jwt }, + headers = { + ["Cookie"] = "skynet-jwt=" .. jwt, + ["Authorization"] = ngx.header["Authorization"], + ["Skynet-Api-Key"] = ngx.header["Skynet-Api-Key"], + }, }) if err or (res and res.status ~= ngx.HTTP_NO_CONTENT) then diff --git a/docker/nginx/conf.d/include/track-registry b/docker/nginx/conf.d/include/track-registry index 8c69172b..ac981466 100644 --- a/docker/nginx/conf.d/include/track-registry +++ b/docker/nginx/conf.d/include/track-registry @@ -7,16 +7,20 @@ log_by_lua_block { local httpc = require("resty.http").new() - -- based on request method we assign a registry action string used + -- based on request method we assign a registry action string used -- in track endpoint namely "read" for GET and "write" for POST local registry_action = request_method == "GET" and "read" or "write" -- 10.10.10.70 points to accounts service (alias not available when using resty-http) local res, err = httpc:request_uri("http://10.10.10.70:3000/track/registry/" .. registry_action, { method = "POST", - headers = { ["Cookie"] = "skynet-jwt=" .. jwt }, + headers = { + ["Cookie"] = "skynet-jwt=" .. jwt, + ["Authorization"] = ngx.header["Authorization"], + ["Skynet-Api-Key"] = ngx.header["Skynet-Api-Key"], + }, }) - + if err or (res and res.status ~= ngx.HTTP_NO_CONTENT) then ngx.log(ngx.ERR, "Failed accounts service request /track/registry/" .. registry_action .. ": ", err or ("[HTTP " .. res.status .. "] " .. res.body)) end diff --git a/docker/nginx/conf.d/include/track-upload b/docker/nginx/conf.d/include/track-upload index 340dd437..53795d55 100644 --- a/docker/nginx/conf.d/include/track-upload +++ b/docker/nginx/conf.d/include/track-upload @@ -10,7 +10,11 @@ log_by_lua_block { -- 10.10.10.70 points to accounts service (alias not available when using resty-http) local res, err = httpc:request_uri("http://10.10.10.70:3000/track/upload/" .. skylink, { method = "POST", - headers = { ["Cookie"] = "skynet-jwt=" .. jwt }, + headers = { + ["Cookie"] = "skynet-jwt=" .. jwt, + ["Authorization"] = ngx.header["Authorization"], + ["Skynet-Api-Key"] = ngx.header["Skynet-Api-Key"], + }, }) if err or (res and res.status ~= ngx.HTTP_NO_CONTENT) then diff --git a/docker/nginx/conf.d/server/server.api b/docker/nginx/conf.d/server/server.api index ce93c669..fc6f7034 100644 --- a/docker/nginx/conf.d/server/server.api +++ b/docker/nginx/conf.d/server/server.api @@ -178,7 +178,11 @@ location /skynet/registry/subscription { -- fetch account limits and set download bandwidth and registry delays accordingly local res, err = httpc:request_uri("http://10.10.10.70:3000/user/limits", { - headers = { ["Cookie"] = "skynet-jwt=" .. ngx.var.skynet_jwt } + headers = { + ["Cookie"] = "skynet-jwt=" .. ngx.var.skynet_jwt, + ["Authorization"] = ngx.header["Authorization"], + ["Skynet-Api-Key"] = ngx.header["Skynet-Api-Key"], + } }) -- fail gracefully in case /user/limits failed @@ -267,10 +271,10 @@ location /skynet/tus { if require("skynet.account").is_access_forbidden() then return require("skynet.account").exit_access_forbidden() end - + -- get account limits of currently authenticated user local limits = require("skynet.account").get_account_limits() - + -- apply upload size limits ngx.req.set_header("SkynetMaxUploadSize", limits.maxUploadSize) end diff --git a/docker/nginx/libs/skynet/account.lua b/docker/nginx/libs/skynet/account.lua index 7be6013f..5319f665 100644 --- a/docker/nginx/libs/skynet/account.lua +++ b/docker/nginx/libs/skynet/account.lua @@ -43,12 +43,16 @@ function _M.get_account_limits() if ngx.var.account_limits == "" then local httpc = require("resty.http").new() - + -- 10.10.10.70 points to accounts service (alias not available when using resty-http) local res, err = httpc:request_uri("http://10.10.10.70:3000/user/limits", { - headers = { ["Cookie"] = "skynet-jwt=" .. ngx.var.skynet_jwt } + headers = { + ["Cookie"] = "skynet-jwt=" .. ngx.var.skynet_jwt, + ["Authorization"] = ngx.header["Authorization"], + ["Skynet-Api-Key"] = ngx.header["Skynet-Api-Key"], + } }) - + -- fail gracefully in case /user/limits failed if err or (res and res.status ~= ngx.HTTP_OK) then ngx.log(ngx.ERR, "Failed accounts service request /user/limits: ", err or ("[HTTP " .. res.status .. "] " .. res.body)) From d631aad058000f2beefffbdd69d95fbb7ef8c9c2 Mon Sep 17 00:00:00 2001 From: Karol Wypchlo Date: Tue, 15 Mar 2022 22:43:35 +0100 Subject: [PATCH 03/14] move req headers to timer arguments --- docker/nginx/conf.d/include/track-download | 18 +++--- docker/nginx/conf.d/include/track-registry | 18 +++--- docker/nginx/conf.d/include/track-upload | 18 +++--- docker/nginx/conf.d/server/server.api | 65 +++++++++++----------- docker/nginx/libs/skynet/account.lua | 43 ++++++++++++-- 5 files changed, 94 insertions(+), 68 deletions(-) diff --git a/docker/nginx/conf.d/include/track-download b/docker/nginx/conf.d/include/track-download index 0bd74dad..7c637fe3 100644 --- a/docker/nginx/conf.d/include/track-download +++ b/docker/nginx/conf.d/include/track-download @@ -1,8 +1,10 @@ # register the download in accounts service (cookies should contain jwt) log_by_lua_block { - -- this block runs only when accounts are enabled - if require("skynet.account").accounts_enabled() then - local function track(premature, skylink, status, body_bytes_sent, jwt) + local skynet_account = require("skynet.account") + + -- tracking runs only when request comes from authenticated user + if skynet_account.is_authenticated() then + local function track(premature, skylink, status, body_bytes_sent, auth_headers) if premature then return end local httpc = require("resty.http").new() @@ -11,11 +13,7 @@ log_by_lua_block { -- 10.10.10.70 points to accounts service (alias not available when using resty-http) local res, err = httpc:request_uri("http://10.10.10.70:3000/track/download/" .. skylink .. "?" .. query, { method = "POST", - headers = { - ["Cookie"] = "skynet-jwt=" .. jwt, - ["Authorization"] = ngx.header["Authorization"], - ["Skynet-Api-Key"] = ngx.header["Skynet-Api-Key"], - }, + headers = auth_headers, }) if err or (res and res.status ~= ngx.HTTP_NO_CONTENT) then @@ -23,8 +21,8 @@ log_by_lua_block { end end - if ngx.header["Skynet-Skylink"] and ngx.var.skynet_jwt ~= "" and ngx.status >= ngx.HTTP_OK and ngx.status < ngx.HTTP_SPECIAL_RESPONSE then - local ok, err = ngx.timer.at(0, track, ngx.header["Skynet-Skylink"], ngx.status, ngx.var.body_bytes_sent, ngx.var.skynet_jwt) + if ngx.header["Skynet-Skylink"] and ngx.status >= ngx.HTTP_OK and ngx.status < ngx.HTTP_SPECIAL_RESPONSE then + local ok, err = ngx.timer.at(0, track, ngx.header["Skynet-Skylink"], ngx.status, ngx.var.body_bytes_sent, skynet_account.get_auth_headers()) if err then ngx.log(ngx.ERR, "Failed to create timer: ", err) end end end diff --git a/docker/nginx/conf.d/include/track-registry b/docker/nginx/conf.d/include/track-registry index ac981466..0344b6c6 100644 --- a/docker/nginx/conf.d/include/track-registry +++ b/docker/nginx/conf.d/include/track-registry @@ -1,8 +1,10 @@ # register the registry access in accounts service (cookies should contain jwt) log_by_lua_block { - -- this block runs only when accounts are enabled - if require("skynet.account").accounts_enabled() then - local function track(premature, request_method, jwt) + local skynet_account = require("skynet.account") + + -- tracking runs only when request comes from authenticated user + if skynet_account.is_authenticated() then + local function track(premature, request_method, auth_headers) if premature then return end local httpc = require("resty.http").new() @@ -14,11 +16,7 @@ log_by_lua_block { -- 10.10.10.70 points to accounts service (alias not available when using resty-http) local res, err = httpc:request_uri("http://10.10.10.70:3000/track/registry/" .. registry_action, { method = "POST", - headers = { - ["Cookie"] = "skynet-jwt=" .. jwt, - ["Authorization"] = ngx.header["Authorization"], - ["Skynet-Api-Key"] = ngx.header["Skynet-Api-Key"], - }, + headers = auth_headers, }) if err or (res and res.status ~= ngx.HTTP_NO_CONTENT) then @@ -26,8 +24,8 @@ log_by_lua_block { end end - if ngx.var.skynet_jwt ~= "" and (ngx.status == ngx.HTTP_OK or ngx.status == ngx.HTTP_NOT_FOUND) then - local ok, err = ngx.timer.at(0, track, ngx.req.get_method(), ngx.var.skynet_jwt) + if ngx.status == ngx.HTTP_OK or ngx.status == ngx.HTTP_NOT_FOUND then + local ok, err = ngx.timer.at(0, track, ngx.req.get_method(), skynet_account.get_auth_headers()) if err then ngx.log(ngx.ERR, "Failed to create timer: ", err) end end end diff --git a/docker/nginx/conf.d/include/track-upload b/docker/nginx/conf.d/include/track-upload index 53795d55..21df6d83 100644 --- a/docker/nginx/conf.d/include/track-upload +++ b/docker/nginx/conf.d/include/track-upload @@ -1,8 +1,10 @@ # register the upload in accounts service (cookies should contain jwt) log_by_lua_block { - -- this block runs only when accounts are enabled - if require("skynet.account").accounts_enabled() then - local function track(premature, skylink, jwt) + local skynet_account = require("skynet.account") + + -- tracking runs only when request comes from authenticated user + if skynet_account.is_authenticated() then + local function track(premature, skylink, auth_headers) if premature then return end local httpc = require("resty.http").new() @@ -10,11 +12,7 @@ log_by_lua_block { -- 10.10.10.70 points to accounts service (alias not available when using resty-http) local res, err = httpc:request_uri("http://10.10.10.70:3000/track/upload/" .. skylink, { method = "POST", - headers = { - ["Cookie"] = "skynet-jwt=" .. jwt, - ["Authorization"] = ngx.header["Authorization"], - ["Skynet-Api-Key"] = ngx.header["Skynet-Api-Key"], - }, + headers = auth_headers, }) if err or (res and res.status ~= ngx.HTTP_NO_CONTENT) then @@ -23,8 +21,8 @@ log_by_lua_block { end -- report all skylinks (header empty if request failed) but only if jwt is preset (user is authenticated) - if ngx.header["Skynet-Skylink"] and ngx.var.skynet_jwt ~= "" then - local ok, err = ngx.timer.at(0, track, ngx.header["Skynet-Skylink"], ngx.var.skynet_jwt) + if ngx.header["Skynet-Skylink"] then + local ok, err = ngx.timer.at(0, track, ngx.header["Skynet-Skylink"], skynet_account.get_auth_headers()) if err then ngx.log(ngx.ERR, "Failed to create timer: ", err) end end end diff --git a/docker/nginx/conf.d/server/server.api b/docker/nginx/conf.d/server/server.api index fc6f7034..24e8509d 100644 --- a/docker/nginx/conf.d/server/server.api +++ b/docker/nginx/conf.d/server/server.api @@ -172,28 +172,25 @@ location /skynet/registry/subscription { set $notificationdelay "0"; rewrite_by_lua_block { - -- this block runs only when accounts are enabled - if os.getenv("PORTAL_MODULES"):match("a") then - local httpc = require("resty.http").new() + local skynet_account = require("skynet.account") - -- fetch account limits and set download bandwidth and registry delays accordingly - local res, err = httpc:request_uri("http://10.10.10.70:3000/user/limits", { - headers = { - ["Cookie"] = "skynet-jwt=" .. ngx.var.skynet_jwt, - ["Authorization"] = ngx.header["Authorization"], - ["Skynet-Api-Key"] = ngx.header["Skynet-Api-Key"], - } - }) - - -- fail gracefully in case /user/limits failed - if err or (res and res.status ~= ngx.HTTP_OK) then - ngx.log(ngx.ERR, "Failed accounts service request /user/limits: ", err or ("[HTTP " .. res.status .. "] " .. res.body)) - elseif res and res.status == ngx.HTTP_OK then - local json = require('cjson') - local limits = json.decode(res.body) - ngx.var.bandwidthlimit = limits.download - ngx.var.notificationdelay = limits.registry + if skynet_account.accounts_enabled() then + -- check if portal is in authenticated only mode + if skynet_account.is_access_unauthorized() then + return skynet_account.exit_access_unauthorized() end + + -- check if portal is in subscription only mode + if skynet_account.is_access_forbidden() then + return skynet_account.exit_access_forbidden() + end + + -- get account limits of currently authenticated user + local limits = skynet_account.get_account_limits() + + -- apply bandwidth limit and notification delay + ngx.var.bandwidthlimit = limits.download + ngx.var.notificationdelay = limits.registry end } @@ -261,19 +258,21 @@ location /skynet/tus { proxy_pass http://sia:9980; access_by_lua_block { - if require("skynet.account").accounts_enabled() then + local skynet_account = require("skynet.account") + + if skynet_account.accounts_enabled() then -- check if portal is in authenticated only mode - if require("skynet.account").is_access_unauthorized() then - return require("skynet.account").exit_access_unauthorized() + if skynet_account.is_access_unauthorized() then + return skynet_account.exit_access_unauthorized() end -- check if portal is in subscription only mode - if require("skynet.account").is_access_forbidden() then - return require("skynet.account").exit_access_forbidden() + if skynet_account.is_access_forbidden() then + return skynet_account.exit_access_forbidden() end -- get account limits of currently authenticated user - local limits = require("skynet.account").get_account_limits() + local limits = skynet_account.get_account_limits() -- apply upload size limits ngx.req.set_header("SkynetMaxUploadSize", limits.maxUploadSize) @@ -365,19 +364,21 @@ location /skynet/trustless/basesector { set $limit_rate 0; access_by_lua_block { - if require("skynet.account").accounts_enabled() then + local skynet_account = require("skynet.account") + + if skynet_account.accounts_enabled() then -- check if portal is in authenticated only mode - if require("skynet.account").is_access_unauthorized() then - return require("skynet.account").exit_access_unauthorized() + if skynet_account.is_access_unauthorized() then + return skynet_account.exit_access_unauthorized() end -- check if portal is in subscription only mode - if require("skynet.account").is_access_forbidden() then - return require("skynet.account").exit_access_forbidden() + if skynet_account.is_access_forbidden() then + return skynet_account.exit_access_forbidden() end -- get account limits of currently authenticated user - local limits = require("skynet.account").get_account_limits() + local limits = skynet_account.get_account_limits() -- apply download speed limit ngx.var.limit_rate = limits.download diff --git a/docker/nginx/libs/skynet/account.lua b/docker/nginx/libs/skynet/account.lua index 5319f665..72a2c9ea 100644 --- a/docker/nginx/libs/skynet/account.lua +++ b/docker/nginx/libs/skynet/account.lua @@ -14,6 +14,39 @@ local anon_limits = { ["registry"] = 250 } +-- utility function for checking if table is empty +function is_table_empty(check) + -- bind next to local variable to achieve ultimate efficiency + -- https://stackoverflow.com/a/1252776 + local next = next + + return next(check) == nil +end + +-- get all non empty authentication headers from request, we want to return +-- all of them and let accounts service deal with validation and prioritisation +function _M.get_auth_headers() + local request_headers = ngx.req.get_headers() + local headers = {} + + -- if skynet_jwt is set, include it as a cookie + if ngx.var.skynet_jwt ~= "" then + headers["Cookie"] = "skynet-jwt=" .. ngx.var.skynet_jwt + end + + -- if authorization header is set, pass it as is + if request_headers["Authorization"] then + headers["Authorization"] = request_headers["Authorization"] + end + + -- if skynet api key header is set, pass it as is + if request_headers["Skynet-Api-Key"] then + headers["Skynet-Api-Key"] = request_headers["Skynet-Api-Key"] + end + + return headers +end + -- handle request exit when access to portal should be restricted to authenticated users only function _M.exit_access_unauthorized(message) ngx.status = ngx.HTTP_UNAUTHORIZED @@ -36,8 +69,10 @@ end function _M.get_account_limits() local cjson = require('cjson') + local auth_headers = _M.get_auth_headers() - if ngx.var.skynet_jwt == "" then + -- simple case of anonymous request - none of available auth headers exist + if is_table_empty(auth_headers) then return anon_limits end @@ -46,11 +81,7 @@ function _M.get_account_limits() -- 10.10.10.70 points to accounts service (alias not available when using resty-http) local res, err = httpc:request_uri("http://10.10.10.70:3000/user/limits", { - headers = { - ["Cookie"] = "skynet-jwt=" .. ngx.var.skynet_jwt, - ["Authorization"] = ngx.header["Authorization"], - ["Skynet-Api-Key"] = ngx.header["Skynet-Api-Key"], - } + headers = auth_headers, }) -- fail gracefully in case /user/limits failed From e8345a3be6cc6bf8054a7e9118056c00b436cc9c Mon Sep 17 00:00:00 2001 From: Karol Wypchlo Date: Tue, 15 Mar 2022 22:53:31 +0100 Subject: [PATCH 04/14] extract is_table_empty to separate utils lib --- docker/nginx/libs/skynet/account.lua | 12 ++---------- docker/nginx/libs/utils.lua | 12 ++++++++++++ docker/nginx/libs/utils.spec.lua | 11 +++++++++++ 3 files changed, 25 insertions(+), 10 deletions(-) create mode 100644 docker/nginx/libs/utils.lua create mode 100644 docker/nginx/libs/utils.spec.lua diff --git a/docker/nginx/libs/skynet/account.lua b/docker/nginx/libs/skynet/account.lua index 72a2c9ea..aa8b4414 100644 --- a/docker/nginx/libs/skynet/account.lua +++ b/docker/nginx/libs/skynet/account.lua @@ -14,15 +14,6 @@ local anon_limits = { ["registry"] = 250 } --- utility function for checking if table is empty -function is_table_empty(check) - -- bind next to local variable to achieve ultimate efficiency - -- https://stackoverflow.com/a/1252776 - local next = next - - return next(check) == nil -end - -- get all non empty authentication headers from request, we want to return -- all of them and let accounts service deal with validation and prioritisation function _M.get_auth_headers() @@ -69,10 +60,11 @@ end function _M.get_account_limits() local cjson = require('cjson') + local utils = require('utils') local auth_headers = _M.get_auth_headers() -- simple case of anonymous request - none of available auth headers exist - if is_table_empty(auth_headers) then + if utils.is_table_empty(auth_headers) then return anon_limits end diff --git a/docker/nginx/libs/utils.lua b/docker/nginx/libs/utils.lua new file mode 100644 index 00000000..b05d0861 --- /dev/null +++ b/docker/nginx/libs/utils.lua @@ -0,0 +1,12 @@ +local _M = {} + +-- utility function for checking if table is empty +function is_table_empty(check) + -- bind next to local variable to achieve ultimate efficiency + -- https://stackoverflow.com/a/1252776 + local next = next + + return next(check) == nil +end + +return _M \ No newline at end of file diff --git a/docker/nginx/libs/utils.spec.lua b/docker/nginx/libs/utils.spec.lua new file mode 100644 index 00000000..970b279f --- /dev/null +++ b/docker/nginx/libs/utils.spec.lua @@ -0,0 +1,11 @@ +local utils = require('utils') + +describe("is_table_empty", function() + it("should return true for empty table", function() + assert.is_true(utils.is_table_empty({})) + end) + + it("should return false for not empty table", function() + assert.is_false(utils.is_table_empty({ ["foo"] = "bar" })) + end) +end) \ No newline at end of file From 8623f53d9dd50a11e239159950856b9287c1a2da Mon Sep 17 00:00:00 2001 From: Karol Wypchlo Date: Tue, 15 Mar 2022 22:56:24 +0100 Subject: [PATCH 05/14] export is_table_empty from utils module --- docker/nginx/libs/utils.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/nginx/libs/utils.lua b/docker/nginx/libs/utils.lua index b05d0861..b58c2711 100644 --- a/docker/nginx/libs/utils.lua +++ b/docker/nginx/libs/utils.lua @@ -1,7 +1,7 @@ local _M = {} -- utility function for checking if table is empty -function is_table_empty(check) +function _M.is_table_empty(check) -- bind next to local variable to achieve ultimate efficiency -- https://stackoverflow.com/a/1252776 local next = next From 18228144417a458d02cf798a86e263ff44ac9d86 Mon Sep 17 00:00:00 2001 From: Karol Wypchlo Date: Fri, 18 Mar 2022 16:45:01 +0100 Subject: [PATCH 06/14] do not use PORTAL_DOMAIN for api requests --- packages/dashboard/src/services/accountsApi.js | 4 +--- packages/dashboard/src/services/useAccountsApi.js | 4 +--- packages/dashboard/src/services/useAnonRoute.js | 4 +--- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/packages/dashboard/src/services/accountsApi.js b/packages/dashboard/src/services/accountsApi.js index e09626b1..37244e5f 100644 --- a/packages/dashboard/src/services/accountsApi.js +++ b/packages/dashboard/src/services/accountsApi.js @@ -1,5 +1,3 @@ import ky from "ky"; -const prefix = process.env.NEXT_PUBLIC_PORTAL_DOMAIN ? `https://account.${process.env.NEXT_PUBLIC_PORTAL_DOMAIN}` : ""; - -export default ky.create({ prefixUrl: `${prefix}/api` }); +export default ky.create({ prefixUrl: "/api" }); diff --git a/packages/dashboard/src/services/useAccountsApi.js b/packages/dashboard/src/services/useAccountsApi.js index 4d522764..b98d8b92 100644 --- a/packages/dashboard/src/services/useAccountsApi.js +++ b/packages/dashboard/src/services/useAccountsApi.js @@ -2,8 +2,6 @@ import useSWR from "swr"; import { useRouter } from "next/router"; import { StatusCodes } from "http-status-codes"; -const prefix = process.env.NEXT_PUBLIC_PORTAL_DOMAIN ? `https://account.${process.env.NEXT_PUBLIC_PORTAL_DOMAIN}` : ""; - const fetcher = (url, router) => { return fetch(url).then((res) => { if (res.status === StatusCodes.UNAUTHORIZED) { @@ -17,5 +15,5 @@ const fetcher = (url, router) => { export default function useAccountsApi(key, config) { const router = useRouter(); - return useSWR(`${prefix}/api/${key}`, (url) => fetcher(url, router), config); + return useSWR(`/api/${key}`, (url) => fetcher(url, router), config); } diff --git a/packages/dashboard/src/services/useAnonRoute.js b/packages/dashboard/src/services/useAnonRoute.js index b516011d..5bb65338 100644 --- a/packages/dashboard/src/services/useAnonRoute.js +++ b/packages/dashboard/src/services/useAnonRoute.js @@ -2,8 +2,6 @@ import useSWR from "swr"; import { useRouter } from "next/router"; import { StatusCodes } from "http-status-codes"; -const prefix = process.env.NEXT_PUBLIC_PORTAL_DOMAIN ? `https://account.${process.env.NEXT_PUBLIC_PORTAL_DOMAIN}` : ""; - const fetcher = (url, router) => { return fetch(url).then((res) => { if (res.status === StatusCodes.OK) router.push("/"); @@ -13,5 +11,5 @@ const fetcher = (url, router) => { export default function useAnonRoute() { const router = useRouter(); - return useSWR(`${prefix}/api/user`, (url) => fetcher(url, router)); + return useSWR("/api/user", (url) => fetcher(url, router)); } From 27bfac680104cad6386bd1cc904fe249170f2a83 Mon Sep 17 00:00:00 2001 From: Karol Wypchlo Date: Mon, 21 Mar 2022 13:18:20 +0100 Subject: [PATCH 07/14] add empty lines --- docker/nginx/libs/utils.lua | 2 +- docker/nginx/libs/utils.spec.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/nginx/libs/utils.lua b/docker/nginx/libs/utils.lua index b58c2711..83faf09b 100644 --- a/docker/nginx/libs/utils.lua +++ b/docker/nginx/libs/utils.lua @@ -9,4 +9,4 @@ function _M.is_table_empty(check) return next(check) == nil end -return _M \ No newline at end of file +return _M diff --git a/docker/nginx/libs/utils.spec.lua b/docker/nginx/libs/utils.spec.lua index 970b279f..6299d010 100644 --- a/docker/nginx/libs/utils.spec.lua +++ b/docker/nginx/libs/utils.spec.lua @@ -8,4 +8,4 @@ describe("is_table_empty", function() it("should return false for not empty table", function() assert.is_false(utils.is_table_empty({ ["foo"] = "bar" })) end) -end) \ No newline at end of file +end) From 18822edae8bb867dafbee4cc97258ea7bde74ce8 Mon Sep 17 00:00:00 2001 From: Karol Wypchlo Date: Mon, 21 Mar 2022 13:24:25 +0100 Subject: [PATCH 08/14] clean up unnecessary boolean comparison --- packages/website/src/components/Uploader/Uploader.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/website/src/components/Uploader/Uploader.js b/packages/website/src/components/Uploader/Uploader.js index 5a48a811..7851147a 100644 --- a/packages/website/src/components/Uploader/Uploader.js +++ b/packages/website/src/components/Uploader/Uploader.js @@ -67,11 +67,11 @@ const Uploader = () => { const { data: accounts } = useAccounts(); // variables extracted from useAccounts response - const isAccountsEnabled = accounts?.enabled === true; - const isSubscriptionRequired = accounts?.subscription_required === true; - const isAuthRequired = isSubscriptionRequired || accounts?.auth_required === true; - const isAuthenticated = accounts?.authenticated === true; - const hasSubscription = accounts?.subscription === true; + const isAccountsEnabled = accounts?.enabled; + const isSubscriptionRequired = accounts?.subscription_required; + const isAuthRequired = isSubscriptionRequired || accounts?.auth_required; + const isAuthenticated = accounts?.authenticated; + const hasSubscription = accounts?.subscription; // derive current app state and extract it into variables const showAccountFeatures = isAccountsEnabled && !isAuthRequired && !isAuthenticated; From d0de18fcd0270a5bda3835048b83aba6c21310c4 Mon Sep 17 00:00:00 2001 From: Karol Wypchlo Date: Mon, 21 Mar 2022 13:29:48 +0100 Subject: [PATCH 09/14] explain subscription mode --- docker/nginx/libs/skynet/account.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker/nginx/libs/skynet/account.lua b/docker/nginx/libs/skynet/account.lua index 7f000d6e..34fe15f5 100644 --- a/docker/nginx/libs/skynet/account.lua +++ b/docker/nginx/libs/skynet/account.lua @@ -78,7 +78,8 @@ function _M.has_subscription() end function _M.is_auth_required() - -- authentication is required if mode is set to "authenticated" or "subscription" + -- authentication is required if mode is set to "authenticated" + -- or "subscription" (require active subscription to a premium plan) return os.getenv("ACCOUNTS_LIMIT_ACCESS") == "authenticated" or _M.is_subscription_required() end From b42ac0678b2c04ff33a2e1a7b7edb6874077d94f Mon Sep 17 00:00:00 2001 From: Karol Wypchlo Date: Mon, 21 Mar 2022 14:23:26 +0100 Subject: [PATCH 10/14] clean up cookie extraction --- docker/nginx/libs/skynet/account.lua | 10 ++-- docker/nginx/libs/utils.lua | 28 ++++++++++++ docker/nginx/libs/utils.spec.lua | 68 ++++++++++++++++++++++++++++ docker/nginx/nginx.conf | 7 --- 4 files changed, 103 insertions(+), 10 deletions(-) diff --git a/docker/nginx/libs/skynet/account.lua b/docker/nginx/libs/skynet/account.lua index d31ec57e..8003c60e 100644 --- a/docker/nginx/libs/skynet/account.lua +++ b/docker/nginx/libs/skynet/account.lua @@ -17,12 +17,16 @@ local anon_limits = { -- get all non empty authentication headers from request, we want to return -- all of them and let accounts service deal with validation and prioritisation function _M.get_auth_headers() + local utils = require("utils") local request_headers = ngx.req.get_headers() local headers = {} - -- if skynet_jwt is set, include it as a cookie - if ngx.var.skynet_jwt ~= "" then - headers["Cookie"] = "skynet-jwt=" .. ngx.var.skynet_jwt + -- try to extract skynet-jwt cookie from cookie header + local skynet_jwt_cookie = utils.extract_cookie(request_headers["Cookie"], "skynet[-]jwt") + + -- if skynet-jwt cookie is present, pass it as is + if skynet_jwt_cookie then + headers["Cookie"] = skynet_jwt_cookie end -- if authorization header is set, pass it as is diff --git a/docker/nginx/libs/utils.lua b/docker/nginx/libs/utils.lua index 83faf09b..6b392c99 100644 --- a/docker/nginx/libs/utils.lua +++ b/docker/nginx/libs/utils.lua @@ -9,4 +9,32 @@ function _M.is_table_empty(check) return next(check) == nil end +-- extract full cookie name and value by its name from cookie string +-- note: name matcher argument is a pattern so you will need to escape +-- any special characters, read more https://www.lua.org/pil/20.2.html +function _M.extract_cookie(cookie_string, name_matcher) + if cookie_string == nil then return nil end -- nil safeguard + + local start, stop = string.find(cookie_string, name_matcher .. "=[^;]+") + + if start then + return string.sub(cookie_string, start, stop) + end + + return nil +end + +-- extract just the cookie value by its name from cookie string +-- note: name matcher argument is a pattern so you will need to escape +-- any special characters, read more https://www.lua.org/pil/20.2.html +function _M.extract_cookie_value(cookie_string, name_matcher) + local cookie = _M.extract_cookie(cookie_string, name_matcher) + + if cookie == nil then return nil end + + local value_start = string.find(cookie, "=") + 1 + + return string.sub(cookie, value_start) +end + return _M diff --git a/docker/nginx/libs/utils.spec.lua b/docker/nginx/libs/utils.spec.lua index 6299d010..8dd68e6e 100644 --- a/docker/nginx/libs/utils.spec.lua +++ b/docker/nginx/libs/utils.spec.lua @@ -9,3 +9,71 @@ describe("is_table_empty", function() assert.is_false(utils.is_table_empty({ ["foo"] = "bar" })) end) end) + +describe("extract_cookie", function() + local cookie_string = "aaa=bbb; skynet-jwt=MTY0NzUyr8jD-ytiWtspm0tGabKfooxeIDuWcXhJ3lnY0eEw==; xxx=yyy" + + it("should return nil if cookie string is nil", function() + local cookie = utils.extract_cookie_value(nil, "aaa") + + assert.is_nil(cookie) + end) + + it("should return nil if cookie name is not found", function() + local cookie = utils.extract_cookie(cookie_string, "foo") + + assert.is_nil(cookie) + end) + + it("should return cookie if cookie_string starts with that cookie name", function() + local cookie = utils.extract_cookie(cookie_string, "aaa") + + assert.are.equals(cookie, "aaa=bbb") + end) + + it("should return cookie if cookie_string ends with that cookie name", function() + local cookie = utils.extract_cookie(cookie_string, "xxx") + + assert.are.equals(cookie, "xxx=yyy") + end) + + it("should return cookie with custom matcher", function() + local cookie = utils.extract_cookie(cookie_string, "skynet[-]jwt") + + assert.are.equals(cookie, "skynet-jwt=MTY0NzUyr8jD-ytiWtspm0tGabKfooxeIDuWcXhJ3lnY0eEw==") + end) +end) + +describe("extract_cookie_value", function() + local cookie_string = "aaa=bbb; skynet-jwt=MTY0NzUyr8jD-ytiWtspm0tGabKfooxeIDuWcXhJ3lnY0eEw==; xxx=yyy" + + it("should return nil if cookie string is nil", function() + local value = utils.extract_cookie_value(nil, "aaa") + + assert.is_nil(value) + end) + + it("should return nil if cookie name is not found", function() + local value = utils.extract_cookie_value(cookie_string, "foo") + + assert.is_nil(value) + end) + + it("should return value if cookie_string starts with that cookie name", function() + local value = utils.extract_cookie_value(cookie_string, "aaa") + + assert.are.equals(value, "bbb") + end) + + it("should return cookie if cookie_string ends with that cookie name", function() + local value = utils.extract_cookie_value(cookie_string, "xxx") + + assert.are.equals(value, "yyy") + end) + + it("should return cookie with custom matcher", function() + local value = utils.extract_cookie_value(cookie_string, "skynet[-]jwt") + + assert.are.equals(value, "MTY0NzUyr8jD-ytiWtspm0tGabKfooxeIDuWcXhJ3lnY0eEw==") + end) +end) diff --git a/docker/nginx/nginx.conf b/docker/nginx/nginx.conf index 95bb61ac..3517a6bc 100644 --- a/docker/nginx/nginx.conf +++ b/docker/nginx/nginx.conf @@ -117,13 +117,6 @@ http { proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; - # skynet-jwt contains dash so we cannot use $cookie_skynet-jwt - # https://richardhart.me/2012/03/18/logging-nginx-cookies-with-dashes/ - map $http_cookie $skynet_jwt { - default ''; - ~skynet-jwt=(?[^\;]+) $match; - } - include /etc/nginx/conf.d/*.conf; include /etc/nginx/conf.extra.d/*.conf; } From 75fad4fb9116f83246f0cc0edb52cec0cbfdf6f7 Mon Sep 17 00:00:00 2001 From: Karol Wypchlo Date: Mon, 21 Mar 2022 14:38:57 +0100 Subject: [PATCH 11/14] reformat --- docker/nginx/libs/utils.lua | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docker/nginx/libs/utils.lua b/docker/nginx/libs/utils.lua index 6b392c99..4330c94c 100644 --- a/docker/nginx/libs/utils.lua +++ b/docker/nginx/libs/utils.lua @@ -13,7 +13,10 @@ end -- note: name matcher argument is a pattern so you will need to escape -- any special characters, read more https://www.lua.org/pil/20.2.html function _M.extract_cookie(cookie_string, name_matcher) - if cookie_string == nil then return nil end -- nil safeguard + -- nil cookie string safeguard + if cookie_string == nil then + return nil + end local start, stop = string.find(cookie_string, name_matcher .. "=[^;]+") @@ -30,7 +33,9 @@ end function _M.extract_cookie_value(cookie_string, name_matcher) local cookie = _M.extract_cookie(cookie_string, name_matcher) - if cookie == nil then return nil end + if cookie == nil then + return nil + end local value_start = string.find(cookie, "=") + 1 From c19ef307d8dea5976dcdb002c83f9e45145dcb73 Mon Sep 17 00:00:00 2001 From: Karol Wypchlo Date: Mon, 21 Mar 2022 14:43:42 +0100 Subject: [PATCH 12/14] clean up code and comments --- docker/nginx/conf.d/include/track-download | 4 ++-- docker/nginx/conf.d/include/track-registry | 4 ++-- docker/nginx/conf.d/include/track-upload | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docker/nginx/conf.d/include/track-download b/docker/nginx/conf.d/include/track-download index 7c637fe3..408e4150 100644 --- a/docker/nginx/conf.d/include/track-download +++ b/docker/nginx/conf.d/include/track-download @@ -1,4 +1,3 @@ -# register the download in accounts service (cookies should contain jwt) log_by_lua_block { local skynet_account = require("skynet.account") @@ -22,7 +21,8 @@ log_by_lua_block { end if ngx.header["Skynet-Skylink"] and ngx.status >= ngx.HTTP_OK and ngx.status < ngx.HTTP_SPECIAL_RESPONSE then - local ok, err = ngx.timer.at(0, track, ngx.header["Skynet-Skylink"], ngx.status, ngx.var.body_bytes_sent, skynet_account.get_auth_headers()) + local auth_headers = skynet_account.get_auth_headers() + local ok, err = ngx.timer.at(0, track, ngx.header["Skynet-Skylink"], ngx.status, ngx.var.body_bytes_sent, auth_headers) if err then ngx.log(ngx.ERR, "Failed to create timer: ", err) end end end diff --git a/docker/nginx/conf.d/include/track-registry b/docker/nginx/conf.d/include/track-registry index 0344b6c6..8e8ae1d4 100644 --- a/docker/nginx/conf.d/include/track-registry +++ b/docker/nginx/conf.d/include/track-registry @@ -1,4 +1,3 @@ -# register the registry access in accounts service (cookies should contain jwt) log_by_lua_block { local skynet_account = require("skynet.account") @@ -25,7 +24,8 @@ log_by_lua_block { end if ngx.status == ngx.HTTP_OK or ngx.status == ngx.HTTP_NOT_FOUND then - local ok, err = ngx.timer.at(0, track, ngx.req.get_method(), skynet_account.get_auth_headers()) + local auth_headers = skynet_account.get_auth_headers() + local ok, err = ngx.timer.at(0, track, ngx.req.get_method(), auth_headers) if err then ngx.log(ngx.ERR, "Failed to create timer: ", err) end end end diff --git a/docker/nginx/conf.d/include/track-upload b/docker/nginx/conf.d/include/track-upload index 21df6d83..edca6bd7 100644 --- a/docker/nginx/conf.d/include/track-upload +++ b/docker/nginx/conf.d/include/track-upload @@ -1,4 +1,3 @@ -# register the upload in accounts service (cookies should contain jwt) log_by_lua_block { local skynet_account = require("skynet.account") @@ -22,7 +21,8 @@ log_by_lua_block { -- report all skylinks (header empty if request failed) but only if jwt is preset (user is authenticated) if ngx.header["Skynet-Skylink"] then - local ok, err = ngx.timer.at(0, track, ngx.header["Skynet-Skylink"], skynet_account.get_auth_headers()) + local auth_headers = skynet_account.get_auth_headers() + local ok, err = ngx.timer.at(0, track, ngx.header["Skynet-Skylink"], auth_headers) if err then ngx.log(ngx.ERR, "Failed to create timer: ", err) end end end From 8ebdc5d8b9c15d9cff4621f8157eecfd4d398af6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 15:15:21 +0000 Subject: [PATCH 13/14] build(deps-dev): bump autoprefixer in /packages/website Bumps [autoprefixer](https://github.com/postcss/autoprefixer) from 10.4.2 to 10.4.4. - [Release notes](https://github.com/postcss/autoprefixer/releases) - [Changelog](https://github.com/postcss/autoprefixer/blob/main/CHANGELOG.md) - [Commits](https://github.com/postcss/autoprefixer/compare/10.4.2...10.4.4) --- updated-dependencies: - dependency-name: autoprefixer dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- packages/website/package.json | 12 ++--- packages/website/yarn.lock | 89 ++++++++++++++++++----------------- 2 files changed, 53 insertions(+), 48 deletions(-) diff --git a/packages/website/package.json b/packages/website/package.json index 1414f3e9..79092f78 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -18,14 +18,14 @@ "gatsby-plugin-image": "2.9.0", "gatsby-plugin-manifest": "4.9.1", "gatsby-plugin-postcss": "5.9.0", - "gatsby-plugin-react-helmet": "5.9.0", + "gatsby-plugin-react-helmet": "5.10.0", "gatsby-plugin-robots-txt": "1.7.0", "gatsby-plugin-sharp": "4.9.1", - "gatsby-plugin-sitemap": "5.9.0", + "gatsby-plugin-sitemap": "5.10.1", "gatsby-plugin-svgr": "3.0.0-beta.0", "gatsby-source-filesystem": "4.9.1", "gatsby-transformer-sharp": "4.9.0", - "gatsby-transformer-yaml": "4.9.0", + "gatsby-transformer-yaml": "4.10.0", "gbimage-bridge": "0.2.1", "http-status-codes": "2.2.0", "ms": "2.1.3", @@ -33,7 +33,7 @@ "normalize.css": "8.0.1", "path-browserify": "1.0.1", "polished": "4.1.4", - "postcss": "8.4.8", + "postcss": "8.4.12", "prop-types": "15.8.1", "react": "17.0.2", "react-dom": "17.0.2", @@ -46,10 +46,10 @@ }, "devDependencies": { "@tailwindcss/typography": "0.5.2", - "autoprefixer": "10.4.2", + "autoprefixer": "10.4.4", "cross-env": "7.0.3", "cypress": "9.5.1", - "prettier": "2.5.1", + "prettier": "2.6.0", "tailwindcss": "3.0.23" }, "keywords": [ diff --git a/packages/website/yarn.lock b/packages/website/yarn.lock index 06bd1277..3f9b9145 100644 --- a/packages/website/yarn.lock +++ b/packages/website/yarn.lock @@ -3222,14 +3222,14 @@ attr-accept@^2.2.2: resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.2.2.tgz#646613809660110749e92f2c10833b70968d929b" integrity sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg== -autoprefixer@10.4.2, autoprefixer@^10.4.0: - version "10.4.2" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.2.tgz#25e1df09a31a9fba5c40b578936b90d35c9d4d3b" - integrity sha512-9fOPpHKuDW1w/0EKfRmVnxTDt8166MAnLI3mgZ1JCnhNtYWxcJ6Ud5CO/AVOZi/AvFa8DY9RTy3h3+tFBlrrdQ== +autoprefixer@10.4.4, autoprefixer@^10.4.0: + version "10.4.4" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.4.tgz#3e85a245b32da876a893d3ac2ea19f01e7ea5a1e" + integrity sha512-Tm8JxsB286VweiZ5F0anmbyGiNI3v3wGv3mz9W+cxEDYB/6jbnj6GM9H9mK3wIL8ftgl+C07Lcwb8PG5PCCPzA== dependencies: - browserslist "^4.19.1" - caniuse-lite "^1.0.30001297" - fraction.js "^4.1.2" + browserslist "^4.20.2" + caniuse-lite "^1.0.30001317" + fraction.js "^4.2.0" normalize-range "^0.1.2" picocolors "^1.0.0" postcss-value-parser "^4.2.0" @@ -3642,13 +3642,13 @@ browserslist@4.14.2: escalade "^3.0.2" node-releases "^1.1.61" -browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.3, browserslist@^4.16.6, browserslist@^4.17.5, browserslist@^4.19.1, browserslist@^4.6.6: - version "4.19.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.3.tgz#29b7caad327ecf2859485f696f9604214bedd383" - integrity sha512-XK3X4xtKJ+Txj8G5c30B4gsm71s69lqXlkYui4s6EkKxuv49qjYlY6oVd+IFJ73d4YymtM3+djvvt/R/iJwwDg== +browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.3, browserslist@^4.16.6, browserslist@^4.17.5, browserslist@^4.19.1, browserslist@^4.20.2, browserslist@^4.6.6: + version "4.20.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.2.tgz#567b41508757ecd904dab4d1c646c612cd3d4f88" + integrity sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA== dependencies: - caniuse-lite "^1.0.30001312" - electron-to-chromium "^1.4.71" + caniuse-lite "^1.0.30001317" + electron-to-chromium "^1.4.84" escalade "^3.1.1" node-releases "^2.0.2" picocolors "^1.0.0" @@ -3827,10 +3827,10 @@ 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.30001297, caniuse-lite@^1.0.30001312: - version "1.0.30001312" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz#e11eba4b87e24d22697dae05455d5aea28550d5f" - integrity sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001317: + version "1.0.30001319" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001319.tgz#eb4da4eb3ecdd409f7ba1907820061d56096e88f" + integrity sha512-xjlIAFHucBRSMUo1kb5D4LYgcN1M45qdKP++lhqowDpwJwGkpIRTt5qQqnhxjj1vHcI7nrJxWhCC1ATrCEBTcw== caseless@~0.12.0: version "0.12.0" @@ -5079,11 +5079,16 @@ ee-first@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.4.71: +electron-to-chromium@^1.3.564: version "1.4.75" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.75.tgz#d1ad9bb46f2f1bf432118c2be21d27ffeae82fdd" integrity sha512-LxgUNeu3BVU7sXaKjUDD9xivocQLxFtq6wgERrutdY/yIOps3ODOZExK1jg8DTEg4U8TUCb5MLGeWFOYuxjF3Q== +electron-to-chromium@^1.4.84: + version "1.4.88" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.88.tgz#ebe6a2573b563680c7a7bf3a51b9e465c9c501db" + integrity sha512-oA7mzccefkvTNi9u7DXmT0LqvhnOiN2BhSrKerta7HeUC1cLoIwtbf2wL+Ah2ozh5KQd3/1njrGrwDBXx6d14Q== + elliptic@^6.5.3: version "6.5.4" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" @@ -6065,10 +6070,10 @@ forwarded@0.2.0: resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== -fraction.js@^4.1.2: - version "4.1.3" - resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.1.3.tgz#be65b0f20762ef27e1e793860bc2dfb716e99e65" - integrity sha512-pUHWWt6vHzZZiQJcM6S/0PXfS+g6FM4BF5rj9wZyreivhQPdsh5PpE25VtSNxq80wHS5RfY51Ii+8Z0Zl/pmzg== +fraction.js@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" + integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== fragment-cache@^0.2.1: version "0.2.1" @@ -6356,10 +6361,10 @@ gatsby-plugin-postcss@5.9.0: "@babel/runtime" "^7.15.4" postcss-loader "^4.3.0" -gatsby-plugin-react-helmet@5.9.0: - version "5.9.0" - resolved "https://registry.yarnpkg.com/gatsby-plugin-react-helmet/-/gatsby-plugin-react-helmet-5.9.0.tgz#6ac992628f99451ec72d8ceeae11f456f7409366" - integrity sha512-TpPxg0Cl+zH34P9rVzKW+o6ejC6fZpvZMZ4Gs/zZ4uFswSJo6hwj/teUjB1rGAytPE+d6w9cZ2IP1gEM2RR9Ig== +gatsby-plugin-react-helmet@5.10.0: + version "5.10.0" + resolved "https://registry.yarnpkg.com/gatsby-plugin-react-helmet/-/gatsby-plugin-react-helmet-5.10.0.tgz#d6491d35d4b4e3bb36631c1a93f4e53913f42cbb" + integrity sha512-QcypYLqnwKoD84f9c6Yfajs/sLfVmxPSOPWwHaK+3NG1IjmmQrL42qn2CP6gs29WznGzrThGeGiwIVdA5x31JA== dependencies: "@babel/runtime" "^7.15.4" @@ -6396,10 +6401,10 @@ gatsby-plugin-sharp@4.9.1: svgo "1.3.2" uuid "3.4.0" -gatsby-plugin-sitemap@5.9.0: - version "5.9.0" - resolved "https://registry.yarnpkg.com/gatsby-plugin-sitemap/-/gatsby-plugin-sitemap-5.9.0.tgz#b99e58fb6c93da5991e007605b61ab553129d540" - integrity sha512-7ihuL0dy2ZenUcJvDcwyajAIf3roEwX/dyx43bOakxxo7tdcVWVuS3trQRQHfrDmLJ7i78hSYlXBLpxxZ4a+gg== +gatsby-plugin-sitemap@5.10.1: + version "5.10.1" + resolved "https://registry.yarnpkg.com/gatsby-plugin-sitemap/-/gatsby-plugin-sitemap-5.10.1.tgz#297e9434802e1d829b257ab9627ba581f48cb154" + integrity sha512-EO5GWLhkN3gfOXLX8QlbIepu2Kq1kk4bBgU5M2CjZAyVQhahZAJxdBat7JgLTpKZL4lSJgVSCl9IkeKgHvm+pg== dependencies: "@babel/runtime" "^7.15.4" common-tags "^1.8.2" @@ -6505,10 +6510,10 @@ gatsby-transformer-sharp@4.9.0: semver "^7.3.5" sharp "^0.30.1" -gatsby-transformer-yaml@4.9.0: - version "4.9.0" - resolved "https://registry.yarnpkg.com/gatsby-transformer-yaml/-/gatsby-transformer-yaml-4.9.0.tgz#644bba1f5e8a8628b8f2aa67f8f48b1b2ee1e391" - integrity sha512-nEEn/cM4ZizfUHFlGh0+j9YcfryMZGhfW1QHsX3c6mkw7ZUkpoA6rI8n2rKxfBWDbMBeCiDtIbEB+Scx57krUQ== +gatsby-transformer-yaml@4.10.0: + version "4.10.0" + resolved "https://registry.yarnpkg.com/gatsby-transformer-yaml/-/gatsby-transformer-yaml-4.10.0.tgz#cc227d30710daee7ba3034e0c567463503b99167" + integrity sha512-CSSiCo1TPi07jDbdw2Gm66Ao20kgvXHMa7YEnK94tCIZwjBpkognkUf3qHXRs6MhRTyx1gjnVQPmeAVg/1geJQ== dependencies: "@babel/runtime" "^7.15.4" js-yaml "^3.14.1" @@ -9890,10 +9895,10 @@ postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@8.4.8, postcss@^8.2.15, postcss@^8.2.9, postcss@^8.3.11, postcss@^8.4.6: - version "8.4.8" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.8.tgz#dad963a76e82c081a0657d3a2f3602ce10c2e032" - integrity sha512-2tXEqGxrjvAO6U+CJzDL2Fk2kPHTv1jQsYkSoMeOis2SsYaXRO2COxTdQp99cYvif9JTXaAk9lYGc3VhJt7JPQ== +postcss@8.4.12, postcss@^8.2.15, postcss@^8.2.9, postcss@^8.3.11, postcss@^8.4.6: + version "8.4.12" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.12.tgz#1e7de78733b28970fa4743f7da6f3763648b1905" + integrity sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg== dependencies: nanoid "^3.3.1" picocolors "^1.0.0" @@ -9935,10 +9940,10 @@ prepend-http@^2.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= -prettier@2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a" - integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg== +prettier@2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.0.tgz#12f8f504c4d8ddb76475f441337542fa799207d4" + integrity sha512-m2FgJibYrBGGgQXNzfd0PuDGShJgRavjUoRCw1mZERIWVSXF0iLzLm+aOqTAbLnC3n6JzUhAA8uZnFVghHJ86A== pretty-bytes@^5.4.1, pretty-bytes@^5.6.0: version "5.6.0" From 99dc8cbcd9c2b869f76287a0eefe2f35a1117ea3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 15:16:19 +0000 Subject: [PATCH 14/14] build(deps): bump gatsby-plugin-manifest in /packages/website Bumps [gatsby-plugin-manifest](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-manifest) from 4.9.1 to 4.10.1. - [Release notes](https://github.com/gatsbyjs/gatsby/releases) - [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-manifest/CHANGELOG.md) - [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-manifest@4.10.1/packages/gatsby-plugin-manifest) --- updated-dependencies: - dependency-name: gatsby-plugin-manifest dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- packages/website/package.json | 12 ++++---- packages/website/yarn.lock | 52 +++++++++++++++++------------------ 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/packages/website/package.json b/packages/website/package.json index 1414f3e9..c254e1a2 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -16,16 +16,16 @@ "gatsby": "4.10.1", "gatsby-background-image": "1.6.0", "gatsby-plugin-image": "2.9.0", - "gatsby-plugin-manifest": "4.9.1", + "gatsby-plugin-manifest": "4.10.1", "gatsby-plugin-postcss": "5.9.0", - "gatsby-plugin-react-helmet": "5.9.0", + "gatsby-plugin-react-helmet": "5.10.0", "gatsby-plugin-robots-txt": "1.7.0", "gatsby-plugin-sharp": "4.9.1", - "gatsby-plugin-sitemap": "5.9.0", + "gatsby-plugin-sitemap": "5.10.1", "gatsby-plugin-svgr": "3.0.0-beta.0", "gatsby-source-filesystem": "4.9.1", "gatsby-transformer-sharp": "4.9.0", - "gatsby-transformer-yaml": "4.9.0", + "gatsby-transformer-yaml": "4.10.0", "gbimage-bridge": "0.2.1", "http-status-codes": "2.2.0", "ms": "2.1.3", @@ -33,7 +33,7 @@ "normalize.css": "8.0.1", "path-browserify": "1.0.1", "polished": "4.1.4", - "postcss": "8.4.8", + "postcss": "8.4.12", "prop-types": "15.8.1", "react": "17.0.2", "react-dom": "17.0.2", @@ -49,7 +49,7 @@ "autoprefixer": "10.4.2", "cross-env": "7.0.3", "cypress": "9.5.1", - "prettier": "2.5.1", + "prettier": "2.6.0", "tailwindcss": "3.0.23" }, "keywords": [ diff --git a/packages/website/yarn.lock b/packages/website/yarn.lock index 06bd1277..2666c047 100644 --- a/packages/website/yarn.lock +++ b/packages/website/yarn.lock @@ -6320,14 +6320,14 @@ gatsby-plugin-image@2.9.0: objectFitPolyfill "^2.3.5" prop-types "^15.7.2" -gatsby-plugin-manifest@4.9.1: - version "4.9.1" - resolved "https://registry.yarnpkg.com/gatsby-plugin-manifest/-/gatsby-plugin-manifest-4.9.1.tgz#20513c7d942b424795b802506893c0f909c69b7a" - integrity sha512-Fye2vr7ioc7ETVKdCfpbc5ByU28+EB7ocqSORbazPgAT8OiPazpaBAYm98BONceuK3WaxGoEXMsmwmNBIIPjRA== +gatsby-plugin-manifest@4.10.1: + version "4.10.1" + resolved "https://registry.yarnpkg.com/gatsby-plugin-manifest/-/gatsby-plugin-manifest-4.10.1.tgz#01949125a70bac22f2d8946d5829b49f7f188ca2" + integrity sha512-D4WYQD1gDdyvWt8RYl4OC/i7thPkgtkm+kZW+d1JVpUTu+BrbdPYCIUMGdSrDyKxx3x0bhMmEf9hZW25acew0Q== dependencies: "@babel/runtime" "^7.15.4" - gatsby-core-utils "^3.9.1" - gatsby-plugin-utils "^3.3.0" + gatsby-core-utils "^3.10.0" + gatsby-plugin-utils "^3.4.1" semver "^7.3.5" sharp "^0.30.1" @@ -6356,10 +6356,10 @@ gatsby-plugin-postcss@5.9.0: "@babel/runtime" "^7.15.4" postcss-loader "^4.3.0" -gatsby-plugin-react-helmet@5.9.0: - version "5.9.0" - resolved "https://registry.yarnpkg.com/gatsby-plugin-react-helmet/-/gatsby-plugin-react-helmet-5.9.0.tgz#6ac992628f99451ec72d8ceeae11f456f7409366" - integrity sha512-TpPxg0Cl+zH34P9rVzKW+o6ejC6fZpvZMZ4Gs/zZ4uFswSJo6hwj/teUjB1rGAytPE+d6w9cZ2IP1gEM2RR9Ig== +gatsby-plugin-react-helmet@5.10.0: + version "5.10.0" + resolved "https://registry.yarnpkg.com/gatsby-plugin-react-helmet/-/gatsby-plugin-react-helmet-5.10.0.tgz#d6491d35d4b4e3bb36631c1a93f4e53913f42cbb" + integrity sha512-QcypYLqnwKoD84f9c6Yfajs/sLfVmxPSOPWwHaK+3NG1IjmmQrL42qn2CP6gs29WznGzrThGeGiwIVdA5x31JA== dependencies: "@babel/runtime" "^7.15.4" @@ -6396,10 +6396,10 @@ gatsby-plugin-sharp@4.9.1: svgo "1.3.2" uuid "3.4.0" -gatsby-plugin-sitemap@5.9.0: - version "5.9.0" - resolved "https://registry.yarnpkg.com/gatsby-plugin-sitemap/-/gatsby-plugin-sitemap-5.9.0.tgz#b99e58fb6c93da5991e007605b61ab553129d540" - integrity sha512-7ihuL0dy2ZenUcJvDcwyajAIf3roEwX/dyx43bOakxxo7tdcVWVuS3trQRQHfrDmLJ7i78hSYlXBLpxxZ4a+gg== +gatsby-plugin-sitemap@5.10.1: + version "5.10.1" + resolved "https://registry.yarnpkg.com/gatsby-plugin-sitemap/-/gatsby-plugin-sitemap-5.10.1.tgz#297e9434802e1d829b257ab9627ba581f48cb154" + integrity sha512-EO5GWLhkN3gfOXLX8QlbIepu2Kq1kk4bBgU5M2CjZAyVQhahZAJxdBat7JgLTpKZL4lSJgVSCl9IkeKgHvm+pg== dependencies: "@babel/runtime" "^7.15.4" common-tags "^1.8.2" @@ -6505,10 +6505,10 @@ gatsby-transformer-sharp@4.9.0: semver "^7.3.5" sharp "^0.30.1" -gatsby-transformer-yaml@4.9.0: - version "4.9.0" - resolved "https://registry.yarnpkg.com/gatsby-transformer-yaml/-/gatsby-transformer-yaml-4.9.0.tgz#644bba1f5e8a8628b8f2aa67f8f48b1b2ee1e391" - integrity sha512-nEEn/cM4ZizfUHFlGh0+j9YcfryMZGhfW1QHsX3c6mkw7ZUkpoA6rI8n2rKxfBWDbMBeCiDtIbEB+Scx57krUQ== +gatsby-transformer-yaml@4.10.0: + version "4.10.0" + resolved "https://registry.yarnpkg.com/gatsby-transformer-yaml/-/gatsby-transformer-yaml-4.10.0.tgz#cc227d30710daee7ba3034e0c567463503b99167" + integrity sha512-CSSiCo1TPi07jDbdw2Gm66Ao20kgvXHMa7YEnK94tCIZwjBpkognkUf3qHXRs6MhRTyx1gjnVQPmeAVg/1geJQ== dependencies: "@babel/runtime" "^7.15.4" js-yaml "^3.14.1" @@ -9890,10 +9890,10 @@ postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@8.4.8, postcss@^8.2.15, postcss@^8.2.9, postcss@^8.3.11, postcss@^8.4.6: - version "8.4.8" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.8.tgz#dad963a76e82c081a0657d3a2f3602ce10c2e032" - integrity sha512-2tXEqGxrjvAO6U+CJzDL2Fk2kPHTv1jQsYkSoMeOis2SsYaXRO2COxTdQp99cYvif9JTXaAk9lYGc3VhJt7JPQ== +postcss@8.4.12, postcss@^8.2.15, postcss@^8.2.9, postcss@^8.3.11, postcss@^8.4.6: + version "8.4.12" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.12.tgz#1e7de78733b28970fa4743f7da6f3763648b1905" + integrity sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg== dependencies: nanoid "^3.3.1" picocolors "^1.0.0" @@ -9935,10 +9935,10 @@ prepend-http@^2.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= -prettier@2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a" - integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg== +prettier@2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.0.tgz#12f8f504c4d8ddb76475f441337542fa799207d4" + integrity sha512-m2FgJibYrBGGgQXNzfd0PuDGShJgRavjUoRCw1mZERIWVSXF0iLzLm+aOqTAbLnC3n6JzUhAA8uZnFVghHJ86A== pretty-bytes@^5.4.1, pretty-bytes@^5.6.0: version "5.6.0"