From b915b504ef0c78100b01f9f4b2303c1594983a9e Mon Sep 17 00:00:00 2001 From: shuli-ogp <63710093+shuli-ogp@users.noreply.github.com> Date: Tue, 3 Nov 2020 10:12:30 +0800 Subject: [PATCH 01/26] chore: shift webhook field to bottom of settings page, update copy (#553) --- .../modules/forms/admin/css/settings-form.css | 11 +++ .../settings-form.client.view.html | 69 ++++++++++--------- 2 files changed, 46 insertions(+), 34 deletions(-) diff --git a/src/public/modules/forms/admin/css/settings-form.css b/src/public/modules/forms/admin/css/settings-form.css index 86209bac74..adf25f65f9 100644 --- a/src/public/modules/forms/admin/css/settings-form.css +++ b/src/public/modules/forms/admin/css/settings-form.css @@ -15,6 +15,17 @@ margin: 0; } +#settings-form #enable-webhooks .field-optional { + font-size: 15px; + font-weight: normal; + color: #b8b8b8; + margin-left: 10px; +} + +#settings-form .webhook-divider { + margin-top: 40px; +} + #settings-form #enable-webhooks .glyphicon { margin-left: 40px !important; } diff --git a/src/public/modules/forms/admin/directiveViews/settings-form.client.view.html b/src/public/modules/forms/admin/directiveViews/settings-form.client.view.html index be54e8eb11..4e955e2e06 100644 --- a/src/public/modules/forms/admin/directiveViews/settings-form.client.view.html +++ b/src/public/modules/forms/admin/directiveViews/settings-form.client.view.html @@ -251,6 +251,39 @@
+ + + + + + +
+
+ Mode for receiving form data +
+
+ + Storage + Email + +
+
+ +
+
beta + (optional)
- -
- - - - - - - -
-
- Mode for receiving form data -
-
- - Storage - Email - -
-
From f3320bbe8de88a706e57495ae087e11d9117b057 Mon Sep 17 00:00:00 2001 From: Antariksh Mahajan Date: Tue, 3 Nov 2020 14:19:45 +0800 Subject: [PATCH 02/26] refactor: convert MyInfo hash update to static domain method (#562) --- .../controllers/myinfo.server.controller.js | 42 +---- src/app/models/myinfo_hash.server.model.ts | 35 ++++- src/types/myinfo_hash.ts | 19 ++- .../models/myinfo_hash.server.model.spec.ts | 148 ++++++++++++++++++ 4 files changed, 200 insertions(+), 44 deletions(-) create mode 100644 tests/unit/backend/models/myinfo_hash.server.model.spec.ts diff --git a/src/app/controllers/myinfo.server.controller.js b/src/app/controllers/myinfo.server.controller.js index c393bf2625..43c899e06a 100644 --- a/src/app/controllers/myinfo.server.controller.js +++ b/src/app/controllers/myinfo.server.controller.js @@ -83,45 +83,17 @@ exports.addMyInfo = (myInfoService) => async (req, res, next) => { Promise.props(readOnlyHashPromises) .then((readOnlyHashes) => { - // Add to DB only if uinFin-form combo not already present - let filter = { - uinFin: hashedUinFin, - form: formId, - } - MyInfoHash.findOneAndUpdate( - filter, - { - $set: _.extend( - { - fields: readOnlyHashes, - expireAt: Date.now() + myInfoService.spCookieMaxAge, - }, - filter, - ), - }, - { - upsert: true, - }, - (err) => { - if (err) { - res.locals.myInfoError = true - logger.error({ - message: 'Error writing to DB', - meta: { - action: 'addMyInfo', - ...createReqMeta(req), - formId, - }, - error: err, - }) - } - return next() - }, + return MyInfoHash.updateHashes( + hashedUinFin, + formId, + readOnlyHashes, + myInfoService.spCookieMaxAge, ) }) + .then(() => next()) .catch((error) => { logger.error({ - message: 'Error hashing MyInfo fields', + message: 'Error saving MyInfo hashes', meta: { action: 'addMyInfo', ...createReqMeta(req), diff --git a/src/app/models/myinfo_hash.server.model.ts b/src/app/models/myinfo_hash.server.model.ts index 29727d6a73..8ab2f54b6f 100644 --- a/src/app/models/myinfo_hash.server.model.ts +++ b/src/app/models/myinfo_hash.server.model.ts @@ -1,6 +1,6 @@ -import { Model, Mongoose, Schema } from 'mongoose' +import { Mongoose, Schema } from 'mongoose' -import { IMyInfoHashSchema } from '../../types' +import { IHashes, IMyInfoHashModel, IMyInfoHashSchema } from '../../types' import { FORM_SCHEMA_ID } from './form.server.model' @@ -43,8 +43,33 @@ MyInfoHashSchema.index({ }) MyInfoHashSchema.index({ expireAt: 1 }, { expireAfterSeconds: 0 }) +MyInfoHashSchema.statics.updateHashes = async function ( + this: IMyInfoHashModel, + hashedUinFin: string, + formId: string, + readOnlyHashes: IHashes, + spCookieMaxAge: number, +): Promise { + return this.findOneAndUpdate( + { + uinFin: hashedUinFin, + form: formId, + }, + { + $set: { + fields: readOnlyHashes, + expireAt: new Date(Date.now() + spCookieMaxAge), + }, + }, + { upsert: true, new: true }, + ) +} + const compileMyInfoHashModel = (db: Mongoose) => - db.model(MYINFO_HASH_SCHEMA_ID, MyInfoHashSchema) + db.model( + MYINFO_HASH_SCHEMA_ID, + MyInfoHashSchema, + ) /** * Retrieves the MyInfoHash model on the given Mongoose instance. If the model is @@ -52,9 +77,9 @@ const compileMyInfoHashModel = (db: Mongoose) => * @param db The mongoose instance to retrieve the MyInfoHash model from * @returns The MyInfoHash model */ -const getMyInfoHashModel = (db: Mongoose) => { +const getMyInfoHashModel = (db: Mongoose): IMyInfoHashModel => { try { - return db.model(MYINFO_HASH_SCHEMA_ID) as Model + return db.model(MYINFO_HASH_SCHEMA_ID) as IMyInfoHashModel } catch { return compileMyInfoHashModel(db) } diff --git a/src/types/myinfo_hash.ts b/src/types/myinfo_hash.ts index 4a591a749d..32e51f23f8 100644 --- a/src/types/myinfo_hash.ts +++ b/src/types/myinfo_hash.ts @@ -1,11 +1,13 @@ -import { Document } from 'mongoose' +import { Document, Model } from 'mongoose' import { MyInfoAttribute } from './field' import { IFormSchema } from './form' -type IHashes = { - [key in MyInfoAttribute]: string -} +export type IHashes = Partial< + { + [key in MyInfoAttribute]: string + } +> interface IMyInfoHash { uinFin: string @@ -17,3 +19,12 @@ interface IMyInfoHash { } export interface IMyInfoHashSchema extends IMyInfoHash, Document {} + +export interface IMyInfoHashModel extends Model { + updateHashes: ( + hashedUinFin: string, + formId: string, + readOnlyHashes: IHashes, + spCookieMaxAge: number, + ) => Promise +} diff --git a/tests/unit/backend/models/myinfo_hash.server.model.spec.ts b/tests/unit/backend/models/myinfo_hash.server.model.spec.ts new file mode 100644 index 0000000000..784189d476 --- /dev/null +++ b/tests/unit/backend/models/myinfo_hash.server.model.spec.ts @@ -0,0 +1,148 @@ +import { ObjectId } from 'bson' +import { omit, pick } from 'lodash' +import mongoose from 'mongoose' + +import getMyInfoHashModel from 'src/app/models/myinfo_hash.server.model' + +import dbHandler from '../helpers/jest-db' + +const MyInfoHash = getMyInfoHashModel(mongoose) + +const DEFAULT_PARAMS = { + uinFin: 'testUinFin', + form: new ObjectId(), + fields: { name: 'mockHash' }, + expireAt: new Date(Date.now()), + created: new Date(Date.now()), +} +const DEFAULT_COOKIE_MAX_AGE = 5 + +describe('MyInfo Hash Model', () => { + beforeAll(async () => await dbHandler.connect()) + beforeEach(async () => await dbHandler.clearDatabase()) + afterAll(async () => await dbHandler.closeDatabase()) + + describe('Schema', () => { + it('should create and save successfully', async () => { + // Act + const actual = await MyInfoHash.create(DEFAULT_PARAMS) + + // Assert + // All fields should exist + // Object Id should be defined when successfully saved to MongoDB. + expect(actual._id).toBeDefined() + expect( + pick(actual, ['uinFin', 'form', 'fields', 'created', 'expireAt']), + ).toEqual(DEFAULT_PARAMS) + }) + + it('should throw validation error on missing uinFin', async () => { + // Arrange + const missingParams = omit(DEFAULT_PARAMS, 'uinFin') + + // Act + const myInfoHash = new MyInfoHash(missingParams) + const actualPromise = myInfoHash.save() + + // Assert + await expect(actualPromise).rejects.toThrowError( + mongoose.Error.ValidationError, + ) + }) + + it('should throw validation error on missing form', async () => { + // Arrange + const missingParams = omit(DEFAULT_PARAMS, 'form') + + // Act + const myInfoHash = new MyInfoHash(missingParams) + const actualPromise = myInfoHash.save() + + // Assert + await expect(actualPromise).rejects.toThrowError( + mongoose.Error.ValidationError, + ) + }) + + it('should throw validation error on missing fields', async () => { + // Arrange + const missingParams = omit(DEFAULT_PARAMS, 'fields') + + // Act + const myInfoHash = new MyInfoHash(missingParams) + const actualPromise = myInfoHash.save() + + // Assert + await expect(actualPromise).rejects.toThrowError( + mongoose.Error.ValidationError, + ) + }) + + it('should throw validation error on missing expireAt', async () => { + // Arrange + const missingParams = omit(DEFAULT_PARAMS, 'expireAt') + + // Act + const myInfoHash = new MyInfoHash(missingParams) + const actualPromise = myInfoHash.save() + + // Assert + await expect(actualPromise).rejects.toThrowError( + mongoose.Error.ValidationError, + ) + }) + }) + + describe('Statics', () => { + describe('updateHashes', () => { + it('should create successfully when document does not exist', async () => { + // Should have no documents yet. + await expect(MyInfoHash.countDocuments()).resolves.toEqual(0) + + // Act + const actual = await MyInfoHash.updateHashes( + DEFAULT_PARAMS.uinFin, + DEFAULT_PARAMS.form.toHexString(), + DEFAULT_PARAMS.fields, + DEFAULT_COOKIE_MAX_AGE, + ) + + // Assert + // Should now have one document. + await expect(MyInfoHash.countDocuments()).resolves.toEqual(1) + const found = await MyInfoHash.findOne({}) + // Both the returned document and the found document should match + expect(pick(actual, ['uinFin', 'form', 'fields'])).toEqual( + pick(DEFAULT_PARAMS, ['uinFin', 'form', 'fields']), + ) + expect(pick(found, ['uinFin', 'form', 'fields'])).toEqual( + pick(DEFAULT_PARAMS, ['uinFin', 'form', 'fields']), + ) + }) + + it('should update successfully when a document already exists', async () => { + // Arrange + // Insert mock document into collection. + await MyInfoHash.create(DEFAULT_PARAMS) + // Should have the added document. + await expect(MyInfoHash.countDocuments()).resolves.toEqual(1) + + const mockFields = { sex: 'F' } + + // Act + const actual = await MyInfoHash.updateHashes( + DEFAULT_PARAMS.uinFin, + DEFAULT_PARAMS.form.toHexString(), + mockFields, + DEFAULT_COOKIE_MAX_AGE, + ) + // Assert + await expect(MyInfoHash.countDocuments()).resolves.toEqual(1) + const found = await MyInfoHash.findOne({}) + // Both the returned document and the found document should match + expect(actual!.fields).toEqual(mockFields) + expect(found!.fields).toEqual(mockFields) + }) + }) + }) +}) From c7a6222a2148c1574b2116ed731eee6aabb330e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Nov 2020 12:06:53 +0800 Subject: [PATCH 03/26] chore(deps-dev): bump jest from 26.5.3 to 26.6.2 (#570) Bumps [jest](https://github.com/facebook/jest) from 26.5.3 to 26.6.2. - [Release notes](https://github.com/facebook/jest/releases) - [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md) - [Commits](https://github.com/facebook/jest/compare/v26.5.3...v26.6.2) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 1345 ++++++++++++++++++--------------------------- package.json | 2 +- 2 files changed, 545 insertions(+), 802 deletions(-) diff --git a/package-lock.json b/package-lock.json index 255f9976a3..120379ad85 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3055,23 +3055,23 @@ "dev": true }, "@jest/console": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.5.2.tgz", - "integrity": "sha512-lJELzKINpF1v74DXHbCRIkQ/+nUV1M+ntj+X1J8LxCgpmJZjfLmhFejiMSbjjD66fayxl5Z06tbs3HMyuik6rw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.5.2", - "jest-util": "^26.5.2", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -3081,15 +3081,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -3131,12 +3122,12 @@ "dev": true }, "jest-util": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.5.2.tgz", - "integrity": "sha512-WTL675bK+GSSAYgS8z9FWdCT2nccO1yTIplNLPlP0OD8tUk/H5IrWKMMRudIQQ0qp8bb4k+1Qa8CxGKq9qnYdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -3156,34 +3147,34 @@ } }, "@jest/core": { - "version": "26.5.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.5.3.tgz", - "integrity": "sha512-CiU0UKFF1V7KzYTVEtFbFmGLdb2g4aTtY0WlyUfLgj/RtoTnJFhh50xKKr7OYkdmBUlGFSa2mD1TU3UZ6OLd4g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.2.tgz", + "integrity": "sha512-x0v0LVlEslGYGYk4StT90NUp7vbFBrh0K7KDyAg3hMhG0drrxOIQHsY05uC7XVlKHXFgGI+HdnU35qewMZOLFQ==", "dev": true, "requires": { - "@jest/console": "^26.5.2", - "@jest/reporters": "^26.5.3", - "@jest/test-result": "^26.5.2", - "@jest/transform": "^26.5.2", - "@jest/types": "^26.5.2", + "@jest/console": "^26.6.2", + "@jest/reporters": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.5.2", - "jest-config": "^26.5.3", - "jest-haste-map": "^26.5.2", - "jest-message-util": "^26.5.2", + "jest-changed-files": "^26.6.2", + "jest-config": "^26.6.2", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.5.2", - "jest-resolve-dependencies": "^26.5.3", - "jest-runner": "^26.5.3", - "jest-runtime": "^26.5.3", - "jest-snapshot": "^26.5.3", - "jest-util": "^26.5.2", - "jest-validate": "^26.5.3", - "jest-watcher": "^26.5.2", + "jest-resolve": "^26.6.2", + "jest-resolve-dependencies": "^26.6.2", + "jest-runner": "^26.6.2", + "jest-runtime": "^26.6.2", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "jest-watcher": "^26.6.2", "micromatch": "^4.0.2", "p-each-series": "^2.1.0", "rimraf": "^3.0.0", @@ -3192,9 +3183,9 @@ }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -3204,15 +3195,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -3260,12 +3242,12 @@ "dev": true }, "jest-util": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.5.2.tgz", - "integrity": "sha512-WTL675bK+GSSAYgS8z9FWdCT2nccO1yTIplNLPlP0OD8tUk/H5IrWKMMRudIQQ0qp8bb4k+1Qa8CxGKq9qnYdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -3294,21 +3276,21 @@ } }, "@jest/environment": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.5.2.tgz", - "integrity": "sha512-YjhCD/Zhkz0/1vdlS/QN6QmuUdDkpgBdK4SdiVg4Y19e29g4VQYN5Xg8+YuHjdoWGY7wJHMxc79uDTeTOy9Ngw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "requires": { - "@jest/fake-timers": "^26.5.2", - "@jest/types": "^26.5.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", "@types/node": "*", - "jest-mock": "^26.5.2" + "jest-mock": "^26.6.2" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -3318,15 +3300,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -3379,23 +3352,23 @@ } }, "@jest/fake-timers": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.5.2.tgz", - "integrity": "sha512-09Hn5Oraqt36V1akxQeWMVL0fR9c6PnEhpgLaYvREXZJAh2H2Y+QLCsl0g7uMoJeoWJAuz4tozk1prbR1Fc1sw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", "@types/node": "*", - "jest-message-util": "^26.5.2", - "jest-mock": "^26.5.2", - "jest-util": "^26.5.2" + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -3405,15 +3378,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -3455,12 +3419,12 @@ "dev": true }, "jest-util": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.5.2.tgz", - "integrity": "sha512-WTL675bK+GSSAYgS8z9FWdCT2nccO1yTIplNLPlP0OD8tUk/H5IrWKMMRudIQQ0qp8bb4k+1Qa8CxGKq9qnYdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -3480,20 +3444,20 @@ } }, "@jest/globals": { - "version": "26.5.3", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.5.3.tgz", - "integrity": "sha512-7QztI0JC2CuB+Wx1VdnOUNeIGm8+PIaqngYsZXQCkH2QV0GFqzAYc9BZfU0nuqA6cbYrWh5wkuMzyii3P7deug==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", + "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", "dev": true, "requires": { - "@jest/environment": "^26.5.2", - "@jest/types": "^26.5.2", - "expect": "^26.5.3" + "@jest/environment": "^26.6.2", + "@jest/types": "^26.6.2", + "expect": "^26.6.2" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -3503,15 +3467,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -3564,16 +3519,16 @@ } }, "@jest/reporters": { - "version": "26.5.3", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.5.3.tgz", - "integrity": "sha512-X+vR0CpfMQzYcYmMFKNY9n4jklcb14Kffffp7+H/MqitWnb0440bW2L76NGWKAa+bnXhNoZr+lCVtdtPmfJVOQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", + "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.5.2", - "@jest/test-result": "^26.5.2", - "@jest/transform": "^26.5.2", - "@jest/types": "^26.5.2", + "@jest/console": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", @@ -3584,22 +3539,22 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.5.2", - "jest-resolve": "^26.5.2", - "jest-util": "^26.5.2", - "jest-worker": "^26.5.0", + "jest-haste-map": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", "node-notifier": "^8.0.0", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", "terminal-link": "^2.0.0", - "v8-to-istanbul": "^6.0.1" + "v8-to-istanbul": "^7.0.0" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -3609,15 +3564,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -3659,12 +3605,12 @@ "dev": true }, "jest-util": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.5.2.tgz", - "integrity": "sha512-WTL675bK+GSSAYgS8z9FWdCT2nccO1yTIplNLPlP0OD8tUk/H5IrWKMMRudIQQ0qp8bb4k+1Qa8CxGKq9qnYdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -3690,9 +3636,9 @@ } }, "@jest/source-map": { - "version": "26.5.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.5.0.tgz", - "integrity": "sha512-jWAw9ZwYHJMe9eZq/WrsHlwF8E3hM9gynlcDpOyCb9bR8wEd9ZNBZCi7/jZyzHxC7t3thZ10gO2IDhu0bPKS5g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", + "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", "dev": true, "requires": { "callsites": "^3.0.0", @@ -3709,21 +3655,21 @@ } }, "@jest/test-result": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.5.2.tgz", - "integrity": "sha512-E/Zp6LURJEGSCWpoMGmCFuuEI1OWuI3hmZwmULV0GsgJBh7u0rwqioxhRU95euUuviqBDN8ruX/vP/4bwYolXw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "requires": { - "@jest/console": "^26.5.2", - "@jest/types": "^26.5.2", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -3733,15 +3679,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -3794,34 +3731,34 @@ } }, "@jest/test-sequencer": { - "version": "26.5.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.5.3.tgz", - "integrity": "sha512-Wqzb7aQ13L3T47xHdpUqYMOpiqz6Dx2QDDghp5AV/eUDXR7JieY+E1s233TQlNyl+PqtqgjVokmyjzX/HA51BA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.2.tgz", + "integrity": "sha512-iHiEXLMP69Ohe6kFMOVz6geADRxwK+OkLGg0VIGfZrUdkJGiCpghkMb2946FLh7jvzOwwZGyQoMi+kaHiOdM5g==", "dev": true, "requires": { - "@jest/test-result": "^26.5.2", + "@jest/test-result": "^26.6.2", "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.5.2", - "jest-runner": "^26.5.3", - "jest-runtime": "^26.5.3" + "jest-haste-map": "^26.6.2", + "jest-runner": "^26.6.2", + "jest-runtime": "^26.6.2" } }, "@jest/transform": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.5.2.tgz", - "integrity": "sha512-AUNjvexh+APhhmS8S+KboPz+D3pCxPvEAGduffaAJYxIFxGi/ytZQkrqcKDUU0ERBAo5R7087fyOYr2oms1seg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", + "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "babel-plugin-istanbul": "^6.0.0", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.5.2", + "jest-haste-map": "^26.6.2", "jest-regex-util": "^26.0.0", - "jest-util": "^26.5.2", + "jest-util": "^26.6.2", "micromatch": "^4.0.2", "pirates": "^4.0.1", "slash": "^3.0.0", @@ -3830,9 +3767,9 @@ }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -3842,15 +3779,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -3892,12 +3820,12 @@ "dev": true }, "jest-util": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.5.2.tgz", - "integrity": "sha512-WTL675bK+GSSAYgS8z9FWdCT2nccO1yTIplNLPlP0OD8tUk/H5IrWKMMRudIQQ0qp8bb4k+1Qa8CxGKq9qnYdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -4346,9 +4274,9 @@ "integrity": "sha512-zneUmi5I6oSkGBqkRP9rxbWX1mi6Yj7gNV+WNffmJLf8x4cnV0MGqXFNSP90NZ1kRRLCOdKBf9RIVD1TMg4aog==" }, "@types/babel__core": { - "version": "7.1.10", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.10.tgz", - "integrity": "sha512-x8OM8XzITIMyiwl5Vmo2B1cR1S1Ipkyv4mdlbJjMa1lmuKvKY9FrBbEANIaMlnWn5Rf7uO+rC/VgYabNkE17Hw==", + "version": "7.1.11", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.11.tgz", + "integrity": "sha512-E5nSOzrjnvhURYnbOR2dClTqcyhPbPvtEwLHf7JJADKedPbcZsoJVfP+I2vBNfBjz4bnZIuhL/tNmRi5nJ7Jlw==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -4576,9 +4504,9 @@ } }, "@types/graceful-fs": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", - "integrity": "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.4.tgz", + "integrity": "sha512-mWA/4zFQhfvOA8zWkXobwJvBD7vzcxgrOQ0J5CH1votGqdq9m7+FwtGaqyCZqC3NyyBkc9z4m+iry4LlqcMWJg==", "dev": true, "requires": { "@types/node": "*" @@ -4830,9 +4758,9 @@ "dev": true }, "@types/prettier": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.1.2.tgz", - "integrity": "sha512-IiPhNnenzkqdSdQH3ifk9LoX7oQe61ZlDdDO4+MUv6FyWdPGDPr26gCPVs3oguZEMq//nFZZpwUZcVuNJsG+DQ==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.1.5.tgz", + "integrity": "sha512-UEyp8LwZ4Dg30kVU2Q3amHHyTn1jEdhCIE59ANed76GaT1Vp76DD3ZWSAxgCrw6wJ0TqeoBpqmfUHiUDPs//HQ==", "dev": true }, "@types/promise-retry": { @@ -6379,25 +6307,25 @@ } }, "babel-jest": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.5.2.tgz", - "integrity": "sha512-U3KvymF3SczA3vOL/cgiUFOznfMET+XDIXiWnoJV45siAp2pLMG8i2+/MGZlAC3f/F6Q40LR4M4qDrWZ9wkK8A==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.2.tgz", + "integrity": "sha512-pysyz/mZ7T5sozKnvSa1n7QEf22W9yc+dUmn2zNuQTN0saG51q8A/8k9wbED9X4YNxmwjuhIwf4JRXXQGzui3Q==", "dev": true, "requires": { - "@jest/transform": "^26.5.2", - "@jest/types": "^26.5.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", "@types/babel__core": "^7.1.7", "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.5.0", + "babel-preset-jest": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "slash": "^3.0.0" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -6407,15 +6335,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -6521,9 +6440,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "26.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.5.0.tgz", - "integrity": "sha512-ck17uZFD3CDfuwCLATWZxkkuGGFhMij8quP8CNhwj8ek1mqFgbFzRJ30xwC04LLscj/aKsVFfRST+b5PT7rSuw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", + "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", "dev": true, "requires": { "@babel/template": "^7.3.3", @@ -7026,9 +6945,9 @@ } }, "babel-preset-current-node-syntax": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.4.tgz", - "integrity": "sha512-5/INNCYhUGqw7VbVjT/hb3ucjgkVHKXY7lX3ZjlN4gm565VyFmJUrJ/h+h16ECVB38R/9SF6aACydpKMLZ/c9w==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.0.tgz", + "integrity": "sha512-mGkvkpocWJes1CmMKtgGUwCeeq0pOhALyymozzDWYomHTbDLwueDYG6p4TK1YOeYHCzBzYPsWkgTto10JubI1Q==", "dev": true, "requires": { "@babel/plugin-syntax-async-generators": "^7.8.4", @@ -7041,7 +6960,8 @@ "@babel/plugin-syntax-numeric-separator": "^7.8.3", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" } }, "babel-preset-env": { @@ -7104,13 +7024,13 @@ } }, "babel-preset-jest": { - "version": "26.5.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.5.0.tgz", - "integrity": "sha512-F2vTluljhqkiGSJGBg/jOruA8vIIIL11YrxRcO7nviNTMbbofPSHwnm8mgP7d/wS7wRSexRoI6X1A6T74d4LQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", + "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^26.5.0", - "babel-preset-current-node-syntax": "^0.1.3" + "babel-plugin-jest-hoist": "^26.6.2", + "babel-preset-current-node-syntax": "^1.0.0" } }, "babel-preset-react": { @@ -8250,6 +8170,12 @@ "safe-buffer": "^5.0.1" } }, + "cjs-module-lexer": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", + "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", + "dev": true + }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", @@ -11527,23 +11453,23 @@ } }, "expect": { - "version": "26.5.3", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.5.3.tgz", - "integrity": "sha512-kkpOhGRWGOr+TEFUnYAjfGvv35bfP+OlPtqPIJpOCR9DVtv8QV+p8zG0Edqafh80fsjeE+7RBcVUq1xApnYglw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "ansi-styles": "^4.0.0", "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.5.2", - "jest-message-util": "^26.5.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -11553,15 +11479,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -11602,12 +11519,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -13890,6 +13801,15 @@ "rgba-regex": "^1.0.0" } }, + "is-core-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.0.0.tgz", + "integrity": "sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -14367,20 +14287,20 @@ } }, "jest": { - "version": "26.5.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.5.3.tgz", - "integrity": "sha512-uJi3FuVSLmkZrWvaDyaVTZGLL8WcfynbRnFXyAHuEtYiSZ+ijDDIMOw1ytmftK+y/+OdAtsG9QrtbF7WIBmOyA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.2.tgz", + "integrity": "sha512-lL0hW7mh/2hhQmpo/1fDWQji/BUB3Xcxxj7r0fAOa3t56OAnwbE0HEl2bZ7XjAwV5TXOt8UpCgaa/WBJBB0CYw==", "dev": true, "requires": { - "@jest/core": "^26.5.3", + "@jest/core": "^26.6.2", "import-local": "^3.0.2", - "jest-cli": "^26.5.3" + "jest-cli": "^26.6.2" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -14390,15 +14310,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -14440,33 +14351,33 @@ "dev": true }, "jest-cli": { - "version": "26.5.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.5.3.tgz", - "integrity": "sha512-HkbSvtugpSXBf2660v9FrNVUgxvPkssN8CRGj9gPM8PLhnaa6zziFiCEKQAkQS4uRzseww45o0TR+l6KeRYV9A==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.2.tgz", + "integrity": "sha512-5SBxa0bXc43fTHgxMfonDFDWTmQTiC6RSS4GpKhVekWkwpaeMHWt/FvGIy5GlTHMbCpzULWV++N3v93OdlFfQA==", "dev": true, "requires": { - "@jest/core": "^26.5.3", - "@jest/test-result": "^26.5.2", - "@jest/types": "^26.5.2", + "@jest/core": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", "import-local": "^3.0.2", "is-ci": "^2.0.0", - "jest-config": "^26.5.3", - "jest-util": "^26.5.2", - "jest-validate": "^26.5.3", + "jest-config": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", "prompts": "^2.0.1", "yargs": "^15.4.1" } }, "jest-util": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.5.2.tgz", - "integrity": "sha512-WTL675bK+GSSAYgS8z9FWdCT2nccO1yTIplNLPlP0OD8tUk/H5IrWKMMRudIQQ0qp8bb4k+1Qa8CxGKq9qnYdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -14486,20 +14397,20 @@ } }, "jest-changed-files": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.5.2.tgz", - "integrity": "sha512-qSmssmiIdvM5BWVtyK/nqVpN3spR5YyvkvPqz1x3BR1bwIxsWmU/MGwLoCrPNLbkG2ASAKfvmJpOduEApBPh2w==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", + "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "execa": "^4.0.0", "throat": "^5.0.0" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -14509,15 +14420,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -14564,9 +14466,9 @@ } }, "execa": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz", - "integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", "dev": true, "requires": { "cross-spawn": "^7.0.0", @@ -14643,35 +14545,35 @@ } }, "jest-config": { - "version": "26.5.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.5.3.tgz", - "integrity": "sha512-NVhZiIuN0GQM6b6as4CI5FSCyXKxdrx5ACMCcv/7Pf+TeCajJhJc+6dwgdAVPyerUFB9pRBIz3bE7clSrRge/w==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.2.tgz", + "integrity": "sha512-0ApZqPd+L/BUWvNj1GHcptb5jwF23lo+BskjgJV/Blht1hgpu6eIwaYRgHPrS6I6HrxwRfJvlGbzoZZVb3VHTA==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.5.3", - "@jest/types": "^26.5.2", - "babel-jest": "^26.5.2", + "@jest/test-sequencer": "^26.6.2", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.2", "chalk": "^4.0.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.5.2", - "jest-environment-node": "^26.5.2", + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.5.3", + "jest-jasmine2": "^26.6.2", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.5.2", - "jest-util": "^26.5.2", - "jest-validate": "^26.5.3", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", "micromatch": "^4.0.2", - "pretty-format": "^26.5.2" + "pretty-format": "^26.6.2" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -14681,15 +14583,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -14736,19 +14629,13 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, "jest-util": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.5.2.tgz", - "integrity": "sha512-WTL675bK+GSSAYgS8z9FWdCT2nccO1yTIplNLPlP0OD8tUk/H5IrWKMMRudIQQ0qp8bb4k+1Qa8CxGKq9qnYdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -14757,15 +14644,15 @@ } }, "pretty-format": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.5.2.tgz", - "integrity": "sha512-VizyV669eqESlkOikKJI8Ryxl/kPpbdLwNdPs2GrbQs18MpySB5S0Yo0N7zkg2xTRiFq4CFw8ct5Vg4a0xP0og==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, "supports-color": { @@ -14852,22 +14739,22 @@ } }, "jest-each": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.5.2.tgz", - "integrity": "sha512-w7D9FNe0m2D3yZ0Drj9CLkyF/mGhmBSULMQTypzAKR746xXnjUrK8GUJdlLTWUF6dd0ks3MtvGP7/xNFr9Aphg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", + "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "jest-get-type": "^26.3.0", - "jest-util": "^26.5.2", - "pretty-format": "^26.5.2" + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -14877,15 +14764,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -14932,19 +14810,13 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, "jest-util": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.5.2.tgz", - "integrity": "sha512-WTL675bK+GSSAYgS8z9FWdCT2nccO1yTIplNLPlP0OD8tUk/H5IrWKMMRudIQQ0qp8bb4k+1Qa8CxGKq9qnYdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -14953,15 +14825,15 @@ } }, "pretty-format": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.5.2.tgz", - "integrity": "sha512-VizyV669eqESlkOikKJI8Ryxl/kPpbdLwNdPs2GrbQs18MpySB5S0Yo0N7zkg2xTRiFq4CFw8ct5Vg4a0xP0og==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, "supports-color": { @@ -14976,24 +14848,24 @@ } }, "jest-environment-jsdom": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.5.2.tgz", - "integrity": "sha512-fWZPx0bluJaTQ36+PmRpvUtUlUFlGGBNyGX1SN3dLUHHMcQ4WseNEzcGGKOw4U5towXgxI4qDoI3vwR18H0RTw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", + "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", "dev": true, "requires": { - "@jest/environment": "^26.5.2", - "@jest/fake-timers": "^26.5.2", - "@jest/types": "^26.5.2", + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", "@types/node": "*", - "jest-mock": "^26.5.2", - "jest-util": "^26.5.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2", "jsdom": "^16.4.0" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -15003,15 +14875,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -15053,12 +14916,12 @@ "dev": true }, "jest-util": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.5.2.tgz", - "integrity": "sha512-WTL675bK+GSSAYgS8z9FWdCT2nccO1yTIplNLPlP0OD8tUk/H5IrWKMMRudIQQ0qp8bb4k+1Qa8CxGKq9qnYdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -15078,23 +14941,23 @@ } }, "jest-environment-node": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.5.2.tgz", - "integrity": "sha512-YHjnDsf/GKFCYMGF1V+6HF7jhY1fcLfLNBDjhAOvFGvt6d8vXvNdJGVM7uTZ2VO/TuIyEFhPGaXMX5j3h7fsrA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", + "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", "dev": true, "requires": { - "@jest/environment": "^26.5.2", - "@jest/fake-timers": "^26.5.2", - "@jest/types": "^26.5.2", + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", "@types/node": "*", - "jest-mock": "^26.5.2", - "jest-util": "^26.5.2" + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -15104,15 +14967,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -15154,12 +15008,12 @@ "dev": true }, "jest-util": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.5.2.tgz", - "integrity": "sha512-WTL675bK+GSSAYgS8z9FWdCT2nccO1yTIplNLPlP0OD8tUk/H5IrWKMMRudIQQ0qp8bb4k+1Qa8CxGKq9qnYdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -15185,12 +15039,12 @@ "dev": true }, "jest-haste-map": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.5.2.tgz", - "integrity": "sha512-lJIAVJN3gtO3k4xy+7i2Xjtwh8CfPcH08WYjZpe9xzveDaqGw9fVNCpkYu6M525wKFVkLmyi7ku+DxCAP1lyMA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "@types/graceful-fs": "^4.1.2", "@types/node": "*", "anymatch": "^3.0.3", @@ -15198,18 +15052,18 @@ "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", "jest-regex-util": "^26.0.0", - "jest-serializer": "^26.5.0", - "jest-util": "^26.5.2", - "jest-worker": "^26.5.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", "micromatch": "^4.0.2", "sane": "^4.0.3", "walker": "^1.0.7" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -15219,15 +15073,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -15269,12 +15114,12 @@ "dev": true }, "jest-util": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.5.2.tgz", - "integrity": "sha512-WTL675bK+GSSAYgS8z9FWdCT2nccO1yTIplNLPlP0OD8tUk/H5IrWKMMRudIQQ0qp8bb4k+1Qa8CxGKq9qnYdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -15294,35 +15139,35 @@ } }, "jest-jasmine2": { - "version": "26.5.3", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.5.3.tgz", - "integrity": "sha512-nFlZOpnGlNc7y/+UkkeHnvbOM+rLz4wB1AimgI9QhtnqSZte0wYjbAm8hf7TCwXlXgDwZxAXo6z0a2Wzn9FoOg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.2.tgz", + "integrity": "sha512-Om6q632kogggOBGjSr34jErXGOQy0+IkxouGUbyzB0lQmufu8nm1AcxLIKpB/FN36I43f2T3YajeNlxwJZ94PQ==", "dev": true, "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.5.2", - "@jest/source-map": "^26.5.0", - "@jest/test-result": "^26.5.2", - "@jest/types": "^26.5.2", + "@jest/environment": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^26.5.3", + "expect": "^26.6.2", "is-generator-fn": "^2.0.0", - "jest-each": "^26.5.2", - "jest-matcher-utils": "^26.5.2", - "jest-message-util": "^26.5.2", - "jest-runtime": "^26.5.3", - "jest-snapshot": "^26.5.3", - "jest-util": "^26.5.2", - "pretty-format": "^26.5.2", + "jest-each": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-runtime": "^26.6.2", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2", "throat": "^5.0.0" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -15332,15 +15177,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -15388,12 +15224,12 @@ "dev": true }, "jest-util": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.5.2.tgz", - "integrity": "sha512-WTL675bK+GSSAYgS8z9FWdCT2nccO1yTIplNLPlP0OD8tUk/H5IrWKMMRudIQQ0qp8bb4k+1Qa8CxGKq9qnYdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -15402,15 +15238,15 @@ } }, "pretty-format": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.5.2.tgz", - "integrity": "sha512-VizyV669eqESlkOikKJI8Ryxl/kPpbdLwNdPs2GrbQs18MpySB5S0Yo0N7zkg2xTRiFq4CFw8ct5Vg4a0xP0og==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, "supports-color": { @@ -15425,19 +15261,19 @@ } }, "jest-leak-detector": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.5.2.tgz", - "integrity": "sha512-h7ia3dLzBFItmYERaLPEtEKxy3YlcbcRSjj0XRNJgBEyODuu+3DM2o62kvIFvs3PsaYoIIv+e+nLRI61Dj1CNw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", + "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", "dev": true, "requires": { "jest-get-type": "^26.3.0", - "pretty-format": "^26.5.2" + "pretty-format": "^26.6.2" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -15447,15 +15283,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -15502,22 +15329,16 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, "pretty-format": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.5.2.tgz", - "integrity": "sha512-VizyV669eqESlkOikKJI8Ryxl/kPpbdLwNdPs2GrbQs18MpySB5S0Yo0N7zkg2xTRiFq4CFw8ct5Vg4a0xP0og==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, "supports-color": { @@ -15532,21 +15353,21 @@ } }, "jest-matcher-utils": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.5.2.tgz", - "integrity": "sha512-W9GO9KBIC4gIArsNqDUKsLnhivaqf8MSs6ujO/JDcPIQrmY+aasewweXVET8KdrJ6ADQaUne5UzysvF/RR7JYA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^26.5.2", + "jest-diff": "^26.6.2", "jest-get-type": "^26.3.0", - "pretty-format": "^26.5.2" + "pretty-format": "^26.6.2" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -15556,15 +15377,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -15606,9 +15418,9 @@ "dev": true }, "diff-sequences": { - "version": "26.5.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.5.0.tgz", - "integrity": "sha512-ZXx86srb/iYy6jG71k++wBN9P9J05UNQ5hQHQd9MtMPvcqXPx/vKU69jfHV637D00Q2gSgPk2D+jSx3l1lDW/Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true }, "has-flag": { @@ -15618,33 +15430,27 @@ "dev": true }, "jest-diff": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.5.2.tgz", - "integrity": "sha512-HCSWDUGwsov5oTlGzrRM+UPJI/Dpqi9jzeV0fdRNi3Ch5bnoXhnyJMmVg2juv9081zLIy3HGPI5mcuGgXM2xRA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^26.5.0", + "diff-sequences": "^26.6.2", "jest-get-type": "^26.3.0", - "pretty-format": "^26.5.2" + "pretty-format": "^26.6.2" } }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, "pretty-format": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.5.2.tgz", - "integrity": "sha512-VizyV669eqESlkOikKJI8Ryxl/kPpbdLwNdPs2GrbQs18MpySB5S0Yo0N7zkg2xTRiFq4CFw8ct5Vg4a0xP0og==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, "supports-color": { @@ -15659,25 +15465,26 @@ } }, "jest-message-util": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.5.2.tgz", - "integrity": "sha512-Ocp9UYZ5Jl15C5PNsoDiGEk14A4NG0zZKknpWdZGoMzJuGAkVt10e97tnEVMYpk7LnQHZOfuK2j/izLBMcuCZw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -15687,14 +15494,11 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true }, "ansi-styles": { "version": "4.3.0", @@ -15736,6 +15540,18 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -15748,19 +15564,19 @@ } }, "jest-mock": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.5.2.tgz", - "integrity": "sha512-9SiU4b5PtO51v0MtJwVRqeGEroH66Bnwtq4ARdNP7jNXbpT7+ByeWNAk4NeT/uHfNSVDXEXgQo1XRuwEqS6Rdw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "@types/node": "*" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -15770,15 +15586,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -15843,25 +15650,25 @@ "dev": true }, "jest-resolve": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.5.2.tgz", - "integrity": "sha512-XsPxojXGRA0CoDD7Vis59ucz2p3cQFU5C+19tz3tLEAlhYKkK77IL0cjYjikY9wXnOaBeEdm1rOgSJjbZWpcZg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.5.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -15871,15 +15678,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -15921,12 +15719,12 @@ "dev": true }, "jest-util": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.5.2.tgz", - "integrity": "sha512-WTL675bK+GSSAYgS8z9FWdCT2nccO1yTIplNLPlP0OD8tUk/H5IrWKMMRudIQQ0qp8bb4k+1Qa8CxGKq9qnYdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -15934,6 +15732,16 @@ "micromatch": "^4.0.2" } }, + "resolve": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz", + "integrity": "sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA==", + "dev": true, + "requires": { + "is-core-module": "^2.0.0", + "path-parse": "^1.0.6" + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -15946,20 +15754,20 @@ } }, "jest-resolve-dependencies": { - "version": "26.5.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.5.3.tgz", - "integrity": "sha512-+KMDeke/BFK+mIQ2IYSyBz010h7zQaVt4Xie6cLqUGChorx66vVeQVv4ErNoMwInnyYHi1Ud73tDS01UbXbfLQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.2.tgz", + "integrity": "sha512-lXXQqBLlKlnOPyCfJZnrYydd7lZzWux9sMwKJxOmjsuVmoSlnmTOJ8kW1FYxotTyMzqoNtBuSF6qE+iXuAr6qQ==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.5.3" + "jest-snapshot": "^26.6.2" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -15969,15 +15777,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -16030,37 +15829,37 @@ } }, "jest-runner": { - "version": "26.5.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.5.3.tgz", - "integrity": "sha512-qproP0Pq7IIule+263W57k2+8kWCszVJTC9TJWGUz0xJBr+gNiniGXlG8rotd0XxwonD5UiJloYoSO5vbUr5FQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.2.tgz", + "integrity": "sha512-OsWTIGx/MHSuPqjYwap1LAxT0qvlqmwTYSFOwc+G14AtyZlL7ngrrDes7moLRqFkDVpCHL2RT0i317jogyw81Q==", "dev": true, "requires": { - "@jest/console": "^26.5.2", - "@jest/environment": "^26.5.2", - "@jest/test-result": "^26.5.2", - "@jest/types": "^26.5.2", + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.7.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-config": "^26.5.3", + "jest-config": "^26.6.2", "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.5.2", - "jest-leak-detector": "^26.5.2", - "jest-message-util": "^26.5.2", - "jest-resolve": "^26.5.2", - "jest-runtime": "^26.5.3", - "jest-util": "^26.5.2", - "jest-worker": "^26.5.0", + "jest-haste-map": "^26.6.2", + "jest-leak-detector": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-runtime": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", "source-map-support": "^0.5.6", "throat": "^5.0.0" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -16070,15 +15869,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -16114,9 +15904,9 @@ "dev": true }, "emittery": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.1.tgz", - "integrity": "sha512-d34LN4L6h18Bzz9xpoku2nPwKxCPlPMr3EEKTkoEBi+1/+b0lcRkRJ1UVyyZaKNeqGR3swcGl6s390DNO4YVgQ==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", + "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", "dev": true }, "has-flag": { @@ -16126,12 +15916,12 @@ "dev": true }, "jest-util": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.5.2.tgz", - "integrity": "sha512-WTL675bK+GSSAYgS8z9FWdCT2nccO1yTIplNLPlP0OD8tUk/H5IrWKMMRudIQQ0qp8bb4k+1Qa8CxGKq9qnYdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -16151,43 +15941,44 @@ } }, "jest-runtime": { - "version": "26.5.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.5.3.tgz", - "integrity": "sha512-IDjalmn2s/Tc4GvUwhPHZ0iaXCdMRq5p6taW9P8RpU+FpG01O3+H8z+p3rDCQ9mbyyyviDgxy/LHPLzrIOKBkQ==", - "dev": true, - "requires": { - "@jest/console": "^26.5.2", - "@jest/environment": "^26.5.2", - "@jest/fake-timers": "^26.5.2", - "@jest/globals": "^26.5.3", - "@jest/source-map": "^26.5.0", - "@jest/test-result": "^26.5.2", - "@jest/transform": "^26.5.2", - "@jest/types": "^26.5.2", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.2.tgz", + "integrity": "sha512-VEjfoim4tkvq8Gh8z7wMXlKva3DnIlgvmGR1AajiRK1nEHuXtuaR17jnVYOi+wW0i1dS3NH4jVdUQl08GodgZQ==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/globals": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", "@types/yargs": "^15.0.0", "chalk": "^4.0.0", + "cjs-module-lexer": "^0.6.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-config": "^26.5.3", - "jest-haste-map": "^26.5.2", - "jest-message-util": "^26.5.2", - "jest-mock": "^26.5.2", + "jest-config": "^26.6.2", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.5.2", - "jest-snapshot": "^26.5.3", - "jest-util": "^26.5.2", - "jest-validate": "^26.5.3", + "jest-resolve": "^26.6.2", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", "slash": "^3.0.0", "strip-bom": "^4.0.0", "yargs": "^15.4.1" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -16197,15 +15988,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -16247,12 +16029,12 @@ "dev": true }, "jest-util": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.5.2.tgz", - "integrity": "sha512-WTL675bK+GSSAYgS8z9FWdCT2nccO1yTIplNLPlP0OD8tUk/H5IrWKMMRudIQQ0qp8bb4k+1Qa8CxGKq9qnYdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -16278,9 +16060,9 @@ } }, "jest-serializer": { - "version": "26.5.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.5.0.tgz", - "integrity": "sha512-+h3Gf5CDRlSLdgTv7y0vPIAoLgX/SI7T4v6hy+TEXMgYbv+ztzbg5PSN6mUXAT/hXYHvZRWm+MaObVfqkhCGxA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", "dev": true, "requires": { "@types/node": "*", @@ -16288,33 +16070,33 @@ } }, "jest-snapshot": { - "version": "26.5.3", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.5.3.tgz", - "integrity": "sha512-ZgAk0Wm0JJ75WS4lGaeRfa0zIgpL0KD595+XmtwlIEMe8j4FaYHyZhP1LNOO+8fXq7HJ3hll54+sFV9X4+CGVw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", "dev": true, "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.5.3", + "expect": "^26.6.2", "graceful-fs": "^4.2.4", - "jest-diff": "^26.5.2", + "jest-diff": "^26.6.2", "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.5.2", - "jest-matcher-utils": "^26.5.2", - "jest-message-util": "^26.5.2", - "jest-resolve": "^26.5.2", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", "natural-compare": "^1.4.0", - "pretty-format": "^26.5.2", + "pretty-format": "^26.6.2", "semver": "^7.3.2" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -16324,15 +16106,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -16374,9 +16147,9 @@ "dev": true }, "diff-sequences": { - "version": "26.5.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.5.0.tgz", - "integrity": "sha512-ZXx86srb/iYy6jG71k++wBN9P9J05UNQ5hQHQd9MtMPvcqXPx/vKU69jfHV637D00Q2gSgPk2D+jSx3l1lDW/Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true }, "has-flag": { @@ -16386,33 +16159,27 @@ "dev": true }, "jest-diff": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.5.2.tgz", - "integrity": "sha512-HCSWDUGwsov5oTlGzrRM+UPJI/Dpqi9jzeV0fdRNi3Ch5bnoXhnyJMmVg2juv9081zLIy3HGPI5mcuGgXM2xRA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^26.5.0", + "diff-sequences": "^26.6.2", "jest-get-type": "^26.3.0", - "pretty-format": "^26.5.2" + "pretty-format": "^26.6.2" } }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, "pretty-format": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.5.2.tgz", - "integrity": "sha512-VizyV669eqESlkOikKJI8Ryxl/kPpbdLwNdPs2GrbQs18MpySB5S0Yo0N7zkg2xTRiFq4CFw8ct5Vg4a0xP0og==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, "semver": { @@ -16520,23 +16287,23 @@ } }, "jest-validate": { - "version": "26.5.3", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.5.3.tgz", - "integrity": "sha512-LX07qKeAtY+lsU0o3IvfDdN5KH9OulEGOMN1sFo6PnEf5/qjS1LZIwNk9blcBeW94pQUI9dLN9FlDYDWI5tyaA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", + "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "camelcase": "^6.0.0", "chalk": "^4.0.0", "jest-get-type": "^26.3.0", "leven": "^3.1.0", - "pretty-format": "^26.5.2" + "pretty-format": "^26.6.2" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -16546,15 +16313,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -16571,9 +16329,9 @@ } }, "camelcase": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.1.0.tgz", - "integrity": "sha512-WCMml9ivU60+8rEJgELlFp1gxFcEGxwYleE3bziHEDeqsqAWGHdimB7beBFGjLzVNgPGyDsfgXLQEYMpmIFnVQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true }, "chalk": { @@ -16607,22 +16365,16 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, "pretty-format": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.5.2.tgz", - "integrity": "sha512-VizyV669eqESlkOikKJI8Ryxl/kPpbdLwNdPs2GrbQs18MpySB5S0Yo0N7zkg2xTRiFq4CFw8ct5Vg4a0xP0og==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, "supports-color": { @@ -16637,24 +16389,24 @@ } }, "jest-watcher": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.5.2.tgz", - "integrity": "sha512-i3m1NtWzF+FXfJ3ljLBB/WQEp4uaNhX7QcQUWMokcifFTUQBDFyUMEwk0JkJ1kopHbx7Een3KX0Q7+9koGM/Pw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", + "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", "dev": true, "requires": { - "@jest/test-result": "^26.5.2", - "@jest/types": "^26.5.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^26.5.2", + "jest-util": "^26.6.2", "string-length": "^4.0.1" }, "dependencies": { "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -16664,15 +16416,6 @@ "chalk": "^4.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -16714,12 +16457,12 @@ "dev": true }, "jest-util": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.5.2.tgz", - "integrity": "sha512-WTL675bK+GSSAYgS8z9FWdCT2nccO1yTIplNLPlP0OD8tUk/H5IrWKMMRudIQQ0qp8bb4k+1Qa8CxGKq9qnYdg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.5.2", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -16739,9 +16482,9 @@ } }, "jest-worker": { - "version": "26.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.5.0.tgz", - "integrity": "sha512-kTw66Dn4ZX7WpjZ7T/SUDgRhapFRKWmisVAF0Rv4Fu8SLFD7eLbqpLvbxVqYhSgaWa7I+bW7pHnbyfNsH6stug==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "dev": true, "requires": { "@types/node": "*", @@ -21201,13 +20944,13 @@ } }, "prompts": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", - "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz", + "integrity": "sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==", "dev": true, "requires": { "kleur": "^3.0.3", - "sisteransi": "^1.0.4" + "sisteransi": "^1.0.5" } }, "proxy-addr": { @@ -21544,9 +21287,9 @@ } }, "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", "dev": true }, "read-file-relative": { @@ -26050,9 +25793,9 @@ "dev": true }, "v8-to-istanbul": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-6.0.1.tgz", - "integrity": "sha512-PzM1WlqquhBvsV+Gco6WSFeg1AGdD53ccMRkFeyHRE/KRZaVacPOmQYP3EeVgDBtKD2BJ8kgynBQ5OtKiHCH+w==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.0.0.tgz", + "integrity": "sha512-fLL2rFuQpMtm9r8hrAV2apXX/WqHJ6+IC4/eQVdMDGBUgH/YMV4Gv3duk3kjmyg6uiQWBAA9nJwue4iJUOkHeA==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.1", diff --git a/package.json b/package.json index 402ea68165..b1b78d8dab 100644 --- a/package.json +++ b/package.json @@ -221,7 +221,7 @@ "jasmine-core": "^3.1.0", "jasmine-sinon": "^0.4.0", "jasmine-spec-reporter": "^6.0.0", - "jest": "^26.5.3", + "jest": "^26.6.2", "lint-staged": "^10.4.0", "maildev": "^1.1.0", "mini-css-extract-plugin": "^0.5.0", From 3746d84d1358a9002db072c9a35a77ca601f71ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Nov 2020 12:08:22 +0800 Subject: [PATCH 04/26] chore(deps-dev): bump eslint-plugin-import from 2.22.0 to 2.22.1 (#580) Bumps [eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import) from 2.22.0 to 2.22.1. - [Release notes](https://github.com/benmosher/eslint-plugin-import/releases) - [Changelog](https://github.com/benmosher/eslint-plugin-import/blob/master/CHANGELOG.md) - [Commits](https://github.com/benmosher/eslint-plugin-import/compare/v2.22.0...v2.22.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index d73da25bbc..45e7e582b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11120,9 +11120,9 @@ "dev": true }, "eslint-plugin-import": { - "version": "2.22.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.0.tgz", - "integrity": "sha512-66Fpf1Ln6aIS5Gr/55ts19eUuoDhAbZgnr6UxK5hbDx6l/QgQgx61AePq+BV4PP2uXQFClgMVzep5zZ94qqsxg==", + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", + "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==", "dev": true, "requires": { "array-includes": "^3.1.1", @@ -11130,7 +11130,7 @@ "contains-path": "^0.1.0", "debug": "^2.6.9", "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.3", + "eslint-import-resolver-node": "^0.3.4", "eslint-module-utils": "^2.6.0", "has": "^1.0.3", "minimatch": "^3.0.4", diff --git a/package.json b/package.json index 6ad60d1c28..41f5d720e5 100644 --- a/package.json +++ b/package.json @@ -209,7 +209,7 @@ "eslint": "^7.12.1", "eslint-config-prettier": "^6.15.0", "eslint-plugin-angular": "^4.0.1", - "eslint-plugin-import": "^2.22.0", + "eslint-plugin-import": "^2.22.1", "eslint-plugin-jest": "^24.0.2", "eslint-plugin-prettier": "^3.1.3", "eslint-plugin-simple-import-sort": "^5.0.3", From 34705fc1b941b8cc4468b81e60ab3933ed77c0c2 Mon Sep 17 00:00:00 2001 From: Kar Rui Lau Date: Wed, 4 Nov 2020 16:06:50 +0800 Subject: [PATCH 05/26] feat: remove exclamation when user updates contact (#586) --- .../modules/core/components/avatar-dropdown.client.component.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/public/modules/core/components/avatar-dropdown.client.component.js b/src/public/modules/core/components/avatar-dropdown.client.component.js index 2f21f54df9..633906acd5 100644 --- a/src/public/modules/core/components/avatar-dropdown.client.component.js +++ b/src/public/modules/core/components/avatar-dropdown.client.component.js @@ -98,6 +98,7 @@ function avatarDropdownController( if (returnVal) { vm.user = returnVal Auth.setUser(returnVal) + vm.showExclamation = !returnVal.contact } }) .finally(angular.noop) From 7c567978f630ec7ffefaea1b42806455c2469068 Mon Sep 17 00:00:00 2001 From: Antariksh Mahajan Date: Thu, 5 Nov 2020 00:09:57 +0800 Subject: [PATCH 06/26] feat: deprecate MYINFO_APP_KEY (#557) --- docs/DEPLOYMENT_SETUP.md | 1 - src/app/factories/spcp-myinfo.factory.js | 5 ----- 2 files changed, 6 deletions(-) diff --git a/docs/DEPLOYMENT_SETUP.md b/docs/DEPLOYMENT_SETUP.md index 60f3b48beb..fdf42b1318 100644 --- a/docs/DEPLOYMENT_SETUP.md +++ b/docs/DEPLOYMENT_SETUP.md @@ -302,7 +302,6 @@ Note that MyInfo is currently not supported for storage mode forms and enabling | `CP_IDP_CERT_PATH` | Path to National Digital Identity office's X.509 cert used for CorpPass related communication. | | `MYINFO_CLIENT_CONFIG` | Configures [MyInfoGovClient](https://github.com/opengovsg/myinfo-gov-client). Set this to either`stg` or `prod` to fetch MyInfo data from the corresponding endpoints. | | `MYINFO_FORMSG_KEY_PATH` | Filepath to MyInfo private key, which is used to decrypt returned responses. | -| `MYINFO_APP_KEY` | (deprecated) Directly specify contents of the MyInfo FormSG private key. Only works if `NODE_ENV` is set to `development`. | | `IS_SP_MAINTENANCE` | If set, displays a banner message on SingPass forms. Overrides `IS_CP_MAINTENANCE`. | | `IS_CP_MAINTENANCE` | If set, displays a banner message on CorpPass forms. | | `FILE_SYSTEM_ID` | The id of the AWS Elastic File System (EFS) file system to mount onto the instances. | diff --git a/src/app/factories/spcp-myinfo.factory.js b/src/app/factories/spcp-myinfo.factory.js index 6a1918a323..fb8befa061 100644 --- a/src/app/factories/spcp-myinfo.factory.js +++ b/src/app/factories/spcp-myinfo.factory.js @@ -66,11 +66,6 @@ const spcpFactory = ({ isEnabled, props }) => { myInfoConfig.appId = myInfoPrefix + myInfoConfig.singpassEserviceId myInfoConfig.mode = process.env.MYINFO_CLIENT_CONFIG myInfoGovClient = new MyInfoGovClient(myInfoConfig) - } else if (config.isDev && process.env.MYINFO_APP_KEY) { - myInfoConfig.appId = 'STG2-' + myInfoConfig.singpassEserviceId - myInfoConfig.privateKey = process.env.MYINFO_APP_KEY - myInfoConfig.mode = 'stg' - myInfoGovClient = new MyInfoGovClient(myInfoConfig) } else { logger.warn({ message: `\n!!! WARNING !!!\nNo MyInfo keys detected.\nRequests to MyInfo will not work.\nThis should NEVER be seen in production.\nFalling back on MockPass.`, From 720245fe41169897138f4d9973dd354a3bafba0f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Nov 2020 13:50:45 +0800 Subject: [PATCH 07/26] chore(deps-dev): bump jasmine from 3.6.2 to 3.6.3 (#587) Bumps [jasmine](https://github.com/jasmine/jasmine-npm) from 3.6.2 to 3.6.3. - [Release notes](https://github.com/jasmine/jasmine-npm/releases) - [Commits](https://github.com/jasmine/jasmine-npm/compare/v3.6.2...v3.6.3) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 45e7e582b9..29cdfb2b79 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14245,9 +14245,9 @@ } }, "jasmine": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.6.2.tgz", - "integrity": "sha512-Uc0o2MRnC8TS1MjDrB8jE1umKEo2mflzGvdg0Ncs+yuLtOJ+uz/Wz8VmGsNGtuASr8+E0LDgPkOpvdoC76m5WQ==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.6.3.tgz", + "integrity": "sha512-Th91zHsbsALWjDUIiU5d/W5zaYQsZFMPTdeNmi8GivZPmAaUAK8MblSG3yQI4VMGC/abF2us7ex60NH1AAIMTA==", "dev": true, "requires": { "glob": "^7.1.6", diff --git a/package.json b/package.json index 41f5d720e5..348d6b6e6a 100644 --- a/package.json +++ b/package.json @@ -217,7 +217,7 @@ "html-loader": "~0.5.5", "htmlhint": "^0.14.1", "husky": "^4.3.0", - "jasmine": "^3.6.2", + "jasmine": "^3.6.3", "jasmine-core": "^3.1.0", "jasmine-sinon": "^0.4.0", "jasmine-spec-reporter": "^6.0.0", From 2905cbd618a5b846e6e001ab6088d73331427fa2 Mon Sep 17 00:00:00 2001 From: Antariksh Mahajan Date: Thu, 5 Nov 2020 21:39:53 +0800 Subject: [PATCH 08/26] feat: upgrade myinfo-gov-client (#593) --- package-lock.json | 28 +++++++++++++++++++++++++--- package.json | 2 +- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 29cdfb2b79..f6cf32dc56 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4055,14 +4055,36 @@ } }, "@opengovsg/myinfo-gov-client": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@opengovsg/myinfo-gov-client/-/myinfo-gov-client-2.0.0.tgz", - "integrity": "sha512-pRkBhSGIDDq8S2YFhfEGc9toqwm1D0uKhG/U+etjSbp13UXj/8TvLK1dQwTFCJ9NAgSO/S3M6UWrGdUoboUAkw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@opengovsg/myinfo-gov-client/-/myinfo-gov-client-2.1.2.tgz", + "integrity": "sha512-YrHswABeH1Gcl3ga6onQOMa09Ohqe57a+lrCOdFcehlvNSc6QOmN8Sd8Z/nkFJr2xOsgPGl+kcRTYfK4vooV9g==", "requires": { + "axios": "^0.21.0", "jose": "^0.3.2", "node-jose": "^2.0.0", "path": "^0.12.7", + "qs": "^6.9.4", "request": "^2.88.0" + }, + "dependencies": { + "axios": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.0.tgz", + "integrity": "sha512-fmkJBknJKoZwem3/IKSSLpkdNXZeBu5Q7GA/aRsr2btgrptmSCxi2oFjZHqGdK9DoTil9PIHlPIZw2EcRJXRvw==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, + "follow-redirects": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", + "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==" + }, + "qs": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", + "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==" + } } }, "@opengovsg/ng-file-upload": { diff --git a/package.json b/package.json index 348d6b6e6a..8cb1e0534c 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "@opengovsg/angular-legacy-sortablejs-maintained": "^1.0.0", "@opengovsg/angular-recaptcha-fallback": "^5.0.0", "@opengovsg/formsg-sdk": "0.8.2", - "@opengovsg/myinfo-gov-client": "^2.0.0", + "@opengovsg/myinfo-gov-client": "^2.1.2", "@opengovsg/ng-file-upload": "^12.2.14", "@opengovsg/spcp-auth-client": "^1.3.6", "@sentry/browser": "^5.24.2", From 7280e64e7ae1e0458c26d54032d14f54975b3ca4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Nov 2020 21:04:46 +0800 Subject: [PATCH 09/26] fix(deps): bump angular-cookies from 1.8.1 to 1.8.2 (#590) Bumps [angular-cookies](https://github.com/angular/angular.js) from 1.8.1 to 1.8.2. - [Release notes](https://github.com/angular/angular.js/releases) - [Changelog](https://github.com/angular/angular.js/blob/master/CHANGELOG.md) - [Commits](https://github.com/angular/angular.js/compare/v1.8.1...v1.8.2) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index f6cf32dc56..3ae63501bb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5503,9 +5503,9 @@ "integrity": "sha512-eCQI6EwgY6bYHdzIUfDABHnZjoZ3bNYpCsnceQF4bLfbq1QtZ7raRPNca45sj6C9Pfjde6PNcEDvuLozFPYnrQ==" }, "angular-cookies": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/angular-cookies/-/angular-cookies-1.8.1.tgz", - "integrity": "sha512-952lNWW2REfGRwErYB4kLiWCvCE+euaPtIq8iYdZso0T74D6KCz82zSQjO5xnxfIKWMeKp2X2yIMksyH++GZcw==" + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/angular-cookies/-/angular-cookies-1.8.2.tgz", + "integrity": "sha512-M6fCnsnw1pj1+nXuO28ilJ+h6pFCIXQKSEgy9/PIoN0sZr5FqsE9BK18PdBQa8dif+fnHCAYpPU8MgDzT/sZSg==" }, "angular-drag-scroll": { "version": "0.2.2", diff --git a/package.json b/package.json index 8cb1e0534c..5122dbafc0 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "angular": "~1.8.0", "angular-animate": "^1.8.0", "angular-aria": "^1.8.0", - "angular-cookies": "~1.8.1", + "angular-cookies": "~1.8.2", "angular-drag-scroll": "^0.2.1", "angular-messages": "^1.8.1", "angular-moment": "~1.2.0", From f77759c341c21f515eb7a971621193e964cdf4e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Nov 2020 09:56:38 +0800 Subject: [PATCH 10/26] chore(deps-dev): bump ngrok from 3.2.7 to 3.3.0 (#578) Bumps [ngrok](https://github.com/bubenshchykov/ngrok) from 3.2.7 to 3.3.0. - [Release notes](https://github.com/bubenshchykov/ngrok/releases) - [Commits](https://github.com/bubenshchykov/ngrok/commits/v3.3.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 12 ++++++------ package.json | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3ae63501bb..b75cf1cd19 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18993,9 +18993,9 @@ } }, "ngrok": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/ngrok/-/ngrok-3.2.7.tgz", - "integrity": "sha512-B7K15HM0qRZplL2aO/yfxixYubH0M50Pfu0fa4PDcmXP7RC+wyYzu6YtX77BBHHCfbwCzkObX6YdO8ThpCR6Lg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ngrok/-/ngrok-3.3.0.tgz", + "integrity": "sha512-NuTfuxttodW6o9cPEKiJgjmjNzolKHoUPaK7I4SbaJVkHd4cuUTlv9YsXNzBFrcNFSsDLuCyCpjsaqe1OvIPSQ==", "dev": true, "requires": { "@types/node": "^8.10.50", @@ -19007,9 +19007,9 @@ }, "dependencies": { "@types/node": { - "version": "8.10.62", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.62.tgz", - "integrity": "sha512-76fupxOYVxk36kb7O/6KtrAPZ9jnSK3+qisAX4tQMEuGNdlvl7ycwatlHqjoE6jHfVtXFM3pCrCixZOidc5cuw==", + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", "dev": true }, "uuid": { diff --git a/package.json b/package.json index 5122dbafc0..4fdd7a0c68 100644 --- a/package.json +++ b/package.json @@ -228,7 +228,7 @@ "mockdate": "^3.0.2", "mockingoose": "^2.13.2", "mongodb-memory-server-core": "^6.9.2", - "ngrok": "^3.2.7", + "ngrok": "^3.3.0", "optimize-css-assets-webpack-plugin": "^5.0.1", "prettier": "^2.1.2", "proxyquire": "^2.1.3", From 435b223290021ff2a8347393e8ada55265708343 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Nov 2020 09:56:59 +0800 Subject: [PATCH 11/26] chore(deps-dev): bump @types/node from 14.11.2 to 14.14.6 (#588) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.11.2 to 14.14.6. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index b75cf1cd19..9f3de39d59 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4680,9 +4680,9 @@ } }, "@types/node": { - "version": "14.11.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.2.tgz", - "integrity": "sha512-jiE3QIxJ8JLNcb1Ps6rDbysDhN4xa8DJJvuC9prr6w+1tIh+QAbYyNF3tyiZNLDBIuBCf4KEcV2UvQm/V60xfA==" + "version": "14.14.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.6.tgz", + "integrity": "sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw==" }, "@types/nodemailer": { "version": "6.4.0", diff --git a/package.json b/package.json index 4fdd7a0c68..bd8cc7f9dd 100644 --- a/package.json +++ b/package.json @@ -184,7 +184,7 @@ "@types/json-stringify-safe": "^5.0.0", "@types/mongodb-uri": "^0.9.0", "@types/mongoose": "^5.7.36", - "@types/node": "^14.11.2", + "@types/node": "^14.14.6", "@types/nodemailer": "^6.4.0", "@types/nodemailer-direct-transport": "^1.0.31", "@types/promise-retry": "^1.1.3", From 0e1ecee4f2ab32532e7fbd7853c9be7462513084 Mon Sep 17 00:00:00 2001 From: Antariksh Mahajan Date: Mon, 9 Nov 2020 10:05:42 +0800 Subject: [PATCH 12/26] refactor: hash uinFin in domain layer (#596) * ref: move updateHashes hashing into model * test: update updateHashes tests * ref: add findHashes method * ref: use findHashes function * test: add tests for findHashes * test: update jasmine tests * ref: return only fields --- .../controllers/myinfo.server.controller.js | 163 ++++++++---------- src/app/models/myinfo_hash.server.model.ts | 24 ++- src/types/myinfo_hash.ts | 3 +- .../myinfo.server.controller.spec.js | 5 +- .../models/myinfo_hash.server.model.spec.ts | 82 +++++++-- 5 files changed, 161 insertions(+), 116 deletions(-) diff --git a/src/app/controllers/myinfo.server.controller.js b/src/app/controllers/myinfo.server.controller.js index 43c899e06a..1a818b192f 100644 --- a/src/app/controllers/myinfo.server.controller.js +++ b/src/app/controllers/myinfo.server.controller.js @@ -1,7 +1,6 @@ 'use strict' const bcrypt = require('bcrypt') -const crypto = require('crypto') const CircuitBreaker = require('opossum') const to = require('await-to-js').default const Promise = require('bluebird') @@ -10,7 +9,6 @@ const mongoose = require('mongoose') const moment = require('moment') const { StatusCodes } = require('http-status-codes') -const { sessionSecret } = require('../../config/config') const { createReqMeta } = require('../utils/request') const logger = require('../../config/logger').createLoggerWithLabel(module) const getMyInfoHashModel = require('../models/myinfo_hash.server.model').default @@ -76,15 +74,10 @@ exports.addMyInfo = (myInfoService) => async (req, res, next) => { // Set current form fields to the new prefilledFields. req.form.form_fields = prefilledFields - const hashedUinFin = crypto - .createHmac('sha256', sessionSecret) - .update(uinFin) - .digest('hex') - Promise.props(readOnlyHashPromises) .then((readOnlyHashes) => { return MyInfoHash.updateHashes( - hashedUinFin, + uinFin, formId, readOnlyHashes, myInfoService.spCookieMaxAge, @@ -142,7 +135,7 @@ function _preHashCheckConversion(field) { * @param {Object} res.locals.uinFin - UIN/FIN of form submitter * @param {Object} next - Express next middleware function */ -exports.verifyMyInfoVals = function (req, res, next) { +exports.verifyMyInfoVals = async function (req, res, next) { const { authType } = req.form const actualMyInfoFields = req.form.form_fields.filter( (field) => field.myInfo && field.myInfo.attr, @@ -150,101 +143,85 @@ exports.verifyMyInfoVals = function (req, res, next) { if (authType === 'SP' && actualMyInfoFields.length > 0) { const uinFin = res.locals.uinFin const formObjId = req.form._id - - let hashedUinFin = crypto - .createHmac('sha256', sessionSecret) - .update(uinFin) - .digest('hex') - MyInfoHash.findOne( - { uinFin: hashedUinFin, form: formObjId }, - (err, hashedObj) => { - if (err) { - logger.error({ - message: 'Error retrieving MyInfo hash from database', - meta: { - action: 'verifyMyInfoVals', - ...createReqMeta(req), - }, - error: err, - }) - return res.status(StatusCodes.SERVICE_UNAVAILABLE).json({ - message: 'MyInfo verification unavailable, please try again later.', - spcpSubmissionFailure: true, - }) + let hashedFields + try { + hashedFields = await MyInfoHash.findHashes(uinFin, formObjId) + } catch (error) { + logger.error({ + message: 'Error retrieving MyInfo hash from database', + meta: { + action: 'verifyMyInfoVals', + ...createReqMeta(req), + }, + error, + }) + return res.status(StatusCodes.SERVICE_UNAVAILABLE).json({ + message: 'MyInfo verification unavailable, please try again later.', + spcpSubmissionFailure: true, + }) + } + if (!hashedFields) { + logger.error({ + message: `Unable to find MyInfo hashes for ${formObjId}`, + meta: { + action: 'verifyMyInfoVals', + ...createReqMeta(req), + formId: formObjId, + }, + }) + return res.status(StatusCodes.GONE).json({ + message: 'MyInfo verification expired, please refresh and try again.', + spcpSubmissionFailure: true, + }) + } + // Fields from client submission + let clientFormFields = req.body.parsedResponses // responses were transformed in submissions.server.controller.js + let clientMyInfoFields = clientFormFields + .filter((field) => field.isVisible && field.myInfo && field.myInfo.attr) + .map(_preHashCheckConversion) + + // compare hashed values to submission values + const bcryptCompares = clientMyInfoFields.map((clientField) => { + const expected = hashedFields[clientField.attr] + return expected + ? bcrypt.compare(clientField.val, expected) + : Promise.resolve(true) + }) + Promise.all(bcryptCompares) + .then((compare) => { + return { + compare, // Array indicating hash pass/fail + fail: compare.some((v) => !v), // Whether any hashes failed } + }) + .then((hashResults) => { + if (hashResults.fail) { + // Array of MyInfo attributes that failed verification + let hashFailedAttrs = _.zip(clientMyInfoFields, hashResults.compare) + .filter(([_, compare]) => compare === false) + .map(([clientField, _]) => clientField.attr) - if (!hashedObj) { logger.error({ - message: `Unable to find MyInfo hashes for ${formObjId}`, + message: `Hash did not match for form ${formObjId}`, meta: { action: 'verifyMyInfoVals', ...createReqMeta(req), - formId: formObjId, + failedFields: hashFailedAttrs, }, }) - return res.status(StatusCodes.GONE).json({ - message: - 'MyInfo verification expired, please refresh and try again.', + return res.status(StatusCodes.UNAUTHORIZED).json({ + message: 'MyInfo verification failed.', spcpSubmissionFailure: true, }) - } - // Fields from client submission - let clientFormFields = req.body.parsedResponses // responses were transformed in submissions.server.controller.js - let clientMyInfoFields = clientFormFields - .filter( - (field) => field.isVisible && field.myInfo && field.myInfo.attr, + } else { + let verifiedKeys = _.intersection( + _.uniq(clientMyInfoFields.map((field) => field.attr)), + _.keys(hashedFields), ) - .map(_preHashCheckConversion) - - // Fields from saved hash - let hashedFields = hashedObj.fields - // compare hashed values to submission values - const bcryptCompares = clientMyInfoFields.map((clientField) => { - const expected = hashedFields[clientField.attr] - return expected - ? bcrypt.compare(clientField.val, expected) - : Promise.resolve(true) - }) - Promise.all(bcryptCompares) - .then((compare) => { - return { - compare, // Array indicating hash pass/fail - fail: compare.some((v) => !v), // Whether any hashes failed - } - }) - .then((hashResults) => { - if (hashResults.fail) { - // Array of MyInfo attributes that failed verification - let hashFailedAttrs = _.zip( - clientMyInfoFields, - hashResults.compare, - ) - .filter(([_, compare]) => compare === false) - .map(([clientField, _]) => clientField.attr) - - logger.error({ - message: `Hash did not match for form ${formObjId}`, - meta: { - action: 'verifyMyInfoVals', - ...createReqMeta(req), - failedFields: hashFailedAttrs, - }, - }) - return res.status(StatusCodes.UNAUTHORIZED).json({ - message: 'MyInfo verification failed.', - spcpSubmissionFailure: true, - }) - } else { - let verifiedKeys = _.intersection( - _.uniq(clientMyInfoFields.map((field) => field.attr)), - _.keys(hashedFields), - ) - req.hashedFields = _.pick(hashedFields, verifiedKeys) - return next() - } - }) - }, - ) + req.hashedFields = _.pick(hashedFields, verifiedKeys) + return next() + } + }) } else { return next() } diff --git a/src/app/models/myinfo_hash.server.model.ts b/src/app/models/myinfo_hash.server.model.ts index 8ab2f54b6f..67376a3180 100644 --- a/src/app/models/myinfo_hash.server.model.ts +++ b/src/app/models/myinfo_hash.server.model.ts @@ -1,5 +1,7 @@ +import crypto from 'crypto' import { Mongoose, Schema } from 'mongoose' +import { sessionSecret } from '../../config/config' import { IHashes, IMyInfoHashModel, IMyInfoHashSchema } from '../../types' import { FORM_SCHEMA_ID } from './form.server.model' @@ -45,11 +47,15 @@ MyInfoHashSchema.index({ expireAt: 1 }, { expireAfterSeconds: 0 }) MyInfoHashSchema.statics.updateHashes = async function ( this: IMyInfoHashModel, - hashedUinFin: string, + uinFin: string, formId: string, readOnlyHashes: IHashes, spCookieMaxAge: number, ): Promise { + const hashedUinFin = crypto + .createHmac('sha256', sessionSecret) + .update(uinFin) + .digest('hex') return this.findOneAndUpdate( { uinFin: hashedUinFin, @@ -65,6 +71,22 @@ MyInfoHashSchema.statics.updateHashes = async function ( ) } +MyInfoHashSchema.statics.findHashes = async function ( + this: IMyInfoHashModel, + uinFin: string, + formId: string, +): Promise { + const hashedUinFin = crypto + .createHmac('sha256', sessionSecret) + .update(uinFin) + .digest('hex') + const hashInfo = await this.findOne({ + uinFin: hashedUinFin, + form: formId, + }) + return hashInfo ? hashInfo.fields : null +} + const compileMyInfoHashModel = (db: Mongoose) => db.model( MYINFO_HASH_SCHEMA_ID, diff --git a/src/types/myinfo_hash.ts b/src/types/myinfo_hash.ts index 32e51f23f8..81ce6391bf 100644 --- a/src/types/myinfo_hash.ts +++ b/src/types/myinfo_hash.ts @@ -22,9 +22,10 @@ export interface IMyInfoHashSchema extends IMyInfoHash, Document {} export interface IMyInfoHashModel extends Model { updateHashes: ( - hashedUinFin: string, + uinFin: string, formId: string, readOnlyHashes: IHashes, spCookieMaxAge: number, ) => Promise + findHashes: (uinFin: string, formId: string) => Promise } diff --git a/tests/unit/backend/controllers/myinfo.server.controller.spec.js b/tests/unit/backend/controllers/myinfo.server.controller.spec.js index 2759682568..9335766ad1 100644 --- a/tests/unit/backend/controllers/myinfo.server.controller.spec.js +++ b/tests/unit/backend/controllers/myinfo.server.controller.spec.js @@ -495,7 +495,7 @@ const ALL_MYINFO_HASHES = { '$2b$10$eLakOm88NEuUawlGHsiPjeaImpYT5ZBH1JyZUseIRL9kCtDRIKdCe', } -const SESSION_SECRET = 'secret' +const SESSION_SECRET = process.env.SESSION_SECRET const User = dbHandler.makeModel('user.server.model', 'User') const Agency = dbHandler.makeModel('agency.server.model', 'Agency') @@ -506,9 +506,6 @@ const Controller = spec( 'dist/backend/app/controllers/myinfo.server.controller', { mongoose: Object.assign(mongoose, { '@noCallThru': true }), - '../../config/config': { - sessionSecret: SESSION_SECRET, - }, }, ) diff --git a/tests/unit/backend/models/myinfo_hash.server.model.spec.ts b/tests/unit/backend/models/myinfo_hash.server.model.spec.ts index 784189d476..09fffbc2bf 100644 --- a/tests/unit/backend/models/myinfo_hash.server.model.spec.ts +++ b/tests/unit/backend/models/myinfo_hash.server.model.spec.ts @@ -1,31 +1,51 @@ import { ObjectId } from 'bson' +import crypto from 'crypto' import { omit, pick } from 'lodash' import mongoose from 'mongoose' +import { mocked } from 'ts-jest/utils' -import getMyInfoHashModel from 'src/app/models/myinfo_hash.server.model' +import config from 'src/config/config' import dbHandler from '../helpers/jest-db' +jest.mock('src/config/config') +const MockConfig = mocked(config, true) + +// eslint-disable-next-line import/first +import getMyInfoHashModel from 'src/app/models/myinfo_hash.server.model' + const MyInfoHash = getMyInfoHashModel(mongoose) -const DEFAULT_PARAMS = { +const MOCK_SESSION_SECRET = 'mockSecret' +const DEFAULT_INPUT_PARAMS = { uinFin: 'testUinFin', form: new ObjectId(), fields: { name: 'mockHash' }, expireAt: new Date(Date.now()), created: new Date(Date.now()), } +const DEFAULT_HASHED_UINFIN = crypto + .createHmac('sha256', MOCK_SESSION_SECRET) + .update(DEFAULT_INPUT_PARAMS.uinFin) + .digest('hex') +const DEFAULT_SAVED_PARAMS = { + ...DEFAULT_INPUT_PARAMS, + uinFin: DEFAULT_HASHED_UINFIN, +} const DEFAULT_COOKIE_MAX_AGE = 5 describe('MyInfo Hash Model', () => { - beforeAll(async () => await dbHandler.connect()) + beforeAll(async () => { + await dbHandler.connect() + MockConfig.sessionSecret = MOCK_SESSION_SECRET + }) beforeEach(async () => await dbHandler.clearDatabase()) afterAll(async () => await dbHandler.closeDatabase()) describe('Schema', () => { it('should create and save successfully', async () => { // Act - const actual = await MyInfoHash.create(DEFAULT_PARAMS) + const actual = await MyInfoHash.create(DEFAULT_INPUT_PARAMS) // Assert // All fields should exist @@ -33,12 +53,12 @@ describe('MyInfo Hash Model', () => { expect(actual._id).toBeDefined() expect( pick(actual, ['uinFin', 'form', 'fields', 'created', 'expireAt']), - ).toEqual(DEFAULT_PARAMS) + ).toEqual(DEFAULT_INPUT_PARAMS) }) it('should throw validation error on missing uinFin', async () => { // Arrange - const missingParams = omit(DEFAULT_PARAMS, 'uinFin') + const missingParams = omit(DEFAULT_INPUT_PARAMS, 'uinFin') // Act const myInfoHash = new MyInfoHash(missingParams) @@ -52,7 +72,7 @@ describe('MyInfo Hash Model', () => { it('should throw validation error on missing form', async () => { // Arrange - const missingParams = omit(DEFAULT_PARAMS, 'form') + const missingParams = omit(DEFAULT_INPUT_PARAMS, 'form') // Act const myInfoHash = new MyInfoHash(missingParams) @@ -66,7 +86,7 @@ describe('MyInfo Hash Model', () => { it('should throw validation error on missing fields', async () => { // Arrange - const missingParams = omit(DEFAULT_PARAMS, 'fields') + const missingParams = omit(DEFAULT_INPUT_PARAMS, 'fields') // Act const myInfoHash = new MyInfoHash(missingParams) @@ -80,7 +100,7 @@ describe('MyInfo Hash Model', () => { it('should throw validation error on missing expireAt', async () => { // Arrange - const missingParams = omit(DEFAULT_PARAMS, 'expireAt') + const missingParams = omit(DEFAULT_INPUT_PARAMS, 'expireAt') // Act const myInfoHash = new MyInfoHash(missingParams) @@ -100,10 +120,11 @@ describe('MyInfo Hash Model', () => { await expect(MyInfoHash.countDocuments()).resolves.toEqual(0) // Act + // Note: we are passing the PLAIN uinFin const actual = await MyInfoHash.updateHashes( - DEFAULT_PARAMS.uinFin, - DEFAULT_PARAMS.form.toHexString(), - DEFAULT_PARAMS.fields, + DEFAULT_INPUT_PARAMS.uinFin, + DEFAULT_INPUT_PARAMS.form.toHexString(), + DEFAULT_INPUT_PARAMS.fields, DEFAULT_COOKIE_MAX_AGE, ) @@ -112,27 +133,30 @@ describe('MyInfo Hash Model', () => { await expect(MyInfoHash.countDocuments()).resolves.toEqual(1) const found = await MyInfoHash.findOne({}) // Both the returned document and the found document should match + // Note: we are checking that the document contains the HASHED uinFin expect(pick(actual, ['uinFin', 'form', 'fields'])).toEqual( - pick(DEFAULT_PARAMS, ['uinFin', 'form', 'fields']), + pick(DEFAULT_SAVED_PARAMS, ['uinFin', 'form', 'fields']), ) expect(pick(found, ['uinFin', 'form', 'fields'])).toEqual( - pick(DEFAULT_PARAMS, ['uinFin', 'form', 'fields']), + pick(DEFAULT_SAVED_PARAMS, ['uinFin', 'form', 'fields']), ) }) it('should update successfully when a document already exists', async () => { // Arrange // Insert mock document into collection. - await MyInfoHash.create(DEFAULT_PARAMS) + // Note: we are inserting the HASHED uinFin directly. + await MyInfoHash.create(DEFAULT_SAVED_PARAMS) // Should have the added document. await expect(MyInfoHash.countDocuments()).resolves.toEqual(1) const mockFields = { sex: 'F' } // Act + // Note: we are passing the PLAIN uinFin and checking that it gets hashed const actual = await MyInfoHash.updateHashes( - DEFAULT_PARAMS.uinFin, - DEFAULT_PARAMS.form.toHexString(), + DEFAULT_INPUT_PARAMS.uinFin, + DEFAULT_INPUT_PARAMS.form.toHexString(), mockFields, DEFAULT_COOKIE_MAX_AGE, ) @@ -142,6 +166,30 @@ describe('MyInfo Hash Model', () => { // Both the returned document and the found document should match expect(actual!.fields).toEqual(mockFields) expect(found!.fields).toEqual(mockFields) + + expect(actual!.uinFin).toBe(DEFAULT_HASHED_UINFIN) + expect(found!.uinFin).toEqual(DEFAULT_HASHED_UINFIN) + }) + }) + + describe('findHashes', () => { + it('should find the correct document', async () => { + // Arrange + // Insert mock document into collection. + // Note: we are inserting the HASHED uinFin directly. + await MyInfoHash.create(DEFAULT_SAVED_PARAMS) + // Should have the added document. + await expect(MyInfoHash.countDocuments()).resolves.toEqual(1) + + // Act + // Note: we are passing the PLAIN uinFin and checking that it gets hashed + const actual = await MyInfoHash.findHashes( + DEFAULT_INPUT_PARAMS.uinFin, + DEFAULT_INPUT_PARAMS.form.toHexString(), + ) + // Assert + // Both the returned document and the found document should match + expect(actual).toEqual(DEFAULT_SAVED_PARAMS.fields) }) }) }) From 7f9a0aa9cab3e9a48085bf3ec4abbf18813498df Mon Sep 17 00:00:00 2001 From: Kar Rui Lau Date: Mon, 9 Nov 2020 10:44:53 +0800 Subject: [PATCH 13/26] feat: use auth middleware to protect routes (#568) * refactor: migrate extended express typing to vendor directory * feat(AuthMiddleware): add withUserAuthentication middleware * feat(ExampleRoutes): use withUserAuthentication middleware * test: remove 401 checks on controller tests As the authentication middleware is now on the router level and covered by integration tests * test(AuthMdw): add unit tests for withUserAuthenticated * refactor: replace auth.authenticateUser fn with withUserAuthentication * chore: trigger travis rebuild --- .../authentication.server.controller.js | 16 ------- .../auth/__tests__/auth.middlewares.spec.ts | 44 +++++++++++++++++++ src/app/modules/auth/auth.middlewares.ts | 20 +++++++++ .../__tests__/billing.controller.spec.ts | 20 --------- .../billing/__tests__/billing.routes.spec.ts | 2 +- src/app/modules/billing/billing.controller.ts | 11 ++--- src/app/modules/billing/billing.routes.ts | 5 +++ .../__tests__/examples.controller.spec.ts | 38 ---------------- .../modules/examples/examples.controller.ts | 15 +------ src/app/modules/examples/examples.routes.ts | 6 +++ src/app/routes/admin-forms.server.routes.js | 9 ++-- src/types/{ => vendor}/express.d.ts | 0 .../authentication.server.controller.spec.js | 18 -------- 13 files changed, 87 insertions(+), 117 deletions(-) create mode 100644 src/app/modules/auth/__tests__/auth.middlewares.spec.ts create mode 100644 src/app/modules/auth/auth.middlewares.ts rename src/types/{ => vendor}/express.d.ts (100%) diff --git a/src/app/controllers/authentication.server.controller.js b/src/app/controllers/authentication.server.controller.js index f2a801a54b..8d30da5e0b 100755 --- a/src/app/controllers/authentication.server.controller.js +++ b/src/app/controllers/authentication.server.controller.js @@ -8,22 +8,6 @@ const PERMISSIONS = require('../utils/permission-levels').default const { createReqMeta } = require('../utils/request') const logger = require('../../config/logger').createLoggerWithLabel(module) -/** - * Middleware that authenticates admin-user - * @param {Object} req - Express request object - * @param {Object} res - Express response object - * @param {Object} next - Express next middleware function - */ -exports.authenticateUser = function (req, res, next) { - if (req.session && req.session.user) { - return next() - } else { - return res - .status(StatusCodes.UNAUTHORIZED) - .json({ message: 'User is unauthorized.' }) - } -} - /** * Returns the error message when a user cannot perform an action on a form * @param {String} user - user email diff --git a/src/app/modules/auth/__tests__/auth.middlewares.spec.ts b/src/app/modules/auth/__tests__/auth.middlewares.spec.ts new file mode 100644 index 0000000000..eaecdc1928 --- /dev/null +++ b/src/app/modules/auth/__tests__/auth.middlewares.spec.ts @@ -0,0 +1,44 @@ +import expressHandler from 'tests/unit/backend/helpers/jest-express' + +import { withUserAuthentication } from '../auth.middlewares' + +describe('auth.middlewares', () => { + describe('withUserAuthentication', () => { + it('should pass on to the next handler if authenticated', async () => { + // Arrange + const mockReqAuthed = expressHandler.mockRequest({ + session: { + user: { + _id: 'exists', + }, + }, + }) + + const mockRes = expressHandler.mockResponse() + const nextSpy = jest.fn() + + // Act + await withUserAuthentication(mockReqAuthed, mockRes, nextSpy) + + // Assert + expect(nextSpy).toHaveBeenCalled() + }) + + it('should return 401 if not authenticated', async () => { + // Arrange + const mockReqNotAuthed = expressHandler.mockRequest() + const mockRes = expressHandler.mockResponse() + const nextSpy = jest.fn() + + // Act + await withUserAuthentication(mockReqNotAuthed, mockRes, nextSpy) + + // Assert + expect(nextSpy).not.toHaveBeenCalled() + expect(mockRes.status).toHaveBeenCalledWith(401) + expect(mockRes.json).toHaveBeenCalledWith({ + message: 'User is unauthorized.', + }) + }) + }) +}) diff --git a/src/app/modules/auth/auth.middlewares.ts b/src/app/modules/auth/auth.middlewares.ts new file mode 100644 index 0000000000..32c086363b --- /dev/null +++ b/src/app/modules/auth/auth.middlewares.ts @@ -0,0 +1,20 @@ +import { RequestHandler } from 'express' +import { StatusCodes } from 'http-status-codes' + +import { isUserInSession } from './auth.utils' + +/** + * Middleware that only allows authenticated users to pass through to the next + * handler. + * @returns next if user exists in session + * @returns 401 if user does not exist in session + */ +export const withUserAuthentication: RequestHandler = (req, res, next) => { + if (isUserInSession(req.session)) { + return next() + } + + return res + .status(StatusCodes.UNAUTHORIZED) + .json({ message: 'User is unauthorized.' }) +} diff --git a/src/app/modules/billing/__tests__/billing.controller.spec.ts b/src/app/modules/billing/__tests__/billing.controller.spec.ts index 45bf606aea..7e3c0da8b1 100644 --- a/src/app/modules/billing/__tests__/billing.controller.spec.ts +++ b/src/app/modules/billing/__tests__/billing.controller.spec.ts @@ -76,26 +76,6 @@ describe('billing.controller', () => { expect(mockRes.json).toBeCalledWith({ loginStats: mockLoginStats }) }) - it('should return 401 when user is not logged in', async () => { - // Arrange - const mockReqWithoutSession = expressHandler.mockRequest({ - query: MOCK_REQ_QUERY, - }) - const mockRes = expressHandler.mockResponse() - - // Act - await BillingController.handleGetBillInfo( - mockReqWithoutSession, - mockRes, - jest.fn(), - ) - - // Assert - expect(MockBillingService.getSpLoginStats).not.toHaveBeenCalled() - expect(mockRes.status).toBeCalledWith(401) - expect(mockRes.json).toBeCalledWith('User is unauthorized.') - }) - it('should return 500 when database error occurs', async () => { // Arrange const mockRes = expressHandler.mockResponse() diff --git a/src/app/modules/billing/__tests__/billing.routes.spec.ts b/src/app/modules/billing/__tests__/billing.routes.spec.ts index c8865d7271..3dfa904ba7 100644 --- a/src/app/modules/billing/__tests__/billing.routes.spec.ts +++ b/src/app/modules/billing/__tests__/billing.routes.spec.ts @@ -183,7 +183,7 @@ describe('billing.routes', () => { // Assert expect(response.status).toEqual(401) - expect(response.body).toEqual('User is unauthorized.') + expect(response.body).toEqual({ message: 'User is unauthorized.' }) }) it('should return 500 when error occurs whilst querying the database', async () => { diff --git a/src/app/modules/billing/billing.controller.ts b/src/app/modules/billing/billing.controller.ts index 9d4a72f5e6..09d0032c34 100644 --- a/src/app/modules/billing/billing.controller.ts +++ b/src/app/modules/billing/billing.controller.ts @@ -5,7 +5,6 @@ import moment from 'moment-timezone' import { createLoggerWithLabel } from '../../../config/logger' import { createReqMeta } from '../../utils/request' -import { isUserInSession } from '../auth/auth.utils' import { BillingFactory } from './billing.factory' @@ -13,6 +12,8 @@ const logger = createLoggerWithLabel(module) /** * Handler for GET /billing endpoint. + * @security session + * * @return 200 with login statistics when query is valid * @return 401 when request does not contain a user session * @return 500 when error occurs whilst querying database @@ -27,12 +28,8 @@ export const handleGetBillInfo: RequestHandler< mth: string } > = async (req, res) => { - // Restricted route. - if (!isUserInSession(req.session)) { - return res.status(StatusCodes.UNAUTHORIZED).json('User is unauthorized.') - } - const { esrvcId, mth, yr } = req.query + const authedUser = (req.session as Express.AuthedSession).user const startOfMonth = moment .tz([parseInt(yr), parseInt(mth)], 'Asia/Singapore') @@ -62,7 +59,7 @@ export const handleGetBillInfo: RequestHandler< // Retrieved login stats successfully. logger.info({ - message: `Billing search for ${esrvcId} by ${req.session.user.email}`, + message: `Billing search for ${esrvcId} by ${authedUser.email}`, meta: { action: 'handleGetBillInfo', ...createReqMeta(req), diff --git a/src/app/modules/billing/billing.routes.ts b/src/app/modules/billing/billing.routes.ts index 3fab4cc2a2..ca53f8b546 100644 --- a/src/app/modules/billing/billing.routes.ts +++ b/src/app/modules/billing/billing.routes.ts @@ -1,10 +1,15 @@ import { celebrate, Joi, Segments } from 'celebrate' import { Router } from 'express' +import { withUserAuthentication } from '../auth/auth.middlewares' + import * as BillingController from './billing.controller' export const BillingRouter = Router() +// All routes in this router are protected. +BillingRouter.use(withUserAuthentication) + /** * Lists the SingPass/CorpPass (SPCP) logins made to forms * created by the user's agency, serving as the basis for billing diff --git a/src/app/modules/examples/__tests__/examples.controller.spec.ts b/src/app/modules/examples/__tests__/examples.controller.spec.ts index 217487053b..5e1efc357b 100644 --- a/src/app/modules/examples/__tests__/examples.controller.spec.ts +++ b/src/app/modules/examples/__tests__/examples.controller.spec.ts @@ -53,25 +53,6 @@ describe('examples.controller', () => { expect(mockRes.json).toBeCalledWith(mockResult) }) - it('should return 401 when user is not in session', async () => { - // Arrange - const mockReqNoSession = expressHandler.mockRequest({ - query: MOCK_REQ_QUERY, - }) - const mockRes = expressHandler.mockResponse() - - // Act - await ExamplesController.handleGetExamples( - mockReqNoSession, - mockRes, - jest.fn(), - ) - - // Assert - expect(mockRes.status).toBeCalledWith(401) - expect(mockRes.json).toBeCalledWith({ message: 'User is unauthorized.' }) - }) - it('should return 500 when error occurs whilst retrieving example forms', async () => { // Arrange const mockRes = expressHandler.mockResponse() @@ -144,25 +125,6 @@ describe('examples.controller', () => { expect(mockRes.json).toBeCalledWith(mockResult) }) - it('should return 401 when user is not in session', async () => { - // Arrange - const mockReqNoSession = expressHandler.mockRequest({ - params: MOCK_REQ_PARAMS, - }) - const mockRes = expressHandler.mockResponse() - - // Act - await ExamplesController.handleGetExampleByFormId( - mockReqNoSession, - mockRes, - jest.fn(), - ) - - // Assert - expect(mockRes.status).toBeCalledWith(401) - expect(mockRes.json).toBeCalledWith({ message: 'User is unauthorized.' }) - }) - it('should return 404 when the form with given formId does not exist in the database', async () => { // Arrange const mockRes = expressHandler.mockResponse() diff --git a/src/app/modules/examples/examples.controller.ts b/src/app/modules/examples/examples.controller.ts index ddd0a86dff..0de411868e 100644 --- a/src/app/modules/examples/examples.controller.ts +++ b/src/app/modules/examples/examples.controller.ts @@ -4,7 +4,6 @@ import { StatusCodes } from 'http-status-codes' import { createLoggerWithLabel } from '../../../config/logger' import { createReqMeta } from '../../utils/request' -import { isUserInSession } from '../auth/auth.utils' import { ExamplesFactory } from './examples.factory' import { ExamplesQueryParams } from './examples.types' @@ -14,6 +13,7 @@ const logger = createLoggerWithLabel(module) /** * Handler for GET /examples endpoint. + * @security session * @returns 200 with an array of forms to be listed on the examples page * @returns 401 when user does not exist in session * @returns 500 when error occurs whilst querying the database @@ -24,12 +24,6 @@ export const handleGetExamples: RequestHandler< unknown, Query & ExamplesQueryParams > = (req, res) => { - if (!isUserInSession(req.session)) { - return res - .status(StatusCodes.UNAUTHORIZED) - .json({ message: 'User is unauthorized.' }) - } - return ExamplesFactory.getExampleForms(req.query) .map((result) => res.status(StatusCodes.OK).json(result)) .mapErr((error) => { @@ -49,6 +43,7 @@ export const handleGetExamples: RequestHandler< /** * Handler for GET /examples/:formId endpoint. + * @security session * @returns 200 with the retrieved form example * @returns 401 when user does not exist in session * @returns 404 when the form with given formId does not exist in the database @@ -57,12 +52,6 @@ export const handleGetExamples: RequestHandler< export const handleGetExampleByFormId: RequestHandler<{ formId: string }> = (req, res) => { - if (!isUserInSession(req.session)) { - return res - .status(StatusCodes.UNAUTHORIZED) - .json({ message: 'User is unauthorized.' }) - } - const { formId } = req.params return ExamplesFactory.getSingleExampleForm(formId) diff --git a/src/app/modules/examples/examples.routes.ts b/src/app/modules/examples/examples.routes.ts index 488594db67..611a1547b9 100644 --- a/src/app/modules/examples/examples.routes.ts +++ b/src/app/modules/examples/examples.routes.ts @@ -1,12 +1,18 @@ import { celebrate, Joi, Segments } from 'celebrate' import { Router } from 'express' +import { withUserAuthentication } from '../auth/auth.middlewares' + import * as ExamplesController from './examples.controller' export const ExamplesRouter = Router() +// All routes in this router are protected. +ExamplesRouter.use(withUserAuthentication) + /** * Lists publicly available forms that can be used as templates. + * @security session * @route GET /examples * @param pageNo.query.required the page number of results returned * @param agency.query the _id of agency to filter examples by diff --git a/src/app/routes/admin-forms.server.routes.js b/src/app/routes/admin-forms.server.routes.js index 2475d3bc1c..14f1853ee6 100644 --- a/src/app/routes/admin-forms.server.routes.js +++ b/src/app/routes/admin-forms.server.routes.js @@ -15,6 +15,7 @@ let encryptSubmissions = require('../../app/controllers/encrypt-submissions.serv let PERMISSIONS = require('../utils/permission-levels').default const spcpFactory = require('../factories/spcp-myinfo.factory') const webhookVerifiedContentFactory = require('../factories/webhook-verified-content.factory') +const { withUserAuthentication } = require('../modules/auth/auth.middlewares') const emailValOpts = { minDomainSegments: 2, // Number of segments required for the domain @@ -28,7 +29,7 @@ const emailValOpts = { * @param {enum} requiredPermission */ let authActiveForm = (requiredPermission) => [ - auth.authenticateUser, + withUserAuthentication, forms.formById, adminForms.isFormActive, auth.verifyPermission(requiredPermission), @@ -38,7 +39,7 @@ let authActiveForm = (requiredPermission) => [ * Authenticates logged in user, before retrieving non-archived form. */ let authAdminActiveAnyForm = [ - auth.authenticateUser, + withUserAuthentication, forms.formById, adminForms.isFormActive, ] @@ -85,8 +86,8 @@ module.exports = function (app) { */ app .route('/adminform') - .get(auth.authenticateUser, adminForms.list) - .post(auth.authenticateUser, adminForms.create) + .get(withUserAuthentication, adminForms.list) + .post(withUserAuthentication, adminForms.create) /** * @typedef AdminForm diff --git a/src/types/express.d.ts b/src/types/vendor/express.d.ts similarity index 100% rename from src/types/express.d.ts rename to src/types/vendor/express.d.ts diff --git a/tests/unit/backend/controllers/authentication.server.controller.spec.js b/tests/unit/backend/controllers/authentication.server.controller.spec.js index 350c1b922e..dc0b9ffdfd 100644 --- a/tests/unit/backend/controllers/authentication.server.controller.spec.js +++ b/tests/unit/backend/controllers/authentication.server.controller.spec.js @@ -60,24 +60,6 @@ describe('Authentication Controller', () => { testForm = collections.form }) - describe('authenticateUser', () => { - it('should pass on to the next middleware if authenticated', () => { - let next = jasmine.createSpy() - Controller.authenticateUser(req, res, next) - expect(next).toHaveBeenCalled() - }) - - it('should return 401 if not authenticated', (done) => { - req.session = null - res.status.and.callFake(() => { - expect(res.status).toHaveBeenCalledWith(StatusCodes.UNAUTHORIZED) - done() - return res - }) - Controller.authenticateUser(req, res, () => {}) - }) - }) - describe('hasFormAdminAuthorization', () => { it('should authorize if session user is admin', () => { let next = jasmine.createSpy() From b5f29bea33c5ec46af35b71b02c4613e1cd241ef Mon Sep 17 00:00:00 2001 From: tshuli <63710093+tshuli@users.noreply.github.com> Date: Mon, 9 Nov 2020 11:00:01 +0800 Subject: [PATCH 14/26] fix: overflow when printing responses (#585) * fix: overflow when printing responses * refactor: shift print style to core.css --- src/public/modules/core/css/core.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/public/modules/core/css/core.css b/src/public/modules/core/css/core.css index 612671eacb..feb60b77b9 100755 --- a/src/public/modules/core/css/core.css +++ b/src/public/modules/core/css/core.css @@ -717,3 +717,9 @@ i.glyphicon-question-sign { font-size: 60px; color: #3263cb; } + +@media print { + * { + overflow: visible !important; + } +} From fe75228d1e3f2193d6df38fd3920cf16d1df51dc Mon Sep 17 00:00:00 2001 From: Kar Rui Lau Date: Mon, 9 Nov 2020 11:06:00 +0800 Subject: [PATCH 15/26] feat: move public spcp login form messaging (#589) * feat: move spcp gated form message to start page * feat: move MyInfo error to outside of form title * style: update styling of locked form message --- .../forms/base/componentViews/start-page.html | 20 ++++++++++++++++ .../components/start-page.client.component.js | 1 + src/public/modules/forms/base/css/form.css | 14 +++++++---- .../submit-form.directive.view.html | 24 +------------------ 4 files changed, 32 insertions(+), 27 deletions(-) diff --git a/src/public/modules/forms/base/componentViews/start-page.html b/src/public/modules/forms/base/componentViews/start-page.html index 9f9c191f97..24faa382dc 100644 --- a/src/public/modules/forms/base/componentViews/start-page.html +++ b/src/public/modules/forms/base/componentViews/start-page.html @@ -95,6 +95,16 @@

{{ vm.formTitle }}

+
+
+ Login with SingPass to access this form. Your SingPass ID will be + included with your form submission. +
+
+ Login with CorpPass to access this form. Your Entity ID and + CorpPass ID will be included with your form submission. +
+