diff --git a/frappe/oauth.py b/frappe/oauth.py index 122c806072..bf225ac118 100644 --- a/frappe/oauth.py +++ b/frappe/oauth.py @@ -13,7 +13,7 @@ from oauthlib.oauth2.rfc6749.endpoints.token import TokenEndpoint from oauthlib.oauth2.rfc6749.endpoints.resource import ResourceEndpoint from oauthlib.oauth2.rfc6749.endpoints.revocation import RevocationEndpoint from oauthlib.common import Request -from six.moves.urllib.parse import parse_qs, urlparse, unquote +from six.moves.urllib.parse import unquote def get_url_delimiter(separator_character=" "): return separator_character @@ -94,19 +94,13 @@ class OAuthWebRequestValidator(RequestValidator): def validate_scopes(self, client_id, scopes, client, request, *args, **kwargs): # Is the client allowed to access the requested scopes? - client_scopes = frappe.db.get_value("OAuth Client", client_id, 'scopes').split(get_url_delimiter()) - - are_scopes_valid = True - - for scp in scopes: - are_scopes_valid = are_scopes_valid and True if scp in client_scopes else False - - return are_scopes_valid + allowed_scopes = get_client_scopes(client_id) + return all(scope in allowed_scopes for scope in scopes) def get_default_scopes(self, client_id, request, *args, **kwargs): # Scopes a client will authorize for if none are supplied in the # authorization request. - scopes = frappe.db.get_value("OAuth Client", client_id, 'scopes').split(get_url_delimiter()) + scopes = get_client_scopes(client_id) request.scopes = scopes #Apparently this is possible. return scopes @@ -440,3 +434,8 @@ def delete_oauth2_data(): frappe.delete_doc("OAuth Bearer Token", token["name"]) if commit_code or commit_token: frappe.db.commit() + + +def get_client_scopes(client_id): + scopes_string = frappe.db.get_value("OAuth Client", client_id, "scopes") + return scopes_string.split() diff --git a/frappe/public/js/frappe/desk.js b/frappe/public/js/frappe/desk.js index 1b064aa0f8..97d5239a72 100644 --- a/frappe/public/js/frappe/desk.js +++ b/frappe/public/js/frappe/desk.js @@ -52,7 +52,7 @@ frappe.Application = Class.extend({ this.set_favicon(); this.setup_analytics(); this.set_fullwidth_if_enabled(); - + this.add_browser_class(); this.setup_energy_point_listeners(); frappe.ui.keys.setup(); @@ -511,6 +511,16 @@ frappe.Application = Class.extend({ } }, + add_browser_class() { + let browsers = ['Chrome', 'Firefox', 'Safari']; + for (let browser of browsers) { + if (navigator.userAgent.includes(browser)) { + $('html').addClass(browser.toLowerCase()); + return; + } + } + }, + set_fullwidth_if_enabled() { frappe.ui.toolbar.set_fullwidth_if_enabled(); }, diff --git a/frappe/public/less/desk.less b/frappe/public/less/desk.less index 36ceed9bfa..ea2c744111 100644 --- a/frappe/public/less/desk.less +++ b/frappe/public/less/desk.less @@ -847,9 +847,13 @@ input[type="checkbox"] { // Firefox doesn't support // pseudo elements on checkbox -@supports (-moz-appearance: none) or (-ms-ime-align:auto) { +html.firefox, html.safari { input[type="checkbox"] { - height: @checkbox-height !important + height: @checkbox-height !important; + + &:before { + visibility: hidden; + } } } @@ -1188,4 +1192,4 @@ body.no-sidebar { &:not(:last-child) { margin-bottom: 1em; } -} \ No newline at end of file +} diff --git a/frappe/public/less/form_grid.less b/frappe/public/less/form_grid.less index d9e7d8bceb..3c9e096444 100644 --- a/frappe/public/less/form_grid.less +++ b/frappe/public/less/form_grid.less @@ -98,7 +98,7 @@ text-align: right; } -.grid-row .grid-row-check { +html.chrome .grid-row .grid-row-check { margin-top: 12px; } diff --git a/frappe/tests/test_oauth20.py b/frappe/tests/test_oauth20.py index 941533f2ae..f4ecc8a68d 100644 --- a/frappe/tests/test_oauth20.py +++ b/frappe/tests/test_oauth20.py @@ -4,21 +4,27 @@ from __future__ import unicode_literals import unittest, frappe, requests, time from frappe.test_runner import make_test_records -from six.moves.urllib.parse import urlparse, parse_qs +from six.moves.urllib.parse import urlparse, parse_qs, urljoin +from urllib.parse import urlencode, quote class TestOAuth20(unittest.TestCase): + def setUp(self): make_test_records("OAuth Client") make_test_records("User") self.client_id = frappe.get_all("OAuth Client", fields=["*"])[0].get("client_id") + self.form_header = {"content-type": "application/x-www-form-urlencoded"} + self.scope = "all openid" + self.redirect_uri = "http://localhost" # Set Frappe server URL reqired for id_token generation try: frappe_login_key = frappe.get_doc("Social Login Key", "frappe") except frappe.DoesNotExistError: frappe_login_key = frappe.new_doc("Social Login Key") + frappe_login_key.get_social_login_provider("Frappe", initialize=True) - frappe_login_key.base_url = "http://localhost:8000" + frappe_login_key.base_url = frappe.utils.get_url() frappe_login_key.enable_social_login = 0 frappe_login_key.save() frappe.db.commit() @@ -34,38 +40,39 @@ class TestOAuth20(unittest.TestCase): frappe.db.commit() session = requests.Session() - - # Login - session.post( - frappe.get_site_config().host_name + "/api/method/login", - data={"usr":"test@example.com","pwd":"Eastern_43A1W"} - ) + login(session) redirect_destination = None # Go to Authorize url try: session.get( - frappe.get_site_config().host_name + "/api/method/frappe.integrations.oauth2.authorize?client_id=" + - self.client_id + - "&scope=all%20openid&response_type=code&redirect_uri=http%3A%2F%2Flocalhost" + get_full_url("/api/method/frappe.integrations.oauth2.authorize"), + params=encode_params({ + "client_id": self.client_id, + "scope": self.scope, + "response_type": "code", + "redirect_uri": self.redirect_uri + }) ) except requests.exceptions.ConnectionError as ex: redirect_destination = ex.request.url # Get authorization code from redirected URL - auth_code = urlparse(redirect_destination).query.split("=")[1] - - payload = "grant_type=authorization_code&code=" - payload += auth_code - payload += "&redirect_uri=http%3A%2F%2Flocalhost&client_id=" - payload += self.client_id - - headers = {'content-type':'application/x-www-form-urlencoded'} + query = parse_qs(urlparse(redirect_destination).query) + auth_code = query.get("code")[0] # Request for bearer token - token_response = requests.post( frappe.get_site_config().host_name + - "/api/method/frappe.integrations.oauth2.get_token", data=payload, headers=headers) + token_response = requests.post( + get_full_url("/api/method/frappe.integrations.oauth2.get_token"), + headers=self.form_header, + data=encode_params({ + "grant_type": "authorization_code", + "code": auth_code, + "redirect_uri": self.redirect_uri, + "client_id": self.client_id + }) + ) # Parse bearer token json bearer_token = token_response.json() @@ -86,45 +93,49 @@ class TestOAuth20(unittest.TestCase): frappe.db.commit() session = requests.Session() - - # Login - session.post( - frappe.get_site_config().host_name + "/api/method/login", - data={"usr":"test@example.com","pwd":"Eastern_43A1W"} - ) + login(session) redirect_destination = None # Go to Authorize url try: session.get( - frappe.get_site_config().host_name + "/api/method/frappe.integrations.oauth2.authorize?client_id=" + - self.client_id + - "&scope=all%20openid&response_type=code&redirect_uri=http%3A%2F%2Flocalhost" + get_full_url("/api/method/frappe.integrations.oauth2.authorize"), + params=encode_params({ + "client_id": self.client_id, + "scope": self.scope, + "response_type": "code", + "redirect_uri": self.redirect_uri + }) ) except requests.exceptions.ConnectionError as ex: redirect_destination = ex.request.url # Get authorization code from redirected URL - auth_code = urlparse(redirect_destination).query.split("=")[1] - - payload = "grant_type=authorization_code&code=" - payload += auth_code - payload += "&redirect_uri=http%3A%2F%2Flocalhost&client_id=" - payload += self.client_id - - headers = {'content-type':'application/x-www-form-urlencoded'} + query = parse_qs(urlparse(redirect_destination).query) + auth_code = query.get("code")[0] # Request for bearer token - token_response = requests.post( frappe.get_site_config().host_name + - "/api/method/frappe.integrations.oauth2.get_token", data=payload, headers=headers) + token_response = requests.post( + get_full_url("/api/method/frappe.integrations.oauth2.get_token"), + headers=self.form_header, + data=encode_params({ + "grant_type": "authorization_code", + "code": auth_code, + "redirect_uri": self.redirect_uri, + "client_id": self.client_id + }) + ) # Parse bearer token json bearer_token = token_response.json() # Revoke Token - revoke_token_response = requests.post(frappe.get_site_config().host_name + "/api/method/frappe.integrations.oauth2.revoke_token", - data="token=" + bearer_token.get("access_token"), headers=headers) + revoke_token_response = requests.post( + get_full_url("/api/method/frappe.integrations.oauth2.revoke_token"), + headers=self.form_header, + data={"token": bearer_token.get("access_token")} + ) self.assertTrue(revoke_token_response.status_code == 200) @@ -138,18 +149,18 @@ class TestOAuth20(unittest.TestCase): client.save() frappe.db.commit() - # Set payload - payload = "grant_type=password" - payload += "&username=test@example.com" - payload += "&password=Eastern_43A1W" - payload += "&client_id=" + self.client_id - payload += "&scope=openid%20all" - - headers = {'content-type':'application/x-www-form-urlencoded'} - # Request for bearer token - token_response = requests.post( frappe.get_site_config().host_name + - "/api/method/frappe.integrations.oauth2.get_token", data=payload, headers=headers) + token_response = requests.post( + get_full_url("/api/method/frappe.integrations.oauth2.get_token"), + headers=self.form_header, + data=encode_params({ + "grant_type": "password", + "username": "test@example.com", + "password": "Eastern_43A1W", + "client_id": self.client_id, + "scope": self.scope + }) + ) # Parse bearer token json bearer_token = token_response.json() @@ -158,7 +169,6 @@ class TestOAuth20(unittest.TestCase): self.assertTrue(check_valid_openid_response(bearer_token.get("access_token"))) def test_login_using_implicit_token(self): - oauth_client = frappe.get_doc("OAuth Client", self.client_id) oauth_client.grant_type = "Implicit" oauth_client.response_type = "Token" @@ -166,43 +176,69 @@ class TestOAuth20(unittest.TestCase): frappe.db.commit() session = requests.Session() - - # Login - session.post( - frappe.get_site_config().host_name + "/api/method/login", - data={"usr":"test@example.com","pwd":"Eastern_43A1W"} - ) + login(session) redirect_destination = None # Go to Authorize url try: session.get( - frappe.get_site_config().host_name + "/api/method/frappe.integrations.oauth2.authorize?client_id=" + - self.client_id + - "&scope=all%20openid&response_type=token&redirect_uri=http%3A%2F%2Flocalhost" + get_full_url("/api/method/frappe.integrations.oauth2.authorize"), + params=encode_params({ + "client_id": self.client_id, + "scope": self.scope, + "response_type": "token", + "redirect_uri": self.redirect_uri + }) ) except requests.exceptions.ConnectionError as ex: redirect_destination = ex.request.url - response_url = dict(parse_qs(urlparse(redirect_destination).fragment)) + response_dict = parse_qs(urlparse(redirect_destination).fragment) + + self.assertTrue(response_dict.get("access_token")) + self.assertTrue(response_dict.get("expires_in")) + self.assertTrue(response_dict.get("scope")) + self.assertTrue(response_dict.get("token_type")) + self.assertTrue(check_valid_openid_response(response_dict.get("access_token")[0])) - self.assertTrue(response_url.get("access_token")) - self.assertTrue(response_url.get("expires_in")) - self.assertTrue(response_url.get("scope")) - self.assertTrue(response_url.get("token_type")) - self.assertTrue(check_valid_openid_response(response_url.get("access_token")[0])) def check_valid_openid_response(access_token=None): - # Returns True for valid response - + """Return True for valid response.""" # Use token in header headers = {} if access_token: - headers["Authorization"] = 'Bearer ' + access_token + headers["Authorization"] = "Bearer " + access_token # check openid for email test@example.com - openid_response = requests.get(frappe.get_site_config().host_name + - "/api/method/frappe.integrations.oauth2.openid_profile", headers=headers) + openid_response = requests.get( + get_full_url("/api/method/frappe.integrations.oauth2.openid_profile"), + headers=headers + ) - return True if openid_response.status_code == 200 else False + return openid_response.status_code == 200 + + +def login(session): + session.post( + get_full_url("/api/method/login"), + data={ + "usr": "test@example.com", + "pwd": "Eastern_43A1W" + } + ) + + +def get_full_url(endpoint): + """Turn '/endpoint' into 'http://127.0.0.1:8000/endpoint'.""" + return urljoin(frappe.utils.get_url(), endpoint) + +def encode_params(params): + """ + Encode a dict of params into a query string. + + Use `quote_via=urllib.parse.quote` so that whitespaces will be encoded as + `%20` instead of as `+`. This is needed because oauthlib cannot handle `+` + as a whitespace. + """ + return urlencode(params, quote_via=quote) diff --git a/package.json b/package.json index 9d9940b186..4095c76ef3 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "jsbarcode": "^3.9.0", "moment": "^2.20.1", "moment-timezone": "^0.5.28", - "node-sass": "^4.13.1", + "node-sass": "^4.14.1", "quagga": "^0.12.1", "quill": "2.0.0-dev.4", "quill-image-resize": "^3.0.9", @@ -50,8 +50,7 @@ "superagent": "^3.8.2", "touch": "^3.1.0", "vue": "^2.6.11", - "vue-router": "^2.0.0", - "node-sass": "^4.14.1" + "vue-router": "^2.0.0" }, "devDependencies": { "babel-runtime": "^6.26.0", diff --git a/yarn.lock b/yarn.lock index df4a018ec8..29b443fb00 100644 --- a/yarn.lock +++ b/yarn.lock @@ -377,10 +377,10 @@ agent-base@~4.2.1: dependencies: jquery ">=2.0.0 <4.0.0" -ajv@^6.5.5: - version "6.12.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd" - integrity sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ== +ajv@^6.12.3: + version "6.12.5" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.5.tgz#19b0e8bae8f476e5ba666300387775fb1a00a4da" + integrity sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag== dependencies: fast-deep-equal "^3.1.1" fast-json-stable-stringify "^2.0.0" @@ -631,9 +631,9 @@ aws-sign2@~0.7.0: integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= aws4@^1.8.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" - integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== + version "1.10.1" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.1.tgz#e1e82e4f3e999e2cfd61b161280d16a111f86428" + integrity sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA== babel-runtime@^6.26.0: version "6.26.0" @@ -2327,9 +2327,9 @@ fast-deep-equal@^2.0.1: integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= fast-deep-equal@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" - integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-diff@1.1.2: version "1.1.2" @@ -2707,9 +2707,9 @@ global-prefix@^1.0.1: which "^1.2.14" globule@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.1.tgz#5dffb1b191f22d20797a9369b49eab4e9839696d" - integrity sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ== + version "1.3.2" + resolved "https://registry.yarnpkg.com/globule/-/globule-1.3.2.tgz#d8bdd9e9e4eef8f96e245999a5dee7eb5d8529c4" + integrity sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA== dependencies: glob "~7.1.1" lodash "~4.17.10" @@ -2749,7 +2749,12 @@ got@^9.6.0: to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" -graceful-fs@^4.1.2, graceful-fs@^4.1.6: +graceful-fs@^4.1.2: + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + +graceful-fs@^4.1.6: version "4.2.3" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== @@ -2778,12 +2783,12 @@ har-schema@^2.0.0: resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= -har-validator@~5.1.0: - version "5.1.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== +har-validator@~5.1.0, har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== dependencies: - ajv "^6.5.5" + ajv "^6.12.3" har-schema "^2.0.0" has-ansi@^2.0.0: @@ -2913,9 +2918,9 @@ homedir-polyfill@^1.0.1: parse-passwd "^1.0.0" hosted-git-info@^2.1.4: - version "2.7.1" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" - integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== + version "2.8.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" + integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== hosted-git-info@^2.7.1: version "2.8.5" @@ -3069,9 +3074,9 @@ imurmurhash@^0.1.4: integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= in-publish@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.0.tgz#e20ff5e3a2afc2690320b6dc552682a9c7fadf51" - integrity sha1-4g/146KvwmkDILbcVSaCqcf631E= + version "2.0.1" + resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.1.tgz#948b1a535c8030561cea522f73f78f4be357e00c" + integrity sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ== indent-string@^2.1.0: version "2.1.0" @@ -3587,7 +3592,12 @@ jpeg-js@^0.3.2: resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.4.1.tgz#714f1f8d9dde4bdfa55764ba37ef214630d80ef2" integrity sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw== -js-base64@^2.1.8, js-base64@^2.1.9: +js-base64@^2.1.8: + version "2.6.4" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.6.4.tgz#f4e686c5de1ea1f867dbcad3d46d969428df98c4" + integrity sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ== + +js-base64@^2.1.9: version "2.5.1" resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.1.tgz#1efa39ef2c5f7980bb1784ade4a8af2de3291121" integrity sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw== @@ -3946,12 +3956,12 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@4.17.15, lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@~4.17.10: +lodash@4.17.15, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== -lodash@^4.17.19, lodash@^4.17.20: +lodash@^4.0.0, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@~4.17.10: version "4.17.20" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== @@ -4152,6 +4162,11 @@ mime-db@1.43.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== +mime-db@1.44.0: + version "1.44.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" + integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== + mime-types@^2.0.1: version "2.1.24" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" @@ -4159,7 +4174,14 @@ mime-types@^2.0.1: dependencies: mime-db "1.40.0" -mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: +mime-types@^2.1.12, mime-types@~2.1.19: + version "2.1.27" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" + integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== + dependencies: + mime-db "1.44.0" + +mime-types@~2.1.24: version "2.1.26" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== @@ -4198,11 +4220,16 @@ minimist@0.0.8: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= -minimist@1.2.0, minimist@^1.1.3, minimist@^1.2.0: +minimist@1.2.0, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= +minimist@^1.1.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== + mixin-deep@^1.2.0: version "1.3.2" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" @@ -4211,13 +4238,20 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: +mkdirp@0.5.1, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= dependencies: minimist "0.0.8" +"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" @@ -4256,9 +4290,9 @@ mute-stream@0.0.8: integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== nan@^2.13.2: - version "2.14.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" - integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== + version "2.14.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" + integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== nanomatch@^1.2.9: version "1.2.13" @@ -4676,9 +4710,9 @@ p-finally@^1.0.0: integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= p-limit@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" - integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" @@ -5382,7 +5416,7 @@ pseudomap@^1.0.2: resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= -psl@^1.1.24: +psl@^1.1.24, psl@^1.1.28: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== @@ -5422,7 +5456,7 @@ punycode@^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.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== @@ -5770,7 +5804,7 @@ request-progress@3.0.0: dependencies: throttleit "^1.0.0" -request@2.88.0, request@^2.44.0, request@^2.83.0, request@^2.87.0, request@^2.88.0: +request@2.88.0, request@^2.44.0, request@^2.83.0: version "2.88.0" resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== @@ -5796,6 +5830,32 @@ request@2.88.0, request@^2.44.0, request@^2.83.0, request@^2.87.0, request@^2.88 tunnel-agent "^0.6.0" uuid "^3.3.2" +request@^2.87.0, request@^2.88.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -5839,7 +5899,14 @@ 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.4.0, resolve@^1.5.0: +resolve@^1.10.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== + dependencies: + path-parse "^1.0.6" + +resolve@^1.4.0, resolve@^1.5.0: version "1.10.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.0.tgz#3bdaaeaf45cc07f375656dfd2e54ed0810b101ba" integrity sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg== @@ -6025,12 +6092,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@^5.0.1, safe-buffer@^5.1.2: - version "5.2.0" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" - integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== - -safe-buffer@~5.2.0: +safe-buffer@^5.0.1, safe-buffer@^5.1.2, 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== @@ -6492,7 +6554,7 @@ snyk-try-require@1.3.1, snyk-try-require@^1.1.1, snyk-try-require@^1.3.1: lru-cache "^4.0.0" then-fs "^2.0.0" -snyk@1.398.1, snyk@^1.398.1: +snyk@^1.398.1: version "1.398.1" resolved "https://registry.yarnpkg.com/snyk/-/snyk-1.398.1.tgz#19aec8dfffa60e7412e6309117e96b2cfa960355" integrity sha512-jH24ztdJY8DQlqkd1z8n/JutdOqHtTPccCynM2hfOedW20yAp9c108LFjXvqBEk/EH3YyNmWzyLkkHOySeDkwQ== @@ -6673,30 +6735,30 @@ sourcemap-codec@^1.4.4: integrity sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg== spdx-correct@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" - integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== dependencies: spdx-expression-parse "^3.0.0" spdx-license-ids "^3.0.0" spdx-exceptions@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" - integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== spdx-expression-parse@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" - integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== dependencies: spdx-exceptions "^2.1.0" spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz#81c0ce8f21474756148bbb5f3bfc0f36bf15d76e" - integrity sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g== + version "3.0.6" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz#c80757383c28abf7296744998cbc106ae8b854ce" + integrity sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw== split-ca@^1.0.1: version "1.0.1" @@ -7198,6 +7260,14 @@ tough-cookie@~2.4.3: psl "^1.1.24" punycode "^1.4.1" +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + tree-kill@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" @@ -7382,9 +7452,9 @@ update-notifier@^4.1.0: xdg-basedir "^4.0.0" uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + version "4.4.0" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.0.tgz#aa714261de793e8a82347a7bcc9ce74e86f28602" + integrity sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g== dependencies: punycode "^2.1.0"