diff --git a/package-lock.json b/package-lock.json index 836fdb6ef..8f24ed029 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2857,7 +2857,7 @@ "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, "@types/methods": { @@ -3094,7 +3094,7 @@ "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, "array-includes": { "version": "3.1.6", @@ -4762,7 +4762,7 @@ "bcryptjs": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", - "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" + "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" }, "bignumber.js": { "version": "9.0.2", @@ -4896,7 +4896,7 @@ "buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" }, "buffer-from": { "version": "1.1.2", @@ -4930,7 +4930,6 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001697", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001697.tgz", "integrity": "sha512-GwNPlWJin8E+d7Gxq96jxM6w0w+VFeyyXRsjU58emtkYqnbwHqXm5uT2uCmO0RQE9htWknOP4xtBlLmM/gWxvQ==" @@ -5153,7 +5152,7 @@ "clone": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==" }, "clone-deep": { "version": "4.0.1", @@ -5207,7 +5206,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "color-string": { "version": "1.9.1", @@ -5240,7 +5239,7 @@ "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" }, "component-emitter": { "version": "1.3.1", @@ -5250,7 +5249,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "confusing-browser-globals": { "version": "1.0.11", @@ -5299,7 +5298,7 @@ "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "cookiejar": { "version": "2.1.4", @@ -5837,7 +5836,7 @@ "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "electron-to-chromium": { "version": "1.4.81", @@ -5859,7 +5858,7 @@ "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" }, "end-of-stream": { "version": "1.4.4", @@ -6003,12 +6002,12 @@ "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint": { "version": "8.47.0", @@ -6938,7 +6937,7 @@ "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" }, "event-target-shim": { "version": "5.0.1", @@ -7106,7 +7105,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "safe-buffer": { "version": "5.2.1", @@ -7151,7 +7150,7 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "fast-safe-stringify": { @@ -7225,7 +7224,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" } } }, @@ -7377,7 +7376,7 @@ "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" }, "fs-constants": { "version": "1.0.0", @@ -7392,7 +7391,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "fsevents": { "version": "2.3.3", @@ -7752,7 +7751,7 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "has-property-descriptors": { "version": "1.0.0", @@ -7962,7 +7961,7 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true }, "indent-string": { @@ -7974,7 +7973,7 @@ "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "requires": { "once": "^1.3.0", "wrappy": "1" @@ -8173,7 +8172,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-fullwidth-code-point": { "version": "3.0.0", @@ -8286,13 +8285,13 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" }, "istanbul-lib-coverage": { "version": "3.2.2", @@ -10728,7 +10727,7 @@ "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "json5": { @@ -11093,7 +11092,7 @@ "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" }, "lodash.defaults": { "version": "4.2.0", @@ -11119,7 +11118,6 @@ "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==" - }, "lodash.merge": { "version": "4.6.2", @@ -11337,7 +11335,7 @@ "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" }, "memory-pager": { "version": "1.5.0", @@ -11348,7 +11346,7 @@ "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "merge-stream": { "version": "2.0.0", @@ -11359,7 +11357,7 @@ "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" }, "micromatch": { "version": "4.0.5", @@ -11700,7 +11698,7 @@ "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "negotiator": { @@ -11904,7 +11902,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-inspect": { "version": "1.12.0", @@ -12623,7 +12621,7 @@ "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "requires": { "wrappy": "1" } @@ -12713,7 +12711,7 @@ "parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" + "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==" }, "parse-srcset": { "version": "1.0.2", @@ -12728,12 +12726,12 @@ "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==" + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-key": { "version": "3.1.1", @@ -12749,7 +12747,7 @@ "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "pend": { "version": "1.2.0", @@ -13610,7 +13608,7 @@ "sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", "optional": true, "requires": { "memory-pager": "^1.0.2" @@ -14357,7 +14355,7 @@ "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true }, "strip-final-newline": { @@ -14556,13 +14554,13 @@ "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, "tmp": { @@ -14580,7 +14578,7 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" }, "to-regex-range": { "version": "5.0.1", @@ -14607,7 +14605,7 @@ "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "tsconfig-paths": { "version": "3.14.2", @@ -14781,7 +14779,7 @@ "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" }, "update-browserslist-db": { "version": "1.1.2", @@ -14819,17 +14817,17 @@ "url-template": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" + "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==" }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" }, "uuid": { "version": "3.4.0", @@ -14893,7 +14891,7 @@ "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" }, "walker": { "version": "1.0.8", @@ -14907,12 +14905,12 @@ "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "requires": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -15038,7 +15036,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "write-file-atomic": { "version": "4.0.2", diff --git a/src/controllers/userProfileController.js b/src/controllers/userProfileController.js index 07ba75e1e..20462ae1b 100644 --- a/src/controllers/userProfileController.js +++ b/src/controllers/userProfileController.js @@ -47,10 +47,13 @@ async function ValidatePassword(req, res) { }); return; } + + const canUpdate = await hasPermission(req.body.requestor, 'updatePassword'); + // Verify request is authorized by self or adminsitrator if ( userId !== requestor.requestorId && - !(await hasPermission(req.body.requestor, 'updatePassword')) + !canUpdate ) { res.status(403).send({ error: "You are unauthorized to update this user's password", @@ -60,8 +63,7 @@ async function ValidatePassword(req, res) { // Verify request is authorized by self or adminsitrator if ( - userId === requestor.requestorId || - !(await hasPermission(req.body.requestor, 'updatePassword')) + userId === requestor.requestorId && !canUpdate ) { res.status(403).send({ error: "You are unauthorized to update this user's password", @@ -523,14 +525,14 @@ const userProfileController = function (UserProfile, Project) { } // validate userprofile pic - if (req.body.profilePic) { - const results = userHelper.validateProfilePic(req.body.profilePic); + // if (req.body.profilePic) { + // const results = userHelper.validateProfilePic(req.body.profilePic); - if (!results.result) { - res.status(400).json(results.errors); - return; - } - } + // if (!results.result) { + // res.status(400).json(results.errors); + // return; + // } + // } const canEditTeamCode = req.body.requestor.role === 'Owner' || @@ -1412,7 +1414,7 @@ const userProfileController = function (UserProfile, Project) { const resetPassword = async function (req, res) { try { - ValidatePassword(req); + await ValidatePassword(req); const requestor = await UserProfile.findById(req.body.requestor.requestorId) .select('firstName lastName email role') @@ -1433,11 +1435,6 @@ const userProfileController = function (UserProfile, Project) { return; } - if (!(await hasPermission(requestor, 'putUserProfileImportantInfo'))) { - res.status(403).send('You are not authorized to reset this users password'); - return; - } - if (user.role === 'Owner' && !(await hasPermission(requestor, 'addDeleteEditOwners'))) { res.status(403).send('You are not authorized to reset this user password'); return; @@ -1957,6 +1954,41 @@ const userProfileController = function (UserProfile, Project) { } }; + const replaceTeamCodeForUsers = async (req, res) => { + const { oldTeamCodes, newTeamCode } = req.body; + + // Validate input + if (!Array.isArray(oldTeamCodes) || oldTeamCodes.length === 0 || !newTeamCode) { + console.error('Validation Failed:', { oldTeamCodes, newTeamCode }); + return res.status(400).send({ error: 'Invalid input. Provide oldTeamCodes as an array and a valid newTeamCode.' }); + } + + try { + // Sanitize input + const sanitizedOldTeamCodes = oldTeamCodes.map(code => String(code).trim()); + + // Find and update users + const usersToUpdate = await UserProfile.find({ teamCode: { $in: sanitizedOldTeamCodes } }); + + if (usersToUpdate.length === 0) { + return res.status(404).send({ error: 'No users found with the specified team codes.' }); + } + + const updateResult = await UserProfile.updateMany( + { teamCode: { $in: sanitizedOldTeamCodes } }, + { $set: { teamCode: newTeamCode } } + ); + + return res.status(200).send({ + message: 'Team codes updated successfully.', + updatedCount: updateResult.nModified, + }); + } catch (error) { + console.error('Error updating team codes:', error); + return res.status(500).send({ error: 'An error occurred while updating team codes.' }); + } + }; + return { postUserProfile, getUserProfiles, @@ -1992,6 +2024,7 @@ const userProfileController = function (UserProfile, Project) { getUserByAutocomplete, getUserProfileBasicInfo, updateUserInformation, + replaceTeamCodeForUsers, }; }; diff --git a/src/cronjobs/userProfileJobs.js b/src/cronjobs/userProfileJobs.js index 1b9644092..efce6a824 100644 --- a/src/cronjobs/userProfileJobs.js +++ b/src/cronjobs/userProfileJobs.js @@ -30,6 +30,8 @@ const userProfileJobs = () => { const SUNDAY = 0; if (moment().tz('America/Los_Angeles').day() === SUNDAY) { await userhelper.completeHoursAndMissedSummary(); + await userhelper.weeklyBlueSquareReminderFunction(); + await userhelper.inCompleteHoursEmailFunction(); } }, null, diff --git a/src/helpers/helperModels/myTeam.js b/src/helpers/helperModels/myTeam.js index 61e35f0d8..a6a225201 100644 --- a/src/helpers/helperModels/myTeam.js +++ b/src/helpers/helperModels/myTeam.js @@ -13,5 +13,7 @@ const myTeamSchema = new Schema({ }], }); - +// Add index on the 'myteam._id' field to optimize lookups on team members +myTeamSchema.index({ 'myteam._id': 1 }); +myTeamSchema.index({ 'myteam.role': 1 }); module.exports = mongoose.model('myTeam', myTeamSchema, 'myTeam'); diff --git a/src/helpers/userHelper.js b/src/helpers/userHelper.js index 3b08a47b9..03fffdda6 100644 --- a/src/helpers/userHelper.js +++ b/src/helpers/userHelper.js @@ -30,9 +30,11 @@ const { NEW_USER_BLUE_SQUARE_NOTIFICATION_MESSAGE } = require('../constants/mess const timeUtils = require('../utilities/timeUtils'); const fs = require('fs'); const cheerio = require('cheerio'); -const axios = require('axios'); -const sharp = require('sharp'); +const axios=require('axios'); +const sharp = require("sharp"); +const Team=require('../models/team'); const BlueSquareEmailAssignmentModel = require('../models/BlueSquareEmailAssignment'); + const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); const userHelper = function () { @@ -53,6 +55,46 @@ const userHelper = function () { }); }; + const getTeamMembersForBadge = async function (user) { + + try{ + const results = await Team.aggregate([ + { + $match: { + "members.userId": mongoose.Types.ObjectId(user._id) + } + }, + { $unwind: "$members" }, // Deconstructs the 'members' array to get each member as a separate document + { + $lookup: { + from: "userProfiles", // Joining with 'userProfiles' collection + localField: "members.userId", + foreignField: "_id", + as: "userProfile", + }, + }, + { $unwind: { path: "$userProfile", preserveNullAndEmptyArrays: true } }, // Preserves members even if they have no profile + { + $project: { + team_id: "$_id", // Keeping team ID + _id: "$members.userId", // Member ID + role: "$userProfile.role", // Role from user profile + firstName: "$userProfile.firstName", // First name from user profile + lastName: "$userProfile.lastName", // Last name from user profile + fullName:"$userProfile.fullName", + addDateTime: "$members.addDateTime", // Date they joined the team + teamName: "$teamName", // Team name + }, + }, + ]); + return results; + }catch(error){ + console.log(error); + return error; + } + }; + + const getTeamManagementEmail = function (teamId) { const parsedTeamId = mongoose.Types.ObjectId(teamId); return userProfile @@ -913,7 +955,7 @@ const userHelper = function () { const missedSummaryTemplate = (firstname) => { return ( `
Good Morning Jae,
+Good Morning ${firstname},
When you read this, please input your summary into the software. When you do, please be sure to put it in using the tab for "Last Week".
If you also forgot to submit your weekly media files, be sure to fix that too.
Reply All to this email once you've done this, so we know to review what you've submitted. Do this before tomorrow (Monday) at 3 PM (Pacific Time) and "reply all" so we know and we will remove this blue square.
@@ -941,16 +983,14 @@ const userHelper = function () { bluesquareemails.push("onecommunityglobal@gmail.com"); bluesquareemails.push("jae@onecommunityglobal.org"); for (let i = 0; i < users.length; i += 1) { - const allowedEmails = [ - "jae@onecommunityglobal.org", //Summary turned off Owner - "onecommunityhospitality@gmail.com", //Summary turned off Admin - "one.community@me.com", //Manager, did hours but no summary - "jatinagrawal0801@gmail.com", //Volunteer, did hours but no summary - "ttertitsa1@gmail.com", //Volunteer did hours with summary - "osorare@yahoo.com", //Core Team, did hours with summary - ]; - - if(allowedEmails.includes(users[i].email)){ + // const allowedEmails = [ + // "jae@onecommunityglobal.org", //Summary turned off Owner + // "onecommunityhospitality@gmail.com", //Summary turned off Admin + // "one.community@me.com", //Manager, did hours but no summary + // "jatinagrawal0801@gmail.com", //Volunteer, did hours but no summary + // "ttertitsa1@gmail.com", //Volunteer did hours with summary + // "osorare@yahoo.com", //Core Team, did hours with summary + // ]; const user = users[i]; const personId = mongoose.Types.ObjectId(user._id); let hasWeeklySummary = false; @@ -986,14 +1026,14 @@ const userHelper = function () { if(hasTimeOffRequest===false && timeNotMet===false && hasWeeklySummary===false){ emailSender( users[i].email, - 'Weekly Summary Missing', + 'Re: Infringement Assigned', missedSummaryTemplate(users[i].firstName), null, bluesquareemails, 'jae@onecommunityglobal.org', ); } - }} + } }catch(err){ console.log(err) } @@ -1391,7 +1431,7 @@ const userHelper = function () { }; const removeDupBadge = async function (personId, badgeId) { - userProfile.findByIdAndUpdate( + await userProfile.findByIdAndUpdate( personId, { $pull: { @@ -1921,68 +1961,62 @@ const userHelper = function () { const leaderRoles = ['Mentor', 'Manager', 'Administrator', 'Owner', 'Core Team']; const approvedRoles = ['Mentor', 'Manager']; if (!approvedRoles.includes(user.role)) return; - - let teamMembers; - await getTeamMembers({ - _id: personId, - }).then((results) => { - if (results) { - teamMembers = results.myteam; - } else { - teamMembers = []; - } - }); - - const objIds = {}; - - teamMembers = teamMembers.filter((member) => { - if (leaderRoles.includes(member.role)) return false; - if (objIds[member._id]) return false; - objIds[member._id] = true; - - return true; + var teams=await getAllTeamMembers(personId); + // Calculate total unique non-leader members across all teams + let uniqueMembers = new Set(); + let totalNonLeaderMembers = 0; + + teams.forEach(team => { + // Filter out leaders and duplicates from each team + const nonLeaderMembers = team.members.filter(member => { + if (leaderRoles.includes(member.role)) return false; + if (uniqueMembers.has(member.userId.toString())) return false; + uniqueMembers.add(member.userId.toString()); + return true; + }); + totalNonLeaderMembers += nonLeaderMembers.length; }); + let badgeOfType; for (let i = 0; i < badgeCollection.length; i += 1) { if (badgeCollection[i].badge?.type === 'Lead a team of X+') { if (badgeOfType && badgeOfType.people <= badgeCollection[i].badge.people) { - removeDupBadge(personId, badgeOfType._id); + await removeDupBadge(personId, badgeOfType._id); badgeOfType = badgeCollection[i].badge; } else if (badgeOfType && badgeOfType.people > badgeCollection[i].badge.people) { - removeDupBadge(personId, badgeCollection[i].badge._id); + await removeDupBadge(personId, badgeCollection[i].badge._id); } else if (!badgeOfType) { badgeOfType = badgeCollection[i].badge; } } } - await badge - .find({ type: 'Lead a team of X+' }) - .sort({ people: -1 }) + // Get all available team size badges, sorted by people count descending + await badge + .find({ + type: 'Lead a team of X+', + people: { $lte: totalNonLeaderMembers } // Only get badges where requirement is <= team size + }) + .sort({ people: -1 }) // Sort descending + .limit(1) // Get only the highest qualifying badge .then((results) => { - if (!Array.isArray(results) || !results.length) { - return; - } - results.every((bg) => { - if (teamMembers && teamMembers.length >= bg.people) { - if (badgeOfType) { - if ( - badgeOfType._id.toString() !== bg._id.toString() && - badgeOfType.people < bg.people - ) { - replaceBadge( - personId, - mongoose.Types.ObjectId(badgeOfType._id), - - mongoose.Types.ObjectId(bg._id), - ); + if (!Array.isArray(results) || !results.length) return; + + const qualifyingBadge = results[0]; // This will be the 60+ badge for a team of 65 + + if (badgeOfType) { + // If user has an existing badge + if (badgeOfType._id.toString() !== qualifyingBadge._id.toString() && + badgeOfType.people < qualifyingBadge.people) { + replaceBadge( + personId, + mongoose.Types.ObjectId(badgeOfType._id), + mongoose.Types.ObjectId(qualifyingBadge._id) + ); } - return false; - } - addBadge(personId, mongoose.Types.ObjectId(bg._id)); - return false; + } else { + // If user doesn't have a badge yet + addBadge(personId, mongoose.Types.ObjectId(qualifyingBadge._id)); } - return true; - }); }); }; @@ -2072,10 +2106,96 @@ const userHelper = function () { }); }; + const getAllTeamMembers = async (userId) => { + try { + // Add match stage to filter teams containing the specified user + let results = await Team.aggregate([ + { + $match: { + 'members.userId': mongoose.Types.ObjectId(userId) + } + }, + // Unwind members to process each team member + { $unwind: '$members' }, + { + $lookup: { + from: 'userProfiles', + localField: 'members.userId', + foreignField: '_id', + as: 'userProfile' + } + }, + { $unwind: '$userProfile' }, + // Lookup badges + { + $lookup: { + from: 'badges', + localField: 'userProfile.badgeCollection.badge', + foreignField: '_id', + as: 'badgeDetails' + } + }, + // Group back by team to get team structure + { + $group: { + _id: '$_id', + teamName: { $first: '$teamName' }, + members: { + $push: { + userId: '$userProfile._id', + role: '$userProfile.role', + firstName: '$userProfile.firstName', + lastName: '$userProfile.lastName', + addDateTime: '$members.addDateTime', + badgeCollection: { + $map: { + input: '$userProfile.badgeCollection', + as: 'badgeItem', + in: { + $mergeObjects: [ + '$$badgeItem', + { + badge: { + $arrayElemAt: [ + { + $filter: { + input: '$badgeDetails', + as: 'badge', + cond: { $eq: ['$$badge._id', '$$badgeItem.badge'] } + } + }, + 0 + ] + } + } + ] + } + } + } + } + } + } + } + ]); + + return results; // Returns array of teams the user is in with all members + + } catch (error) { + console.error("Error fetching team members:", error); + throw error; + } +}; + const awardNewBadges = async () => { try { - const users = await userProfile.find({isActive: true}).populate('badgeCollection.badge'); - console.log("awardNewBadge working") + const users = await userProfile.find({ + isActive: true, + $or: [ + { 'badgeCollection.badge': { $exists: true }}, + { badgeCollection: { $size: 0 }}, + { badgeCollection: { $exists: false }} + ] + }).populate('badgeCollection.badge'); for (let i = 0; i < users.length; i += 1) { const user = users[i]; const { _id, badgeCollection } = user; @@ -2086,15 +2206,16 @@ const userHelper = function () { await checkMostHrsWeek(personId, user, badgeCollection); await checkMinHoursMultiple(personId, user, badgeCollection); await checkTotalHrsInCat(personId, user, badgeCollection); - await checkLeadTeamOfXplus(personId, user, badgeCollection); await checkXHrsForXWeeks(personId, user, badgeCollection); await checkNoInfringementStreak(personId, user, badgeCollection); + await checkLeadTeamOfXplus(personId, user, badgeCollection); //remove cache after badge asssignment. if (cache.hasCache(`user-${_id}`)) { cache.removeCache(`user-${_id}`); } } } catch (err) { + console.log(err) logger.logException(err); } }; @@ -2389,31 +2510,6 @@ const userHelper = function () { return false; } - // async function imageUrlToPngBase64(url) { - // try { - // // Fetch the image as a buffer - // const response = await axios.get(url, { responseType: 'arraybuffer' }); - - // if (response.status !== 200) { - // throw new Error(`Failed to fetch the image: ${response.statusText}`); - // } - - // const imageBuffer = Buffer.from(response.data); - // // Compress and resize the image using sharp - // const pngBuffer = await sharp(imageBuffer) - // // .resize(1000, 1000) // Resize to given dimensions - // // .png({ quality: 100 }) // Compress PNG with quality 80 (lower = more compression) - // .toBuffer(); - - // // Convert the PNG buffer to a base64 string - // const base64Png = pngBuffer.toString('base64'); - - // return `data:image/png;base64,${base64Png}`; - // } catch (error) { - // console.error(`An error occurred: ${error.message}`); - // return null; - // } - // } async function imageUrlToPngBase64(url, maxSizeKB = 45) { try { // Fetch the image as a buffer @@ -2510,17 +2606,6 @@ const userHelper = function () { await userProfile.updateOne({ _id: u._id }, { $set: { profilePic: image } }); } } - // else if (result.length > 1) { - // if(!result[0].src.startsWith('http')){ - // for(let i=0; iGood Morning ${firstName},
+You completed close enough to your total hours for us to remove this blue square. Please be sure to complete the minimum or more of your hours from now on though.
+With Gratitude,
+One Community
+Good Morning ${firstName},
+We’re checking in to see if everything is ok with you. You completed most but not all of your hours this last week. Is everything ok?
+Please reply all to let us know.
+With Gratitude,
+One Community
+Good Morning ${firstName},
+This email is checking in to see if everything is ok with you. You completed some but not all of your hours this last week. Is everything ok? Is there a reason you didn’t use the blue square scheduler on your Profile Page to schedule the week off?
+Please reply all to let us know.
+With Gratitude,
+One Community
+Good Morning ${firstName},
+It’s very unusual for someone to get a blue square in their first few weeks on the team. This email is to check in with you to see if everything is ok and if you are still wanting to volunteer with us.
+Please reply all to let us know.
+With Gratitude,
+One Community
+Good Morning ${firstName},
+We noticed that you’ve received two blue squares within your first couple of months on the team, which is somewhat unusual. We’re reaching out to check in, understand what happened, and see if this role still aligns with your interests, availability, and energy.
+Please reply all to let us know.
+Looking forward to your response.
+With Gratitude,
+One Community
+Good Morning ${firstName},
+We noticed that you’ve received two blue squares within your first few weeks on the team, which is quite unusual. When this happens, we start to wonder whether this position is the right fit for you and if you still wish to continue volunteering with us
+Do you still feel this role aligns with your interests, availability, and energy? If so, what steps will you take to meet the requirements of being a One Community team member moving forward?
+Please reply all to let us know your thoughts.
+Looking forward to your response.
+With Gratitude,
+One Community
+Good Morning ${firstName},
+It’s very unusual for people to get 3 blue squares in less than 2 months on the team. We’re writing to check in with you to see if A) everything is OK and B) if you still have the time and desire to continue with us?
+Please reply all to let us know what happened and your desire/intent for continuing.
+Looking forward to your response.
+Sincerely,
+One Community
+Good Morning ${firstName},
+We wanted to reach out because you’ve received four blue squares. As you may know, we allow a maximum of five, so we want to ensure you’re aware that you are nearing the limit.
+We appreciate your contributions and hope to see you avoiding any further blue squares. Please let us know if you have any concerns or need support in this.
+With Gratitude,
+One Community
+Good Morning ${firstName},
+Thank you for scheduling off the time you needed. Advanced notice like this is helpful and appreciated.
+With Gratitude,
+One Community
+