diff --git a/config.json.example b/config.json.example index 04c1c535b4..3875097d6c 100644 --- a/config.json.example +++ b/config.json.example @@ -1,4 +1,5 @@ { + "ACCOUNT_MIN_CHAT_AGE": "0", "ADMIN_EMAIL": "you@example.com", "AMAZON_PAYMENTS_CLIENT_ID": "CLIENT_ID", "AMAZON_PAYMENTS_MODE": "sandbox", diff --git a/package-lock.json b/package-lock.json index b6e905add9..32a407777f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1597,6 +1597,27 @@ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.0.tgz", "integrity": "sha512-SfJxIxNVYLTsKwzB3MoOQ1yxf4w/E6MdkvTgrgAt1bfxjSrLUoHMKrDOykwN14q65waezZIdqDneUIPh4/sKxg==" }, + "@jridgewell/source-map": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", + "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } + } + }, "@jridgewell/sourcemap-codec": { "version": "1.4.11", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", @@ -1876,18 +1897,18 @@ } }, "@types/eslint": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.1.tgz", - "integrity": "sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA==", + "version": "8.4.5", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.5.tgz", + "integrity": "sha512-dhsC09y1gpJWnK+Ff4SGvCuSnk9DaU0BJZSzOwa6GVSg65XtTugLBITDAAzRU5duGBoXBHpdR/9jHGxJjNflJQ==", "requires": { "@types/estree": "*", "@types/json-schema": "*" } }, "@types/eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==", + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", + "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", "requires": { "@types/eslint": "*", "@types/estree": "*" @@ -2148,22 +2169,22 @@ } }, "@webpack-cli/configtest": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.1.tgz", - "integrity": "sha512-1FBc1f9G4P/AxMqIgfZgeOTuRnwZMten8E7zap5zgpPInnCrP8D4Q81+4CWIch8i/Nf7nXjP0v6CjjbHOrXhKg==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", + "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==" }, "@webpack-cli/info": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.4.1.tgz", - "integrity": "sha512-PKVGmazEq3oAo46Q63tpMr4HipI3OPfP7LiNOEJg963RMgT0rqheag28NCML0o3GIzA3DmxP1ZIAv9oTX1CUIA==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz", + "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==", "requires": { "envinfo": "^7.7.3" } }, "@webpack-cli/serve": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.1.tgz", - "integrity": "sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw==" + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", + "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==" }, "@xtuc/ieee754": { "version": "1.2.0", @@ -2373,9 +2394,9 @@ } }, "apidoc": { - "version": "0.51.1", - "resolved": "https://registry.npmjs.org/apidoc/-/apidoc-0.51.1.tgz", - "integrity": "sha512-0dcL7NSUWDibgQ051ne/wXT0Dp+ArD66jwofuurxzRAPMuf2cRwa7GxRm9xlGXbOLaU7dVSZDr8LVeVBdI/oTQ==", + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/apidoc/-/apidoc-0.52.0.tgz", + "integrity": "sha512-k0gaMI7LWxaqKt2D+twC6XpI8X5SHkJalfo8TmF72d2TSNABquqB8LyIrVYzLcadcHuLMRFDaDibOK271gD67w==", "requires": { "bootstrap": "3.4.1", "commander": "^8.3.0", @@ -2399,19 +2420,6 @@ "winston": "^3.3.3" }, "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, "anymatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", @@ -2431,26 +2439,6 @@ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.4.1.tgz", "integrity": "sha512-yN5oZVmRCwe5aKwzRj6736nSmKDX7pLYwsXiCj/EYmo16hODaBiT4En5btW/jhBF/seV+XMx3aYwukYC3A49DA==" }, - "boxen": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", - "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", - "requires": { - "ansi-align": "^3.0.0", - "camelcase": "^6.2.0", - "chalk": "^4.1.0", - "cli-boxes": "^2.2.1", - "string-width": "^4.2.2", - "type-fest": "^0.20.2", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" - } - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" - }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -2466,24 +2454,6 @@ "readdirp": "~3.6.0" } }, - "cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==" - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, "debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", @@ -2492,11 +2462,6 @@ "ms": "^2.1.1" } }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, "entities": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", @@ -2509,14 +2474,14 @@ "optional": true }, "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } @@ -2529,38 +2494,6 @@ "is-glob": "^4.0.1" } }, - "global-dirs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", - "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", - "requires": { - "ini": "2.0.0" - } - }, - "ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==" - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "requires": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - } - }, - "is-npm": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", - "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==" - }, "linkify-it": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", @@ -2581,10 +2514,18 @@ "uc.micro": "^1.0.5" } }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, "nodemon": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", - "integrity": "sha512-gdHMNx47Gw7b3kWxJV64NI+Q5nfl0y5DgDbiVtShiwa7Z0IZ07Ll4RLFo6AjrhzMtoEZn5PDE3/c2AbVsiCkpA==", + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.19.tgz", + "integrity": "sha512-4pv1f2bMDj0Eeg/MhGqxrtveeQ5/G/UVe9iO6uTZzjnRluSA4PVWf8CW99LUPwGB3eNIA7zUFoP77YuI7hOc0A==", "requires": { "chokidar": "^3.5.2", "debug": "^3.2.7", @@ -2592,10 +2533,10 @@ "minimatch": "^3.0.4", "pstree.remy": "^1.1.8", "semver": "^5.7.1", + "simple-update-notifier": "^1.0.7", "supports-color": "^5.5.0", "touch": "^3.1.0", - "undefsafe": "^2.0.5", - "update-notifier": "^5.1.0" + "undefsafe": "^2.0.5" }, "dependencies": { "semver": { @@ -2605,14 +2546,6 @@ } } }, - "pupa": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", - "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", - "requires": { - "escape-goat": "^2.0.0" - } - }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -2629,64 +2562,10 @@ "lru-cache": "^6.0.0" } }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" - }, "undefsafe": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" - }, - "update-notifier": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", - "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", - "requires": { - "boxen": "^5.0.0", - "chalk": "^4.1.0", - "configstore": "^5.0.1", - "has-yarn": "^2.1.0", - "import-lazy": "^2.1.0", - "is-ci": "^2.0.0", - "is-installed-globally": "^0.4.0", - "is-npm": "^5.0.0", - "is-yarn-global": "^0.3.0", - "latest-version": "^5.1.0", - "pupa": "^2.1.1", - "semver": "^7.3.4", - "semver-diff": "^3.1.1", - "xdg-basedir": "^4.0.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } } } }, @@ -3985,21 +3864,20 @@ "dev": true }, "browserslist": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", - "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.2.tgz", + "integrity": "sha512-MonuOgAtUB46uP5CezYbRaYKBNt2LxP0yX+Pmj4LkcDFGkn9Cbpi83d9sCjwQDErXsIJSzY5oKGDbgOlF/LPAA==", "requires": { - "caniuse-lite": "^1.0.30001286", - "electron-to-chromium": "^1.4.17", - "escalade": "^3.1.1", - "node-releases": "^2.0.1", - "picocolors": "^1.0.0" + "caniuse-lite": "^1.0.30001366", + "electron-to-chromium": "^1.4.188", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.4" }, "dependencies": { "electron-to-chromium": { - "version": "1.4.28", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.28.tgz", - "integrity": "sha512-Gzbf0wUtKfyPaqf0Plz+Ctinf9eQIzxEqBHwSvbGfeOm9GMNdLxyu1dNiCUfM+x6r4BE0xUJNh3Nmg9gfAtTmg==" + "version": "1.4.192", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.192.tgz", + "integrity": "sha512-8nCXyIQY9An88NXAp+PuPy5h3/w5ZY7Iu2lag65Q0XREprcat5F8gKhoHsBUnQcFuCRnmevpR8yEBYRU3d2HDw==" } } }, @@ -4157,9 +4035,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001292", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001292.tgz", - "integrity": "sha512-jnT4Tq0Q4ma+6nncYQVe7d73kmDmE9C3OGTx3MvW7lBM/eY1S1DZTMBON7dqV481RhNiS5OxD7k9JQvmDOTirw==" + "version": "1.0.30001367", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001367.tgz", + "integrity": "sha512-XDgbeOHfifWV3GEES2B8rtsrADx4Jf+juKX2SICJcaUhjYBO3bR96kvEIHa15VU6ohtOhBZuPGGYGbXMRn0NCw==" }, "caseless": { "version": "0.12.0", @@ -4543,9 +4421,9 @@ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" }, "colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==" + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" }, "colors": { "version": "1.4.0", @@ -5710,9 +5588,9 @@ } }, "enhanced-resolve": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz", - "integrity": "sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", + "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", "requires": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -5822,122 +5700,122 @@ } }, "esbuild": { - "version": "0.14.36", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.36.tgz", - "integrity": "sha512-HhFHPiRXGYOCRlrhpiVDYKcFJRdO0sBElZ668M4lh2ER0YgnkLxECuFe7uWCf23FrcLc59Pqr7dHkTqmRPDHmw==", + "version": "0.14.49", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.49.tgz", + "integrity": "sha512-/TlVHhOaq7Yz8N1OJrjqM3Auzo5wjvHFLk+T8pIue+fhnhIMpfAzsG6PLVMbFveVxqD2WOp3QHei+52IMUNmCw==", "requires": { - "esbuild-android-64": "0.14.36", - "esbuild-android-arm64": "0.14.36", - "esbuild-darwin-64": "0.14.36", - "esbuild-darwin-arm64": "0.14.36", - "esbuild-freebsd-64": "0.14.36", - "esbuild-freebsd-arm64": "0.14.36", - "esbuild-linux-32": "0.14.36", - "esbuild-linux-64": "0.14.36", - "esbuild-linux-arm": "0.14.36", - "esbuild-linux-arm64": "0.14.36", - "esbuild-linux-mips64le": "0.14.36", - "esbuild-linux-ppc64le": "0.14.36", - "esbuild-linux-riscv64": "0.14.36", - "esbuild-linux-s390x": "0.14.36", - "esbuild-netbsd-64": "0.14.36", - "esbuild-openbsd-64": "0.14.36", - "esbuild-sunos-64": "0.14.36", - "esbuild-windows-32": "0.14.36", - "esbuild-windows-64": "0.14.36", - "esbuild-windows-arm64": "0.14.36" + "esbuild-android-64": "0.14.49", + "esbuild-android-arm64": "0.14.49", + "esbuild-darwin-64": "0.14.49", + "esbuild-darwin-arm64": "0.14.49", + "esbuild-freebsd-64": "0.14.49", + "esbuild-freebsd-arm64": "0.14.49", + "esbuild-linux-32": "0.14.49", + "esbuild-linux-64": "0.14.49", + "esbuild-linux-arm": "0.14.49", + "esbuild-linux-arm64": "0.14.49", + "esbuild-linux-mips64le": "0.14.49", + "esbuild-linux-ppc64le": "0.14.49", + "esbuild-linux-riscv64": "0.14.49", + "esbuild-linux-s390x": "0.14.49", + "esbuild-netbsd-64": "0.14.49", + "esbuild-openbsd-64": "0.14.49", + "esbuild-sunos-64": "0.14.49", + "esbuild-windows-32": "0.14.49", + "esbuild-windows-64": "0.14.49", + "esbuild-windows-arm64": "0.14.49" } }, "esbuild-android-64": { - "version": "0.14.36", - "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.36.tgz", - "integrity": "sha512-jwpBhF1jmo0tVCYC/ORzVN+hyVcNZUWuozGcLHfod0RJCedTDTvR4nwlTXdx1gtncDqjk33itjO+27OZHbiavw==", + "version": "0.14.49", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.49.tgz", + "integrity": "sha512-vYsdOTD+yi+kquhBiFWl3tyxnj2qZJsl4tAqwhT90ktUdnyTizgle7TjNx6Ar1bN7wcwWqZ9QInfdk2WVagSww==", "optional": true }, "esbuild-android-arm64": { - "version": "0.14.36", - "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.36.tgz", - "integrity": "sha512-/hYkyFe7x7Yapmfv4X/tBmyKnggUmdQmlvZ8ZlBnV4+PjisrEhAvC3yWpURuD9XoB8Wa1d5dGkTsF53pIvpjsg==", + "version": "0.14.49", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.49.tgz", + "integrity": "sha512-g2HGr/hjOXCgSsvQZ1nK4nW/ei8JUx04Li74qub9qWrStlysaVmadRyTVuW32FGIpLQyc5sUjjZopj49eGGM2g==", "optional": true }, "esbuild-darwin-64": { - "version": "0.14.36", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.36.tgz", - "integrity": "sha512-kkl6qmV0dTpyIMKagluzYqlc1vO0ecgpviK/7jwPbRDEv5fejRTaBBEE2KxEQbTHcLhiiDbhG7d5UybZWo/1zQ==", + "version": "0.14.49", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.49.tgz", + "integrity": "sha512-3rvqnBCtX9ywso5fCHixt2GBCUsogNp9DjGmvbBohh31Ces34BVzFltMSxJpacNki96+WIcX5s/vum+ckXiLYg==", "optional": true }, "esbuild-darwin-arm64": { - "version": "0.14.36", - "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.36.tgz", - "integrity": "sha512-q8fY4r2Sx6P0Pr3VUm//eFYKVk07C5MHcEinU1BjyFnuYz4IxR/03uBbDwluR6ILIHnZTE7AkTUWIdidRi1Jjw==", + "version": "0.14.49", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.49.tgz", + "integrity": "sha512-XMaqDxO846srnGlUSJnwbijV29MTKUATmOLyQSfswbK/2X5Uv28M9tTLUJcKKxzoo9lnkYPsx2o8EJcTYwCs/A==", "optional": true }, "esbuild-freebsd-64": { - "version": "0.14.36", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.36.tgz", - "integrity": "sha512-Hn8AYuxXXRptybPqoMkga4HRFE7/XmhtlQjXFHoAIhKUPPMeJH35GYEUWGbjteai9FLFvBAjEAlwEtSGxnqWww==", + "version": "0.14.49", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.49.tgz", + "integrity": "sha512-NJ5Q6AjV879mOHFri+5lZLTp5XsO2hQ+KSJYLbfY9DgCu8s6/Zl2prWXVANYTeCDLlrIlNNYw8y34xqyLDKOmQ==", "optional": true }, "esbuild-freebsd-arm64": { - "version": "0.14.36", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.36.tgz", - "integrity": "sha512-S3C0attylLLRiCcHiJd036eDEMOY32+h8P+jJ3kTcfhJANNjP0TNBNL30TZmEdOSx/820HJFgRrqpNAvTbjnDA==", + "version": "0.14.49", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.49.tgz", + "integrity": "sha512-lFLtgXnAc3eXYqj5koPlBZvEbBSOSUbWO3gyY/0+4lBdRqELyz4bAuamHvmvHW5swJYL7kngzIZw6kdu25KGOA==", "optional": true }, "esbuild-linux-32": { - "version": "0.14.36", - "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.36.tgz", - "integrity": "sha512-Eh9OkyTrEZn9WGO4xkI3OPPpUX7p/3QYvdG0lL4rfr73Ap2HAr6D9lP59VMF64Ex01LhHSXwIsFG/8AQjh6eNw==", + "version": "0.14.49", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.49.tgz", + "integrity": "sha512-zTTH4gr2Kb8u4QcOpTDVn7Z8q7QEIvFl/+vHrI3cF6XOJS7iEI1FWslTo3uofB2+mn6sIJEQD9PrNZKoAAMDiA==", "optional": true }, "esbuild-linux-64": { - "version": "0.14.36", - "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.36.tgz", - "integrity": "sha512-vFVFS5ve7PuwlfgoWNyRccGDi2QTNkQo/2k5U5ttVD0jRFaMlc8UQee708fOZA6zTCDy5RWsT5MJw3sl2X6KDg==", + "version": "0.14.49", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.49.tgz", + "integrity": "sha512-hYmzRIDzFfLrB5c1SknkxzM8LdEUOusp6M2TnuQZJLRtxTgyPnZZVtyMeCLki0wKgYPXkFsAVhi8vzo2mBNeTg==", "optional": true }, "esbuild-linux-arm": { - "version": "0.14.36", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.36.tgz", - "integrity": "sha512-NhgU4n+NCsYgt7Hy61PCquEz5aevI6VjQvxwBxtxrooXsxt5b2xtOUXYZe04JxqQo+XZk3d1gcr7pbV9MAQ/Lg==", + "version": "0.14.49", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.49.tgz", + "integrity": "sha512-iE3e+ZVv1Qz1Sy0gifIsarJMQ89Rpm9mtLSRtG3AH0FPgAzQ5Z5oU6vYzhc/3gSPi2UxdCOfRhw2onXuFw/0lg==", "optional": true }, "esbuild-linux-arm64": { - "version": "0.14.36", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.36.tgz", - "integrity": "sha512-24Vq1M7FdpSmaTYuu1w0Hdhiqkbto1I5Pjyi+4Cdw5fJKGlwQuw+hWynTcRI/cOZxBcBpP21gND7W27gHAiftw==", + "version": "0.14.49", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.49.tgz", + "integrity": "sha512-KLQ+WpeuY+7bxukxLz5VgkAAVQxUv67Ft4DmHIPIW+2w3ObBPQhqNoeQUHxopoW/aiOn3m99NSmSV+bs4BSsdA==", "optional": true }, "esbuild-linux-mips64le": { - "version": "0.14.36", - "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.36.tgz", - "integrity": "sha512-hZUeTXvppJN+5rEz2EjsOFM9F1bZt7/d2FUM1lmQo//rXh1RTFYzhC0txn7WV0/jCC7SvrGRaRz0NMsRPf8SIA==", + "version": "0.14.49", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.49.tgz", + "integrity": "sha512-n+rGODfm8RSum5pFIqFQVQpYBw+AztL8s6o9kfx7tjfK0yIGF6tm5HlG6aRjodiiKkH2xAiIM+U4xtQVZYU4rA==", "optional": true }, "esbuild-linux-ppc64le": { - "version": "0.14.36", - "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.36.tgz", - "integrity": "sha512-1Bg3QgzZjO+QtPhP9VeIBhAduHEc2kzU43MzBnMwpLSZ890azr4/A9Dganun8nsqD/1TBcqhId0z4mFDO8FAvg==", + "version": "0.14.49", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.49.tgz", + "integrity": "sha512-WP9zR4HX6iCBmMFH+XHHng2LmdoIeUmBpL4aL2TR8ruzXyT4dWrJ5BSbT8iNo6THN8lod6GOmYDLq/dgZLalGw==", "optional": true }, "esbuild-linux-riscv64": { - "version": "0.14.36", - "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.36.tgz", - "integrity": "sha512-dOE5pt3cOdqEhaufDRzNCHf5BSwxgygVak9UR7PH7KPVHwSTDAZHDoEjblxLqjJYpc5XaU9+gKJ9F8mp9r5I4A==", + "version": "0.14.49", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.49.tgz", + "integrity": "sha512-h66ORBz+Dg+1KgLvzTVQEA1LX4XBd1SK0Fgbhhw4akpG/YkN8pS6OzYI/7SGENiN6ao5hETRDSkVcvU9NRtkMQ==", "optional": true }, "esbuild-linux-s390x": { - "version": "0.14.36", - "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.36.tgz", - "integrity": "sha512-g4FMdh//BBGTfVHjF6MO7Cz8gqRoDPzXWxRvWkJoGroKA18G9m0wddvPbEqcQf5Tbt2vSc1CIgag7cXwTmoTXg==", + "version": "0.14.49", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.49.tgz", + "integrity": "sha512-DhrUoFVWD+XmKO1y7e4kNCqQHPs6twz6VV6Uezl/XHYGzM60rBewBF5jlZjG0nCk5W/Xy6y1xWeopkrhFFM0sQ==", "optional": true }, "esbuild-loader": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-2.18.0.tgz", - "integrity": "sha512-AKqxM3bI+gvGPV8o6NAhR+cBxVO8+dh+O0OXBHIXXwuSGumckbPWHzZ17subjBGI2YEGyJ1STH7Haj8aCrwL/w==", + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-2.19.0.tgz", + "integrity": "sha512-urGNVE6Tl2rqx92ElKi/LiExXjGvcH6HfDBFzJ9Ppwqh4n6Jmx8x7RKAyMzSM78b6CAaJLhDncG5sPrL0ROh5Q==", "requires": { - "esbuild": "^0.14.6", + "esbuild": "^0.14.39", "joycon": "^3.0.1", "json5": "^2.2.0", "loader-utils": "^2.0.0", @@ -5946,39 +5824,39 @@ } }, "esbuild-netbsd-64": { - "version": "0.14.36", - "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.36.tgz", - "integrity": "sha512-UB2bVImxkWk4vjnP62ehFNZ73lQY1xcnL5ZNYF3x0AG+j8HgdkNF05v67YJdCIuUJpBuTyCK8LORCYo9onSW+A==", + "version": "0.14.49", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.49.tgz", + "integrity": "sha512-BXaUwFOfCy2T+hABtiPUIpWjAeWK9P8O41gR4Pg73hpzoygVGnj0nI3YK4SJhe52ELgtdgWP/ckIkbn2XaTxjQ==", "optional": true }, "esbuild-openbsd-64": { - "version": "0.14.36", - "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.36.tgz", - "integrity": "sha512-NvGB2Chf8GxuleXRGk8e9zD3aSdRO5kLt9coTQbCg7WMGXeX471sBgh4kSg8pjx0yTXRt0MlrUDnjVYnetyivg==", + "version": "0.14.49", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.49.tgz", + "integrity": "sha512-lP06UQeLDGmVPw9Rg437Btu6J9/BmyhdoefnQ4gDEJTtJvKtQaUcOQrhjTq455ouZN4EHFH1h28WOJVANK41kA==", "optional": true }, "esbuild-sunos-64": { - "version": "0.14.36", - "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.36.tgz", - "integrity": "sha512-VkUZS5ftTSjhRjuRLp+v78auMO3PZBXu6xl4ajomGenEm2/rGuWlhFSjB7YbBNErOchj51Jb2OK8lKAo8qdmsQ==", + "version": "0.14.49", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.49.tgz", + "integrity": "sha512-4c8Zowp+V3zIWje329BeLbGh6XI9c/rqARNaj5yPHdC61pHI9UNdDxT3rePPJeWcEZVKjkiAS6AP6kiITp7FSw==", "optional": true }, "esbuild-windows-32": { - "version": "0.14.36", - "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.36.tgz", - "integrity": "sha512-bIar+A6hdytJjZrDxfMBUSEHHLfx3ynoEZXx/39nxy86pX/w249WZm8Bm0dtOAByAf4Z6qV0LsnTIJHiIqbw0w==", + "version": "0.14.49", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.49.tgz", + "integrity": "sha512-q7Rb+J9yHTeKr9QTPDYkqfkEj8/kcKz9lOabDuvEXpXuIcosWCJgo5Z7h/L4r7rbtTH4a8U2FGKb6s1eeOHmJA==", "optional": true }, "esbuild-windows-64": { - "version": "0.14.36", - "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.36.tgz", - "integrity": "sha512-+p4MuRZekVChAeueT1Y9LGkxrT5x7YYJxYE8ZOTcEfeUUN43vktSn6hUNsvxzzATrSgq5QqRdllkVBxWZg7KqQ==", + "version": "0.14.49", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.49.tgz", + "integrity": "sha512-+Cme7Ongv0UIUTniPqfTX6mJ8Deo7VXw9xN0yJEN1lQMHDppTNmKwAM3oGbD/Vqff+07K2gN0WfNkMohmG+dVw==", "optional": true }, "esbuild-windows-arm64": { - "version": "0.14.36", - "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.36.tgz", - "integrity": "sha512-fBB4WlDqV1m18EF/aheGYQkQZHfPHiHJSBYzXIo8yKehek+0BtBwo/4PNwKGJ5T0YK0oc8pBKjgwPbzSrPLb+Q==", + "version": "0.14.49", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.49.tgz", + "integrity": "sha512-v+HYNAXzuANrCbbLFJ5nmO3m5y2PGZWLe3uloAkLt87aXiO2mZr3BTmacZdjwNkNEHuH3bNtN8cak+mzVjVPfA==", "optional": true }, "escalade": { @@ -8678,9 +8556,9 @@ "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=" }, "image-size": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.1.tgz", - "integrity": "sha512-VAwkvNSNGClRw9mDHhc5Efax8PLlsOGcUTh0T/LIriC8vPA3U5PdqXWqkz406MoYHMKW8Uf9gWr05T/rYB44kQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.2.tgz", + "integrity": "sha512-xfOoWjceHntRb3qFCrh5ZFORYH8XCdYpASltMhZ/Q0KZiOwjdE/Yl2QCiWdwD+lygV5bMCvauzgu5PxBX/Yerg==", "requires": { "queue": "6.0.2" } @@ -9627,10 +9505,10 @@ "resolved": "https://registry.npmjs.org/json-content-demux/-/json-content-demux-0.1.4.tgz", "integrity": "sha512-3GqPH2O0+8qBMTa1YTuL+7L24YJYNDjdXfa798y9S6GetScZAY2iAOGCdFkEPZJZdafPKv8ZUnp18VCCPTs0Nw==" }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "json-schema": { "version": "0.2.3", @@ -11350,9 +11228,9 @@ } }, "node-releases": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", - "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==" + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" }, "nodemon": { "version": "2.0.4", @@ -13433,6 +13311,21 @@ "is-arrayish": "^0.3.1" } }, + "simple-update-notifier": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz", + "integrity": "sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew==", + "requires": { + "semver": "~7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==" + } + } + }, "sinon": { "version": "13.0.2", "resolved": "https://registry.npmjs.org/sinon/-/sinon-13.0.2.tgz", @@ -14066,7 +13959,8 @@ "strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "optional": true }, "strip-indent": { "version": "1.0.1", @@ -14395,20 +14289,20 @@ "integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw==" }, "terser": { - "version": "5.12.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.12.1.tgz", - "integrity": "sha512-NXbs+7nisos5E+yXwAD+y7zrcTkMqb0dEJxIGtSKPdCBzopf7ni4odPul2aechpV7EXNvOudYOX2bb5tln1jbQ==", + "version": "5.14.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz", + "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==", "requires": { + "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", "commander": "^2.20.0", - "source-map": "~0.7.2", "source-map-support": "~0.5.20" }, "dependencies": { "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==" + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==" }, "commander": { "version": "2.20.3", @@ -14416,9 +14310,9 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, "source-map-support": { "version": "0.5.21", @@ -14427,34 +14321,20 @@ "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } } } } }, "terser-webpack-plugin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz", - "integrity": "sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.3.tgz", + "integrity": "sha512-Fx60G5HNYknNTNQnzQ1VePRuu89ZVYWfjRAeT5rITuCY/1b08s49e5kSQwHDirKZWuoKOBRFS98EUUoZ9kLEwQ==", "requires": { + "@jridgewell/trace-mapping": "^0.3.7", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", "terser": "^5.7.2" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } } }, "text-hex": { @@ -15546,9 +15426,9 @@ } }, "watchpack": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz", - "integrity": "sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", "requires": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -15560,9 +15440,9 @@ "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" }, "webpack": { - "version": "5.72.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.72.0.tgz", - "integrity": "sha512-qmSmbspI0Qo5ld49htys8GY9XhS9CGqFoHTsOVAnjBdg0Zn79y135R+k4IR4rKK6+eKaabMhJwiVB7xw0SJu5w==", + "version": "5.73.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.73.0.tgz", + "integrity": "sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA==", "requires": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^0.0.51", @@ -15573,13 +15453,13 @@ "acorn-import-assertions": "^1.7.6", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.9.2", + "enhanced-resolve": "^5.9.3", "es-module-lexer": "^0.9.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.9", - "json-parse-better-errors": "^1.0.2", + "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", @@ -15591,9 +15471,9 @@ }, "dependencies": { "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==" + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==" }, "eslint-scope": { "version": "5.1.1", @@ -15632,17 +15512,17 @@ } }, "webpack-cli": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.2.tgz", - "integrity": "sha512-m3/AACnBBzK/kMTcxWHcZFPrw/eQuY4Df1TxvIWfWM2x7mRqBQCqKEd96oCUa9jkapLBaFfRce33eGDb4Pr7YQ==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz", + "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", "requires": { "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.1.1", - "@webpack-cli/info": "^1.4.1", - "@webpack-cli/serve": "^1.6.1", + "@webpack-cli/configtest": "^1.2.0", + "@webpack-cli/info": "^1.5.0", + "@webpack-cli/serve": "^1.7.0", "colorette": "^2.0.14", "commander": "^7.0.0", - "execa": "^5.0.0", + "cross-spawn": "^7.0.3", "fastest-levenshtein": "^1.0.12", "import-local": "^3.0.2", "interpret": "^2.2.0", @@ -15655,58 +15535,11 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" - }, "interpret": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==" }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "requires": { - "path-key": "^3.0.0" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, "rechoir": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", diff --git a/package.json b/package.json index 0476235ff1..68c3a46de1 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "accepts": "^1.3.8", "amazon-payments": "^0.2.9", "amplitude": "^6.0.0", - "apidoc": "^0.51.1", + "apidoc": "^0.52.0", "apple-auth": "^1.0.7", "bcrypt": "^5.0.1", "body-parser": "^1.20.0", @@ -39,7 +39,7 @@ "gulp.spritesmith": "^6.13.0", "habitica-markdown": "^3.0.0", "helmet": "^4.6.0", - "image-size": "^1.0.1", + "image-size": "^1.0.2", "in-app-purchase": "^1.11.3", "js2xmlparser": "^4.0.2", "jsonwebtoken": "^8.5.1", diff --git a/test/api/v3/integration/chat/DELETE-chat_id.test.js b/test/api/v3/integration/chat/DELETE-chat_id.test.js index 0d53dfa999..7a9756e673 100644 --- a/test/api/v3/integration/chat/DELETE-chat_id.test.js +++ b/test/api/v3/integration/chat/DELETE-chat_id.test.js @@ -15,6 +15,10 @@ describe('DELETE /groups/:groupId/chat/:chatId', () => { type: 'guild', privacy: 'public', }, + leaderDetails: { + 'auth.timestamps.created': new Date('2022-01-01'), + balance: 10, + }, }); groupWithChat = group; diff --git a/test/api/v3/integration/chat/POST-chat.flag.test.js b/test/api/v3/integration/chat/POST-chat.flag.test.js index acff8b507b..909fbfa7a0 100644 --- a/test/api/v3/integration/chat/POST-chat.flag.test.js +++ b/test/api/v3/integration/chat/POST-chat.flag.test.js @@ -117,7 +117,9 @@ describe('POST /chat/:chatId/flag', () => { }); it('Flags a chat when the author\'s account was deleted', async () => { - const deletedUser = await generateUser(); + const deletedUser = await generateUser({ + 'auth.timestamps.created': new Date('2022-01-01'), + }); const { message } = await deletedUser.post(`/groups/${group._id}/chat`, { message: TEST_MESSAGE }); await deletedUser.del('/user', { password: 'password', diff --git a/test/api/v3/integration/chat/POST-chat.like.test.js b/test/api/v3/integration/chat/POST-chat.like.test.js index 192f3e3aa7..beab851bb0 100644 --- a/test/api/v3/integration/chat/POST-chat.like.test.js +++ b/test/api/v3/integration/chat/POST-chat.like.test.js @@ -18,11 +18,16 @@ describe('POST /chat/:chatId/like', () => { privacy: 'public', }, members: 1, + leaderDetails: { + 'auth.timestamps.created': new Date('2022-01-01'), + balance: 10, + }, }); user = groupLeader; groupWithChat = group; anotherUser = members[0]; // eslint-disable-line prefer-destructuring + await anotherUser.update({ 'auth.timestamps.created': new Date('2022-01-01') }); }); it('Returns an error when chat message is not found', async () => { diff --git a/test/api/v3/integration/chat/POST-chat.test.js b/test/api/v3/integration/chat/POST-chat.test.js index 24283de89e..73ee343c79 100644 --- a/test/api/v3/integration/chat/POST-chat.test.js +++ b/test/api/v3/integration/chat/POST-chat.test.js @@ -38,10 +38,15 @@ describe('POST /chat', () => { members: 2, }); user = groupLeader; - await user.update({ 'contributor.level': SPAM_MIN_EXEMPT_CONTRIB_LEVEL }); // prevent tests accidentally throwing messageGroupChatSpam + await user.update({ + 'contributor.level': SPAM_MIN_EXEMPT_CONTRIB_LEVEL, + 'auth.timestamps.created': new Date('2022-01-01'), + }); // prevent tests accidentally throwing messageGroupChatSpam groupWithChat = group; member = members[0]; // eslint-disable-line prefer-destructuring additionalMember = members[1]; // eslint-disable-line prefer-destructuring + await member.update({ 'auth.timestamps.created': new Date('2022-01-01') }); + await additionalMember.update({ 'auth.timestamps.created': new Date('2022-01-01') }); }); it('Returns an error when no message is provided', async () => { @@ -104,7 +109,10 @@ describe('POST /chat', () => { }); const privateGuildMemberWithChatsRevoked = members[0]; - await privateGuildMemberWithChatsRevoked.update({ 'flags.chatRevoked': true }); + await privateGuildMemberWithChatsRevoked.update({ + 'flags.chatRevoked': true, + 'auth.timestamps.created': new Date('2022-01-01'), + }); const message = await privateGuildMemberWithChatsRevoked.post(`/groups/${group._id}/chat`, { message: testMessage }); @@ -122,7 +130,10 @@ describe('POST /chat', () => { }); const privatePartyMemberWithChatsRevoked = members[0]; - await privatePartyMemberWithChatsRevoked.update({ 'flags.chatRevoked': true }); + await privatePartyMemberWithChatsRevoked.update({ + 'flags.chatRevoked': true, + 'auth.timestamps.created': new Date('2022-01-01'), + }); const message = await privatePartyMemberWithChatsRevoked.post(`/groups/${group._id}/chat`, { message: testMessage }); @@ -183,7 +194,10 @@ describe('POST /chat', () => { }); const userWithChatShadowMuted = members[0]; - await userWithChatShadowMuted.update({ 'flags.chatShadowMuted': true }); + await userWithChatShadowMuted.update({ + 'flags.chatShadowMuted': true, + 'auth.timestamps.created': new Date('2022-01-01'), + }); const message = await userWithChatShadowMuted.post(`/groups/${group._id}/chat`, { message: testMessage }); @@ -202,7 +216,10 @@ describe('POST /chat', () => { }); const userWithChatShadowMuted = members[0]; - await userWithChatShadowMuted.update({ 'flags.chatShadowMuted': true }); + await userWithChatShadowMuted.update({ + 'flags.chatShadowMuted': true, + 'auth.timestamps.created': new Date('2022-01-01'), + }); const message = await userWithChatShadowMuted.post(`/groups/${group._id}/chat`, { message: testMessage }); @@ -312,6 +329,7 @@ describe('POST /chat', () => { }, members: 1, }); + await members[0].update({ 'auth.timestamps.created': new Date('2022-01-01') }); const message = await members[0].post(`/groups/${group._id}/chat`, { message: testBannedWordMessage }); @@ -330,6 +348,7 @@ describe('POST /chat', () => { // Update the bannedWordsAllowed property for the group group.update({ bannedWordsAllowed: true }); + await members[0].update({ 'auth.timestamps.created': new Date('2022-01-01') }); const message = await members[0].post(`/groups/${group._id}/chat`, { message: testBannedWordMessage }); @@ -345,6 +364,7 @@ describe('POST /chat', () => { }, members: 1, }); + await members[0].update({ 'auth.timestamps.created': new Date('2022-01-01') }); const message = await members[0].post(`/groups/${group._id}/chat`, { message: testBannedWordMessage }); @@ -411,6 +431,7 @@ describe('POST /chat', () => { }, members: 1, }); + await members[0].update({ 'auth.timestamps.created': new Date('2022-01-01') }); const message = await members[0].post(`/groups/${group._id}/chat`, { message: testSlurMessage }); @@ -430,6 +451,16 @@ describe('POST /chat', () => { }); }); + it('errors when user account is too young', async () => { + const brandNewUser = await generateUser(); + await expect(brandNewUser.post('/groups/habitrpg/chat', { message: 'hi im new' })) + .to.eventually.be.rejected.and.eql({ + code: 400, + error: 'BadRequest', + message: t('chatTemporarilyUnavailable'), + }); + }); + it('creates a chat', async () => { const newMessage = await user.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage }); const groupMessages = await user.get(`/groups/${groupWithChat._id}/chat`); @@ -492,6 +523,7 @@ describe('POST /chat', () => { 'items.currentMount': mount, 'items.currentPet': pet, 'preferences.style': style, + 'auth.timestamps.created': new Date('2022-01-01'), }); await userWithStyle.sync(); @@ -517,6 +549,7 @@ describe('POST /chat', () => { }; const backer = await generateUser({ backer: backerInfo, + 'auth.timestamps.created': new Date('2022-01-01'), }); const message = await backer.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage }); @@ -587,6 +620,9 @@ describe('POST /chat', () => { privacy: 'private', }, members: 1, + leaderDetails: { + 'auth.timestamps.created': new Date('2022-01-01'), + }, }); const message = await groupLeader.post(`/groups/${group._id}/chat`, { message: testMessage }); diff --git a/test/api/v3/integration/chat/POST-chat_seen.test.js b/test/api/v3/integration/chat/POST-chat_seen.test.js index f64df56146..9cd2103bc6 100644 --- a/test/api/v3/integration/chat/POST-chat_seen.test.js +++ b/test/api/v3/integration/chat/POST-chat_seen.test.js @@ -15,6 +15,10 @@ describe('POST /groups/:id/chat/seen', () => { privacy: 'public', }, members: 1, + leaderDetails: { + 'auth.timestamps.created': new Date('2022-01-01'), + balance: 10, + }, }); guild = group; @@ -51,6 +55,9 @@ describe('POST /groups/:id/chat/seen', () => { privacy: 'private', }, members: 1, + leaderDetails: { + 'auth.timestamps.created': new Date('2022-01-01'), + }, }); party = group; diff --git a/test/api/v3/integration/chat/POST-groups_id_chat_id_clear_flags.test.js b/test/api/v3/integration/chat/POST-groups_id_chat_id_clear_flags.test.js index e9f77e5561..4bb99cc33f 100644 --- a/test/api/v3/integration/chat/POST-groups_id_chat_id_clear_flags.test.js +++ b/test/api/v3/integration/chat/POST-groups_id_chat_id_clear_flags.test.js @@ -18,6 +18,10 @@ describe('POST /groups/:id/chat/:id/clearflags', () => { type: 'guild', privacy: 'public', }, + leaderDetails: { + 'auth.timestamps.created': new Date('2022-01-01'), + balance: 10, + }, }); groupWithChat = group; @@ -65,6 +69,7 @@ describe('POST /groups/:id/chat/:id/clearflags', () => { members: 1, }); + await members[0].update({ 'auth.timestamps.created': new Date('2022-01-01') }); let privateMessage = await members[0].post(`/groups/${group._id}/chat`, { message: 'Some message' }); privateMessage = privateMessage.message; diff --git a/test/api/v3/integration/groups/POST-groups_groupId_leave.test.js b/test/api/v3/integration/groups/POST-groups_groupId_leave.test.js index 56de50b822..b7b16a7f04 100644 --- a/test/api/v3/integration/groups/POST-groups_groupId_leave.test.js +++ b/test/api/v3/integration/groups/POST-groups_groupId_leave.test.js @@ -37,6 +37,7 @@ describe('POST /groups/:groupId/leave', () => { leader = groupLeader; member = members[0]; // eslint-disable-line prefer-destructuring memberCount = group.memberCount; + await members[0].update({ 'auth.timestamps.created': new Date('2022-01-01') }); }); it('prevents non members from leaving', async () => { @@ -152,6 +153,10 @@ describe('POST /groups/:groupId/leave', () => { type: 'guild', }, invites: 1, + leaderDetails: { + 'auth.timestamps.created': new Date('2022-01-01'), + balance: 10, + }, }); privateGuild = group; diff --git a/test/api/v3/integration/groups/POST-groups_id_removeMember.test.js b/test/api/v3/integration/groups/POST-groups_id_removeMember.test.js index 7b7fc0e56e..c8a903d891 100644 --- a/test/api/v3/integration/groups/POST-groups_id_removeMember.test.js +++ b/test/api/v3/integration/groups/POST-groups_id_removeMember.test.js @@ -153,6 +153,7 @@ describe('POST /groups/:groupId/removeMember/:memberId', () => { }, invites: 1, members: 2, + leaderDetails: { 'auth.timestamps.created': new Date('2022-01-01') }, }); party = group; diff --git a/test/api/v3/integration/notifications/prevent-multiple-notification.js b/test/api/v3/integration/notifications/prevent-multiple-notification.js index cc4fd20a3d..31da8c1e16 100644 --- a/test/api/v3/integration/notifications/prevent-multiple-notification.js +++ b/test/api/v3/integration/notifications/prevent-multiple-notification.js @@ -25,6 +25,7 @@ describe('Prevent multiple notifications', () => { for (let i = 0; i < 4; i += 1) { for (let memberIndex = 0; memberIndex < partyMembers.length; memberIndex += 1) { + await partyMembers[memberIndex].update({ 'auth.timestamps.created': new Date('2022-01-01') }); // eslint-disable-line no-await-in-loop multipleChatMessages.push( partyMembers[memberIndex].post(`/groups/${party._id}/chat`, { message: `Message ${i}_${memberIndex}` }), ); diff --git a/test/api/v3/integration/user/buy/POST-user_buy_quest.test.js b/test/api/v3/integration/user/buy/POST-user_buy_quest.test.js index 025f8dd3bd..9d24286c36 100644 --- a/test/api/v3/integration/user/buy/POST-user_buy_quest.test.js +++ b/test/api/v3/integration/user/buy/POST-user_buy_quest.test.js @@ -39,25 +39,38 @@ describe('POST /user/buy-quest/:key', () => { })); }); - it('returns an error if quest prerequisites are not met', async () => { - const key = 'dilatoryDistress2'; + it('returns an error if not all quest prerequisites are met', async () => { + const prerequisites = ['dilatoryDistress1', 'dilatoryDistress2']; + const key = 'dilatoryDistress3'; + + const achievementName1 = `achievements.quests.${prerequisites[0]}`; + + await user.update({ + [achievementName1]: true, + 'stats.gp': 9999, + }); await expect(user.post(`/user/buy-quest/${key}`)) .to.eventually.be.rejected.and.eql({ code: 401, error: 'NotAuthorized', - message: t('mustComplete', { quest: 'dilatoryDistress1' }), + message: t('mustComplete', { quest: prerequisites[1] }), }); }); it('allows purchase of a quest if prerequisites are met', async () => { - const prerequisite = 'dilatoryDistress1'; - const key = 'dilatoryDistress2'; + const prerequisites = ['dilatoryDistress1', 'dilatoryDistress2']; + const key = 'dilatoryDistress3'; const item = content.quests[key]; - const achievementName = `achievements.quests.${prerequisite}`; + const achievementName1 = `achievements.quests.${prerequisites[0]}`; + const achievementName2 = `achievements.quests.${prerequisites[1]}`; - await user.update({ [achievementName]: true, 'stats.gp': 9999 }); + await user.update({ + [achievementName1]: true, + [achievementName2]: true, + 'stats.gp': 9999, + }); const res = await user.post(`/user/buy-quest/${key}`); await user.sync(); diff --git a/test/common/ops/buy/buyQuestGems.js b/test/common/ops/buy/buyQuestGems.js index 17e1c54dde..bb5346b420 100644 --- a/test/common/ops/buy/buyQuestGems.js +++ b/test/common/ops/buy/buyQuestGems.js @@ -33,7 +33,7 @@ describe('shared.ops.buyQuestGems', () => { pinnedGearUtils.removeItemByPath.restore(); }); - context('successful purchase', () => { + context('single purchase', () => { const userGemAmount = 10; before(() => { @@ -44,7 +44,7 @@ describe('shared.ops.buyQuestGems', () => { user.pinnedItems.push({ type: 'quests', key: 'gryphon' }); }); - it('purchases quests', async () => { + it('successfully purchases quest', async () => { const key = 'gryphon'; await buyQuest(user, { params: { key } }); @@ -58,6 +58,28 @@ describe('shared.ops.buyQuestGems', () => { await buyQuest(user, { params: { key } }); + expect(user.items.quests[key]).to.equal(1); + expect(pinnedGearUtils.removeItemByPath.notCalled).to.equal(true); + }); + it('errors if the user has not completed prerequisite quests', async () => { + const key = 'atom3'; + user.achievements.quests.atom1 = 1; + + try { + await buyQuest(user, { params: { key } }); + } catch (err) { + expect(err).to.be.an.instanceof(NotAuthorized); + expect(err.message).to.equal(i18n.t('mustComplete', { quest: 'atom2' })); + expect(user.items.quests[key]).to.eql(undefined); + } + }); + it('successfully purchases quest if user has completed all prerequisite quests', async () => { + const key = 'atom3'; + user.achievements.quests.atom1 = 1; + user.achievements.quests.atom2 = 1; + + await buyQuest(user, { params: { key } }); + expect(user.items.quests[key]).to.equal(1); expect(pinnedGearUtils.removeItemByPath.notCalled).to.equal(true); }); diff --git a/test/common/ops/buy/buyQuestGold.js b/test/common/ops/buy/buyQuestGold.js index 4a13cda6ca..6206cc62ba 100644 --- a/test/common/ops/buy/buyQuestGold.js +++ b/test/common/ops/buy/buyQuestGold.js @@ -162,7 +162,9 @@ describe('shared.ops.buyQuest', () => { } }); - it('does not buy a quest without completing previous quests', async () => { + it('returns error if user has not completed all prerequisite quests', async () => { + user.stats.gp = 9999; + user.achievements.quests.dilatoryDistress1 = 1; try { await buyQuest(user, { params: { @@ -175,4 +177,22 @@ describe('shared.ops.buyQuest', () => { expect(user.items.quests).to.eql({}); } }); + + it('successfully purchases quest if user has completed all prerequisite quests', async () => { + user.stats.gp = 500; + user.achievements.quests.dilatoryDistress1 = 1; + user.achievements.quests.dilatoryDistress2 = 1; + + await buyQuest(user, { + params: { + key: 'dilatoryDistress3', + }, + }, analytics); + + expect(user.items.quests).to.eql({ + dilatoryDistress3: 1, + }); + expect(user.stats.gp).to.equal(100); + expect(analytics.track).to.be.calledOnce; + }); }); diff --git a/test/helpers/start-server.js b/test/helpers/start-server.js index 8830224f70..570f53461f 100644 --- a/test/helpers/start-server.js +++ b/test/helpers/start-server.js @@ -11,6 +11,7 @@ if (process.env.LOAD_SERVER === '0') { // when the server is in a different proc setupNconf('./config.json.example'); nconf.set('NODE_DB_URI', nconf.get('TEST_DB_URI')); nconf.set('NODE_ENV', 'test'); + nconf.set('ACCOUNT_MIN_CHAT_AGE', '2'); nconf.set('IS_TEST', true); // We require src/server and not src/index because // 1. nconf is already setup diff --git a/website/client/package-lock.json b/website/client/package-lock.json index 665172c843..033c3516a6 100644 --- a/website/client/package-lock.json +++ b/website/client/package-lock.json @@ -15839,9 +15839,9 @@ } }, "core-js": { - "version": "3.23.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.23.3.tgz", - "integrity": "sha512-oAKwkj9xcWNBAvGbT//WiCdOMpb9XQG92/Fe3ABFM/R16BsHgePG00mFOgKf7IsCtfj8tA1kHtf/VwErhriz5Q==" + "version": "3.23.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.23.5.tgz", + "integrity": "sha512-7Vh11tujtAZy82da4duVreQysIoO2EvVrur7y6IzZkH1IHPSekuDi8Vuw1+YKjkbfWLRD7Nc9ICQ/sIUDutcyg==" }, "core-js-compat": { "version": "3.11.0", diff --git a/website/client/package.json b/website/client/package.json index 5e0526848a..b06039e038 100644 --- a/website/client/package.json +++ b/website/client/package.json @@ -32,7 +32,7 @@ "bootstrap": "^4.6.0", "bootstrap-vue": "^2.22.0", "chai": "^4.3.6", - "core-js": "^3.23.3", + "core-js": "^3.23.5", "dompurify": "^2.3.8", "eslint": "^6.8.0", "eslint-config-habitrpg": "^6.2.0", diff --git a/website/client/src/assets/scss/form.scss b/website/client/src/assets/scss/form.scss index c5cf0b61f7..8e21bc06a4 100644 --- a/website/client/src/assets/scss/form.scss +++ b/website/client/src/assets/scss/form.scss @@ -82,7 +82,7 @@ input, textarea, input.form-control, textarea.form-control { } } -/** Colored Input-Groups, ignoring checklist */ +// Colored Input-Groups, ignoring checklist .input-group:not(.checklist-group) { border-radius: 2px; border: solid 1px $gray-400; @@ -100,7 +100,7 @@ input, textarea, input.form-control, textarea.form-control { } } -/** Generic Input Group Styles */ +// Generic Input Group Styles .input-group { height: 2rem; @@ -179,10 +179,11 @@ input, textarea, input.form-control, textarea.form-control { padding-left: 0px; } -// Checkboxes and radios +// used in checkboxes and radios $bg-focused-active-control: #4f2993; $bg-disabled-control: #34303a; +// custom control .custom-control { margin-bottom: .5rem; @@ -205,6 +206,7 @@ $bg-disabled-control: #34303a; } } +// checkboxes .custom-checkbox { .custom-control-label::before { border-radius: 2px; @@ -280,11 +282,26 @@ $bg-disabled-control: #34303a; padding-left: 36px; } +// radio buttons +$bg-color: $purple-400; + +// svg for the purple dot @mixin custom-radio-checked-icon ($bg-color) { background-image: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='#{$bg-color}'/%3E%3C/svg%3E"), "#", "%23"); } .custom-radio .custom-control-input { + opacity: 0; + margin: 15px 25px 34px 25px; + + // outside circle + &:checked~.custom-control-label::before { + background-color: $gray-700; + background-size: 12px 12px; + border-color: $purple-400; + } + + // checked indicator &:checked~.custom-control-label::after { @include custom-radio-checked-icon($purple-400); width: 18px; @@ -292,51 +309,84 @@ $bg-disabled-control: #34303a; background-size: 12px 12px; } - &:checked~.custom-control-label::before { - background-color: $gray-700; - background-size: 12px 12px; - border-color: $purple-400; - } - &:active~.custom-control-label::before { background-color: inherit; } - &:focus:not(:checked):not(:disabled)~.custom-control-label::before, &:active:not(:checked):not(:disabled)~.custom-control-label::before { - box-shadow: 0 0 0 6px rgba($bg-focused-active-control, 0.1); +// focus / not checked / not disabled + &:focus:not(:checked):not(:disabled)~.custom-control-label::before, + &:active:not(:checked):not(:disabled)~.custom-control-label::before { + border: 2px solid $gray-300; + box-shadow: 0 0 0 2px rgba(146, 92, 243, 0.5); } - &:focus:checked:not(:disabled)~.custom-control-label::before, &:active:checked:not(:disabled)~.custom-control-label::before { - box-shadow: 0 0 0 6px rgba($bg-focused-active-control, 0.1); - border-color: $purple-400; - background-color: rgba($bg-focused-active-control, 0.1); +// focus / checked / not disabled + &:focus:checked:not(:disabled)~.custom-control-label::before, + &:active:checked:not(:disabled)~.custom-control-label::before { + border: 2px solid $purple-400; + box-shadow: 0 0 0 2px rgba(146, 92, 243, 0.5); } - &:disabled:checked~.custom-control-label::before { - border-color: $gray-400; - background-color: transparent; +// hover / not checked / not disabled + &:hover:not(:checked):not(:disabled)~.custom-control-label::before, + &:active:not(:checked):not(:disabled)~.custom-control-label::before { + width: 18px; + height: 18px; + background: 50%/50% 50% no-repeat; + @include custom-radio-checked-icon($purple-400); + background-size: 12px 12px; + border: solid 2px $purple-400; } - &:disabled:checked~.custom-control-label::after { +// hover / checked / not disabled + &:hover:checked:not(:disabled)~.custom-control-label::before, + &:active::checked:not(:disabled)~.custom-control-label::before { + width: 18px; + height: 18px; + background: 50%/50% 50% no-repeat; @include custom-radio-checked-icon($gray-400); + background-size: 12px 12px; + border: solid 2px $purple-300; + } + +// disabled / checked / before + &:disabled:checked~.custom-control-label::before { + background: 50%/50% 50% no-repeat; + @include custom-radio-checked-icon($gray-300); + border: 2px solid $gray-200; + background-color: transparent; + opacity: 0.75; + } + +// disabled / checked / after + &:disabled:checked~.custom-control-label::after { + background: 50%/50% 50% no-repeat; + @include custom-radio-checked-icon($gray-300); width: 18px; height: 18px; background-size: 12px 12px; } +// disabled / not checked / before &:disabled:not(:checked)~.custom-control-label::before { - border-color: $gray-300; - background-color: transparent; + background-color: $gray-600; + border: 2px solid $gray-200; } - &:focus:disabled~.custom-control-label::before, &:active:disabled~.custom-control-label::before { - box-shadow: 0 0 0 6px rgba($bg-disabled-control, 0.1); - border-color: $gray-300; +// focus and disabled / not checked / before + &:focus:disabled~.custom-control-label::before, + &:active:disabled~.custom-control-label::before { background-color: rgba($bg-disabled-control, 0.1); + box-shadow: 0 0 0 6px rgba($bg-disabled-control, 0.1); + border: 2px solid $gray-200; } - &:focus:disabled:checked~.custom-control-label::before, &:active:disabled:checked~.custom-control-label::before { - border-color: $gray-400; +// focus and disabled / checked / before + &:focus:disabled:checked~.custom-control-label::before, + &:active:disabled:checked~.custom-control-label::before { + background: 50%/50% 50% no-repeat; + @include custom-radio-checked-icon($gray-300); + border: 2px solid $gray-200; } } diff --git a/website/client/src/assets/svg/big-gift.svg b/website/client/src/assets/svg/big-gift.svg new file mode 100644 index 0000000000..1d756e4dfa --- /dev/null +++ b/website/client/src/assets/svg/big-gift.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/client/src/assets/svg/close.svg b/website/client/src/assets/svg/close.svg index 5070218c06..398440da99 100644 --- a/website/client/src/assets/svg/close.svg +++ b/website/client/src/assets/svg/close.svg @@ -1,5 +1,11 @@ - - - + + + Icon/Close + + + + + + - + \ No newline at end of file diff --git a/website/client/src/components/group-plans/createGroupModalPages.vue b/website/client/src/components/group-plans/createGroupModalPages.vue index 2b314834ad..b354f6ac63 100644 --- a/website/client/src/components/group-plans/createGroupModalPages.vue +++ b/website/client/src/components/group-plans/createGroupModalPages.vue @@ -122,6 +122,11 @@ font-weight: bold; } + .custom-control-input { + z-index: -1; + opacity: 0; + } + .box:hover { cursor: pointer; opacity: 0.7; diff --git a/website/client/src/components/header/menu.vue b/website/client/src/components/header/menu.vue index d77c6f8e0d..fbfdaed141 100644 --- a/website/client/src/components/header/menu.vue +++ b/website/client/src/components/header/menu.vue @@ -3,7 +3,7 @@ - +
+

{{ $t('choosePaymentMethod') }}