From 81f61d3c3399b1ddf2e2496cd4e2bb4e81b50b41 Mon Sep 17 00:00:00 2001 From: "Ifedapo .A. Olarewaju" Date: Thu, 30 Apr 2020 10:37:31 +0100 Subject: [PATCH] companion: mask secrets present in log messages (#2214) * companion: mask secrets present in log messages * companion: escape secrets that should be masked * companion: log error stacks optionally * companion: restore old node enging compatibility * companion: refactor conditional error response --- package-lock.json | 350 ++++++------------ packages/@uppy/companion/package.json | 1 + packages/@uppy/companion/src/companion.js | 28 ++ packages/@uppy/companion/src/server/logger.js | 50 ++- .../@uppy/companion/src/standalone/index.js | 23 +- .../@uppy/companion/test/__tests__/logger.js | 113 ++++++ 6 files changed, 322 insertions(+), 243 deletions(-) create mode 100644 packages/@uppy/companion/test/__tests__/logger.js diff --git a/package-lock.json b/package-lock.json index 6ed80e791..ae52897ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6255,8 +6255,7 @@ "dependencies": { "@babel/core": { "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", - "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", + "bundled": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.9.0", @@ -6290,8 +6289,7 @@ "dependencies": { "@babel/core": { "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", - "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", + "bundled": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.9.0", @@ -6313,8 +6311,7 @@ }, "browserify": { "version": "16.5.1", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.5.1.tgz", - "integrity": "sha512-EQX0h59Pp+0GtSRb5rL6OTfrttlzv+uyaUVlK6GX3w11SQ0jKPKyjC/54RhPR2ib2KmfcELM06e8FxcI5XNU2A==", + "bundled": true, "requires": { "JSONStream": "^1.0.3", "assert": "^1.4.0", @@ -6368,8 +6365,7 @@ }, "buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", - "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "bundled": true, "requires": { "base64-js": "^1.0.2", "ieee754": "^1.1.4" @@ -6377,8 +6373,7 @@ }, "events": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", - "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==" + "bundled": true } } }, @@ -6398,8 +6393,7 @@ "dependencies": { "@babel/core": { "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", - "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", + "bundled": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.9.0", @@ -6438,8 +6432,7 @@ "dependencies": { "@babel/core": { "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", - "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", + "bundled": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.9.0", @@ -6474,8 +6467,7 @@ "dependencies": { "@babel/core": { "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", - "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", + "bundled": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.9.0", @@ -6497,8 +6489,7 @@ }, "es6-promise": { "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + "bundled": true } } }, @@ -6516,8 +6507,7 @@ "dependencies": { "@babel/core": { "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", - "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", + "bundled": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.9.0", @@ -6550,8 +6540,7 @@ "dependencies": { "@babel/core": { "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", - "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", + "bundled": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.9.0", @@ -6590,8 +6579,7 @@ "dependencies": { "@babel/core": { "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", - "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", + "bundled": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.9.0", @@ -6630,8 +6618,7 @@ "dependencies": { "@babel/core": { "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", - "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", + "bundled": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.9.0", @@ -6670,8 +6657,7 @@ "dependencies": { "@babel/core": { "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", - "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", + "bundled": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.9.0", @@ -6707,8 +6693,7 @@ "dependencies": { "@babel/core": { "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", - "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", + "bundled": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.9.0", @@ -6730,8 +6715,7 @@ }, "react": { "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz", - "integrity": "sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==", + "bundled": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -6740,8 +6724,7 @@ }, "react-dom": { "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz", - "integrity": "sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==", + "bundled": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -6772,8 +6755,7 @@ "dependencies": { "react": { "version": "16.5.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.5.0.tgz", - "integrity": "sha512-nw/yB/L51kA9PsAy17T1JrzzGRk+BlFCJwFF7p+pwVxgqwPjYNeZEkkH7LXn9dmflolrYMXLWMTkQ77suKPTNQ==", + "bundled": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -6796,8 +6778,7 @@ "dependencies": { "@babel/core": { "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", - "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", + "bundled": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.9.0", @@ -6832,8 +6813,7 @@ "dependencies": { "@babel/core": { "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", - "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", + "bundled": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.9.0", @@ -6867,8 +6847,7 @@ "dependencies": { "browserify": { "version": "16.5.1", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.5.1.tgz", - "integrity": "sha512-EQX0h59Pp+0GtSRb5rL6OTfrttlzv+uyaUVlK6GX3w11SQ0jKPKyjC/54RhPR2ib2KmfcELM06e8FxcI5XNU2A==", + "bundled": true, "requires": { "JSONStream": "^1.0.3", "assert": "^1.4.0", @@ -6922,8 +6901,7 @@ }, "buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", - "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "bundled": true, "requires": { "base64-js": "^1.0.2", "ieee754": "^1.1.4" @@ -6931,8 +6909,7 @@ }, "events": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", - "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==" + "bundled": true } } }, @@ -6961,8 +6938,7 @@ "dependencies": { "@babel/core": { "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", - "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", + "bundled": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.9.0", @@ -7012,6 +6988,7 @@ "common-tags": "1.8.0", "connect-redis": "4.0.3", "cookie-parser": "1.4.4", + "escape-string-regexp": "4.0.0", "express": "4.17.1", "express-interceptor": "1.2.0", "express-prom-bundle": "3.3.0", @@ -7042,18 +7019,15 @@ "dependencies": { "@purest/providers": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@purest/providers/-/providers-1.0.1.tgz", - "integrity": "sha512-1ekKViRit0jo1IzDLSRSziU/OpX9ckoj8uWvSWzHLASyTqhKZL9Pdq628guq7yT3qFcJeeaeaA5T97a4w7fpqA==" + "bundled": true }, "atob": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + "bundled": true }, "aws-sdk": { "version": "2.587.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.587.0.tgz", - "integrity": "sha512-MAdUE4BC+hyfFPoQc61aV/tIfApp5ifqe3segW4GJq6dMmSCZdFbDwvs5ZUkgOSJ4ks3ZrpH9eCHpt6r0dFJYQ==", + "bundled": true, "requires": { "buffer": "4.9.1", "events": "1.1.1", @@ -7068,15 +7042,13 @@ "dependencies": { "uuid": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + "bundled": true } } }, "body-parser": { "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "bundled": true, "requires": { "bytes": "3.1.0", "content-type": "~1.0.4", @@ -7092,8 +7064,7 @@ }, "buffer": { "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "bundled": true, "requires": { "base64-js": "^1.0.2", "ieee754": "^1.1.4", @@ -7102,33 +7073,34 @@ }, "buffer-from": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.2.tgz", - "integrity": "sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg==" + "bundled": true }, "chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "bundled": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "bundled": true + } } }, "content-security-policy-builder": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/content-security-policy-builder/-/content-security-policy-builder-2.1.0.tgz", - "integrity": "sha512-/MtLWhJVvJNkA9dVLAp6fg9LxD2gfI6R2Fi1hPmfjYXSahJJzcfvoeDOxSyp4NvxMuwWv3WMssE9o31DoULHrQ==" + "bundled": true }, "cookie": { "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + "bundled": true }, "cookie-parser": { "version": "1.4.4", - "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.4.tgz", - "integrity": "sha512-lo13tqF3JEtFO7FyA49CqbhaFkskRJ0u/UAiINgrIXeRCY41c88/zxtrECl8AKH3B0hj9q10+h3Kt8I7KlW4tw==", + "bundled": true, "requires": { "cookie": "0.3.1", "cookie-signature": "1.0.6" @@ -7136,38 +7108,36 @@ }, "debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "bundled": true, "requires": { "ms": "2.0.0" }, "dependencies": { "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "bundled": true } } }, "dns-prefetch-control": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dns-prefetch-control/-/dns-prefetch-control-0.2.0.tgz", - "integrity": "sha512-hvSnros73+qyZXhHFjx2CMLwoj3Fe7eR9EJsFsqmcI1bB2OBWL/+0YzaEaKssCHnj/6crawNnUyw74Gm2EKe+Q==" + "bundled": true }, "dont-sniff-mimetype": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/dont-sniff-mimetype/-/dont-sniff-mimetype-1.1.0.tgz", - "integrity": "sha512-ZjI4zqTaxveH2/tTlzS1wFp+7ncxNZaIEWYg3lzZRHkKf5zPT/MnEG6WL0BhHMJUabkh8GeU5NL5j+rEUCb7Ug==" + "bundled": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "bundled": true }, "expect-ct": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/expect-ct/-/expect-ct-0.2.0.tgz", - "integrity": "sha512-6SK3MG/Bbhm8MsgyJAylg+ucIOU71/FzyFalcfu5nY19dH8y/z0tBJU0wrNBXD4B27EoQtqPF/9wqH0iYAd04g==" + "bundled": true }, "express-session": { "version": "1.15.6", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.15.6.tgz", - "integrity": "sha512-r0nrHTCYtAMrFwZ0kBzZEXa1vtPVrw0dKvGSrKP4dahwBQ1BJpF2/y1Pp4sCD/0kvxV4zZeclyvfmw0B4RMJQA==", + "bundled": true, "requires": { "cookie": "0.3.1", "cookie-signature": "1.0.6", @@ -7182,13 +7152,11 @@ }, "frameguard": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/frameguard/-/frameguard-3.1.0.tgz", - "integrity": "sha512-TxgSKM+7LTA6sidjOiSZK9wxY0ffMPY3Wta//MqwmX0nZuEHc8QrkV8Fh3ZhMJeiH+Uyh/tcaarImRy8u77O7g==" + "bundled": true }, "grant": { "version": "4.6.5", - "resolved": "https://registry.npmjs.org/grant/-/grant-4.6.5.tgz", - "integrity": "sha512-gxMaIw6MRI/HaPxuV04NTOCZTFtPRCjpZIAQH3NqCnOHUHXenor+IOTYqjmeSQzcH0KJ0rv3PQp9Q3Cj18n8jw==", + "bundled": true, "requires": { "qs": "^6.9.1", "request-compose": "^1.2.1", @@ -7197,15 +7165,13 @@ "dependencies": { "qs": { "version": "6.9.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.1.tgz", - "integrity": "sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA==" + "bundled": true } } }, "helmet": { "version": "3.21.2", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.21.2.tgz", - "integrity": "sha512-okUo+MeWgg00cKB8Csblu8EXgcIoDyb5ZS/3u0W4spCimeVuCUvVZ6Vj3O2VJ1Sxpyb8jCDvzu0L1KKT11pkIg==", + "bundled": true, "requires": { "depd": "2.0.0", "dns-prefetch-control": "0.2.0", @@ -7226,15 +7192,13 @@ "dependencies": { "depd": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + "bundled": true } } }, "helmet-csp": { "version": "2.9.4", - "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.9.4.tgz", - "integrity": "sha512-qUgGx8+yk7Xl8XFEGI4MFu1oNmulxhQVTlV8HP8tV3tpfslCs30OZz/9uQqsWPvDISiu/NwrrCowsZBhFADYqg==", + "bundled": true, "requires": { "bowser": "^2.7.0", "camelize": "1.0.0", @@ -7244,38 +7208,32 @@ }, "hide-powered-by": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.1.0.tgz", - "integrity": "sha512-Io1zA2yOA1YJslkr+AJlWSf2yWFkKjvkcL9Ni1XSUqnGLr/qRQe2UI3Cn/J9MsJht7yEVCe0SscY1HgVMujbgg==" + "bundled": true }, "hsts": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.2.0.tgz", - "integrity": "sha512-ToaTnQ2TbJkochoVcdXYm4HOCliNozlviNsg+X2XQLQvZNI/kCHR9rZxVYpJB3UPcHz80PgxRyWQ7PdU1r+VBQ==", + "bundled": true, "requires": { "depd": "2.0.0" }, "dependencies": { "depd": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + "bundled": true } } }, "ienoopen": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ienoopen/-/ienoopen-1.1.0.tgz", - "integrity": "sha512-MFs36e/ca6ohEKtinTJ5VvAJ6oDRAYFdYXweUnGY9L9vcoqFOU4n2ZhmJ0C4z/cwGZ3YIQRSB3XZ1+ghZkY5NQ==" + "bundled": true }, "isarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "bundled": true }, "jsonwebtoken": { "version": "8.5.1", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", - "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "bundled": true, "requires": { "jws": "^3.2.2", "lodash.includes": "^4.3.0", @@ -7291,28 +7249,24 @@ "dependencies": { "semver": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + "bundled": true } } }, "mime-db": { "version": "1.42.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", - "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==" + "bundled": true }, "mime-types": { "version": "2.1.25", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", - "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", + "bundled": true, "requires": { "mime-db": "1.42.0" } }, "morgan": { "version": "1.9.1", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", - "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", + "bundled": true, "requires": { "basic-auth": "~2.0.0", "debug": "2.6.9", @@ -7323,18 +7277,15 @@ }, "ms": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "bundled": true }, "nocache": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz", - "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==" + "bundled": true }, "node-redis-pubsub": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/node-redis-pubsub/-/node-redis-pubsub-4.0.0.tgz", - "integrity": "sha512-sAUOzisio/8UYCRbjPo6+u7aTpBmxSBjTJYwu49x9KruIQgi//wbEnvbqGSH5JWViP7HyQSMtkHUcZXH7qGsOQ==", + "bundled": true, "requires": { "redis": "^2.7.1" }, @@ -7353,8 +7304,7 @@ }, "node-schedule": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/node-schedule/-/node-schedule-1.3.2.tgz", - "integrity": "sha512-GIND2pHMHiReSZSvS6dpZcDH7pGPGFfWBIEud6S00Q8zEIzAs9ommdyRK1ZbQt8y1LyZsJYZgPnyi7gpU2lcdw==", + "bundled": true, "requires": { "cron-parser": "^2.7.3", "long-timeout": "0.1.1", @@ -7363,21 +7313,18 @@ }, "prom-client": { "version": "11.5.3", - "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-11.5.3.tgz", - "integrity": "sha512-iz22FmTbtkyL2vt0MdDFY+kWof+S9UB/NACxSn2aJcewtw+EERsen0urSkZ2WrHseNdydsvcxCTAnPcSMZZv4Q==", + "bundled": true, "requires": { "tdigest": "^0.1.1" } }, "punycode": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + "bundled": true }, "purest": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/purest/-/purest-3.1.0.tgz", - "integrity": "sha512-9slCC5je2UNERS/YNcrs1/7K5Bh7Uvl6OY1S+XZ6iDNMCwk8Fio6VBdrklo7eMzt5M/Wt2fQlwXRjn4puBccRQ==", + "bundled": true, "requires": { "@purest/config": "^1.0.0", "@request/api": "^0.6.0", @@ -7386,8 +7333,7 @@ }, "redis": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/redis/-/redis-3.0.2.tgz", - "integrity": "sha512-PNhLCrjU6vKVuMOyFu7oSP296mwBkcE6lrAjruBYG5LgdSqtRBoVQIylrMyVZD/lkF24RSNNatzvYag6HRBHjQ==", + "bundled": true, "requires": { "denque": "^1.4.1", "redis-commands": "^1.5.0", @@ -7407,13 +7353,11 @@ }, "referrer-policy": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz", - "integrity": "sha512-LgQJIuS6nAy1Jd88DCQRemyE3mS+ispwlqMk3b0yjZ257fI1v9c+/p6SD5gP5FGyXUIgrNOAfmyioHwZtYv2VA==" + "bundled": true }, "request": { "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "bundled": true, "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -7446,23 +7390,19 @@ }, "request-compose": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/request-compose/-/request-compose-1.2.1.tgz", - "integrity": "sha512-w4qjUH1N4OdMfnHVi4Z0oKvDZyu75rJlvnuKe40wVg+khnfdJLt0qf+LF8QjIiDqSOSYdbMZE6a0ixU58B3Jow==" + "bundled": true }, "sax": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" + "bundled": true }, "semver": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "bundled": true }, "tough-cookie": { "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "bundled": true, "requires": { "psl": "^1.1.24", "punycode": "^1.4.1" @@ -7477,8 +7417,7 @@ }, "tus-js-client": { "version": "1.8.0", - "resolved": "https://registry.npmjs.org/tus-js-client/-/tus-js-client-1.8.0.tgz", - "integrity": "sha512-qPX3TywqzxocTxUZtcS8X7Aik72SVMa0jKi4hWyfvRV+s9raVzzYGaP4MoJGaF0yOgm2+b6jXaVEHogxcJ8LGw==", + "bundled": true, "requires": { "buffer-from": "^0.1.1", "combine-errors": "^3.0.3", @@ -7491,8 +7430,7 @@ }, "url": { "version": "0.10.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", - "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "bundled": true, "requires": { "punycode": "1.3.2", "querystring": "0.2.0" @@ -7500,26 +7438,22 @@ }, "uuid": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", - "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" + "bundled": true }, "validator": { "version": "12.1.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-12.1.0.tgz", - "integrity": "sha512-gIC2RBuFRi574Rb9vewGCJ7TCLxHXNx6EKthEgs+Iz0pYa9a9Te1VLG/bGLsAyGWrqR5FfR7tbFUI7FEF2LiGA==" + "bundled": true }, "ws": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "bundled": true, "requires": { "async-limiter": "~1.0.0" } }, "x-xss-protection": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.3.0.tgz", - "integrity": "sha512-kpyBI9TlVipZO4diReZMAHWtS0MMa/7Kgx8hwG/EuZLiA6sg4Ah/4TRdASHhRRN3boobzcYgFRUFSgHRge6Qhg==" + "bundled": true } } }, @@ -7697,8 +7631,7 @@ "dependencies": { "es6-promise": { "version": "4.2.5", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz", - "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==" + "bundled": true } } }, @@ -7737,8 +7670,7 @@ "dependencies": { "exifr": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/exifr/-/exifr-5.0.1.tgz", - "integrity": "sha512-6Vq+IVvq7oyRSTpEDMDalzupJZs7rauXL0gZeS2yU1BSA+1fAzJCJrfRHXjMMggtUyb/hJ9m9MlLf8AtvEsrUw==" + "bundled": true } } }, @@ -17274,7 +17206,7 @@ "qs": "^6.5.0", "react-native-branch": "2.2.5", "react-native-gesture-handler": "~1.0.14", - "react-native-maps": "github:expo/react-native-maps#v0.22.1-exp.0", + "react-native-maps": "github:expo/react-native-maps#e6f98ff7272e5d0a7fe974a41f28593af2d77bb2", "react-native-reanimated": "1.0.0-alpha.11", "react-native-screens": "1.0.0-alpha.22", "react-native-svg": "8.0.10", @@ -18565,8 +18497,7 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true, - "optional": true + "bundled": true }, "aproba": { "version": "1.2.0", @@ -18584,13 +18515,11 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true, - "optional": true + "bundled": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -18603,18 +18532,15 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "concat-map": { "version": "0.0.1", - "bundled": true, - "optional": true + "bundled": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "core-util-is": { "version": "1.0.2", @@ -18717,8 +18643,7 @@ }, "inherits": { "version": "2.0.4", - "bundled": true, - "optional": true + "bundled": true }, "ini": { "version": "1.3.5", @@ -18728,7 +18653,6 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -18741,20 +18665,17 @@ "minimatch": { "version": "3.0.4", "bundled": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "1.2.5", - "bundled": true, - "optional": true + "bundled": true }, "minipass": { "version": "2.9.0", "bundled": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -18771,7 +18692,6 @@ "mkdirp": { "version": "0.5.3", "bundled": true, - "optional": true, "requires": { "minimist": "^1.2.5" } @@ -18827,8 +18747,7 @@ }, "npm-normalize-package-bin": { "version": "1.0.1", - "bundled": true, - "optional": true + "bundled": true }, "npm-packlist": { "version": "1.4.8", @@ -18853,8 +18772,7 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true, - "optional": true + "bundled": true }, "object-assign": { "version": "4.1.1", @@ -18864,7 +18782,6 @@ "once": { "version": "1.4.0", "bundled": true, - "optional": true, "requires": { "wrappy": "1" } @@ -18933,8 +18850,7 @@ }, "safe-buffer": { "version": "5.1.2", - "bundled": true, - "optional": true + "bundled": true }, "safer-buffer": { "version": "2.1.2", @@ -18964,7 +18880,6 @@ "string-width": { "version": "1.0.2", "bundled": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -18982,7 +18897,6 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -19021,13 +18935,11 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true, - "optional": true + "bundled": true }, "yallist": { "version": "3.1.1", - "bundled": true, - "optional": true + "bundled": true } } }, @@ -37559,7 +37471,7 @@ "hexo": "4.0.0", "hexo-browsersync": "^0.3.0", "hexo-cli": "3.1.0", - "hexo-filter-github-emojis": "github:arturi/hexo-filter-github-emojis", + "hexo-filter-github-emojis": "github:arturi/hexo-filter-github-emojis#c0b188687b47669d0aa452d6f9adbb7487925baf", "hexo-generator-alias": "^0.1.3", "hexo-generator-archive": "^1.0.0", "hexo-generator-category": "^1.0.0", @@ -37587,8 +37499,7 @@ "dependencies": { "@babel/core": { "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", - "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", + "bundled": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.9.0", @@ -37610,13 +37521,11 @@ }, "ansi-regex": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + "bundled": true }, "autoprefixer": { "version": "9.7.6", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.6.tgz", - "integrity": "sha512-F7cYpbN7uVVhACZTeeIeealwdGM6wMtfWARVLTy5xmKtgVdBNJvbDRoCK3YO1orcs7gv/KwYlb3iXwu9Ug9BkQ==", + "bundled": true, "requires": { "browserslist": "^4.11.1", "caniuse-lite": "^1.0.30001039", @@ -37629,16 +37538,14 @@ }, "braces": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "bundled": true, "requires": { "fill-range": "^7.0.1" } }, "browserify": { "version": "16.5.1", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.5.1.tgz", - "integrity": "sha512-EQX0h59Pp+0GtSRb5rL6OTfrttlzv+uyaUVlK6GX3w11SQ0jKPKyjC/54RhPR2ib2KmfcELM06e8FxcI5XNU2A==", + "bundled": true, "requires": { "JSONStream": "^1.0.3", "assert": "^1.4.0", @@ -37692,8 +37599,7 @@ }, "buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", - "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "bundled": true, "requires": { "base64-js": "^1.0.2", "ieee754": "^1.1.4" @@ -37701,21 +37607,18 @@ }, "events": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", - "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==" + "bundled": true }, "fill-range": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "bundled": true, "requires": { "to-regex-range": "^5.0.1" } }, "hexo": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hexo/-/hexo-4.0.0.tgz", - "integrity": "sha512-woVSeutGyFDLdE3UWJsZWw18KboFSsmmcxuivuLJPQ0pqLLz4zar07BG/YQXgVaXzR1jQ7Hurbx1gGZj5Z7y2w==", + "bundled": true, "requires": { "abbrev": "^1.1.1", "archy": "^1.0.0", @@ -37748,8 +37651,7 @@ }, "hexo-cli": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hexo-cli/-/hexo-cli-3.1.0.tgz", - "integrity": "sha512-Rc2gX2DlsALaFBbfk1XYx2XmeVAX+C7Dxc7UwETZOcu3cbGsf2DpwYTfKQumW3jagi1icA4KgW9aSRPPZZj/zg==", + "bundled": true, "requires": { "abbrev": "^1.1.1", "acorn": "^7.0.0", @@ -37766,18 +37668,15 @@ }, "is-number": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + "bundled": true }, "marked": { "version": "0.7.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", - "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==" + "bundled": true }, "micromatch": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "bundled": true, "requires": { "braces": "^3.0.1", "picomatch": "^2.0.5" @@ -37785,8 +37684,7 @@ }, "postcss": { "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", + "bundled": true, "requires": { "chalk": "^2.4.2", "source-map": "^0.6.1", @@ -37802,29 +37700,25 @@ }, "postcss-value-parser": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz", - "integrity": "sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg==" + "bundled": true }, "strip-ansi": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "bundled": true, "requires": { "ansi-regex": "^4.1.0" } }, "supports-color": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "bundled": true, "requires": { "has-flag": "^3.0.0" } }, "to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "bundled": true, "requires": { "is-number": "^7.0.0" } diff --git a/packages/@uppy/companion/package.json b/packages/@uppy/companion/package.json index 89af76ae4..7f67a6ebc 100644 --- a/packages/@uppy/companion/package.json +++ b/packages/@uppy/companion/package.json @@ -37,6 +37,7 @@ "common-tags": "1.8.0", "connect-redis": "4.0.3", "cookie-parser": "1.4.4", + "escape-string-regexp": "4.0.0", "express": "4.17.1", "express-interceptor": "1.2.0", "express-prom-bundle": "3.3.0", diff --git a/packages/@uppy/companion/src/companion.js b/packages/@uppy/companion/src/companion.js index 08674081e..6d3470e6f 100644 --- a/packages/@uppy/companion/src/companion.js +++ b/packages/@uppy/companion/src/companion.js @@ -57,6 +57,9 @@ module.exports.app = (options = {}) => { providerManager.addCustomProviders(customProviders, providers, grantConfig) } + // mask provider secrets from log messages + maskLogger(options) + // create singleton redis client if (options.redisUrl) { redis.client(merge({ url: options.redisUrl }, options.redisOptions || {})) @@ -272,3 +275,28 @@ const getOptionsMiddleware = (options) => { return middleware } + +/** + * Informs the logger about all provider secrets that should be masked + * if they are found in a log message + * @param {object} companionOptions + */ +const maskLogger = (companionOptions) => { + const secrets = [] + const { providerOptions, customProviders } = companionOptions + Object.keys(providerOptions).forEach((provider) => { + if (providerOptions[provider].secret) { + secrets.push(providerOptions[provider].secret) + } + }) + + if (customProviders) { + Object.keys(customProviders).forEach((provider) => { + if (customProviders[provider].config && customProviders[provider].config.secret) { + secrets.push(customProviders[provider].config.secret) + } + }) + } + + logger.setMaskables(secrets) +} diff --git a/packages/@uppy/companion/src/server/logger.js b/packages/@uppy/companion/src/server/logger.js index 05c217e5c..3f0b8e33c 100644 --- a/packages/@uppy/companion/src/server/logger.js +++ b/packages/@uppy/companion/src/server/logger.js @@ -1,4 +1,19 @@ const chalk = require('chalk') +const escapeStringRegexp = require('escape-string-regexp') + +const valuesToMask = [] +/** + * Adds a list of strings that should be masked by the logger. + * This function can only be called once through out the life of the server. + * @param {Array} maskables a list of strings to be masked + */ +exports.setMaskables = (maskables) => { + maskables.forEach((i) => { + valuesToMask.push(escapeStringRegexp(i)) + }) + + Object.freeze(valuesToMask) +} /** * INFO level log @@ -26,10 +41,11 @@ exports.warn = (msg, tag, traceId) => { * @param {string | Error} msg the message to log * @param {string=} tag a unique tag to easily search for this message * @param {string=} traceId a unique id to easily trace logs tied to a request + * @param {boolean=} shouldLogStackTrace when set to true, errors will be logged with their stack trace */ -exports.error = (msg, tag, traceId) => { +exports.error = (msg, tag, traceId, shouldLogStackTrace) => { // @ts-ignore - log(msg, tag, 'error', traceId, chalk.bold.red) + log(msg, tag, 'error', traceId, chalk.bold.red, shouldLogStackTrace) } /** @@ -51,14 +67,42 @@ exports.debug = (msg, tag, traceId) => { * @param {string} level error | info | debug * @param {function=} color function to display the log in appropriate color * @param {string=} id a unique id to easily trace logs tied to a request + * @param {boolean=} shouldLogStackTrace when set to true, errors will be logged with their stack trace */ -const log = (msg, tag, level, id, color) => { +const log = (msg, tag, level, id, color, shouldLogStackTrace) => { const time = new Date().toISOString() tag = tag || '' id = id || '' const whitespace = tag && id ? ' ' : '' color = color || ((message) => message) + if (typeof msg === 'string') { + msg = maskMessage(msg) + } else if (msg && typeof msg.message === 'string') { + msg.message = maskMessage(msg.message) + } + + if (shouldLogStackTrace && msg instanceof Error && typeof msg.stack === 'string') { + msg.stack = maskMessage(msg.stack) + // exclude msg from template string so values such as error objects + // can be well formatted + console.log(color(`companion: ${time} [${level}] ${id}${whitespace}${tag}`), color(msg.stack)) + return + } + // exclude msg from template string so values such as error objects // can be well formatted console.log(color(`companion: ${time} [${level}] ${id}${whitespace}${tag}`), color(msg)) } + +/** + * Mask the secret content of a message + * @param {string} msg the message whose content should be masked + * @returns {string} + */ +const maskMessage = (msg) => { + for (const toBeMasked of valuesToMask) { + const toBeReplaced = new RegExp(toBeMasked, 'gi') + msg = msg.replace(toBeReplaced, '******') + } + return msg +} diff --git a/packages/@uppy/companion/src/standalone/index.js b/packages/@uppy/companion/src/standalone/index.js index 79e22e694..382118a0c 100644 --- a/packages/@uppy/companion/src/standalone/index.js +++ b/packages/@uppy/companion/src/standalone/index.js @@ -5,6 +5,7 @@ const helmet = require('helmet') const morgan = require('morgan') const bodyParser = require('body-parser') const redis = require('../server/redis') +const logger = require('../server/logger') const { parseURL } = require('../server/helpers/utils') const merge = require('lodash.merge') // @ts-ignore @@ -194,24 +195,22 @@ app.use((req, res, next) => { return res.status(404).json({ message: 'Not Found' }) }) -if (app.get('env') === 'production') { - // @ts-ignore - app.use((err, req, res, next) => { +// @ts-ignore +app.use((err, req, res, next) => { + const logStackTrace = true + if (app.get('env') === 'production') { // if the error is a URIError from the requested URL we only log the error message // to avoid uneccessary error alerts if (err.status === 400 && err instanceof URIError) { - console.error('\x1b[31m', req.id, err.message, '\x1b[0m') + logger.error(err.message, 'root.error', req.id) } else { - console.error('\x1b[31m', req.id, err, '\x1b[0m') + logger.error(err, 'root.error', req.id, logStackTrace) } res.status(err.status || 500).json({ message: 'Something went wrong', requestId: req.id }) - }) -} else { - // @ts-ignore - app.use((err, req, res, next) => { - console.error('\x1b[31m', req.id, err, '\x1b[0m') + } else { + logger.error(err, 'root.error', req.id, logStackTrace) res.status(err.status || 500).json({ message: err.message, error: err, requestId: req.id }) - }) -} + } +}) module.exports = { app, companionOptions } diff --git a/packages/@uppy/companion/test/__tests__/logger.js b/packages/@uppy/companion/test/__tests__/logger.js new file mode 100644 index 000000000..e30830a52 --- /dev/null +++ b/packages/@uppy/companion/test/__tests__/logger.js @@ -0,0 +1,113 @@ +/* global test:false, expect:false, describe:false, beforeAll:false, */ +const logger = require('../../src/server/logger') +const chalk = require('chalk') + +describe('Test Logger secret mask', () => { + beforeAll(() => { + logger.setMaskables(['ToBeMasked1', 'toBeMasked2', 'toBeMasked(And)?Escaped']) + }) + + test('masks secret values present in log.info messages', () => { + let loggedMessage = null + + // override the default console.log to capture the logged message + const defaultConsoleLog = console.log + console.log = (logPrefix, message) => { + loggedMessage = message + defaultConsoleLog(logPrefix, message) + } + + logger.info('this info has ToBeMasked1 and toBeMasked2 and case-insensitive TOBEMasKED2') + // restore the default console.log before using "expect" to avoid weird log behaviors + console.log = defaultConsoleLog + + const exptectedMsg = 'this info has ****** and ****** and case-insensitive ******' + + expect(loggedMessage).toBeTruthy() + expect(loggedMessage).toBe(exptectedMsg) + }) + + test('masks secret values present in log.warn messages', () => { + let loggedMessage = null + + // override the default console.log to capture the logged message + const defaultConsoleLog = console.log + console.log = (logPrefix, message) => { + loggedMessage = message + defaultConsoleLog(logPrefix, message) + } + + logger.warn('this warning has ToBeMasked1 and toBeMasked2 and case-insensitive TOBEMasKED2') + // restore the default console.log before using "expect" to avoid weird log behaviors + console.log = defaultConsoleLog + + const exptectedMsg = chalk.bold.yellow('this warning has ****** and ****** and case-insensitive ******') + + expect(loggedMessage).toBeTruthy() + expect(loggedMessage).toBe(exptectedMsg) + }) + + test('masks secret values present in log.error messages', () => { + let loggedMessage = null + + // override the default console.log to capture the logged message + const defaultConsoleLog = console.log + console.log = (logPrefix, message) => { + loggedMessage = message + defaultConsoleLog(logPrefix, message) + } + + logger.error(new Error('this error has ToBeMasked1 and toBeMasked2 and case-insensitive TOBEMasKED2')) + // restore the default console.log before using "expect" to avoid weird log behaviors + console.log = defaultConsoleLog + + const exptectedMsg = chalk.bold.red('Error: this error has ****** and ****** and case-insensitive ******') + + expect(loggedMessage).toBeTruthy() + expect(loggedMessage).toBe(exptectedMsg) + }) + + test('masks secret values present in log.error stack trace', () => { + let loggedMessage = null + + // override the default console.log to capture the logged message + const defaultConsoleLog = console.log + console.log = (logPrefix, message) => { + loggedMessage = message + defaultConsoleLog(logPrefix, message) + } + + const err = new Error('this error has ToBeMasked1 and toBeMasked2 and case-insensitive TOBEMasKED2') + logger.error(err, '', '', true) + // restore the default console.log before using "expect" to avoid weird log behaviors + console.log = defaultConsoleLog + + const exptectedMsg = chalk.bold.red('Error: this error has ****** and ****** and case-insensitive ******') + + expect(loggedMessage).toBeTruthy() + expect(loggedMessage.startsWith(exptectedMsg)).toBe(true) + expect(loggedMessage.includes('ToBeMasked1')).toBe(false) + expect(loggedMessage.includes('toBeMasked2')).toBe(false) + expect(loggedMessage.includes('TOBEMasKED2')).toBe(false) + }) + + test('escape regex characters from secret values before masking them', () => { + let loggedMessage = null + + // override the default console.log to capture the logged message + const defaultConsoleLog = console.log + console.log = (logPrefix, message) => { + loggedMessage = message + defaultConsoleLog(logPrefix, message) + } + + logger.warn('this warning has ToBeMasked(And)?Escaped but not toBeMaskedEscaped ') + // restore the default console.log before using "expect" to avoid weird log behaviors + console.log = defaultConsoleLog + + const exptectedMsg = chalk.bold.yellow('this warning has ****** but not toBeMaskedEscaped ') + + expect(loggedMessage).toBeTruthy() + expect(loggedMessage).toBe(exptectedMsg) + }) +})