diff --git a/migrations/users/tag-challenge-field-string2bool.js b/migrations/users/tag-challenge-field-string2bool.js new file mode 100644 index 0000000000..27bb1f3446 --- /dev/null +++ b/migrations/users/tag-challenge-field-string2bool.js @@ -0,0 +1,73 @@ +import { model as User } from '../../website/server/models/user'; + +const MIGRATION_NAME = 'tag-challenge-field-string2bool'; + +const progressCount = 1000; +let count = 0; + +export default async function processUsers () { + const query = { + migration: { $ne: MIGRATION_NAME }, + tags: { + $elemMatch: { + challenge: { + $exists: true, + $type: 'string', + }, + }, + }, + }; + + while (true) { // eslint-disable-line no-constant-condition + // eslint-disable-next-line no-await-in-loop + const users = await User.find(query) + .sort({ _id: 1 }) + .limit(250) + .select({ _id: 1, tags: 1 }) + .lean() + .exec(); + + if (users.length === 0) { + console.warn('All appropriate users found and modified.'); + console.warn(`\n${count} users processed\n`); + break; + } else { + query._id = { + $gt: users[users.length - 1], + }; + } + + await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop + } +} + +async function updateUser (user) { + count += 1; + if (count % progressCount === 0) console.warn(`${count} ${user._id}`); + let requiresUpdate = false; + + if (user && user.tags) { + user.tags.forEach(tag => { + if (tag && typeof tag.challenge === 'string') { + requiresUpdate = true; + if (tag.challenge === 'true') { + tag.challenge = true; + } else if (tag.challenge === 'false') { + tag.challenge = false; + } else { + tag.challenge = null; + } + } + }); + } + + if (requiresUpdate) { + const set = { + migration: MIGRATION_NAME, + tags: user.tags, + }; + return User.update({ _id: user._id }, { $set: set }).exec(); + } + + return null; +} diff --git a/package-lock.json b/package-lock.json index 4cf6ff3a89..1224fca38c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,18 +23,18 @@ } }, "@babel/core": { - "version": "7.11.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.4.tgz", - "integrity": "sha512-5deljj5HlqRXN+5oJTY7Zs37iH3z3b++KjiKtIsJy1NrjOOVSEaJHEetLBhyu0aQOSNNZ/0IuEAan9GzRuDXHg==", + "version": "7.11.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.6.tgz", + "integrity": "sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg==", "requires": { "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.4", + "@babel/generator": "^7.11.6", "@babel/helper-module-transforms": "^7.11.0", "@babel/helpers": "^7.10.4", - "@babel/parser": "^7.11.4", + "@babel/parser": "^7.11.5", "@babel/template": "^7.10.4", - "@babel/traverse": "^7.11.0", - "@babel/types": "^7.11.0", + "@babel/traverse": "^7.11.5", + "@babel/types": "^7.11.5", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", @@ -46,29 +46,15 @@ }, "dependencies": { "@babel/generator": { - "version": "7.11.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.4.tgz", - "integrity": "sha512-Rn26vueFx0eOoz7iifCN2UHT6rGtnkSGWSoDRIy8jZN3B91PzeSULbswfLoOWuTuAcNwpG/mxy+uCTDnZ9Mp1g==", + "version": "7.11.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.6.tgz", + "integrity": "sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA==", "requires": { - "@babel/types": "^7.11.0", + "@babel/types": "^7.11.5", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, - "@babel/helper-module-transforms": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", - "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", - "requires": { - "@babel/helper-module-imports": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", - "@babel/helper-simple-access": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/template": "^7.10.4", - "@babel/types": "^7.11.0", - "lodash": "^4.17.19" - } - }, "@babel/helper-split-export-declaration": { "version": "7.11.0", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", @@ -78,30 +64,30 @@ } }, "@babel/parser": { - "version": "7.11.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.4.tgz", - "integrity": "sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA==" + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.5.tgz", + "integrity": "sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==" }, "@babel/traverse": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", - "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.5.tgz", + "integrity": "sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ==", "requires": { "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.0", + "@babel/generator": "^7.11.5", "@babel/helper-function-name": "^7.10.4", "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.11.0", - "@babel/types": "^7.11.0", + "@babel/parser": "^7.11.5", + "@babel/types": "^7.11.5", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", - "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", "requires": { "@babel/helper-validator-identifier": "^7.10.4", "lodash": "^4.17.19", @@ -183,11 +169,10 @@ } }, "@babel/helper-explode-assignable-expression": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.4.tgz", - "integrity": "sha512-4K71RyRQNPRrR85sr5QY4X3VwG4wtVoXZB9+L3r1Gp38DhELyHCtovqydRi7c1Ovb17eRGiQ/FD5s8JdU0Uy5A==", + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.11.4.tgz", + "integrity": "sha512-ux9hm3zR4WV1Y3xXxXkdG/0gxF9nvI0YVmKVhvK9AfMoaQkemL3sJpXw+Xbz65azo8qJiEz2XVDUpK3KYhH3ZQ==", "requires": { - "@babel/traverse": "^7.10.4", "@babel/types": "^7.10.4" } }, @@ -234,17 +219,37 @@ } }, "@babel/helper-module-transforms": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.5.tgz", - "integrity": "sha512-4P+CWMJ6/j1W915ITJaUkadLObmCRRSC234uctJfn/vHrsLNxsR8dwlcXv9ZhJWzl77awf+mWXSZEKt5t0OnlA==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", + "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", "requires": { "@babel/helper-module-imports": "^7.10.4", "@babel/helper-replace-supers": "^7.10.4", "@babel/helper-simple-access": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", "@babel/template": "^7.10.4", - "@babel/types": "^7.10.5", + "@babel/types": "^7.11.0", "lodash": "^4.17.19" + }, + "dependencies": { + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/types": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-optimise-call-expression": { @@ -269,14 +274,13 @@ } }, "@babel/helper-remap-async-to-generator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.4.tgz", - "integrity": "sha512-86Lsr6NNw3qTNl+TBcF1oRZMaVzJtbWTyTko+CQL/tvNvcGYEFKbLXDPxtW0HKk3McNOk4KzY55itGWCAGK5tg==", + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.11.4.tgz", + "integrity": "sha512-tR5vJ/vBa9wFy3m5LLv2faapJLnDFxNWff2SAYkSE4rLUdbp7CdObYFgI7wK4T/Mj4UzpjPwzR8Pzmr5m7MHGA==", "requires": { "@babel/helper-annotate-as-pure": "^7.10.4", "@babel/helper-wrap-function": "^7.10.4", "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.4", "@babel/types": "^7.10.4" } }, @@ -309,9 +313,9 @@ }, "dependencies": { "@babel/types": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", - "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", "requires": { "@babel/helper-validator-identifier": "^7.10.4", "lodash": "^4.17.19", @@ -624,9 +628,9 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.5.tgz", - "integrity": "sha512-6Ycw3hjpQti0qssQcA6AMSFDHeNJ++R6dIMnpRqUjFeBBTmTDPa8zgF90OVfTvAo11mXZTlVUViY1g8ffrURLg==", + "version": "7.11.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.11.1.tgz", + "integrity": "sha512-00dYeDE0EVEHuuM+26+0w/SCL0BH2Qy7LwHuI4Hi4MH5gkC8/AqMN5uWFJIsoXZrAphiMm1iXzBw6L2T+eA0ew==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } @@ -881,9 +885,9 @@ } }, "@babel/preset-env": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.11.0.tgz", - "integrity": "sha512-2u1/k7rG/gTh02dylX2kL3S0IJNF+J6bfDSp4DI2Ma8QN6Y9x9pmAax59fsCk6QUQG0yqH47yJWA+u1I1LccAg==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.11.5.tgz", + "integrity": "sha512-kXqmW1jVcnB2cdueV+fyBM8estd5mlNfaQi6lwLgRwCby4edpavgbFhiBNjmWA3JpB/yZGSISa7Srf+TwxDQoA==", "requires": { "@babel/compat-data": "^7.11.0", "@babel/helper-compilation-targets": "^7.10.4", @@ -947,7 +951,7 @@ "@babel/plugin-transform-unicode-escapes": "^7.10.4", "@babel/plugin-transform-unicode-regex": "^7.10.4", "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.11.0", + "@babel/types": "^7.11.5", "browserslist": "^4.12.0", "core-js-compat": "^3.6.2", "invariant": "^2.2.2", @@ -956,9 +960,9 @@ }, "dependencies": { "@babel/types": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", - "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", "requires": { "@babel/helper-validator-identifier": "^7.10.4", "lodash": "^4.17.19", @@ -968,9 +972,9 @@ } }, "@babel/preset-modules": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.3.tgz", - "integrity": "sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", + "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", @@ -980,9 +984,9 @@ } }, "@babel/register": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.10.5.tgz", - "integrity": "sha512-eYHdLv43nyvmPn9bfNfrcC4+iYNwdQ8Pxk1MFJuU/U5LpSYl/PH4dFMazCYZDFVi8ueG3shvO+AQfLrxpYulQw==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.11.5.tgz", + "integrity": "sha512-CAml0ioKX+kOAvBQDHa/+t1fgOt3qkTIz0TrRtRAT6XY0m5qYZXR85k6/sLCNPMGhYDlCFHCYuU0ybTJbvlC6w==", "requires": { "find-cache-dir": "^2.0.0", "lodash": "^4.17.19", @@ -992,9 +996,9 @@ } }, "@babel/runtime": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.0.tgz", - "integrity": "sha512-qArkXsjJq7H+T86WrIFV0Fnu/tNOkZ4cgXmjkzAu3b/58D5mFIO8JH/y77t7C9q0OdDRdh9s7Ue5GasYssxtXw==", + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.2.tgz", + "integrity": "sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==", "requires": { "regenerator-runtime": "^0.13.4" } @@ -1154,9 +1158,9 @@ } }, "@sindresorhus/is": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-3.1.0.tgz", - "integrity": "sha512-n4J+zu52VdY43kdi/XdI9DzuMr1Mur8zFL5ZRG2opCans9aiFwkPxHYFEb5Xgy7n1Z4K6WfI4FpqUqsh3E8BPQ==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-3.1.2.tgz", + "integrity": "sha512-JiX9vxoKMmu8Y3Zr2RVathBL1Cdu4Nt4MuNWemt1Nc06A0RAin9c5FArkhGsyMBWfCu4zj+9b+GxtjAnE4qqLQ==" }, "@sinonjs/commons": { "version": "1.8.1", @@ -1399,9 +1403,9 @@ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" }, "@types/mongodb": { - "version": "3.5.25", - "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.5.25.tgz", - "integrity": "sha512-2H/Owt+pHCl9YmBOYnXc3VdnxejJEjVdH+QCWL5ZAfPehEn3evygKBX3/vKRv7aTwfNbUd0E5vjJdQklH/9a6w==", + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.5.27.tgz", + "integrity": "sha512-1jxKDgdfJEOO9zp+lv43p8jOqRs02xPrdUTzAZIVK9tVEySfCEmktL2jEu9A3wOBEOs18yKzpVIKUh8b8ALk3w==", "dev": true, "requires": { "@types/bson": "*", @@ -3003,14 +3007,14 @@ "dev": true }, "browserslist": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.13.0.tgz", - "integrity": "sha512-MINatJ5ZNrLnQ6blGvePd/QOz9Xtu+Ne+x29iQSCHfkU5BugKVJwZKn/iiL8UbpIpa3JhviKjz+XxMo0m2caFQ==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.1.tgz", + "integrity": "sha512-zyBTIHydW37pnb63c7fHFXUG6EcqWOqoMdDx6cdyaDFriZ20EoVxcE95S54N+heRqY8m8IUgB5zYta/gCwSaaA==", "requires": { - "caniuse-lite": "^1.0.30001093", - "electron-to-chromium": "^1.3.488", - "escalade": "^3.0.1", - "node-releases": "^1.1.58" + "caniuse-lite": "^1.0.30001124", + "electron-to-chromium": "^1.3.562", + "escalade": "^3.0.2", + "node-releases": "^1.1.60" } }, "bson": { @@ -3163,9 +3167,9 @@ "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" }, "caniuse-lite": { - "version": "1.0.30001109", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001109.tgz", - "integrity": "sha512-4JIXRodHzdS3HdK8nSgIqXYLExOvG+D2/EenSvcub2Kp3QEADjo2v2oUn5g0n0D+UNwG9BtwKOyGcSq2qvQXvQ==" + "version": "1.0.30001124", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001124.tgz", + "integrity": "sha512-zQW8V3CdND7GHRH6rxm6s59Ww4g/qGWTheoboW9nfeMg7sUoopIfKCcNZUjwYRCOrvereh3kwDpZj4VLQ7zGtA==" }, "caseless": { "version": "0.12.0", @@ -4624,9 +4628,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.516", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.516.tgz", - "integrity": "sha512-WDM5AAQdOrvLqSX8g3Zd5AujBXfMxf96oeZkff0U2HF5op3tjShE+on2yay3r1UD4M9I3p0iHpAS4+yV8U8A9A==" + "version": "1.3.562", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.562.tgz", + "integrity": "sha512-WhRe6liQ2q/w1MZc8mD8INkenHivuHdrr4r5EQHNomy3NJux+incP6M6lDMd0paShP3MD0WGe5R1TWmEClf+Bg==" }, "emitter-listener": { "version": "1.1.2", @@ -6696,18 +6700,18 @@ } }, "got": { - "version": "11.5.2", - "resolved": "https://registry.npmjs.org/got/-/got-11.5.2.tgz", - "integrity": "sha512-yUhpEDLeuGiGJjRSzEq3kvt4zJtAcjKmhIiwNp/eUs75tRlXfWcHo5tcBaMQtnjHWC7nQYT5HkY/l0QOQTkVww==", + "version": "11.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-11.6.0.tgz", + "integrity": "sha512-ErhWb4IUjQzJ3vGs3+RR12NWlBDDkRciFpAkQ1LPUxi6OnwhGj07gQxjPsyIk69s7qMihwKrKquV6VQq7JNYLA==", "requires": { - "@sindresorhus/is": "^3.0.0", + "@sindresorhus/is": "^3.1.1", "@szmarczak/http-timer": "^4.0.5", "@types/cacheable-request": "^6.0.1", "@types/responselike": "^1.0.0", "cacheable-lookup": "^5.0.3", "cacheable-request": "^7.0.1", "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.0", + "http2-wrapper": "^1.0.0-beta.5.2", "lowercase-keys": "^2.0.0", "p-cancelable": "^2.0.0", "responselike": "^2.0.0" @@ -7056,9 +7060,9 @@ } }, "habitica-markdown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/habitica-markdown/-/habitica-markdown-2.0.2.tgz", - "integrity": "sha512-GGzWuDKbFBMI+GqmQnSPUD5Zi/WPZDDuC2dC2La6uvu1zVNW7uHyQG0lxwCO43t5EdYXtOoOPin1rhhLdTuZfA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/habitica-markdown/-/habitica-markdown-3.0.0.tgz", + "integrity": "sha512-rw1LJ5Vsjx8sfjNa4e2wFuZf5eqqyb5/kfZXPxqfMMgJCCgIhWStDqY3nIclnpGWpemlKd+qbdh2rLiLgm9kng==", "requires": { "habitica-markdown-emoji": "1.2.4", "markdown-it": "10.0.0", @@ -7422,9 +7426,9 @@ } }, "image-size": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.8.3.tgz", - "integrity": "sha512-SMtq1AJ+aqHB45c3FsB4ERK0UCiA2d3H1uq8s+8T0Pf8A3W4teyBQyaFaktH6xvZqh+npwlKU7i4fJo0r7TYTg==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.9.1.tgz", + "integrity": "sha512-yBo6xGGjiWtApYroCGR9wTvaIgande5vmAfTYIld5ss5kN4tyDG5lrW1qGomOXgB05ss7GLXLpDYXEiFqSqkzg==", "requires": { "queue": "6.0.1" } @@ -9364,9 +9368,9 @@ } }, "mongodb": { - "version": "3.5.9", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.5.9.tgz", - "integrity": "sha512-vXHBY1CsGYcEPoVWhwgxIBeWqP3dSu9RuRDsoLRPTITrcrgm1f0Ubu1xqF9ozMwv53agmEiZm0YGo+7WL3Nbug==", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.1.tgz", + "integrity": "sha512-uH76Zzr5wPptnjEKJRQnwTsomtFOU/kQEU8a9hKHr2M7y9qVk7Q4Pkv0EQVp88742z9+RwvsdTw6dRjDZCNu1g==", "dev": true, "requires": { "bl": "^2.2.0", @@ -9378,9 +9382,9 @@ }, "dependencies": { "bl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.0.tgz", - "integrity": "sha512-wbgvOpqopSr7uq6fJrLH8EsvYMJf9gzfo2jCsL2eTy75qXPukA4pCgHamOQkZtY5vmfVtjB+P3LNlMHW5CEZXA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", + "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", "dev": true, "requires": { "readable-stream": "^2.3.5", @@ -9451,13 +9455,13 @@ } }, "mongoose": { - "version": "5.10.2", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.10.2.tgz", - "integrity": "sha512-VO5eZawEMFh2gx9XPg9ZafzFg5eIVs4R7PW6kK1MFqBq34YD7GomkalYWVt02HctvTPDI1mkXsm52LXNZR1NxA==", + "version": "5.10.3", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.10.3.tgz", + "integrity": "sha512-FLemltuzcsCHlFpEZ3bYOiNhJfHful+GoS+3uRgdEWGlY0HKfOjm9xsISM/tql8vRvhjr7qveuRfoBBGO3xNtw==", "requires": { "bson": "^1.1.4", "kareem": "2.3.1", - "mongodb": "3.6.0", + "mongodb": "3.6.1", "mongoose-legacy-pluralize": "1.0.2", "mpath": "0.7.0", "mquery": "3.2.2", @@ -9478,9 +9482,9 @@ } }, "mongodb": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.0.tgz", - "integrity": "sha512-/XWWub1mHZVoqEsUppE0GV7u9kanLvHxho6EvBxQbShXTKYF9trhZC2NzbulRGeG7xMJHD8IOWRcdKx5LPjAjQ==", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.1.tgz", + "integrity": "sha512-uH76Zzr5wPptnjEKJRQnwTsomtFOU/kQEU8a9hKHr2M7y9qVk7Q4Pkv0EQVp88742z9+RwvsdTw6dRjDZCNu1g==", "requires": { "bl": "^2.2.0", "bson": "^1.1.4", @@ -9539,9 +9543,9 @@ "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==" }, "monk": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/monk/-/monk-7.3.1.tgz", - "integrity": "sha512-09+K52A7vfdH7ZxyZyXS6E5C3LUMxXvd8ZLAYLJclXVbqxb6dsmA1ArIWGblhGFEgYOaTI9MOfWO3uE4b5IQkA==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/monk/-/monk-7.3.2.tgz", + "integrity": "sha512-rf44p/l4HRDnrQXWci9SOz5uFAEQsHERVmE0tgya8OjOwqzeztE1sIcZ7JdxqpVk0Y1QyzApZWyBFWfvFB6sfQ==", "dev": true, "requires": { "@types/mongodb": "^3.5.25", diff --git a/package.json b/package.json index b88de28a35..61c7df5328 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,9 @@ "version": "4.156.1", "main": "./website/server/index.js", "dependencies": { - "@babel/core": "^7.11.4", - "@babel/preset-env": "^7.11.0", - "@babel/register": "^7.10.3", + "@babel/core": "^7.11.6", + "@babel/preset-env": "^7.11.5", + "@babel/register": "^7.11.5", "@google-cloud/trace-agent": "^5.1.0", "@slack/client": "^4.12.0", "accepts": "^1.3.5", @@ -30,15 +30,15 @@ "express-basic-auth": "^1.1.5", "express-validator": "^5.2.0", "glob": "^7.1.6", - "got": "^11.5.2", + "got": "^11.6.0", "gulp": "^4.0.0", "gulp-babel": "^8.0.0", "gulp-imagemin": "^7.1.0", "gulp-nodemon": "^2.5.0", "gulp.spritesmith": "^6.9.0", - "habitica-markdown": "^2.0.2", + "habitica-markdown": "^3.0.0", "helmet": "^3.23.3", - "image-size": "^0.8.3", + "image-size": "^0.9.1", "in-app-purchase": "^1.11.3", "js2xmlparser": "^4.0.1", "jsonwebtoken": "^8.5.1", @@ -48,7 +48,7 @@ "method-override": "^3.0.0", "moment": "^2.27.0", "moment-recur": "^1.0.7", - "mongoose": "^5.10.2", + "mongoose": "^5.10.3", "morgan": "^1.10.0", "nconf": "^0.10.0", "node-gcm": "^1.0.3", @@ -118,7 +118,7 @@ "expect.js": "^0.3.1", "istanbul": "^1.1.0-alpha.1", "mocha": "^5.1.1", - "monk": "^7.3.1", + "monk": "^7.3.2", "require-again": "^2.0.0", "run-rs": "^0.6.2", "sinon": "^9.0.3", diff --git a/test/api/v3/integration/challenges/GET-challenges_user.test.js b/test/api/v3/integration/challenges/GET-challenges_user.test.js index 1770745900..2f2076af25 100644 --- a/test/api/v3/integration/challenges/GET-challenges_user.test.js +++ b/test/api/v3/integration/challenges/GET-challenges_user.test.js @@ -6,8 +6,8 @@ import { describe('GET challenges/user', () => { context('no official challenges', () => { - let user; let member; let nonMember; let challenge; let challenge2; let - publicGuild; + let user; let member; let nonMember; let challenge; let challenge2; + let publicGuild; let userData; let groupData; before(async () => { const { group, groupLeader, members } = await createAndPopulateGroup({ @@ -19,225 +19,197 @@ describe('GET challenges/user', () => { members: 1, }); - user = groupLeader; publicGuild = group; + groupData = { + _id: publicGuild._id, + categories: [], + id: publicGuild._id, + type: publicGuild.type, + privacy: publicGuild.privacy, + name: publicGuild.name, + summary: publicGuild.name, + leader: publicGuild.leader._id, + }; + + user = groupLeader; + userData = { + _id: publicGuild.leader._id, + id: publicGuild.leader._id, + profile: { name: user.profile.name }, + auth: { + local: { + username: user.auth.local.username, + }, + }, + flags: { + verifiedUsername: true, + }, + }; + member = members[0]; // eslint-disable-line prefer-destructuring nonMember = await generateUser(); challenge = await generateChallenge(user, group); - await user.post(`/challenges/${challenge._id}/join`); challenge2 = await generateChallenge(user, group); - await user.post(`/challenges/${challenge2._id}/join`); - }); - it('should return challenges user has joined', async () => { await nonMember.post(`/challenges/${challenge._id}/join`); + }); + context('all challenges', () => { + it('should return challenges user has joined', async () => { + const challenges = await nonMember.get('/challenges/user'); - const challenges = await nonMember.get('/challenges/user'); + const foundChallenge = _.find(challenges, { _id: challenge._id }); + expect(foundChallenge).to.exist; + expect(foundChallenge.leader).to.eql(userData); + expect(foundChallenge.group).to.eql(groupData); + }); - const foundChallenge = _.find(challenges, { _id: challenge._id }); - expect(foundChallenge).to.exist; - expect(foundChallenge.leader).to.eql({ - _id: publicGuild.leader._id, - id: publicGuild.leader._id, - profile: { name: user.profile.name }, - auth: { - local: { - username: user.auth.local.username, + it('should not return challenges a non-member has not joined', async () => { + const challenges = await nonMember.get('/challenges/user'); + + const foundChallenge2 = _.find(challenges, { _id: challenge2._id }); + expect(foundChallenge2).to.not.exist; + }); + + it('should return challenges user has created', async () => { + const challenges = await user.get('/challenges/user'); + + const foundChallenge1 = _.find(challenges, { _id: challenge._id }); + expect(foundChallenge1).to.exist; + expect(foundChallenge1.leader).to.eql(userData); + expect(foundChallenge1.group).to.eql(groupData); + const foundChallenge2 = _.find(challenges, { _id: challenge2._id }); + expect(foundChallenge2).to.exist; + expect(foundChallenge2.leader).to.eql(userData); + expect(foundChallenge2.group).to.eql(groupData); + }); + + it('should return challenges in user\'s group', async () => { + const challenges = await member.get('/challenges/user'); + + const foundChallenge1 = _.find(challenges, { _id: challenge._id }); + expect(foundChallenge1).to.exist; + expect(foundChallenge1.leader).to.eql(userData); + expect(foundChallenge1.group).to.eql(groupData); + const foundChallenge2 = _.find(challenges, { _id: challenge2._id }); + expect(foundChallenge2).to.exist; + expect(foundChallenge2.leader).to.eql(userData); + expect(foundChallenge2.group).to.eql(groupData); + }); + + it('should return newest challenges first', async () => { + let challenges = await user.get('/challenges/user'); + + let foundChallengeIndex = _.findIndex(challenges, { _id: challenge2._id }); + expect(foundChallengeIndex).to.eql(0); + + const newChallenge = await generateChallenge(user, publicGuild); + await user.post(`/challenges/${newChallenge._id}/join`); + + challenges = await user.get('/challenges/user'); + + foundChallengeIndex = _.findIndex(challenges, { _id: newChallenge._id }); + expect(foundChallengeIndex).to.eql(0); + }); + + it('should not return challenges user doesn\'t have access to', async () => { + const { group, groupLeader } = await createAndPopulateGroup({ + groupDetails: { + name: 'TestPrivateGuild', + summary: 'summary for TestPrivateGuild', + type: 'guild', + privacy: 'private', }, - }, - flags: { - verifiedUsername: true, - }, - }); - expect(foundChallenge.group).to.eql({ - _id: publicGuild._id, - categories: [], - id: publicGuild._id, - type: publicGuild.type, - privacy: publicGuild.privacy, - name: publicGuild.name, - summary: publicGuild.name, - leader: publicGuild.leader._id, - }); - }); + }); - it('should return challenges user has created', async () => { - const challenges = await user.get('/challenges/user'); + const privateChallenge = await generateChallenge(groupLeader, group); + await groupLeader.post(`/challenges/${privateChallenge._id}/join`); - const foundChallenge1 = _.find(challenges, { _id: challenge._id }); - expect(foundChallenge1).to.exist; - expect(foundChallenge1.leader).to.eql({ - _id: publicGuild.leader._id, - id: publicGuild.leader._id, - profile: { name: user.profile.name }, - auth: { - local: { - username: user.auth.local.username, + const challenges = await nonMember.get('/challenges/user'); + + const foundChallenge = _.find(challenges, { _id: privateChallenge._id }); + expect(foundChallenge).to.not.exist; + }); + + it('should not return challenges user doesn\'t have access to, even with query parameters', async () => { + const { group, groupLeader } = await createAndPopulateGroup({ + groupDetails: { + name: 'TestPrivateGuild', + summary: 'summary for TestPrivateGuild', + type: 'guild', + privacy: 'private', }, - }, - flags: { - verifiedUsername: true, - }, - }); - expect(foundChallenge1.group).to.eql({ - _id: publicGuild._id, - categories: [], - id: publicGuild._id, - type: publicGuild.type, - privacy: publicGuild.privacy, - name: publicGuild.name, - summary: publicGuild.name, - leader: publicGuild.leader._id, - }); - const foundChallenge2 = _.find(challenges, { _id: challenge2._id }); - expect(foundChallenge2).to.exist; - expect(foundChallenge2.leader).to.eql({ - _id: publicGuild.leader._id, - id: publicGuild.leader._id, - profile: { name: user.profile.name }, - auth: { - local: { - username: user.auth.local.username, - }, - }, - flags: { - verifiedUsername: true, - }, - }); - expect(foundChallenge2.group).to.eql({ - _id: publicGuild._id, - categories: [], - id: publicGuild._id, - type: publicGuild.type, - privacy: publicGuild.privacy, - name: publicGuild.name, - summary: publicGuild.name, - leader: publicGuild.leader._id, + }); + + const privateChallenge = await generateChallenge(groupLeader, group, { + categories: [{ + name: 'academics', + slug: 'academics', + }], + }); + await groupLeader.post(`/challenges/${privateChallenge._id}/join`); + + const challenges = await nonMember.get('/challenges/user?categories=academics&owned=not_owned'); + + const foundChallenge = _.find(challenges, { _id: privateChallenge._id }); + expect(foundChallenge).to.not.exist; }); }); - it('should return challenges in user\'s group', async () => { - const challenges = await member.get('/challenges/user'); + context('my challenges', () => { + it('should return challenges user has joined', async () => { + const challenges = await nonMember.get(`/challenges/user?member=${true}`); - const foundChallenge1 = _.find(challenges, { _id: challenge._id }); - expect(foundChallenge1).to.exist; - expect(foundChallenge1.leader).to.eql({ - _id: publicGuild.leader._id, - id: publicGuild.leader._id, - profile: { name: user.profile.name }, - auth: { - local: { - username: user.auth.local.username, - }, - }, - flags: { - verifiedUsername: true, - }, - }); - expect(foundChallenge1.group).to.eql({ - _id: publicGuild._id, - categories: [], - id: publicGuild._id, - type: publicGuild.type, - privacy: publicGuild.privacy, - name: publicGuild.name, - summary: publicGuild.name, - leader: publicGuild.leader._id, - }); - const foundChallenge2 = _.find(challenges, { _id: challenge2._id }); - expect(foundChallenge2).to.exist; - expect(foundChallenge2.leader).to.eql({ - _id: publicGuild.leader._id, - id: publicGuild.leader._id, - profile: { name: user.profile.name }, - auth: { - local: { - username: user.auth.local.username, - }, - }, - flags: { - verifiedUsername: true, - }, - }); - expect(foundChallenge2.group).to.eql({ - _id: publicGuild._id, - categories: [], - id: publicGuild._id, - type: publicGuild.type, - privacy: publicGuild.privacy, - name: publicGuild.name, - summary: publicGuild.name, - leader: publicGuild.leader._id, - }); - }); - - it('should not return challenges in user groups if we send member true param', async () => { - const challenges = await member.get(`/challenges/user?member=${true}`); - - const foundChallenge1 = _.find(challenges, { _id: challenge._id }); - expect(foundChallenge1).to.not.exist; - - const foundChallenge2 = _.find(challenges, { _id: challenge2._id }); - expect(foundChallenge2).to.not.exist; - }); - - it('should return newest challenges first', async () => { - let challenges = await user.get('/challenges/user'); - - let foundChallengeIndex = _.findIndex(challenges, { _id: challenge2._id }); - expect(foundChallengeIndex).to.eql(0); - - const newChallenge = await generateChallenge(user, publicGuild); - await user.post(`/challenges/${newChallenge._id}/join`); - - challenges = await user.get('/challenges/user'); - - foundChallengeIndex = _.findIndex(challenges, { _id: newChallenge._id }); - expect(foundChallengeIndex).to.eql(0); - }); - - it('should not return challenges user doesn\'t have access to', async () => { - const { group, groupLeader } = await createAndPopulateGroup({ - groupDetails: { - name: 'TestPrivateGuild', - summary: 'summary for TestPrivateGuild', - type: 'guild', - privacy: 'private', - }, + const foundChallenge = _.find(challenges, { _id: challenge._id }); + expect(foundChallenge).to.exist; + expect(foundChallenge.leader).to.eql(userData); + expect(foundChallenge.group).to.eql(groupData); }); - const privateChallenge = await generateChallenge(groupLeader, group); - await groupLeader.post(`/challenges/${privateChallenge._id}/join`); + it('should return challenges user has created', async () => { + const challenges = await user.get(`/challenges/user?member=${true}`); - const challenges = await nonMember.get('/challenges/user'); - - const foundChallenge = _.find(challenges, { _id: privateChallenge._id }); - expect(foundChallenge).to.not.exist; - }); - - it('should not return challenges user doesn\'t have access to, even with query parameters', async () => { - const { group, groupLeader } = await createAndPopulateGroup({ - groupDetails: { - name: 'TestPrivateGuild', - summary: 'summary for TestPrivateGuild', - type: 'guild', - privacy: 'private', - }, + const foundChallenge1 = _.find(challenges, { _id: challenge._id }); + expect(foundChallenge1).to.exist; + expect(foundChallenge1.leader).to.eql(userData); + expect(foundChallenge1.group).to.eql(groupData); + const foundChallenge2 = _.find(challenges, { _id: challenge2._id }); + expect(foundChallenge2).to.exist; + expect(foundChallenge2.leader).to.eql(userData); + expect(foundChallenge2.group).to.eql(groupData); }); - const privateChallenge = await generateChallenge(groupLeader, group, { - categories: [{ - name: 'academics', - slug: 'academics', - }], + it('should return challenges user has created if filter by owned', async () => { + const challenges = await user.get(`/challenges/user?member=${true}&owned=owned`); + + const foundChallenge1 = _.find(challenges, { _id: challenge._id }); + expect(foundChallenge1).to.exist; + expect(foundChallenge1.leader).to.eql(userData); + expect(foundChallenge1.group).to.eql(groupData); + const foundChallenge2 = _.find(challenges, { _id: challenge2._id }); + expect(foundChallenge2).to.exist; + expect(foundChallenge2.leader).to.eql(userData); + expect(foundChallenge2.group).to.eql(groupData); }); - await groupLeader.post(`/challenges/${privateChallenge._id}/join`); - const challenges = await nonMember.get('/challenges/user?categories=academics&owned=not_owned'); + it('should not return challenges user has created if filter by not owned', async () => { + const challenges = await user.get(`/challenges/user?owned=not_owned&member=${true}`); - const foundChallenge = _.find(challenges, { _id: privateChallenge._id }); - expect(foundChallenge).to.not.exist; + const foundChallenge1 = _.find(challenges, { _id: challenge._id }); + expect(foundChallenge1).to.not.exist; + const foundChallenge2 = _.find(challenges, { _id: challenge2._id }); + expect(foundChallenge2).to.not.exist; + }); + + it('should not return challenges in user groups', async () => { + const challenges = await member.get(`/challenges/user?member=${true}`); + + const foundChallenge1 = _.find(challenges, { _id: challenge._id }); + expect(foundChallenge1).to.not.exist; + + const foundChallenge2 = _.find(challenges, { _id: challenge2._id }); + expect(foundChallenge2).to.not.exist; + }); }); }); diff --git a/website/client/package-lock.json b/website/client/package-lock.json index 3671661fd9..fd317ee6d6 100644 --- a/website/client/package-lock.json +++ b/website/client/package-lock.json @@ -4922,7 +4922,6 @@ "version": "0.9.1", "resolved": "https://registry.npmjs.org/@types/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.1.tgz", "integrity": "sha512-+mN04Oszdz9tGjUP/c1ReVwJXxSniLd7lF++sv+8dkABxVNthg6uccei+4ssKxRHGoMmPxdn7uBdJWONSJGTGQ==", - "optional": true, "requires": { "@types/webpack": "*" } @@ -6703,7 +6702,6 @@ "version": "npm:vue-loader@16.0.0-beta.5", "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.0.0-beta.5.tgz", "integrity": "sha512-ciWfzNefqWlmzKznCWY9hl+fPP4KlQ0A9MtHbJ/8DpyY+dAM8gDrjufIdxwTgC4szE4EZC3A6ip/BbrqM84GqA==", - "optional": true, "requires": { "@types/mini-css-extract-plugin": "^0.9.1", "chalk": "^3.0.0", @@ -6717,7 +6715,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "optional": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -6726,14 +6723,12 @@ "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "optional": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "optional": true, "requires": { "has-flag": "^4.0.0" } @@ -9645,6 +9640,14 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" }, + "serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "requires": { + "randombytes": "^2.1.0" + } + }, "slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", @@ -12825,9 +12828,9 @@ } }, "habitica-markdown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/habitica-markdown/-/habitica-markdown-2.0.2.tgz", - "integrity": "sha512-GGzWuDKbFBMI+GqmQnSPUD5Zi/WPZDDuC2dC2La6uvu1zVNW7uHyQG0lxwCO43t5EdYXtOoOPin1rhhLdTuZfA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/habitica-markdown/-/habitica-markdown-3.0.0.tgz", + "integrity": "sha512-rw1LJ5Vsjx8sfjNa4e2wFuZf5eqqyb5/kfZXPxqfMMgJCCgIhWStDqY3nIclnpGWpemlKd+qbdh2rLiLgm9kng==", "requires": { "habitica-markdown-emoji": "1.2.4", "markdown-it": "10.0.0", @@ -18639,9 +18642,9 @@ } }, "serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", + "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", "requires": { "randombytes": "^2.1.0" } @@ -20393,11 +20396,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, - "serialize-javascript": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.0.0.tgz", - "integrity": "sha512-skZcHYw2vEX4bw90nAr2iTTsz6x2SrHEnfxgKYmZlvJYBEZrvbKtobJWlQ20zczKb3bsHHXXTYt48zBA7ni9cw==" - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -21338,14 +21336,6 @@ "minimist": "^1.2.5" } }, - "serialize-javascript": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", - "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", - "requires": { - "randombytes": "^2.1.0" - } - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", diff --git a/website/client/package.json b/website/client/package.json index 0133e497b7..b6848421a1 100644 --- a/website/client/package.json +++ b/website/client/package.json @@ -36,7 +36,7 @@ "eslint-config-habitrpg": "^6.2.0", "eslint-plugin-mocha": "^5.3.0", "eslint-plugin-vue": "^6.2.2", - "habitica-markdown": "^2.0.2", + "habitica-markdown": "^3.0.0", "hellojs": "^1.18.4", "inspectpack": "^4.5.2", "intro.js": "^2.9.3", diff --git a/website/client/src/assets/scss/form.scss b/website/client/src/assets/scss/form.scss index f4c2dc3ba1..11fbce2903 100644 --- a/website/client/src/assets/scss/form.scss +++ b/website/client/src/assets/scss/form.scss @@ -202,6 +202,8 @@ $bg-disabled-control: #34303a; } .custom-control-input { + opacity: 0; + &:checked~.custom-control-label::before { background-color: $purple-400; border-color: $purple-400; diff --git a/website/client/src/assets/scss/index.scss b/website/client/src/assets/scss/index.scss index 424cffb0e7..4dbdab2874 100644 --- a/website/client/src/assets/scss/index.scss +++ b/website/client/src/assets/scss/index.scss @@ -37,3 +37,4 @@ @import './tiers'; @import './payments'; @import './spacing'; +@import './modal'; diff --git a/website/client/src/assets/scss/mixins.scss b/website/client/src/assets/scss/mixins.scss new file mode 100644 index 0000000000..561be306ed --- /dev/null +++ b/website/client/src/assets/scss/mixins.scss @@ -0,0 +1,9 @@ +@mixin centeredModal() { + display: flex; + justify-content: center; + flex-direction: column; + + header, footer { + border: 0; + } +} \ No newline at end of file diff --git a/website/client/src/assets/scss/modal.scss b/website/client/src/assets/scss/modal.scss index a595900747..883b17eeec 100644 --- a/website/client/src/assets/scss/modal.scss +++ b/website/client/src/assets/scss/modal.scss @@ -1,16 +1,5 @@ - @import '~@/assets/scss/colors.scss'; -@mixin centeredModal() { - display: flex; - justify-content: center; - flex-direction: column; - - header, footer { - border: 0; - } -} - .modal { z-index: 1350; padding-left: 0px !important; diff --git a/website/client/src/components/achievements/genericAchievement.vue b/website/client/src/components/achievements/genericAchievement.vue index 8ec5f908e8..22b9ba07d1 100644 --- a/website/client/src/components/achievements/genericAchievement.vue +++ b/website/client/src/components/achievements/genericAchievement.vue @@ -45,7 +45,7 @@