From 0bbfafd03f4a82ccb6b747b9fc0f1f7cfcc36ae7 Mon Sep 17 00:00:00 2001 From: Robbie Antenesse Date: Fri, 6 Sep 2019 22:17:45 -0600 Subject: [PATCH] Set up login tokens with dumb examples --- config.example.json | 4 +- package.json | 2 + routes/home.js | 20 ++++- routes/search.js | 2 +- server.js | 32 ++++--- views/home-logged-in.hbs | 22 +++++ views/search.hbs | 6 ++ yarn.lock | 183 +++++++++++++++++++++++++++++++++++++-- 8 files changed, 251 insertions(+), 20 deletions(-) create mode 100644 views/home-logged-in.hbs diff --git a/config.example.json b/config.example.json index af8c047..66a8c76 100644 --- a/config.example.json +++ b/config.example.json @@ -1,4 +1,6 @@ { "port": 3000, - "siteName": "book-tracker" + "siteName": "book-tracker", + "jwtSecretKey": "SomethingAtLeast32CharactersLong!", + "tokenExpireDays": 7 } \ No newline at end of file diff --git a/package.json b/package.json index 96a8e52..2790d78 100644 --- a/package.json +++ b/package.json @@ -24,8 +24,10 @@ "fastify": "^2.8.0", "fastify-caching": "^5.0.0", "fastify-compress": "^0.11.0", + "fastify-cookie": "^3.1.0", "fastify-formbody": "^3.1.0", "fastify-helmet": "^3.0.1", + "fastify-jwt": "^1.0.0", "fastify-static": "^2.5.0", "handlebars": "^4.2.0", "html-minifier": "^4.0.0", diff --git a/routes/home.js b/routes/home.js index 70cd7a0..ae8f4df 100644 --- a/routes/home.js +++ b/routes/home.js @@ -1,6 +1,24 @@ async function routes(fastify, options) { fastify.get('/', async (request, reply) => { - reply.view('home.hbs', { text: 'test' }); + reply.view('home.hbs', { text: request.isLoggedInUser ? JSON.stringify(fastify.jwt.decode(request.cookies.token)) : 'you are NOT logged in' }); + }); + + fastify.get('/loggedin', async (request, reply) => { + const token = fastify.jwt.sign({ loggedin: true }); + const expireTime = fastify.siteConfig.tokenExpireDays * (24 * 60 * 60e3); // The section in parentheses is milliseconds in a day + reply + .setCookie('token', token, { + path: '/', + expires: new Date(Date.now() + expireTime), + maxAge: new Date(Date.now() + expireTime), // Both are set as a "just in case" + httpOnly: true, // Prevents JavaScript on the front end from grabbing it + sameSite: true, // Prevents the cookie from being used outside of this site + }) + .view('home-logged-in.hbs', { statuses: [{ title: 'books' }, { title: 'fun' }] }); + }); + + fastify.get('/loggedout', async (request, reply) => { + reply.clearCookie('token', { path: '/' }).redirect('/'); }); } diff --git a/routes/search.js b/routes/search.js index 3438a12..2f412c8 100644 --- a/routes/search.js +++ b/routes/search.js @@ -6,7 +6,7 @@ async function routes(fastify, options) { const search = new SearchController(searchTerm); const results = await search.searchOpenLibrary(); - reply.view('search.hbs', { results, searchTerm }); + reply.view('search.hbs', { results, searchTerm, arbitraryContent: request.isLoggedInUser ? JSON.stringify(fastify.jwt.decode(request.cookies.token)) : 'you are NOT logged in' }); }); } diff --git a/server.js b/server.js index 5549bb0..0b9ead5 100644 --- a/server.js +++ b/server.js @@ -14,19 +14,20 @@ try { const fastify = require('fastify')({ logger: process.env.NODE_ENV !== 'production', }); -fastify.register(require('fastify-helmet')); -fastify.register(require('fastify-compress')); -fastify.register(require('fastify-formbody')); -fastify.register(require('fastify-static'), { - root: path.join(__dirname, 'public'), +fastify.decorate('siteConfig', siteConfig); // Insert siteConfig into global fastify instance +fastify.register(require('fastify-helmet')); // Add security stuff +fastify.register(require('fastify-compress')); // Compress output data for smaller packet delivery +fastify.register(require('fastify-formbody')); // Enable fastify to parse data sent by POST from forms +fastify.register(require('fastify-static'), { // Enable delivering static content efficiently + root: path.join(__dirname, 'public'), // all static content will be delivered from the public/ folder }); -fastify.register(require('point-of-view'), { +fastify.register(require('point-of-view'), { // Adds the `view()` function to fastify's `reply` objects engine: { - handlebars: require('handlebars'), + handlebars: require('handlebars'), // Use handlebar as the render engine for `reply.view()` }, - templates: 'views', + templates: 'views', // Search for all files referenced in `reply.view()` within the `views/` folder options: { - useHtmlMinifier: require('html-minifier'), + useHtmlMinifier: require('html-minifier'), // Add a minifier to the rendered HTML output htmlMinifierOptions: { removeComments: true, removeCommentsFromCDATA: true, @@ -34,15 +35,24 @@ fastify.register(require('point-of-view'), { collapseBooleanAttributes: true, removeEmptyAttributes: true }, - partials: { + partials: { // Specifies the Handlebars Partials so `point-of-view` knows where they are within the `views` folder and what they're called when referenced in a `.hbs` file layout: 'layout.hbs', header: 'partials/header.hbs', footer: 'partials/footer.hbs', } }, }); +fastify.register(require('fastify-cookie')); // Enable reading and setting http-level cookies for the sole purpose of storing login tokens +fastify.register(require('fastify-jwt'), { // Enable creating, parsing, and verifying JSON Web Tokens from the global fastify object + secret: fastify.siteConfig.jwtSecretKey, // The secret key used to generate JWTs. Make it big and random! +}); + +// Every request, check to see if a valid token exists +fastify.addHook('onRequest', (request, reply, done) => { + request.isLoggedInUser = typeof request.cookies.token !== 'undefined' && fastify.jwt.verify(request.cookies.token); + done(); +}); -fastify.decorate('siteConfig', siteConfig); // Routes fastify.register(require('./routes/resources')); diff --git a/views/home-logged-in.hbs b/views/home-logged-in.hbs new file mode 100644 index 0000000..d8ba552 --- /dev/null +++ b/views/home-logged-in.hbs @@ -0,0 +1,22 @@ +{{#> layout }} + +{{#*inline "page-content-block" }} +
+

You are logged in!

+ + {{#each statuses }} +
+
+

A status about {{title}}

+
+ +
+ {{/each}} + +
+{{/inline}} + +{{/layout}} \ No newline at end of file diff --git a/views/search.hbs b/views/search.hbs index 2b2603a..beac538 100644 --- a/views/search.hbs +++ b/views/search.hbs @@ -28,4 +28,10 @@ {{/inline}} +{{#*inline "footer-block"}} +{{#if arbitraryContent}} + {{arbitraryContent}} +{{/if}} +{{/inline}} + {{/layout}} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 08670af..b36118c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,18 @@ # yarn lockfile v1 +"@types/jsonwebtoken@^8.3.2": + version "8.3.3" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.3.3.tgz#eafeea8239c74b02263d204c0e1175d5cd0bb85f" + integrity sha512-mofwpvFbm2AUxD5mg4iQPc2o/+ubM200R/L86kR17SeC99jM3gEnB9hy16ln3kZkxM5LnGpDJclxeUNEHhehng== + dependencies: + "@types/node" "*" + +"@types/node@*": + version "12.7.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.4.tgz#64db61e0359eb5a8d99b55e05c729f130a678b04" + integrity sha512-W0+n1Y+gK/8G2P/piTkBBN38Qc5Q1ZSO6B5H3QmPCUewaiXOo2GCAWZ4ElZCcNhjJuBSUSLGFUJnmlCn5+nxOQ== + "@types/q@^1.5.1": version "1.5.2" resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" @@ -177,6 +189,11 @@ browserslist@^4.0.0, browserslist@^4.6.3: electron-to-chromium "^1.3.247" node-releases "^1.1.29" +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= + buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" @@ -354,6 +371,11 @@ content-security-policy-builder@2.1.0: resolved "https://registry.yarnpkg.com/content-security-policy-builder/-/content-security-policy-builder-2.1.0.tgz#0a2364d769a3d7014eec79ff7699804deb8cfcbb" integrity sha512-/MtLWhJVvJNkA9dVLAp6fg9LxD2gfI6R2Fi1hPmfjYXSahJJzcfvoeDOxSyp4NvxMuwWv3WMssE9o31DoULHrQ== +cookie@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -659,6 +681,13 @@ duplexify@^4.1.1: readable-stream "^3.1.1" stream-shift "^1.0.0" +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== + dependencies: + safe-buffer "^5.0.1" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -786,6 +815,13 @@ fast-safe-stringify@^2.0.6: resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz#04b26106cc56681f51a044cfc0d76cf0008ac2c2" integrity sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg== +fastfall@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/fastfall/-/fastfall-1.5.1.tgz#3fee03331a49d1d39b3cdf7a5e9cd66f475e7b94" + integrity sha1-P+4DMxpJ0dObPN96XpzWb0dee5Q= + dependencies: + reusify "^1.0.0" + fastify-caching@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/fastify-caching/-/fastify-caching-5.0.0.tgz#28a3b5d2eaa242cd7f89429f025a339100f02b96" @@ -815,6 +851,14 @@ fastify-compress@^0.11.0: string-to-stream "^2.0.0" unzipper "^0.10.1" +fastify-cookie@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/fastify-cookie/-/fastify-cookie-3.1.0.tgz#01c3df5e44ef9feed7b7d25574c8348b8ea10b1d" + integrity sha512-xCy7UJcJcwNBbDPKiczyAvFFTGX9iUgz/7l91N/et97SdbweqYrI3IS8zQLGScWXLm638cvgXPLP7P9w6RYmIg== + dependencies: + cookie "^0.3.1" + fastify-plugin "^1.4.0" + fastify-formbody@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/fastify-formbody/-/fastify-formbody-3.1.0.tgz#604cdafdb9e3af6068e6d9940985baf692d6e922" @@ -844,7 +888,18 @@ fastify-helmet@^3.0.1: referrer-policy "^1.1.0" x-xss-protection "^1.1.0" -fastify-plugin@^1.0.0, fastify-plugin@^1.2.1, fastify-plugin@^1.5.0, fastify-plugin@^1.6.0: +fastify-jwt@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fastify-jwt/-/fastify-jwt-1.0.0.tgz#a732abda7ca89e2d7153bea13703177567eb77dd" + integrity sha512-nyRF43KfabpqiB0pke5WfyHH2lIKtytSWf64B3GcJBbIY2nUxJhJKyfm2bZByCu5H26QJrHvH+j9lfn6EfsdcA== + dependencies: + "@types/jsonwebtoken" "^8.3.2" + fastify-plugin "^1.2.0" + http-errors "^1.7.1" + jsonwebtoken "^8.3.0" + steed "^1.1.3" + +fastify-plugin@^1.0.0, fastify-plugin@^1.2.0, fastify-plugin@^1.2.1, fastify-plugin@^1.4.0, fastify-plugin@^1.5.0, fastify-plugin@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/fastify-plugin/-/fastify-plugin-1.6.0.tgz#c8198b08608f20c502b5dad26b36e9ae27206d7c" integrity sha512-lFa9txg8LZx4tljj33oG53nUXhVg0baZxtP9Pxi0dJmI0NQxzkDk5DS9kr3D7iMalUAp3mvIq16OQumc7eIvLA== @@ -881,13 +936,29 @@ fastify@^2.8.0: secure-json-parse "^1.0.0" tiny-lru "^6.0.1" -fastq@^1.6.0: +fastparallel@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/fastparallel/-/fastparallel-2.3.0.tgz#1e709bfb6a03993f3857e3ce7f01311ce7602613" + integrity sha1-HnCb+2oDmT84V+POfwExHOdgJhM= + dependencies: + reusify "^1.0.0" + xtend "^4.0.1" + +fastq@^1.3.0, fastq@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.6.0.tgz#4ec8a38f4ac25f21492673adb7eae9cfef47d1c2" integrity sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA== dependencies: reusify "^1.0.0" +fastseries@^1.7.0: + version "1.7.2" + resolved "https://registry.yarnpkg.com/fastseries/-/fastseries-1.7.2.tgz#d22ce13b9433dff3388d91dbd6b8bda9b21a0f4b" + integrity sha1-0izhO5Qz3/M4jZHb1ri9qbIaD0s= + dependencies: + reusify "^1.0.0" + xtend "^4.0.0" + feature-policy@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/feature-policy/-/feature-policy-0.3.0.tgz#7430e8e54a40da01156ca30aaec1a381ce536069" @@ -1125,6 +1196,17 @@ html-minifier@^4.0.0: relateurl "^0.2.7" uglify-js "^3.5.1" +http-errors@^1.7.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + http-errors@~1.6.2: version "1.6.3" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" @@ -1161,7 +1243,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -1351,6 +1433,39 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +jsonwebtoken@^8.3.0: + version "8.5.1" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" + integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== + dependencies: + jws "^3.2.2" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + semver "^5.6.0" + +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jws@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + light-my-request@^3.4.1: version "3.4.1" resolved "https://registry.yarnpkg.com/light-my-request/-/light-my-request-3.4.1.tgz#c30087005f6ae64ce5ef92c2484b1ab93c71ad3e" @@ -1364,11 +1479,46 @@ listenercount@~1.0.1: resolved "https://registry.yarnpkg.com/listenercount/-/listenercount-1.0.1.tgz#84c8a72ab59c4725321480c975e6508342e70937" integrity sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc= +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8= + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY= + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M= + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w= + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= + lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= + lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" @@ -2214,7 +2364,7 @@ semver-store@^0.3.0: resolved "https://registry.yarnpkg.com/semver-store/-/semver-store-0.3.0.tgz#ce602ff07df37080ec9f4fb40b29576547befbe9" integrity sha512-TcZvGMMy9vodEFSse30lWinkj+JgOBvPn8wRItpQRSayhc+4ssDs335uklkfvQQJgL/WvmHLVj4Ycv2s7QCQMg== -semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: +semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -2258,6 +2408,11 @@ setprototypeof@1.1.0: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + sharp@^0.23.0: version "0.23.0" resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.23.0.tgz#e34c7c44af219f8fd6b780adaa2b44aa6a22cbd9" @@ -2338,7 +2493,7 @@ stable@^0.1.8: resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== -"statuses@>= 1.4.0 < 2": +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2": version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= @@ -2348,6 +2503,17 @@ statuses@~1.4.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== +steed@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/steed/-/steed-1.1.3.tgz#f1525dd5adb12eb21bf74749537668d625b9abc5" + integrity sha1-8VJd1a2xLrIb90dJU3Zo1iW5q8U= + dependencies: + fastfall "^1.5.0" + fastparallel "^2.2.0" + fastq "^1.3.0" + fastseries "^1.7.0" + reusify "^1.0.0" + stream-shift@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" @@ -2528,6 +2694,11 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + "traverse@>=0.3.0 <0.4": version "0.3.9" resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" @@ -2649,7 +2820,7 @@ x-xss-protection@^1.1.0: resolved "https://registry.yarnpkg.com/x-xss-protection/-/x-xss-protection-1.3.0.tgz#3e3a8dd638da80421b0e9fff11a2dbe168f6d52c" integrity sha512-kpyBI9TlVipZO4diReZMAHWtS0MMa/7Kgx8hwG/EuZLiA6sg4Ah/4TRdASHhRRN3boobzcYgFRUFSgHRge6Qhg== -xtend@~4.0.1: +xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==