diff --git a/CHANGELOG.md b/CHANGELOG.md index 0acd887f..9c153abc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,48 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.0.4 - 20-01-2020 + +### Added + +- Added interface to approve/reject group follow requests +- Added UI for group public Atom/ICS feeds +- Attach ICS files representing the event to notifications and participations emails +- Add initial support to build Elixir releases + +### Changed + +- Added `
` to allowed HTML tags +- Events are now correctly ordered by their beginning date on search and group page + +### Fixed + +- Upgrade PWA support library to avoid a call to Google CDN +- Fixed group avatar & banner upload +- Fixed some events not showing on homepage +- Fixed the `next` and `prev` attribute not being present in `CollectionPage` ActivityPub Collections +- Added a text to explain that group discussions are restricted to members on discussion list page +- Fixed ICS export timezone issues +- Fixed remote interactions when the content was not local to the instance +- Fixed a federation issue with group member removal +- Fixed group remote subscription + +### Translations + +- Bengali (New!) +- Catalan +- Finnish +- French +- Galician +- German +- Italian +- Norwegian +- Polish +- Portuguese (New!) +- Slovenian (New!) +- Spanish +- Swedish + ## 1.0.3 - 18-12-2020 **This release adds new migrations, be sure to run them before restarting Mobilizon** diff --git a/js/package.json b/js/package.json index 047c4072..576506f6 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "mobilizon", - "version": "1.0.3", + "version": "1.0.4", "private": true, "scripts": { "serve": "vue-cli-service serve", @@ -39,10 +39,10 @@ "phoenix": "^1.4.11", "register-service-worker": "^1.7.1", "tippy.js": "^6.2.3", - "tiptap": "^1.26.0", - "tiptap-extensions": "^1.29.1", + "tiptap": "^1.31.0", + "tiptap-extensions": "^1.34.0", "unfetch": "^4.2.0", - "v-tooltip": "2.0.2", + "v-tooltip": "^2.1.2", "vue": "^2.6.11", "vue-apollo": "^3.0.3", "vue-class-component": "^7.2.3", @@ -52,7 +52,7 @@ "vue-router": "^3.1.6", "vue-scrollto": "^2.17.1", "vue2-leaflet": "^2.0.3", - "vuedraggable": "2.23.2" + "vuedraggable": "^2.24.3" }, "devDependencies": { "@types/jest": "^26.0.18", @@ -65,8 +65,8 @@ "@types/prosemirror-state": "^1.2.4", "@types/prosemirror-view": "^1.11.4", "@types/vuedraggable": "^2.23.0", - "@typescript-eslint/eslint-plugin": "^4.0.1", - "@typescript-eslint/parser": "^4.0.1", + "@typescript-eslint/eslint-plugin": "4.13.0", + "@typescript-eslint/parser": "4.13.0", "@vue/cli-plugin-babel": "~4.5.10", "@vue/cli-plugin-e2e-cypress": "~4.5.10", "@vue/cli-plugin-eslint": "~4.5.10", @@ -83,7 +83,7 @@ "eslint-plugin-prettier": "^3.1.3", "eslint-plugin-vue": "^7.0.0", "jest-junit": "^12.0.0", - "mock-apollo-client": "^0.4", + "mock-apollo-client": "^0.5", "prettier": "2.2.1", "prettier-eslint": "^12.0.0", "sass": "^1.29.0", @@ -95,8 +95,6 @@ "webpack-cli": "^3.3" }, "resolutions": { - "prosemirror-model": "1.9.1", - "prosemirror-state": "1.3.3", "workbox-webpack-plugin": "5.1.3" } } diff --git a/js/src/graphql/followers.ts b/js/src/graphql/followers.ts new file mode 100644 index 00000000..660c2e7d --- /dev/null +++ b/js/src/graphql/followers.ts @@ -0,0 +1,49 @@ +import gql from "graphql-tag"; + +export const GROUP_FOLLOWERS = gql` + query( + $name: String! + $followersPage: Int + $followersLimit: Int + $approved: Boolean + ) { + group(preferredUsername: $name) { + id + preferredUsername + name + domain + followers( + page: $followersPage + limit: $followersLimit + approved: $approved + ) { + total + elements { + id + actor { + id + preferredUsername + name + domain + avatar { + id + url + } + } + approved + insertedAt + updatedAt + } + } + } + } +`; + +export const UPDATE_FOLLOWER = gql` + mutation UpdateFollower($id: ID!, $approved: Boolean) { + updateFollower(id: $id, approved: $approved) { + id + approved + } + } +`; diff --git a/js/src/graphql/group.ts b/js/src/graphql/group.ts index 89a14a71..84345a03 100644 --- a/js/src/graphql/group.ts +++ b/js/src/graphql/group.ts @@ -64,6 +64,7 @@ export const GROUP_FIELDS_FRAGMENTS = gql` suspended visibility openness + manuallyApprovesFollowers physicalAddress { description street @@ -265,6 +266,7 @@ export const UPDATE_GROUP = gql` $visibility: GroupVisibility $openness: Openness $physicalAddress: AddressInput + $manuallyApprovesFollowers: Boolean ) { updateGroup( id: $id @@ -275,6 +277,7 @@ export const UPDATE_GROUP = gql` visibility: $visibility openness: $openness physicalAddress: $physicalAddress + manuallyApprovesFollowers: $manuallyApprovesFollowers ) { id preferredUsername @@ -282,6 +285,7 @@ export const UPDATE_GROUP = gql` summary visibility openness + manuallyApprovesFollowers avatar { id url diff --git a/js/src/i18n/en_US.json b/js/src/i18n/en_US.json index d1df8811..fe0b9e62 100644 --- a/js/src/i18n/en_US.json +++ b/js/src/i18n/en_US.json @@ -829,5 +829,12 @@ "It is possible that the content is not accessible on this instance, because this instance has blocked the profiles or groups behind this content.": "It is possible that the content is not accessible on this instance, because this instance has blocked the profiles or groups behind this content.", "Atom feed for events and posts": "Atom feed for events and posts", "ICS feed for events": "ICS feed for events", - "ICS/WebCal Feed": "ICS/WebCal Feed" + "ICS/WebCal Feed": "ICS/WebCal Feed", + "Group Followers": "Group Followers", + "Follower": "Follower", + "Reject": "Reject", + "No follower matches the filters": "No follower matches the filters", + "@{username}'s follow request was rejected": "@{username}'s follow request was rejected", + "Followers will receive new public events and posts.": "Followers will receive new public events and posts.", + "Manually approve new followers": "Manually approve new followers" } diff --git a/js/src/i18n/fr_FR.json b/js/src/i18n/fr_FR.json index 31d1c70f..4433842b 100644 --- a/js/src/i18n/fr_FR.json +++ b/js/src/i18n/fr_FR.json @@ -274,7 +274,7 @@ "Find an address": "Trouver une adresse", "Find an instance": "Trouver une instance", "Find another instance": "Trouver une autre instance", - "Followers": "Abonnés", + "Followers": "Abonné⋅es", "Followings": "Abonnements", "For instance: London": "Par exemple : Lyon", "For instance: London, Taekwondo, Architecture…": "Par exemple : Lyon, Taekwondo, Architecture…", @@ -925,5 +925,11 @@ "© The OpenStreetMap Contributors": "© Les Contributeur⋅ices OpenStreetMap", "Atom feed for events and posts": "Flux Atom pour les événements et les billets", "ICS feed for events": "Flux ICS pour les événements", - "ICS/WebCal Feed": "Flux ICS/WebCal" + "ICS/WebCal Feed": "Flux ICS/WebCal", + "Group Followers": "Abonné⋅es au groupe", + "Follower": "Abonné⋅es", + "No follower matches the filters": "Aucun⋅e abonné⋅e ne correspond aux filtres", + "@{username}'s follow request was rejected": "La demande de suivi de @{username} a été rejettée", + "Followers will receive new public events and posts.": "Les abonnée⋅s recevront les nouveaux événements et billets publics.", + "Manually approve new followers": "Approuver les nouvelles demandes de suivi manuellement" } diff --git a/js/src/i18n/langs.json b/js/src/i18n/langs.json index 2cda8d15..072a8e82 100644 --- a/js/src/i18n/langs.json +++ b/js/src/i18n/langs.json @@ -1,6 +1,7 @@ { "ar": "العربية", "be": "Беларуская мова", + "bn": "বাংলা", "ca": "Català", "cs": "čeština", "de": "Deutsch", @@ -22,5 +23,6 @@ "pt": "Português", "pt_BR": "Português brasileiro", "ru": "Русский", + "sl": "Slovenščina", "sv": "Svenska" } diff --git a/js/src/router/groups.ts b/js/src/router/groups.ts index ae3a9205..75d16ada 100644 --- a/js/src/router/groups.ts +++ b/js/src/router/groups.ts @@ -8,6 +8,7 @@ export enum GroupsRouteName { GROUP_SETTINGS = "GROUP_SETTINGS", GROUP_PUBLIC_SETTINGS = "GROUP_PUBLIC_SETTINGS", GROUP_MEMBERS_SETTINGS = "GROUP_MEMBERS_SETTINGS", + GROUP_FOLLOWERS_SETTINGS = "GROUP_FOLLOWERS_SETTINGS", RESOURCES = "RESOURCES", RESOURCE_FOLDER_ROOT = "RESOURCE_FOLDER_ROOT", RESOURCE_FOLDER = "RESOURCE_FOLDER", @@ -85,6 +86,13 @@ export const groupsRoutes: RouteConfig[] = [ import("../views/Group/GroupMembers.vue"), props: true, }, + { + path: "followers", + name: GroupsRouteName.GROUP_FOLLOWERS_SETTINGS, + component: (): Promise => + import("../views/Group/GroupFollowers.vue"), + props: true, + }, ], }, { diff --git a/js/src/types/actor/group.model.ts b/js/src/types/actor/group.model.ts index f3966c12..c178f404 100644 --- a/js/src/types/actor/group.model.ts +++ b/js/src/types/actor/group.model.ts @@ -19,6 +19,7 @@ export interface IGroup extends IActor { organizedEvents: Paginate; physicalAddress: IAddress; openness: Openness; + manuallyApprovesFollowers: boolean; } export class Group extends Actor implements IGroup { @@ -45,6 +46,8 @@ export class Group extends Actor implements IGroup { physicalAddress: IAddress = new Address(); + manuallyApprovesFollowers = true; + patch(hash: IGroup | Record): void { Object.assign(this, hash); } diff --git a/js/src/views/Group/GroupFollowers.vue b/js/src/views/Group/GroupFollowers.vue new file mode 100644 index 00000000..712a34fe --- /dev/null +++ b/js/src/views/Group/GroupFollowers.vue @@ -0,0 +1,261 @@ + + + diff --git a/js/src/views/Group/GroupSettings.vue b/js/src/views/Group/GroupSettings.vue index 54bfbb9e..f4401059 100644 --- a/js/src/views/Group/GroupSettings.vue +++ b/js/src/views/Group/GroupSettings.vue @@ -134,6 +134,15 @@ + + + {{ $t("Manually approve new followers") }} + + + + diff --git a/js/yarn.lock b/js/yarn.lock index 9de09df8..9e8c2e2e 100644 --- a/js/yarn.lock +++ b/js/yarn.lock @@ -27,6 +27,25 @@ core-js "2.6.0" zen-observable "0.8.11" +"@apollo/client@^3.0.0": + version "3.3.7" + resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.3.7.tgz#f15bf961dc0c2bee37a47bf86b8881fdc6183810" + integrity sha512-Cb0OqqvlehlRHtHIXRIS/Pe5WYU4hHl1FznXTRSxBAN42WmBUM3zy/Unvw183RdWMyV6Kc2pFKOEuaG1K7JTAQ== + dependencies: + "@graphql-typed-document-node/core" "^3.0.0" + "@types/zen-observable" "^0.8.0" + "@wry/context" "^0.5.2" + "@wry/equality" "^0.3.0" + fast-json-stable-stringify "^2.0.0" + graphql-tag "^2.11.0" + hoist-non-react-statics "^3.3.2" + optimism "^0.14.0" + prop-types "^15.7.2" + symbol-observable "^2.0.0" + ts-invariant "^0.6.0" + tslib "^1.10.0" + zen-observable "^0.8.14" + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.11", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" @@ -904,10 +923,10 @@ debug "^3.1.0" lodash.once "^4.1.1" -"@eslint/eslintrc@^0.2.2": - version "0.2.2" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.2.2.tgz#d01fc791e2fc33e88a29d6f3dc7e93d0cd784b76" - integrity sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ== +"@eslint/eslintrc@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.3.0.tgz#d736d6963d7003b6514e6324bec9c602ac340318" + integrity sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg== dependencies: ajv "^6.12.4" debug "^4.1.1" @@ -916,10 +935,15 @@ ignore "^4.0.6" import-fresh "^3.2.1" js-yaml "^3.13.1" - lodash "^4.17.19" + lodash "^4.17.20" minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@graphql-typed-document-node/core@^3.0.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.1.0.tgz#0eee6373e11418bfe0b5638f654df7a4ca6a3950" + integrity sha512-wYn6r8zVZyQJ6rQaALBEln5B1pzxb9shV5Ef97kTvn6yVGrqyXVnDqnU24MXnFubR+rZjBY9NWuxX3FB2sTsjg== + "@hapi/address@2.x.x": version "2.1.4" resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" @@ -1150,9 +1174,9 @@ graphql "14.0.2" "@mdi/font@^5.0.45": - version "5.8.55" - resolved "https://registry.yarnpkg.com/@mdi/font/-/font-5.8.55.tgz#1464155bcbc8a6e4af6dffd611fe8e38e09af285" - integrity sha512-8mrwfFBsmj+D67ZiGQSe5TU/lcWCtDyli2eshQ2fvLCZGRPqFMM23YQp4+JMOTpk5yMZKTeAwNWIYfITy76OHA== + version "5.9.55" + resolved "https://registry.yarnpkg.com/@mdi/font/-/font-5.9.55.tgz#41acd50b88073ded7095fc3029d8712b6e12f38e" + integrity sha512-jswRF6q3eq8NWpWiqct6q+6Fg/I7nUhrxYJfiEM8JJpap0wVJLQdbKtyS65GdlK7S7Ytnx3TTi/bmw+tBhkGmg== "@mrmlnc/readdir-enhanced@^2.2.1": version "2.2.1" @@ -1311,31 +1335,31 @@ integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== "@types/estree@*": - version "0.0.45" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.45.tgz#e9387572998e5ecdac221950dab3e8c3b16af884" - integrity sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g== + version "0.0.46" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.46.tgz#0fb6bfbbeabd7a30880504993369c4bf1deab1fe" + integrity sha512-laIjwTQaD+5DukBZaygQ79K1Z0jb1bPEMRrkXSLjtCcZm+abyp5YbrqpSLzD42FwWW6gK/aS4NYpJ804nG2brg== "@types/estree@0.0.39": version "0.0.39" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== -"@types/express-serve-static-core@*": - version "4.17.17" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.17.tgz#6ba02465165b6c9c3d8db3a28def6b16fc9b70f5" - integrity sha512-YYlVaCni5dnHc+bLZfY908IG1+x5xuibKZMGv8srKkvtul3wUuanYvpIj9GXXoWkQbaAdR+kgX46IETKUALWNQ== +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": + version "4.17.18" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.18.tgz#8371e260f40e0e1ca0c116a9afcd9426fa094c40" + integrity sha512-m4JTwx5RUBNZvky/JJ8swEJPKFd8si08pPF2PfizYjGZOKr/svUWPcoUmLow6MmPzhasphB7gSTINY67xn3JNA== dependencies: "@types/node" "*" "@types/qs" "*" "@types/range-parser" "*" "@types/express@*": - version "4.17.9" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.9.tgz#f5f2df6add703ff28428add52bdec8a1091b0a78" - integrity sha512-SDzEIZInC4sivGIFY4Sz1GG6J9UObPwCInYJjko2jzOf/Imx/dlpume6Xxwj1ORL82tBbmN4cPDIDkLbWHk9hw== + version "4.17.11" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.11.tgz#debe3caa6f8e5fcda96b47bd54e2f40c4ee59545" + integrity sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg== dependencies: "@types/body-parser" "*" - "@types/express-serve-static-core" "*" + "@types/express-serve-static-core" "^4.17.18" "@types/qs" "*" "@types/serve-static" "*" @@ -1362,9 +1386,9 @@ "@types/node" "*" "@types/http-proxy@*": - version "1.17.4" - resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.4.tgz#e7c92e3dbe3e13aa799440ff42e6d3a17a9d045b" - integrity sha512-IrSHl2u6AWXduUaDLqYpt45tLVCtYv7o4Z0s1KghBCDgIIS9oW5K1H8mZG/A2CfeLdEa7rTd1ACOiHBc1EMT2Q== + version "1.17.5" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.5.tgz#c203c5e6e9dc6820d27a40eb1e511c70a220423d" + integrity sha512-GNkDE7bTv6Sf8JbV2GksknKOsk7OznNYHSdrtvPJXO0qJ9odZig6IZKUi5RFGi6d1bf6dgIAe4uXi3DBc7069Q== dependencies: "@types/node" "*" @@ -1411,9 +1435,9 @@ pretty-format "^26.0.0" "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6": - version "7.0.6" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" - integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== + version "7.0.7" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" + integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== "@types/leaflet.locatecontrol@^0.60.7": version "0.60.7" @@ -1423,21 +1447,21 @@ "@types/leaflet" "*" "@types/leaflet@*", "@types/leaflet@^1.5.2": - version "1.5.19" - resolved "https://registry.yarnpkg.com/@types/leaflet/-/leaflet-1.5.19.tgz#f290e21fe7a4744d68bb4b0709e99ce490120e6e" - integrity sha512-ZAKqfvdU/+KFoCpf8aUba09F8mfSc8R2esq++Cha3E2DgwS5K/I/4eJ+0JylrVHZivgY7PSAeXFv/izP+81/MQ== + version "1.5.21" + resolved "https://registry.yarnpkg.com/@types/leaflet/-/leaflet-1.5.21.tgz#994c44f2bfc45744120f01924c8973c5e960e051" + integrity sha512-b+BOkwJDq6DK4m+jFUOHNCFinIkO4CF1MjnOwYgZFX+oElpYpXCCIsxZ3+zQWIRSLVUbRXvaQq2K935jGIyp7A== dependencies: "@types/geojson" "*" "@types/lodash@^4.14.141": - version "4.14.167" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.167.tgz#ce7d78553e3c886d4ea643c37ec7edc20f16765e" - integrity sha512-w7tQPjARrvdeBkX/Rwg95S592JwxqOjmms3zWQ0XZgSyxSLdzWaYH3vErBhdVS/lRBX7F8aBYcYJYTr5TMGOzw== + version "4.14.168" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.168.tgz#fe24632e79b7ade3f132891afff86caa5e5ce008" + integrity sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q== -"@types/mime@*": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.3.tgz#c893b73721db73699943bfc3653b1deb7faa4a3a" - integrity sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q== +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== "@types/minimatch@*": version "3.0.3" @@ -1455,9 +1479,9 @@ integrity sha512-6nlq2eEh75JegDGUXis9wGTYIJpUvbori4qx++PRKQsV3YRkaqUNPNykzphniqPSZADXCouBuAnyptjUkMkhvw== "@types/node@*", "@types/node@>=6": - version "14.14.20" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.20.tgz#f7974863edd21d1f8a494a73e8e2b3658615c340" - integrity sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A== + version "14.14.22" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.22.tgz#0d29f382472c4ccf3bd96ff0ce47daf5b7b84b18" + integrity sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -1475,40 +1499,40 @@ integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== "@types/prosemirror-inputrules@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@types/prosemirror-inputrules/-/prosemirror-inputrules-1.0.3.tgz#3f8f07921f692b6c7e4781fa426aee3e76b9018c" - integrity sha512-cxMkCcu/di8//68jWc/NrRpvpCbizgq9vqv4rCRsAiuSiJ8L5hf4aFlCBUYCffuQnrY98uOfJ8YAUY3dbtaF9A== + version "1.0.4" + resolved "https://registry.yarnpkg.com/@types/prosemirror-inputrules/-/prosemirror-inputrules-1.0.4.tgz#4cb75054d954aa0f6f42099be05eb6c0e6958bae" + integrity sha512-lJIMpOjO47SYozQybUkpV6QmfuQt7GZKHtVrvS+mR5UekA8NMC5HRIVMyaIauJLWhKU6oaNjpVaXdw41kh165g== dependencies: "@types/prosemirror-model" "*" "@types/prosemirror-state" "*" "@types/prosemirror-model@*", "@types/prosemirror-model@^1.7.2": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@types/prosemirror-model/-/prosemirror-model-1.11.1.tgz#f1258bfe8d6f2fb68a2f95b3af57e18e5868cbab" - integrity sha512-sAue1p9V/JjATX1JzQDFzW2ON8QEGUz3eMSpJX94oCr0CoAQgK4/kSM2funtQKy1GHd+xr7wZ509ykt49b+T1Q== + version "1.11.2" + resolved "https://registry.yarnpkg.com/@types/prosemirror-model/-/prosemirror-model-1.11.2.tgz#af7a9571a8d43ad433f0580099628627962cc11b" + integrity sha512-mohs15V+gxj10QWJGVooErzSE9ryTo1Wy92lULiQ0BSN5Po9K4vngPzfKmLft0+gAPbEghovTX+I2zQW3bZo1w== dependencies: "@types/orderedmap" "*" "@types/prosemirror-state@*", "@types/prosemirror-state@^1.2.4": - version "1.2.5" - resolved "https://registry.yarnpkg.com/@types/prosemirror-state/-/prosemirror-state-1.2.5.tgz#a91304e9aab6e71f868e23b3a1ae514a75033f8f" - integrity sha512-a5DxAifiF6vmdSJ5jsDMkpykUgUJUy+T5Q5hCjFOKJ4cfd3m3q1lsFKr7Bc4r91Qb7rfqyiKCMDnASS8LIHrKw== + version "1.2.6" + resolved "https://registry.yarnpkg.com/@types/prosemirror-state/-/prosemirror-state-1.2.6.tgz#bb0169084239a8393b354c6fda5420fc347d6bab" + integrity sha512-tJo0wC+/cQvbrPDVx01Fnng9Fs41bAMVxgJY1KLOyIsUPN0otUN1KdoQurLMmHNHTvIna9ZXxjZD//xJKLYfJw== dependencies: "@types/prosemirror-model" "*" "@types/prosemirror-transform" "*" "@types/prosemirror-view" "*" "@types/prosemirror-transform@*": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@types/prosemirror-transform/-/prosemirror-transform-1.1.1.tgz#5a0de16e8e0123b4c3d9559235e19f39cee85e5c" - integrity sha512-yYCYSoiRH+Wcbl8GJc0PFCzeyMzNQ1vL2xrHHSXZuNcIlH75VoiKrZFeZ6BS9cl8mYXjZrlmdBe8YOxYvyKM6A== + version "1.1.2" + resolved "https://registry.yarnpkg.com/@types/prosemirror-transform/-/prosemirror-transform-1.1.2.tgz#fe883c19a5a9f1882346a294efd09d55c6764c7a" + integrity sha512-Ozyvs5Dquc49gaFysmC4gNhv6E65r569HSzw4RXdZgIljZ5Y9K4kHFlDvsWBBDH19+1178X9LMmM9J620O6Bug== dependencies: "@types/prosemirror-model" "*" "@types/prosemirror-view@*", "@types/prosemirror-view@^1.11.4": - version "1.17.0" - resolved "https://registry.yarnpkg.com/@types/prosemirror-view/-/prosemirror-view-1.17.0.tgz#7e283038730a67c35521c8dbc932765a70291edd" - integrity sha512-1OALGaiRmq3c+Y35QVrqqlEykWEszYYx08jAPBhYe6M+YbC6Y2LnmCDXjEOTI1oToJwoADHFPGHl4W59L3fgGg== + version "1.17.1" + resolved "https://registry.yarnpkg.com/@types/prosemirror-view/-/prosemirror-view-1.17.1.tgz#0895df5a57ae6e68d4f3f8020d9be4ef52192980" + integrity sha512-PNiGGc6BffxHQzMR09UUilsBR8xFPDsKiPIXb4K/g56voPIvqq1pqySnWFfSR50Vo4ZL0tss3VBLWiiiKzVahQ== dependencies: "@types/prosemirror-model" "*" "@types/prosemirror-state" "*" @@ -1537,11 +1561,11 @@ "@types/node" "*" "@types/serve-static@*": - version "1.13.8" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.8.tgz#851129d434433c7082148574ffec263d58309c46" - integrity sha512-MoJhSQreaVoL+/hurAZzIm8wafFR6ajiTM1m4A0kv6AGeVBl4r4pOV8bGFrjjq1sGxDTnCoF8i22o0/aE5XCyA== + version "1.13.9" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.9.tgz#aacf28a85a05ee29a11fb7c3ead935ac56f33e4e" + integrity sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA== dependencies: - "@types/mime" "*" + "@types/mime" "^1" "@types/node" "*" "@types/sizzle@2.3.2": @@ -1581,6 +1605,11 @@ dependencies: source-map "^0.6.1" +"@types/ungap__global-this@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@types/ungap__global-this/-/ungap__global-this-0.3.1.tgz#18ce9f657da556037a29d50604335614ce703f4c" + integrity sha512-+/DsiV4CxXl6ZWefwHZDXSe1Slitz21tom38qPCaG0DYCS1NnDPIQDTKcmQ/tvK/edJUKkmuIDBJbmKDiB0r/g== + "@types/vuedraggable@^2.23.0": version "2.23.2" resolved "https://registry.yarnpkg.com/@types/vuedraggable/-/vuedraggable-2.23.2.tgz#643a10bc07a06760cbf5994aeb2f6b66f64af7da" @@ -1614,9 +1643,9 @@ source-map "^0.7.3" "@types/webpack@*", "@types/webpack@^4.0.0": - version "4.41.25" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.25.tgz#4d3b5aecc4e44117b376280fbfd2dc36697968c4" - integrity sha512-cr6kZ+4m9lp86ytQc1jPOJXgINQyz3kLLunZ57jznW+WIAL0JqZbGubQk4GlD42MuQL5JGOABrxdpqqWeovlVQ== + version "4.41.26" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.26.tgz#27a30d7d531e16489f9c7607c747be6bc1a459ef" + integrity sha512-7ZyTfxjCRwexh+EJFwRUM+CDB2XvgHl4vfuqf1ZKrgGvcS5BrNvPQqJh3tsZ0P6h6Aa1qClVHaJZszLPzpqHeA== dependencies: "@types/anymatch" "*" "@types/node" "*" @@ -1649,15 +1678,16 @@ resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.2.tgz#808c9fa7e4517274ed555fa158f2de4b4f468e71" integrity sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg== -"@typescript-eslint/eslint-plugin@^4.0.1": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.12.0.tgz#00d1b23b40b58031e6d7c04a5bc6c1a30a2e834a" - integrity sha512-wHKj6q8s70sO5i39H2g1gtpCXCvjVszzj6FFygneNFyIAxRvNSVz9GML7XpqrB9t7hNutXw+MHnLN/Ih6uyB8Q== +"@typescript-eslint/eslint-plugin@4.13.0": + version "4.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.13.0.tgz#5f580ea520fa46442deb82c038460c3dd3524bb6" + integrity sha512-ygqDUm+BUPvrr0jrXqoteMqmIaZ/bixYOc3A4BRwzEPTZPi6E+n44rzNZWaB0YvtukgP+aoj0i/fyx7FkM2p1w== dependencies: - "@typescript-eslint/experimental-utils" "4.12.0" - "@typescript-eslint/scope-manager" "4.12.0" + "@typescript-eslint/experimental-utils" "4.13.0" + "@typescript-eslint/scope-manager" "4.13.0" debug "^4.1.1" functional-red-black-tree "^1.0.1" + lodash "^4.17.15" regexpp "^3.0.0" semver "^7.3.2" tsutils "^3.17.1" @@ -1673,18 +1703,28 @@ eslint-scope "^5.0.0" eslint-utils "^2.0.0" -"@typescript-eslint/experimental-utils@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.12.0.tgz#372838e76db76c9a56959217b768a19f7129546b" - integrity sha512-MpXZXUAvHt99c9ScXijx7i061o5HEjXltO+sbYfZAAHxv3XankQkPaNi5myy0Yh0Tyea3Hdq1pi7Vsh0GJb0fA== +"@typescript-eslint/experimental-utils@4.13.0": + version "4.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.13.0.tgz#9dc9ab375d65603b43d938a0786190a0c72be44e" + integrity sha512-/ZsuWmqagOzNkx30VWYV3MNB/Re/CGv/7EzlqZo5RegBN8tMuPaBgNK6vPBCQA8tcYrbsrTdbx3ixMRRKEEGVw== dependencies: "@types/json-schema" "^7.0.3" - "@typescript-eslint/scope-manager" "4.12.0" - "@typescript-eslint/types" "4.12.0" - "@typescript-eslint/typescript-estree" "4.12.0" + "@typescript-eslint/scope-manager" "4.13.0" + "@typescript-eslint/types" "4.13.0" + "@typescript-eslint/typescript-estree" "4.13.0" eslint-scope "^5.0.0" eslint-utils "^2.0.0" +"@typescript-eslint/parser@4.13.0": + version "4.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.13.0.tgz#c413d640ea66120cfcc37f891e8cb3fd1c9d247d" + integrity sha512-KO0J5SRF08pMXzq9+abyHnaGQgUJZ3Z3ax+pmqz9vl81JxmTTOUfQmq7/4awVfq09b6C4owNlOgOwp61pYRBSg== + dependencies: + "@typescript-eslint/scope-manager" "4.13.0" + "@typescript-eslint/types" "4.13.0" + "@typescript-eslint/typescript-estree" "4.13.0" + debug "^4.1.1" + "@typescript-eslint/parser@^3.0.0": version "3.10.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-3.10.1.tgz#1883858e83e8b442627e1ac6f408925211155467" @@ -1696,33 +1736,23 @@ "@typescript-eslint/typescript-estree" "3.10.1" eslint-visitor-keys "^1.1.0" -"@typescript-eslint/parser@^4.0.1": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.12.0.tgz#e1cf30436e4f916c31fcc962158917bd9e9d460a" - integrity sha512-9XxVADAo9vlfjfoxnjboBTxYOiNY93/QuvcPgsiKvHxW6tOZx1W4TvkIQ2jB3k5M0pbFP5FlXihLK49TjZXhuQ== +"@typescript-eslint/scope-manager@4.13.0": + version "4.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.13.0.tgz#5b45912a9aa26b29603d8fa28f5e09088b947141" + integrity sha512-UpK7YLG2JlTp/9G4CHe7GxOwd93RBf3aHO5L+pfjIrhtBvZjHKbMhBXTIQNkbz7HZ9XOe++yKrXutYm5KmjWgQ== dependencies: - "@typescript-eslint/scope-manager" "4.12.0" - "@typescript-eslint/types" "4.12.0" - "@typescript-eslint/typescript-estree" "4.12.0" - debug "^4.1.1" - -"@typescript-eslint/scope-manager@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.12.0.tgz#beeb8beca895a07b10c593185a5612f1085ef279" - integrity sha512-QVf9oCSVLte/8jvOsxmgBdOaoe2J0wtEmBr13Yz0rkBNkl5D8bfnf6G4Vhox9qqMIoG7QQoVwd2eG9DM/ge4Qg== - dependencies: - "@typescript-eslint/types" "4.12.0" - "@typescript-eslint/visitor-keys" "4.12.0" + "@typescript-eslint/types" "4.13.0" + "@typescript-eslint/visitor-keys" "4.13.0" "@typescript-eslint/types@3.10.1": version "3.10.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.10.1.tgz#1d7463fa7c32d8a23ab508a803ca2fe26e758727" integrity sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ== -"@typescript-eslint/types@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.12.0.tgz#fb891fe7ccc9ea8b2bbd2780e36da45d0dc055e5" - integrity sha512-N2RhGeheVLGtyy+CxRmxdsniB7sMSCfsnbh8K/+RUIXYYq3Ub5+sukRCjVE80QerrUBvuEvs4fDhz5AW/pcL6g== +"@typescript-eslint/types@4.13.0": + version "4.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.13.0.tgz#6a7c6015a59a08fbd70daa8c83dfff86250502f8" + integrity sha512-/+aPaq163oX+ObOG00M0t9tKkOgdv9lq0IQv/y4SqGkAXmhFmCfgsELV7kOCTb2vVU5VOmVwXBXJTDr353C1rQ== "@typescript-eslint/typescript-estree@3.10.1": version "3.10.1" @@ -1738,13 +1768,13 @@ semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/typescript-estree@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.12.0.tgz#3963418c850f564bdab3882ae23795d115d6d32e" - integrity sha512-gZkFcmmp/CnzqD2RKMich2/FjBTsYopjiwJCroxqHZIY11IIoN0l5lKqcgoAPKHt33H2mAkSfvzj8i44Jm7F4w== +"@typescript-eslint/typescript-estree@4.13.0": + version "4.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.13.0.tgz#cf6e2207c7d760f5dfd8d18051428fadfc37b45e" + integrity sha512-9A0/DFZZLlGXn5XA349dWQFwPZxcyYyCFX5X88nWs2uachRDwGeyPz46oTsm9ZJE66EALvEns1lvBwa4d9QxMg== dependencies: - "@typescript-eslint/types" "4.12.0" - "@typescript-eslint/visitor-keys" "4.12.0" + "@typescript-eslint/types" "4.13.0" + "@typescript-eslint/visitor-keys" "4.13.0" debug "^4.1.1" globby "^11.0.1" is-glob "^4.0.1" @@ -1759,35 +1789,40 @@ dependencies: eslint-visitor-keys "^1.1.0" -"@typescript-eslint/visitor-keys@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.12.0.tgz#a470a79be6958075fa91c725371a83baf428a67a" - integrity sha512-hVpsLARbDh4B9TKYz5cLbcdMIOAoBYgFPCSP9FFS/liSF+b33gVNq8JHY3QGhHNVz85hObvL7BEYLlgx553WCw== +"@typescript-eslint/visitor-keys@4.13.0": + version "4.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.13.0.tgz#9acb1772d3b3183182b6540d3734143dce9476fe" + integrity sha512-6RoxWK05PAibukE7jElqAtNMq+RWZyqJ6Q/GdIxaiUj2Ept8jh8+FUVlbq9WxMYxkmEOPvCE5cRSyupMpwW31g== dependencies: - "@typescript-eslint/types" "4.12.0" + "@typescript-eslint/types" "4.13.0" eslint-visitor-keys "^2.0.0" +"@ungap/global-this@^0.4.2": + version "0.4.4" + resolved "https://registry.yarnpkg.com/@ungap/global-this/-/global-this-0.4.4.tgz#8a1b2cfcd3e26e079a847daba879308c924dd695" + integrity sha512-mHkm6FvepJECMNthFuIgpAEFmPOk71UyXuIxYfjytvFTnSDBIz7jmViO+LfHI/AjrazWije0PnSP3+/NlwzqtA== + "@vue/babel-helper-vue-jsx-merge-props@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.2.1.tgz#31624a7a505fb14da1d58023725a4c5f270e6a81" integrity sha512-QOi5OW45e2R20VygMSNhyQHvpdUwQZqGPc748JLGCYEy+yp8fNFNdbNIGAgZmi9e+2JHPd6i6idRuqivyicIkA== -"@vue/babel-helper-vue-transform-on@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.0.0.tgz#8cbec6bbcae53626ad70139061be5e73403c9a62" - integrity sha512-svFuKPoXP92TJ76ztENOglOsLjcMGUXkdeQhYDxl6KBnZCpqFjqx6RodUPWFg1bj4zsUVsfoIh1RibLO86fUUQ== +"@vue/babel-helper-vue-transform-on@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.0.2.tgz#9b9c691cd06fc855221a2475c3cc831d774bc7dc" + integrity sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA== "@vue/babel-plugin-jsx@^1.0.0-0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.0.1.tgz#8ece4e521888fabe2c96adca428606e5cea55f54" - integrity sha512-pE1YlINZBzqaLeSNfrvo0nNvYjtWTBU+sXUrx65sLW7DL+nDCZcAVeVkMFDcpT1jIahx4hI3EzOcGZE6oLPLoA== + version "1.0.2" + resolved "https://registry.yarnpkg.com/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.0.2.tgz#6bfd8e39c48e53391a56705649f81a35fe20b6a1" + integrity sha512-1uZlQCLCeuqJgDYLCmg3qfsvTVtOQiXh278ES4bvPTYYbv2Bi/rElLETK6AdjI9xxzyTUf5n1QEiH8Xxz0eZrg== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/plugin-syntax-jsx" "^7.0.0" "@babel/template" "^7.0.0" "@babel/traverse" "^7.0.0" "@babel/types" "^7.0.0" - "@vue/babel-helper-vue-transform-on" "^1.0.0" + "@vue/babel-helper-vue-transform-on" "^1.0.2" camelcase "^6.0.0" html-tags "^3.1.0" svg-tags "^1.0.0" @@ -2271,6 +2306,13 @@ "@types/node" ">=6" tslib "^1.9.3" +"@wry/context@^0.5.2": + version "0.5.3" + resolved "https://registry.yarnpkg.com/@wry/context/-/context-0.5.3.tgz#537db8a5b51f98507dc38f869b3a48c672f48942" + integrity sha512-n0uKHiWpf2ArHhmcHcUsKA+Dj0gtye/h56VmsDcoMRuK/ZPFeHKi8ck5L/ftqtF12ZbQR9l8xMPV7y+xybaRDA== + dependencies: + tslib "^1.14.1" + "@wry/equality@^0.1.2": version "0.1.11" resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.1.11.tgz#35cb156e4a96695aa81a9ecc4d03787bc17f1790" @@ -2278,6 +2320,20 @@ dependencies: tslib "^1.9.3" +"@wry/equality@^0.3.0": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.3.1.tgz#81080cdc2e0d8265cd303faa0c64b38a77884e06" + integrity sha512-8/Ftr3jUZ4EXhACfSwPIfNsE8V6WKesdjp+Dxi78Bej6qlasAxiz0/F8j0miACRj9CL4vC5Y5FsfwwEYAuhWbg== + dependencies: + tslib "^1.14.1" + +"@wry/trie@^0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@wry/trie/-/trie-0.2.1.tgz#4191e1d4a85dd77dfede383d65563138ed82fc47" + integrity sha512-sYkuXZqArky2MLQCv4tLW6hX3N8AfTZ5ZMBc8jC6Yy35WYr82UYLLtjS7k/uRGHOA0yTSjuNadG6QQ6a5CS5hQ== + dependencies: + tslib "^1.14.1" + "@xtuc/ieee754@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" @@ -2485,15 +2541,12 @@ anymatch@~3.1.1: picomatch "^2.0.4" apollo-absinthe-upload-link@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/apollo-absinthe-upload-link/-/apollo-absinthe-upload-link-1.6.0.tgz#f5ef9f4959947abdc1b1f76c5e4a4fae2fdd2866" - integrity sha512-nzxgVbP72btvC1bFpVDuYXPkLNsZa6z3GJvwOLzvBNm42AWhE9usupbdw99yGC37FIDOPza6mAFBg0qiDaEFQA== + version "1.7.0" + resolved "https://registry.yarnpkg.com/apollo-absinthe-upload-link/-/apollo-absinthe-upload-link-1.7.0.tgz#74e76ef510cd6bbf24809f764220280c9e5179e9" + integrity sha512-Dt5R6OkN2xigCaN1WHjpgyf5M5Tx5wFJMF4zA4J72Bjd990ImXhoCT/Gs2Cl8S0lXchpP2BndJSJN7MrSJz2CA== dependencies: - apollo-client "^2.0.4" - apollo-link "^1.0.7" - apollo-link-http "^1.3.2" - apollo-link-http-common "^0.2.4" - graphql "0.11.3" + "@apollo/client" "^3.0.0" + graphql "^15.0.0" rxjs "~6.2.2" apollo-cache-inmemory@^1.6.6: @@ -2515,7 +2568,7 @@ apollo-cache@1.3.5, apollo-cache@^1.3.5: apollo-utilities "^1.3.4" tslib "^1.10.0" -apollo-client@^2.0.4, apollo-client@^2.6.10: +apollo-client@^2.6.10: version "2.6.10" resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.6.10.tgz#86637047b51d940c8eaa771a4ce1b02df16bea6a" integrity sha512-jiPlMTN6/5CjZpJOkGeUV0mb4zxx33uXWdj/xQCfAMkuNAC3HN7CvYDyMHHEzmcQ5GV12LszWoQ/VlxET24CtA== @@ -2538,7 +2591,7 @@ apollo-link-error@^1.1.13: apollo-link-http-common "^0.2.16" tslib "^1.9.3" -apollo-link-http-common@^0.2.16, apollo-link-http-common@^0.2.4: +apollo-link-http-common@^0.2.16: version "0.2.16" resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.16.tgz#756749dafc732792c8ca0923f9a40564b7c59ecc" integrity sha512-2tIhOIrnaF4UbQHf7kjeQA/EmSorB7+HyJIIrUjJOKBgnXwuexi8aMecRlqTIDWcyVXCeqLhUnztMa6bOH/jTg== @@ -2547,7 +2600,7 @@ apollo-link-http-common@^0.2.16, apollo-link-http-common@^0.2.4: ts-invariant "^0.4.0" tslib "^1.9.3" -apollo-link-http@^1.3.2, apollo-link-http@^1.5.17: +apollo-link-http@^1.5.17: version "1.5.17" resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.17.tgz#499e9f1711bf694497f02c51af12d82de5d8d8ba" integrity sha512-uWcqAotbwDEU/9+Dm9e1/clO7hTB2kQ/94JYcGouBVLjoKmTeJTUPQKcJGpPwUjZcSqgYicbFqQSoJIW0yrFvg== @@ -2572,7 +2625,7 @@ apollo-link@1.2.5: apollo-utilities "^1.0.0" zen-observable-ts "^0.8.12" -apollo-link@^1.0.0, apollo-link@^1.0.7, apollo-link@^1.2.14: +apollo-link@^1.0.0, apollo-link@^1.2.14: version "1.2.14" resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.14.tgz#3feda4b47f9ebba7f4160bef8b977ba725b684d9" integrity sha512-p67CMEFP7kOG1JZ0ZkYZwRDa369w5PIjtMjvrQd/HnIV8FRsHRqLqK+oAZQnFa1DDdZtOtHTi+aMIW6EatC2jg== @@ -3184,7 +3237,7 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.0: +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.1: version "4.16.1" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.1.tgz#bf757a2da376b3447b800a16f0f1c96358138766" integrity sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA== @@ -3364,10 +3417,10 @@ cachedir@1.3.0: dependencies: os-homedir "^1.0.1" -call-bind@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.1.tgz#29aca9151f8ddcfd5b9b786898f005f425e88567" - integrity sha512-tvAvUwNcRikl3RVF20X9lsYmmepsovzTWeJiXjO0PkJp15uy/6xKFZOQtuiSULwYW+6ToZBprphCgWXC2dSgcQ== +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== dependencies: function-bind "^1.1.1" get-intrinsic "^1.0.2" @@ -3435,9 +3488,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001173: - version "1.0.30001174" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001174.tgz#0f2aca2153fd88ceb07a2bb982fc2acb787623c4" - integrity sha512-tqClL/4ThQq6cfFXH3oJL4rifFBeM6gTkphjao5kgwMaW9yn0tKgQLAEfKzDwj6HQWCB/aWo8kTFlSvIN8geEA== + version "1.0.30001178" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001178.tgz#3ad813b2b2c7d585b0be0a2440e1e233c6eabdbc" + integrity sha512-VtdZLC0vsXykKni8Uztx45xynytOi71Ufx9T8kHptSw9AL4dpqailUJJHavttuzUe1KYuBYtChiWv+BAb7mPmQ== capture-exit@^2.0.0: version "2.0.0" @@ -3500,9 +3553,9 @@ check-types@^8.0.3: integrity sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ== "chokidar@>=2.0.0 <4.0.0", chokidar@^3.3.0, chokidar@^3.4.1: - version "3.5.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.0.tgz#458a4816a415e9d3b3caa4faec2b96a6935a9e65" - integrity sha512-JgQM9JS92ZbFR4P90EvmzNpSGhpPBGBSj10PILeDyYFwp4h2/D9OM03wsJ4zW1fEp4ka2DGrnUeD7FuvQ2aZ2Q== + version "3.5.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" + integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== dependencies: anymatch "~3.1.1" braces "~3.0.2" @@ -3950,11 +4003,11 @@ copy-webpack-plugin@^5.1.1: webpack-log "^2.0.0" core-js-compat@^3.6.5, core-js-compat@^3.8.0: - version "3.8.2" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.8.2.tgz#3717f51f6c3d2ebba8cbf27619b57160029d1d4c" - integrity sha512-LO8uL9lOIyRRrQmZxHZFl1RV+ZbcsAkFWTktn5SmH40WgLtSNYN4m4W2v9ONT147PxBY/XrRhrWq8TlvObyUjQ== + version "3.8.3" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.8.3.tgz#9123fb6b9cad30f0651332dc77deba48ef9b0b3f" + integrity sha512-1sCb0wBXnBIL16pfFG1Gkvei6UzvKyTNYpiC41yrdjEv0UoJoq9E/abTMzyYJ6JpTkAj15dLjbqifIzEBDVvog== dependencies: - browserslist "^4.16.0" + browserslist "^4.16.1" semver "7.0.0" core-js@2.6.0: @@ -3968,9 +4021,9 @@ core-js@^2.4.0, core-js@^2.5.0: integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== core-js@^3.6.4, core-js@^3.6.5: - version "3.8.2" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.8.2.tgz#0a1fd6709246da9ca8eff5bb0cbd15fba9ac7044" - integrity sha512-FfApuSRgrR6G5s58casCBd9M2k+4ikuu4wbW6pJyYU7bd9zvFc9qf7vr5xmrZOhT9nn+8uwlH1oRR9jTnFoA3A== + version "3.8.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.8.3.tgz#c21906e1f14f3689f93abcc6e26883550dd92dd0" + integrity sha512-KPYXeVZYemC2TkNEkX/01I+7yd+nX3KddKwZ1Ww7SKWdI2wQprSgLmrTddT8nw92AjEklTsPBoSdQBhbI1bQ6Q== core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" @@ -4723,9 +4776,9 @@ ejs@^2.6.1: integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== electron-to-chromium@^1.3.634: - version "1.3.635" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.635.tgz#8d1591eeca6b257d380061a2c04f0b3cc6c9e33b" - integrity sha512-RRriZOLs9CpW6KTLmgBqyUdnY0QNqqWs0HOtuQGGEMizOTNNn1P7sGRBxARnUeLejOsgwjDyRqT3E/CSst02ZQ== + version "1.3.642" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.642.tgz#8b884f50296c2ae2a9997f024d0e3e57facc2b94" + integrity sha512-cev+jOrz/Zm1i+Yh334Hed6lQVOkkemk2wRozfMF4MtTR7pxf3r3L5Rbd7uX1zMcEqVJ7alJBnJL7+JffkC6FQ== elegant-spinner@^1.0.1: version "1.0.1" @@ -4777,10 +4830,10 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0: dependencies: once "^1.4.0" -enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.1, enhanced-resolve@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz#3b806f3bfafc1ec7de69551ef93cca46c1704126" - integrity sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ== +enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.1, enhanced-resolve@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" + integrity sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg== dependencies: graceful-fs "^4.1.2" memory-fs "^0.5.0" @@ -4824,7 +4877,7 @@ error-stack-parser@^2.0.2: dependencies: stackframe "^1.1.1" -es-abstract@^1.17.0-next.1, es-abstract@^1.17.2: +es-abstract@^1.17.2: version "1.17.7" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.7.tgz#a4de61b2f66989fc7421676c1cb9787573ace54c" integrity sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g== @@ -4842,22 +4895,24 @@ es-abstract@^1.17.0-next.1, es-abstract@^1.17.2: string.prototype.trimstart "^1.0.1" es-abstract@^1.18.0-next.1: - version "1.18.0-next.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.1.tgz#6e3a0a4bda717e5023ab3b8e90bec36108d22c68" - integrity sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA== + version "1.18.0-next.2" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.2.tgz#088101a55f0541f595e7e057199e27ddc8f3a5c2" + integrity sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw== dependencies: + call-bind "^1.0.2" es-to-primitive "^1.2.1" function-bind "^1.1.1" + get-intrinsic "^1.0.2" has "^1.0.3" has-symbols "^1.0.1" is-callable "^1.2.2" - is-negative-zero "^2.0.0" + is-negative-zero "^2.0.1" is-regex "^1.1.1" - object-inspect "^1.8.0" + object-inspect "^1.9.0" object-keys "^1.1.1" - object.assign "^4.1.1" - string.prototype.trimend "^1.0.1" - string.prototype.trimstart "^1.0.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.3" + string.prototype.trimstart "^1.0.3" es-to-primitive@^1.2.1: version "1.2.1" @@ -4908,9 +4963,9 @@ eslint-config-prettier@^6.0.0: get-stdin "^6.0.0" eslint-config-prettier@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-7.1.0.tgz#5402eb559aa94b894effd6bddfa0b1ca051c858f" - integrity sha512-9sm5/PxaFG7qNJvJzTROMM1Bk1ozXVTKI0buKOyb0Bsr1hrwi0H/TzxF/COtf1uxikIK8SwhX7K6zg78jAzbeA== + version "7.2.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-7.2.0.tgz#f4a4bd2832e810e8cc7c1411ec85b3e85c0c53f9" + integrity sha512-rV4Qu0C3nfJKPOAhFujFxB7RMP+URFyQqqOZW9DMRD7ZDTFyjaIlETU3xzHELt++4ugC0+Jm084HQYkkJe+Ivg== eslint-loader@^2.2.1: version "2.2.1" @@ -4981,12 +5036,12 @@ eslint-visitor-keys@^2.0.0: integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== eslint@^7.7.0, eslint@^7.9.0: - version "7.17.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.17.0.tgz#4ccda5bf12572ad3bf760e6f195886f50569adb0" - integrity sha512-zJk08MiBgwuGoxes5sSQhOtibZ75pz0J35XTRlZOk9xMffhpA9BTbQZxoXZzOl5zMbleShbGwtw+1kGferfFwQ== + version "7.18.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.18.0.tgz#7fdcd2f3715a41fe6295a16234bd69aed2c75e67" + integrity sha512-fbgTiE8BfUJZuBeq2Yi7J3RB3WGUQ9PNuNbmgi6jt9Iv8qrkxfy19Ds3OpL1Pm7zg3BtTVhvcUZbIRQ0wmSjAQ== dependencies: "@babel/code-frame" "^7.0.0" - "@eslint/eslintrc" "^0.2.2" + "@eslint/eslintrc" "^0.3.0" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -5010,7 +5065,7 @@ eslint@^7.7.0, eslint@^7.9.0: js-yaml "^3.13.1" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" - lodash "^4.17.19" + lodash "^4.17.20" minimatch "^3.0.4" natural-compare "^1.4.0" optionator "^0.9.1" @@ -5368,9 +5423,9 @@ fast-glob@^2.2.6: micromatch "^3.1.10" fast-glob@^3.1.1: - version "3.2.4" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" - integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ== + version "3.2.5" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" + integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -5583,9 +5638,9 @@ flat-cache@^3.0.4: rimraf "^3.0.2" flatted@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.0.tgz#a5d06b4a8b01e3a63771daa5cb7a1903e2e57067" - integrity sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA== + version "3.1.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" + integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== flow-static-land@0.2.7: version "0.2.7" @@ -5725,14 +5780,14 @@ fs-extra@^8.1.0: universalify "^0.1.0" fs-extra@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" - integrity sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ== + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== dependencies: at-least-node "^1.0.0" graceful-fs "^4.2.0" jsonfile "^6.0.1" - universalify "^1.0.0" + universalify "^2.0.0" fs-minipass@^2.0.0: version "2.1.0" @@ -5997,18 +6052,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== -graphql-tag@^2.10.3: +graphql-tag@^2.10.3, graphql-tag@^2.11.0: version "2.11.0" resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.11.0.tgz#1deb53a01c46a7eb401d6cb59dec86fa1cccbffd" integrity sha512-VmsD5pJqWJnQZMUeRwrDhfgoyqcfwEkvtpANqcoUG8/tOLkwNgU9mzub/Mc78OJMhHjx7gfAMTxzdG43VGg3bA== -graphql@0.11.3: - version "0.11.3" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.11.3.tgz#9934e2df28f17d397a85f83cb39d1d179bffef47" - integrity sha512-/WGU673BlQaCw3gDECmqL5+l8kg4Sm3XHvuzPtZLiI/y8Xm7fKq+C0mtJmAImuHJvTBsMtCuX/R9BUQqPm4tzw== - dependencies: - iterall "^1.1.0" - graphql@14.0.2: version "14.0.2" resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.0.2.tgz#7dded337a4c3fd2d075692323384034b357f5650" @@ -6168,6 +6216,13 @@ hmac-drbg@^1.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" +hoist-non-react-statics@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + homedir-polyfill@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" @@ -6772,7 +6827,7 @@ is-module@^1.0.0: resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE= -is-negative-zero@^2.0.0: +is-negative-zero@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== @@ -6987,7 +7042,7 @@ istanbul-reports@^2.2.6: dependencies: html-escaper "^2.0.0" -iterall@^1.1.0, iterall@^1.2.2: +iterall@^1.2.2: version "1.3.0" resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.3.0.tgz#afcb08492e2915cbd8a0884eb93a8c94d0d72fea" integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg== @@ -7427,9 +7482,9 @@ js-base64@^2.1.9: integrity sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ== js-beautify@^1.6.12, js-beautify@^1.6.14: - version "1.13.1" - resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.13.1.tgz#5b9879672beaaa26d0dc25b8fd9a52944e2985e8" - integrity sha512-RGc3cSmQR3xPzTtIFAMwHK0R84MwDNpxpZgoQGySGdzShfNjBjHXqz99kMFwXDGlMSFVJVlsUXBFfqKUzJbzUg== + version "1.13.4" + resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.13.4.tgz#1cad80b9e89cfc455b3a14f0eaf4dc10b6ae1206" + integrity sha512-M5yEWwonlEO3kPcCZ3K3KBSpFRZAEO3FAWC6wtbIGeyg7dusStxvF0WG+HRLBoMZqREXSRSxkkqClDE865x1sg== dependencies: config-chain "^1.1.12" editorconfig "^0.15.3" @@ -7958,7 +8013,7 @@ loglevel@^1.4.1, loglevel@^1.6.8: resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw== -loose-envify@^1.0.0: +loose-envify@^1.0.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -8204,9 +8259,9 @@ mime@1.6.0: integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== mime@^2.4.4: - version "2.4.7" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.7.tgz#962aed9be0ed19c91fd7dc2ece5d7f4e89a90d74" - integrity sha512-dhNd1uA2u397uQk3Nv5LM4lm93WYDUXFn3Fu291FJerns4jyTudqhIWe4W04YLy7Uk1tm1Ore04NpjRvQp/NPA== + version "2.5.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.0.tgz#2b4af934401779806ee98026bb42e8c1ae1876b1" + integrity sha512-ft3WayFSFUVBuJj7BMLKAQcSlItKtfjsKDDsii3rqFDAZ7t11zRe8ASw/GlmivGwVUYtwkQrxiGGpL6gFvB0ag== mimic-fn@^1.0.0: version "1.2.0" @@ -8336,10 +8391,10 @@ mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -mock-apollo-client@^0.4: - version "0.4.0" - resolved "https://registry.yarnpkg.com/mock-apollo-client/-/mock-apollo-client-0.4.0.tgz#556a6090b1816dbf07e51093b652aca84aee979e" - integrity sha512-cHznpkX8uUClkWWJMpgdDWzEgjacM85xt69S9gPLrssM8Vahas0QmEJkFUycrRQyBkaqxvRe58Bg3a5pOvj2zA== +mock-apollo-client@^0.5: + version "0.5.0" + resolved "https://registry.yarnpkg.com/mock-apollo-client/-/mock-apollo-client-0.5.0.tgz#8f0d6a1ba0d349ebde87a1dcd85c7fd353076922" + integrity sha512-qdMUt1NhmNXLjHd/IaHbvbX5LaEE91WZB4glfj7AfUUs413/z148kBuXKg6XpMZqvJr+XdR/9i1V+YGY7UnCKA== moment@2.24.0: version "2.24.0" @@ -8537,9 +8592,9 @@ node-notifier@^5.4.2: which "^1.3.0" node-releases@^1.1.69: - version "1.1.69" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.69.tgz#3149dbde53b781610cd8b486d62d86e26c3725f6" - integrity sha512-DGIjo79VDEyAnRlfSqYTsy+yoHd2IOjJiKUozD2MV2D85Vso6Bug56mb9tT/fY5Urt0iqk01H7x+llAruDR2zA== + version "1.1.70" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.70.tgz#66e0ed0273aa65666d7fe78febe7634875426a08" + integrity sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw== nopt@^5.0.0: version "5.0.0" @@ -8655,7 +8710,7 @@ object-hash@^1.1.4: resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== -object-inspect@^1.8.0: +object-inspect@^1.8.0, object-inspect@^1.9.0: version "1.9.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== @@ -8680,7 +8735,7 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" -object.assign@^4.1.0, object.assign@^4.1.1: +object.assign@^4.1.0, object.assign@^4.1.1, object.assign@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== @@ -8785,6 +8840,14 @@ optimism@^0.10.0: dependencies: "@wry/context" "^0.4.0" +optimism@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.14.0.tgz#256fb079a3428585b40a3a8462f907e0abd2fc49" + integrity sha512-ygbNt8n4DOCVpkwiLF+IrKKeNHOjtr9aXLWGP9HNJGoblSGsnVbJLstcH6/nE9Xy5ZQtlkSioFQNnthmENW6FQ== + dependencies: + "@wry/context" "^0.5.2" + "@wry/trie" "^0.2.1" + optionator@^0.8.1: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" @@ -8978,9 +9041,9 @@ parse-json@^4.0.0: json-parse-better-errors "^1.0.1" parse-json@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.1.0.tgz#f96088cdf24a8faa9aea9a009f2d9d942c999646" - integrity sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ== + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== dependencies: "@babel/code-frame" "^7.0.0" error-ex "^1.3.1" @@ -9196,7 +9259,7 @@ pnp-webpack-plugin@^1.6.4: dependencies: ts-pnp "^1.1.6" -popper.js@^1.15.0: +popper.js@^1.16.0: version "1.16.1" resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== @@ -9734,6 +9797,15 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" +prop-types@^15.7.2: + version "15.7.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.8.1" + prosemirror-collab@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/prosemirror-collab/-/prosemirror-collab-1.2.2.tgz#8d2c0e82779cfef5d051154bd0836428bd6d9c4a" @@ -9741,7 +9813,7 @@ prosemirror-collab@^1.2.2: dependencies: prosemirror-state "^1.0.0" -prosemirror-commands@1.1.4, prosemirror-commands@^1.1.4: +prosemirror-commands@1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.1.4.tgz#991563e67623acab4f8c510fad1570f8b4693780" integrity sha512-kj4Qi+8h3EpJtZuuEDwZ9h2/QNGWDsIX/CzjmClxi9GhxWyBUMVUvIFk0mgdqHyX20lLeGmOpc0TLA5aPzgpWg== @@ -9750,6 +9822,15 @@ prosemirror-commands@1.1.4, prosemirror-commands@^1.1.4: prosemirror-state "^1.0.0" prosemirror-transform "^1.0.0" +prosemirror-commands@^1.1.4: + version "1.1.5" + resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.1.5.tgz#3f07a5b13e424ad8728168b6b45e1b17e47c2b81" + integrity sha512-4CKAnDxLTtUHpjRZZVEF/LLMUYh7NbS3Ze3mP5UEAgar4WRWQYg3Js01wnp/GMqaZueNHhsp9UVvOrAK+7DWbQ== + dependencies: + prosemirror-model "^1.0.0" + prosemirror-state "^1.0.0" + prosemirror-transform "^1.0.0" + prosemirror-dropcursor@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/prosemirror-dropcursor/-/prosemirror-dropcursor-1.3.2.tgz#28738c4ed7102e814d7a8a26d70018523fc7cd6d" @@ -9794,10 +9875,10 @@ prosemirror-keymap@1.1.4, prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.2: prosemirror-state "^1.0.0" w3c-keyname "^2.2.0" -prosemirror-model@1.13.1, prosemirror-model@1.9.1, prosemirror-model@^1.0.0, prosemirror-model@^1.1.0, prosemirror-model@^1.13.1, prosemirror-model@^1.8.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.9.1.tgz#8c08cf556f593c5f015548d2c1a6825661df087f" - integrity sha512-Qblh8pm1c7Ll64sYLauwwzjimo/tFg1zW3Q3IWhKRhvfOEgRKqa6dC5pRrAa+XHOIjBFEYrqbi52J5bqA2dV8Q== +prosemirror-model@1.13.1, prosemirror-model@^1.0.0, prosemirror-model@^1.1.0, prosemirror-model@^1.13.1, prosemirror-model@^1.8.1: + version "1.13.1" + resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.13.1.tgz#fa3dc888cf6928bd3968620588ffe6458d201f9f" + integrity sha512-PNH+b5bilAJi1B5yJ8QzoNY3ZV+nlD0jKG3XCBk7PmE/YUTJomBkFBS005vfU+3M9yeVR8/6spAEDsfVFUhNeQ== dependencies: orderedmap "^1.1.0" @@ -9829,9 +9910,9 @@ prosemirror-tables@^1.1.1: prosemirror-view "^1.13.3" prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transform@^1.2.1, prosemirror-transform@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/prosemirror-transform/-/prosemirror-transform-1.2.8.tgz#4b86544fa43637fe381549fb7b019f4fb71fe65c" - integrity sha512-hKqceqv9ZmMQXNQkhFjr0KFGPvkhygaWND+uIM0GxRpALrKfxP97SsgHTBs3OpJhDmh5N+mB4D/CksB291Eavg== + version "1.2.9" + resolved "https://registry.yarnpkg.com/prosemirror-transform/-/prosemirror-transform-1.2.9.tgz#dfa048102c12a457deaf4c60ae633ac3eaacc7c9" + integrity sha512-oiocfgn7J7Fulvl7luBsyxdAf0CJp96+0FIcqhHSvYVr/R4KqZNxXcU9xESaI9Xw+tTvDUiiS3gedVk3AOic4w== dependencies: prosemirror-model "^1.0.0" @@ -9850,9 +9931,9 @@ prosemirror-view@1.16.5: prosemirror-transform "^1.1.0" prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.16.5: - version "1.17.1" - resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.17.1.tgz#468616c889d33bc268a9b57451a49acbfebe942f" - integrity sha512-n56IjZoJKEQYTh43KVmXMwJPQ+q4jEoPK7vhrb86Q//NxvNdzXWBPM0O8RhMD0wZBZS87WA+TQbftLq4p9WGrg== + version "1.17.2" + resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.17.2.tgz#666c865ae79e129a8933112bdcdf218a42c5a3b5" + integrity sha512-8jHmdl1q/Mvjfv185I5FldBitkkVpNOIK0Z/jIuan4cZIqXRpKu7DxxeLrTouJDzgrf1kWvfG/szEb6Bg9/4dA== dependencies: prosemirror-model "^1.1.0" prosemirror-state "^1.0.0" @@ -10011,7 +10092,7 @@ raw-body@2.4.0: iconv-lite "0.4.24" unpipe "1.0.0" -react-is@^16.8.4: +react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -10141,12 +10222,12 @@ regex-not@^1.0.0, regex-not@^1.0.2: safe-regex "^1.1.0" regexp.prototype.flags@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" - integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ== + version "1.3.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" + integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" regexpp@^3.0.0, regexpp@^3.1.0: version "3.1.0" @@ -10555,9 +10636,9 @@ sane@^4.0.3: walker "~1.0.5" sass-loader@^10.0.1: - version "10.1.0" - resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.1.0.tgz#1727fcc0c32ab3eb197cda61d78adf4e9174a4b3" - integrity sha512-ZCKAlczLBbFd3aGAhowpYEy69Te3Z68cg8bnHHl6WnSCvnKpbM6pQrz957HWMa8LKVuhnD9uMplmMAHwGQtHeg== + version "10.1.1" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.1.1.tgz#4ddd5a3d7638e7949065dd6e9c7c04037f7e663d" + integrity sha512-W6gVDXAd5hR/WHsPicvZdjAWHBcEJ44UahgxcIE196fW2ong0ZHMPO1kZuI5q0VlvMQZh32gpv69PLWQm70qrw== dependencies: klona "^2.0.4" loader-utils "^2.0.0" @@ -10566,9 +10647,9 @@ sass-loader@^10.0.1: semver "^7.3.2" sass@^1.29.0: - version "1.32.2" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.32.2.tgz#66dc0250bc86c15d19ddee7135e93d0cf3d3257b" - integrity sha512-u1pUuzqwz3SAgvHSWp1k0mRhX82b2DdlVnP6UIetQPZtYbuJUDaPQhZE12jyjB7vYeOScfz9WPsZJB6Rpk7heA== + version "1.32.5" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.32.5.tgz#2882d22ad5748c05fa9bff6c3b0ffbc4f4b9e1dc" + integrity sha512-kU1yJ5zUAmPxr7f3q0YXTAd1oZjSR1g3tYyv+xu0HZSl5JiNOaE987eiz7wCUvbm4I9fGWGU2TgApTtcP4GMNQ== dependencies: chokidar ">=2.0.0 <4.0.0" @@ -10884,10 +10965,10 @@ sort-keys@^1.0.0: dependencies: is-plain-obj "^1.0.0" -sortablejs@^1.10.1: - version "1.13.0" - resolved "https://registry.yarnpkg.com/sortablejs/-/sortablejs-1.13.0.tgz#3ab2473f8c69ca63569e80b1cd1b5669b51269e9" - integrity sha512-RBJirPY0spWCrU5yCmWM1eFs/XgX2J5c6b275/YyxFRgnzPhKl/TDeU2hNR8Dt7ITq66NRPM4UlOt+e5O4CFHg== +sortablejs@1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/sortablejs/-/sortablejs-1.10.2.tgz#6e40364d913f98b85a14f6678f92b5c1221f5290" + integrity sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A== source-list-map@^2.0.0: version "2.0.1" @@ -11157,7 +11238,7 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" -string.prototype.trimend@^1.0.1: +string.prototype.trimend@^1.0.1, string.prototype.trimend@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz#a22bd53cca5c7cf44d7c9d5c732118873d6cd18b" integrity sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw== @@ -11165,7 +11246,7 @@ string.prototype.trimend@^1.0.1: call-bind "^1.0.0" define-properties "^1.1.3" -string.prototype.trimstart@^1.0.1: +string.prototype.trimstart@^1.0.1, string.prototype.trimstart@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz#9b4cb590e123bb36564401d59824298de50fd5aa" integrity sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg== @@ -11388,6 +11469,11 @@ symbol-observable@^1.0.2: resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== +symbol-observable@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-2.0.3.tgz#5b521d3d07a43c351055fa43b8355b62d33fd16a" + integrity sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA== + symbol-tree@^3.2.2: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" @@ -11565,7 +11651,7 @@ tiptap-commands@^1.16.0: prosemirror-utils "^0.9.6" tiptap-utils "^1.12.0" -tiptap-extensions@^1.29.1: +tiptap-extensions@^1.34.0: version "1.34.0" resolved "https://registry.yarnpkg.com/tiptap-extensions/-/tiptap-extensions-1.34.0.tgz#59889315ebb843c2b7a7326090a0f5ec13873bd0" integrity sha512-aKTGGPW6dWdVQfyXnuG4KLF+wWE5h7RZYCY72VkaybE1xft2lVcMvWl5G1wi4mvo9RVZYR8SJSGFzLsWLetOkg== @@ -11593,7 +11679,7 @@ tiptap-utils@^1.12.0: prosemirror-tables "^1.1.1" prosemirror-utils "^0.9.6" -tiptap@^1.26.0, tiptap@^1.31.0: +tiptap@^1.31.0: version "1.31.0" resolved "https://registry.yarnpkg.com/tiptap/-/tiptap-1.31.0.tgz#298775603b5e16afe36448c486a2bd1e63ffa690" integrity sha512-FY0juyY7yQwASvGKzle9ndCXlqMzBHZxUQDx2ybI8ghWVNavkMWUUDa+QGbscITYlQc2y43G0QEOqhzzZGLZ7g== @@ -11734,6 +11820,15 @@ ts-invariant@^0.4.0: dependencies: tslib "^1.9.3" +ts-invariant@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.6.0.tgz#44066ecfeb7a806ff1c3b0b283408a337a885412" + integrity sha512-caoafsfgb8QxdrKzFfjKt627m4i8KTtfAiji0DYJfWI4A/S9ORNNpzYuD9br64kyKFgxn9UNaLLbSupam84mCA== + dependencies: + "@types/ungap__global-this" "^0.3.1" + "@ungap/global-this" "^0.4.2" + tslib "^1.9.3" + ts-jest@^24.2.0: version "24.3.0" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.3.0.tgz#b97814e3eab359ea840a1ac112deae68aa440869" @@ -11776,7 +11871,7 @@ tsconfig@^7.0.0: strip-bom "^3.0.0" strip-json-comments "^2.0.0" -tslib@^1.10.0, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: +tslib@^1.10.0, tslib@^1.14.1, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== @@ -11975,11 +12070,6 @@ universalify@^0.1.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== -universalify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d" - integrity sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug== - universalify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" @@ -12130,14 +12220,14 @@ uuid@^3.3.2, uuid@^3.3.3, uuid@^3.4.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== -v-tooltip@2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/v-tooltip/-/v-tooltip-2.0.2.tgz#8610d9eece2cc44fd66c12ef2f12eec6435cab9b" - integrity sha512-xQ+qzOFfywkLdjHknRPgMMupQNS8yJtf9Utd5Dxiu/0n4HtrxqsgDtN2MLZ0LKbburtSAQgyypuE/snM8bBZhw== +v-tooltip@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/v-tooltip/-/v-tooltip-2.1.2.tgz#5d3cd0c13eecdd365a0ad734b2f6c938bc8f7885" + integrity sha512-6c4NotnvDvinmZnBiqW50Rn6Q3MMk+pUV9Nla+JHkgJulgXh5snrU3RYbIZVf9p2ZlFoaZL/3QhTNgcQIc2GFQ== dependencies: - lodash "^4.17.11" - popper.js "^1.15.0" - vue-resize "^0.4.5" + lodash "^4.17.15" + popper.js "^1.16.0" + vue-resize "^1.0.0" v8-compile-cache@^2.0.3, v8-compile-cache@^2.1.1: version "2.2.0" @@ -12242,9 +12332,9 @@ vue-i18n-extract@^1.0.2: js-yaml "^3.14.0" vue-i18n@^8.14.0: - version "8.22.3" - resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-8.22.3.tgz#4ac0fdc3e71d4fe188938c40a9ffca32cde60732" - integrity sha512-Vhyx7sZEmmW/aZLkzSlXei08Rv3hTondx4J9wbOjnThocTIK1QiXV6QRdT4BTnhT24JixDSf6kGkxqCXSaJ3Jw== + version "8.22.4" + resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-8.22.4.tgz#255cbdab4ffa7337c5819b82dd171208af74e385" + integrity sha512-XLI5s0AdqMP2Lf4I4CmdmOq8kjb5DDFGR77wAuxCfpEuYSfhTRyyx6MetgZMiL6Lxa0DasjBOiOcciU3NkL3/Q== vue-jest@^3.0.5: version "3.0.7" @@ -12295,10 +12385,10 @@ vue-property-decorator@^9.0.0: resolved "https://registry.yarnpkg.com/vue-property-decorator/-/vue-property-decorator-9.1.2.tgz#266a2eac61ba6527e2e68a6933cfb98fddab5457" integrity sha512-xYA8MkZynPBGd/w5QFJ2d/NM0z/YeegMqYTphy7NJQXbZcuU6FC6AOdUAcy4SXP+YnkerC6AfH+ldg7PDk9ESQ== -vue-resize@^0.4.5: - version "0.4.5" - resolved "https://registry.yarnpkg.com/vue-resize/-/vue-resize-0.4.5.tgz#4777a23042e3c05620d9cbda01c0b3cc5e32dcea" - integrity sha512-bhP7MlgJQ8TIkZJXAfDf78uJO+mEI3CaLABLjv0WNzr4CcGRGPIAItyWYnP6LsPA4Oq0WE+suidNs6dgpO4RHg== +vue-resize@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/vue-resize/-/vue-resize-1.0.0.tgz#380565b36e411190d85f8fbd3aa230a4cc22f1a5" + integrity sha512-SkIi19neeJClapYavfmHiewFZkkTfITVWskg/dIL8b1Eb+RlvnCb8fjGUwLjQJmsw2qsRiiAo4o7BAJVM4pcOA== vue-router@^3.1.6: version "3.4.9" @@ -12351,12 +12441,12 @@ vue@^2.0.0, vue@^2.6.11: resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.12.tgz#f5ebd4fa6bd2869403e29a896aed4904456c9123" integrity sha512-uhmLFETqPPNyuLLbsKz6ioJ4q7AZHzD8ZVFNATNyICSZouqP2Sz0rotWQC8UNBF6VGSCs5abnKJoStA6JbCbfg== -vuedraggable@2.23.2: - version "2.23.2" - resolved "https://registry.yarnpkg.com/vuedraggable/-/vuedraggable-2.23.2.tgz#0d95d7fdf4f02f56755a26b3c9dca5c7ca9cfa72" - integrity sha512-PgHCjUpxEAEZJq36ys49HfQmXglattf/7ofOzUrW2/rRdG7tu6fK84ir14t1jYv4kdXewTEa2ieKEAhhEMdwkQ== +vuedraggable@^2.24.3: + version "2.24.3" + resolved "https://registry.yarnpkg.com/vuedraggable/-/vuedraggable-2.24.3.tgz#43c93849b746a24ce503e123d5b259c701ba0d19" + integrity sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g== dependencies: - sortablejs "^1.10.1" + sortablejs "1.10.2" w3c-hr-time@^1.0.1: version "1.0.2" @@ -12479,9 +12569,9 @@ webpack-dev-middleware@^3.7.2: webpack-log "^2.0.0" webpack-dev-server@^3.11.0: - version "3.11.1" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.1.tgz#c74028bf5ba8885aaf230e48a20e8936ab8511f0" - integrity sha512-u4R3mRzZkbxQVa+MBWi2uVpB5W59H3ekZAJsQlKUTdl7Elcah2EhygTPLmeFXybQkf9i2+L0kn7ik9SnXa6ihQ== + version "3.11.2" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.2.tgz#695ebced76a4929f0d5de7fd73fafe185fe33708" + integrity sha512-A80BkuHRQfCiNtGBS1EMf2ChTUs0x+B3wGDFmOeT4rmJOHhHTCH2naNxIHhmkr0/UillP4U3yeIyv1pNp+QDLQ== dependencies: ansi-html "0.0.7" bonjour "^3.5.0" @@ -12541,9 +12631,9 @@ webpack-sources@^1.1.0, webpack-sources@^1.3.0, webpack-sources@^1.4.0, webpack- source-map "~0.6.1" webpack@^4.0.0: - version "4.45.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.45.0.tgz#bcdc1ddb43959adb47f8974e60d944027267c1be" - integrity sha512-JhDaVi4CbRcwLLAoqC7eugMSMJnZbIfE2AyjaZ19pnOIh/R2O/lXOiXA2tQFN0iXEcxgpPJsPJHW2wOWqiTLcw== + version "4.46.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.46.0.tgz#bf9b4404ea20a073605e0a011d188d77cb6ad542" + integrity sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q== dependencies: "@webassemblyjs/ast" "1.9.0" "@webassemblyjs/helper-module-context" "1.9.0" @@ -12553,7 +12643,7 @@ webpack@^4.0.0: ajv "^6.10.2" ajv-keywords "^3.4.1" chrome-trace-event "^1.0.2" - enhanced-resolve "^4.3.0" + enhanced-resolve "^4.5.0" eslint-scope "^4.0.3" json-parse-better-errors "^1.0.2" loader-runner "^2.4.0" @@ -13001,7 +13091,7 @@ zen-observable@0.8.11: resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.11.tgz#d3415885eeeb42ee5abb9821c95bb518fcd6d199" integrity sha512-N3xXQVr4L61rZvGMpWe8XoCGX8vhU35dPyQ4fm5CY/KDlG0F75un14hjbckPXTDuKUY6V0dqR2giT6xN8Y4GEQ== -zen-observable@^0.8.0: +zen-observable@^0.8.0, zen-observable@^0.8.14: version "0.8.15" resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15" integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ== diff --git a/lib/federation/activity_pub/activity_pub.ex b/lib/federation/activity_pub/activity_pub.ex index b9208c70..3cf17344 100644 --- a/lib/federation/activity_pub/activity_pub.ex +++ b/lib/federation/activity_pub/activity_pub.ex @@ -50,7 +50,6 @@ defmodule Mobilizon.Federation.ActivityPub do alias Mobilizon.Web.Endpoint alias Mobilizon.Web.Email.{Admin, Group, Mailer} - alias Mobilizon.Web.Email.Follow, as: FollowMailer require Logger @@ -320,13 +319,22 @@ defmodule Mobilizon.Federation.ActivityPub do @doc """ Make an actor follow another """ - def follow(%Actor{} = follower, %Actor{} = followed, activity_id \\ nil, local \\ true) do + def follow( + %Actor{} = follower, + %Actor{} = followed, + activity_id \\ nil, + local \\ true, + additional \\ %{} + ) do with {:different_actors, true} <- {:different_actors, followed.id != follower.id}, - {:ok, %Follower{} = follower} <- - Actors.follow(followed, follower, activity_id, false), - :ok <- FollowMailer.send_notification_to_admins(follower), - follower_as_data <- Convertible.model_to_as(follower), - {:ok, activity} <- create_activity(follower_as_data, local), + {:ok, activity_data, %Follower{} = follower} <- + Types.Actors.follow( + follower, + followed, + local, + Map.merge(additional, %{"activity_id" => activity_id}) + ), + {:ok, activity} <- create_activity(activity_data, local), :ok <- maybe_federate(activity) do {:ok, activity, follower} else diff --git a/lib/federation/activity_pub/transmogrifier.ex b/lib/federation/activity_pub/transmogrifier.ex index ddeec0af..620c2e74 100644 --- a/lib/federation/activity_pub/transmogrifier.ex +++ b/lib/federation/activity_pub/transmogrifier.ex @@ -302,6 +302,10 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do do_handle_incoming_accept_join(accepted_object, actor)} do {:ok, activity, object} else + {:object_not_found, {:error, "Follow already accepted"}} -> + Logger.info("Follow was already accepted. Ignoring.") + :error + {:object_not_found, nil} -> Logger.warn( "Unable to process Accept activity #{inspect(id)}. Object #{inspect(accepted_object)} wasn't found." @@ -761,6 +765,10 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do {:ok, activity, follow} else + {:follow, {:ok, %Follower{approved: true} = _follow}} -> + Logger.debug("Follow already accepted") + {:error, "Follow already accepted"} + {:follow, _} -> Logger.debug( "Tried to handle an Accept activity but it's not containing a Follow activity" @@ -770,9 +778,6 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do {:same_actor} -> {:error, "Actor who accepted the follow wasn't the target. Quite odd."} - - {:ok, %Follower{approved: true} = _follow} -> - {:error, "Follow already accepted"} end end diff --git a/lib/federation/activity_pub/types/actors.ex b/lib/federation/activity_pub/types/actors.ex index 7491d168..1e0cdc67 100644 --- a/lib/federation/activity_pub/types/actors.ex +++ b/lib/federation/activity_pub/types/actors.ex @@ -1,7 +1,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Actors do @moduledoc false alias Mobilizon.Actors - alias Mobilizon.Actors.{Actor, Member} + alias Mobilizon.Actors.{Actor, Follower, Member} alias Mobilizon.Federation.ActivityPub alias Mobilizon.Federation.ActivityPub.Audience alias Mobilizon.Federation.ActivityPub.Types.Entity @@ -9,6 +9,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Actors do alias Mobilizon.GraphQL.API.Utils, as: APIUtils alias Mobilizon.Service.Formatter.HTML alias Mobilizon.Service.Notifications.Scheduler + alias Mobilizon.Web.Email.Follow, as: FollowMailer alias Mobilizon.Web.Endpoint import Mobilizon.Federation.ActivityPub.Utils, only: [make_create_data: 2, make_update_data: 2] @@ -130,6 +131,15 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Actors do end end + def follow(%Actor{} = follower_actor, %Actor{} = followed, _local, additional) do + with {:ok, %Follower{} = follower} <- + Mobilizon.Actors.follow(followed, follower_actor, additional["activity_id"], false), + :ok <- FollowMailer.send_notification_to_admins(follower), + follower_as_data <- Convertible.model_to_as(follower) do + approve_if_manually_approves_followers(follower, follower_as_data) + end + end + defp prepare_args_for_actor(args) do args |> maybe_sanitize_username() @@ -189,4 +199,21 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Actors do {:ok, activity_data, member} end end + + defp approve_if_manually_approves_followers( + %Follower{} = follower, + follow_as_data + ) do + unless follower.target_actor.manually_approves_followers do + {:accept, + ActivityPub.accept( + :follow, + follower, + true, + %{"actor" => follower.actor.url} + )} + end + + {:ok, follow_as_data, follower} + end end diff --git a/lib/graphql/resolvers/followers.ex b/lib/graphql/resolvers/followers.ex new file mode 100644 index 00000000..950115a5 --- /dev/null +++ b/lib/graphql/resolvers/followers.ex @@ -0,0 +1,64 @@ +defmodule Mobilizon.GraphQL.Resolvers.Followers do + @moduledoc """ + Handles the followers-related GraphQL calls. + """ + + import Mobilizon.Users.Guards + alias Mobilizon.{Actors, Users} + alias Mobilizon.Actors.{Actor, Follower} + alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Storage.Page + alias Mobilizon.Users.User + + @spec find_followers_for_group(Actor.t(), map(), map()) :: {:ok, Page.t()} + def find_followers_for_group( + %Actor{id: group_id} = group, + %{page: page, limit: limit} = args, + %{ + context: %{ + current_user: %User{role: user_role} = user + } + } + ) do + with {:actor, %Actor{id: actor_id} = _actor} <- {:actor, Users.get_actor_for_user(user)}, + {:member, true} <- + {:member, Actors.is_moderator?(actor_id, group_id) or is_moderator(user_role)} do + {:ok, + Actors.list_paginated_followers_for_actor(group, Map.get(args, :approved), page, limit)} + else + _ -> {:error, :unauthorized} + end + end + + def find_followers_for_group(_, _, _), do: {:error, :unauthenticated} + + @spec update_follower(any(), map(), map()) :: {:ok, Follower.t()} | {:error, any()} + def update_follower(_, %{id: follower_id, approved: approved}, %{ + context: %{ + current_user: %User{} = user + } + }) do + with {:actor, %Actor{id: actor_id} = _actor} <- {:actor, Users.get_actor_for_user(user)}, + %Follower{target_actor: %Actor{type: :Group, id: group_id}} = follower <- + Actors.get_follower(follower_id), + {:member, true} <- + {:member, Actors.is_moderator?(actor_id, group_id)}, + {:ok, _activity, %Follower{} = follower} <- + (if approved do + ActivityPub.accept(:follow, follower) + else + ActivityPub.reject(:follow, follower) + end) do + {:ok, follower} + else + {:member, _} -> + {:error, :unauthorized} + + _ -> + {:error, + if(approved, do: "Unable to approve follower", else: "Unable to reject follower")} + end + end + + def update_follower(_, _, _), do: {:error, :unauthenticated} +end diff --git a/lib/graphql/resolvers/group.ex b/lib/graphql/resolvers/group.ex index 67e236a7..6c5ffe5c 100644 --- a/lib/graphql/resolvers/group.ex +++ b/lib/graphql/resolvers/group.ex @@ -26,8 +26,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do } } ) do - with {:ok, %Actor{id: group_id} = group} <- - ActivityPub.find_or_make_group_from_nickname(name), + with {:group, {:ok, %Actor{id: group_id} = group}} <- + {:group, ActivityPub.find_or_make_group_from_nickname(name)}, {:actor, %Actor{id: actor_id} = _actor} <- {:actor, Users.get_actor_for_user(user)}, {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)} do {:ok, group} @@ -35,8 +35,11 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do {:member, false} -> find_group(parent, args, nil) - _ -> + {:group, _} -> {:error, :group_not_found} + + _ -> + {:error, :unknown} end end diff --git a/lib/graphql/schema.ex b/lib/graphql/schema.ex index f22c886d..ceca7131 100644 --- a/lib/graphql/schema.ex +++ b/lib/graphql/schema.ex @@ -177,6 +177,7 @@ defmodule Mobilizon.GraphQL.Schema do import_fields(:resource_mutations) import_fields(:post_mutations) import_fields(:actor_mutations) + import_fields(:follower_mutations) end @desc """ diff --git a/lib/graphql/schema/actor.ex b/lib/graphql/schema/actor.ex index 1acad9f0..c2fd097b 100644 --- a/lib/graphql/schema/actor.ex +++ b/lib/graphql/schema/actor.ex @@ -32,8 +32,6 @@ defmodule Mobilizon.GraphQL.Schema.ActorInterface do field(:banner, :media, description: "The actor's banner media") # These one should have a privacy setting - field(:following, list_of(:follower), description: "List of followings") - field(:followers, list_of(:follower), description: "List of followers") field(:followersCount, :integer, description: "Number of followers for this actor") field(:followingCount, :integer, description: "Number of actors following this actor") diff --git a/lib/graphql/schema/actors/application.ex b/lib/graphql/schema/actors/application.ex index 9b89854b..4a8d98ba 100644 --- a/lib/graphql/schema/actors/application.ex +++ b/lib/graphql/schema/actors/application.ex @@ -31,8 +31,6 @@ defmodule Mobilizon.GraphQL.Schema.Actors.ApplicationType do field(:banner, :media, description: "The actor's banner media") # These one should have a privacy setting - field(:following, list_of(:follower), description: "List of followings") - field(:followers, list_of(:follower), description: "List of followers") field(:followersCount, :integer, description: "Number of followers for this actor") field(:followingCount, :integer, description: "Number of actors following this actor") diff --git a/lib/graphql/schema/actors/follower.ex b/lib/graphql/schema/actors/follower.ex index 99d70892..94da4335 100644 --- a/lib/graphql/schema/actors/follower.ex +++ b/lib/graphql/schema/actors/follower.ex @@ -3,11 +3,13 @@ defmodule Mobilizon.GraphQL.Schema.Actors.FollowerType do Schema representation for Follower """ use Absinthe.Schema.Notation + alias Mobilizon.GraphQL.Resolvers.Followers @desc """ Represents an actor's follower """ object :follower do + field(:id, :id, description: "The follow ID") field(:target_actor, :actor, description: "What or who the profile follows") field(:actor, :actor, description: "Which profile follows") @@ -26,4 +28,17 @@ defmodule Mobilizon.GraphQL.Schema.Actors.FollowerType do field(:elements, list_of(:follower), description: "A list of followers") field(:total, :integer, description: "The total number of elements in the list") end + + object :follower_mutations do + @desc "Update follower" + field :update_follower, :follower do + arg(:id, non_null(:id), description: "The follower ID") + + arg(:approved, non_null(:boolean), + description: "Whether the follower has been approved by the target actor or not" + ) + + resolve(&Followers.update_follower/3) + end + end end diff --git a/lib/graphql/schema/actors/group.ex b/lib/graphql/schema/actors/group.ex index ad1fc9de..90588e99 100644 --- a/lib/graphql/schema/actors/group.ex +++ b/lib/graphql/schema/actors/group.ex @@ -8,7 +8,18 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do import Absinthe.Resolution.Helpers, only: [dataloader: 1] alias Mobilizon.Addresses - alias Mobilizon.GraphQL.Resolvers.{Discussion, Group, Media, Member, Post, Resource, Todos} + + alias Mobilizon.GraphQL.Resolvers.{ + Discussion, + Followers, + Group, + Media, + Member, + Post, + Resource, + Todos + } + alias Mobilizon.GraphQL.Schema import_types(Schema.Actors.MemberType) @@ -47,8 +58,6 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do ) # These one should have a privacy setting - field(:following, list_of(:follower), description: "List of followings") - field(:followers, list_of(:follower), description: "List of followers") field(:followersCount, :integer, description: "Number of followers for this actor") field(:followingCount, :integer, description: "Number of actors following this actor") @@ -116,6 +125,23 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do resolve(&Todos.find_todo_lists_for_group/3) description("A paginated list of the todo lists this group has") end + + field :followers, :paginated_follower_list do + arg(:page, :integer, + default_value: 1, + description: "The page in the paginated followers list" + ) + + arg(:limit, :integer, default_value: 10, description: "The limit of followers per page") + + arg(:approved, :boolean, + default_value: nil, + description: "Used to filter the followers list by approved status" + ) + + resolve(&Followers.find_followers_for_group/3) + description("A paginated list of the followers this group has") + end end @desc """ @@ -232,6 +258,10 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do description: "Whether the group can be join freely, with approval or is invite-only." ) + arg(:manually_approves_followers, :boolean, + description: "Whether this group approves new followers manually" + ) + arg(:avatar, :media_input, description: "The avatar for the group, either as an object or directly the ID of an existing media" diff --git a/lib/graphql/schema/actors/person.ex b/lib/graphql/schema/actors/person.ex index bf6327a1..1ed2ce26 100644 --- a/lib/graphql/schema/actors/person.ex +++ b/lib/graphql/schema/actors/person.ex @@ -44,8 +44,6 @@ defmodule Mobilizon.GraphQL.Schema.Actors.PersonType do field(:banner, :media, description: "The actor's banner media") # These one should have a privacy setting - field(:following, list_of(:follower), description: "List of followings") - field(:followers, list_of(:follower), description: "List of followers") field(:followersCount, :integer, description: "Number of followers for this actor") field(:followingCount, :integer, description: "Number of actors following this actor") diff --git a/lib/mobilizon/actors/actors.ex b/lib/mobilizon/actors/actors.ex index d5e88d4d..763d2abb 100644 --- a/lib/mobilizon/actors/actors.ex +++ b/lib/mobilizon/actors/actors.ex @@ -1022,6 +1022,16 @@ defmodule Mobilizon.Actors do @spec list_bots :: [Bot.t()] def list_bots, do: Repo.all(Bot) + @doc """ + Gets a single follower. + """ + @spec get_follower(integer | String.t()) :: Follower.t() | nil + def get_follower(id) do + Follower + |> Repo.get(id) + |> Repo.preload([:actor, :target_actor]) + end + @doc """ Gets a single follower. Raises `Ecto.NoResultsError` if the follower does not exist. @@ -1149,6 +1159,25 @@ defmodule Mobilizon.Actors do |> Repo.aggregate(:count) end + @doc """ + Returns a paginated list of followers for an actor. + """ + @spec list_paginated_followers_for_actor(Actor.t(), boolean | nil, integer | nil, integer | nil) :: + Page.t() + def list_paginated_followers_for_actor( + %Actor{id: actor_id}, + approved \\ nil, + page \\ nil, + limit \\ nil + ) do + actor_id + |> follower_for_actor_query() + |> filter_followed_by_approved_status(approved) + |> order_by(desc: :updated_at) + |> preload([:actor, :target_actor]) + |> Page.build_page(page, limit) + end + @doc """ Returns the list of followings for an actor. If actor A follows actor B and C, actor A's followings are B and C. @@ -1688,6 +1717,13 @@ defmodule Mobilizon.Actors do from(a in query, where: a.preferred_username == ^name and a.domain == ^domain) end + @spec filter_by_name(Ecto.Query.t(), boolean | nil) :: Ecto.Query.t() + defp filter_followed_by_approved_status(query, nil), do: query + + defp filter_followed_by_approved_status(query, approved) do + from(f in query, where: f.approved == ^approved) + end + @spec preload_followers(Actor.t(), boolean) :: Actor.t() defp preload_followers(actor, true), do: Repo.preload(actor, [:followers]) defp preload_followers(actor, false), do: actor diff --git a/mix.exs b/mix.exs index c2d3e012..db83b30e 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule Mobilizon.Mixfile do use Mix.Project - @version "1.0.3" + @version "1.0.4" def project do [ @@ -104,11 +104,13 @@ defmodule Mobilizon.Mixfile do {:geolix, "~> 2.0"}, {:geolix_adapter_mmdb2, "~> 0.6.0"}, {:absinthe, "~> 1.6"}, - {:absinthe_phoenix, github: "tcitworld/absinthe_phoenix", branch: "patch-1"}, + {:absinthe_phoenix, + github: "absinthe-graphql/absinthe_phoenix", + ref: "67dc53db5b826ea12f37860bcce4334d4aaad028"}, {:absinthe_plug, "~> 1.5.0"}, {:dataloader, "~> 1.0.6"}, {:plug_cowboy, "~> 2.0"}, - {:atomex, "0.3.0"}, + {:atomex, github: "Betree/atomex"}, {:cachex, "~> 3.1"}, {:geohax, "~> 0.4.0"}, {:mogrify, "~> 0.8.0"}, @@ -135,7 +137,7 @@ defmodule Mobilizon.Mixfile do {:ecto_shortuuid, "~> 0.1"}, {:tesla, "~> 1.4.0"}, {:sitemapper, "~> 0.5.0"}, - {:xml_builder, "~> 2.1.1", override: true}, + {:xml_builder, "~> 2.1.1"}, {:remote_ip, "~> 0.2.0"}, {:ex_cldr_languages, "~> 0.2.1"}, {:slugger, "~> 0.3"}, diff --git a/mix.lock b/mix.lock index 57ebf8f3..5ac34e9f 100644 --- a/mix.lock +++ b/mix.lock @@ -1,10 +1,10 @@ %{ "absinthe": {:hex, :absinthe, "1.6.0", "7cb42eebbb9cbf5077541d73c189e205ebe12caf1c78372fc5b9e706fc8ac298", [:mix], [{:dataloader, "~> 1.0.0", [hex: :dataloader, repo: "hexpm", optional: true]}, {:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "99915841495522332b3af8ff10c9cbb51e256b28d9b19c0dfaac5f044b6bfb66"}, "absinthe_ecto": {:hex, :absinthe_ecto, "0.1.3", "420b68129e79fe4571a4838904ba03e282330d335da47729ad52ffd7b8c5fcb1", [:mix], [{:absinthe, "~> 1.3.0 or ~> 1.4.0", [hex: :absinthe, repo: "hexpm", optional: false]}, {:ecto, ">= 0.0.0", [hex: :ecto, repo: "hexpm", optional: false]}], "hexpm", "355b9db34abfab96ae1e025434b66e11002babcf4fe6b7144d26ff7548985f52"}, - "absinthe_phoenix": {:git, "https://github.com/tcitworld/absinthe_phoenix.git", "4759d4141fb6254f5e7726ad6a00d7618116fb9e", [branch: "patch-1"]}, + "absinthe_phoenix": {:git, "https://github.com/absinthe-graphql/absinthe_phoenix.git", "67dc53db5b826ea12f37860bcce4334d4aaad028", [ref: "67dc53db5b826ea12f37860bcce4334d4aaad028"]}, "absinthe_plug": {:hex, :absinthe_plug, "1.5.3", "40b62edddc7db94098ab2f4a3011c17189862a3dbc50580fc92e3cb7953e9b36", [:mix], [{:absinthe, "~> 1.5", [hex: :absinthe, repo: "hexpm", optional: false]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "8378204b9b0c1f37bd7a52ecde8fa627e553a8bf04610d20e1bce2dbde71fdb2"}, "argon2_elixir": {:hex, :argon2_elixir, "2.4.0", "2a22ea06e979f524c53b42b598fc6ba38cdcbc977a155e33e057732cfb1fb311", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "4ea82e183cf8e7f66dab1f767fedcfe6a195e140357ef2b0423146b72e0a551d"}, - "atomex": {:hex, :atomex, "0.3.0", "19b5d1a2aef8706dbd307385f7d5d9f6f273869226d317492c396c7bacf26402", [:mix], [{:xml_builder, "~> 2.0.0", [hex: :xml_builder, repo: "hexpm", optional: false]}], "hexpm", "025dbc3a3e99380894791a093019f535d0ef6cf1916f6ec1b778ac107fcfc3e4"}, + "atomex": {:git, "https://github.com/Betree/atomex.git", "d1cc0988fe9d2c5f4d1feb8c6a89b1ea2266199c", []}, "auto_linker": {:git, "https://git.pleroma.social/pleroma/auto_linker.git", "95e8188490e97505c56636c1379ffdf036c1fdde", [ref: "95e8188490e97505c56636c1379ffdf036c1fdde"]}, "bamboo": {:hex, :bamboo, "1.6.0", "adfb583bef028923aae6f22deaea6667290561da1246058556ecaeb0fec5a175", [:mix], [{:hackney, ">= 1.13.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "454e67feacbc9b6e00553ce1d2fba003c861e0035600d59b09d6159985b17f9b"}, "bamboo_smtp": {:hex, :bamboo_smtp, "3.0.0", "b7f0c371af96a1cb7131908918b02abb228f9db234910bf10cf4fb177c083259", [:mix], [{:bamboo, "~> 1.2", [hex: :bamboo, repo: "hexpm", optional: false]}, {:gen_smtp, "~> 0.15.0", [hex: :gen_smtp, repo: "hexpm", optional: false]}], "hexpm", "77cb1fa3076b24109e54df622161fe1e5619376b4ecf86d8b99b46f327acc49f"}, @@ -13,7 +13,7 @@ "certifi": {:hex, :certifi, "2.5.3", "70bdd7e7188c804f3a30ee0e7c99655bc35d8ac41c23e12325f36ab449b70651", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "ed516acb3929b101208a9d700062d520f3953da3b6b918d866106ffa980e1c10"}, "cldr_utils": {:hex, :cldr_utils, "2.14.0", "edcef8dd2654b93d84a90087f3536ffabf9c9d82b34ff82bc9ca54c0668b3a4a", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.5", [hex: :certifi, repo: "hexpm", optional: true]}, {:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "6903356ff6988342a29b90637eece4ca98a4ed2b9759c22233d3474ade57645a"}, "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"}, - "comeonin": {:hex, :comeonin, "5.3.1", "7fe612b739c78c9c1a75186ef2d322ce4d25032d119823269d0aa1e2f1e20025", [:mix], [], "hexpm", "d6222483060c17f0977fad1b7401ef0c5863c985a64352755f366aee3799c245"}, + "comeonin": {:hex, :comeonin, "5.3.2", "5c2f893d05c56ae3f5e24c1b983c2d5dfb88c6d979c9287a76a7feb1e1d8d646", [:mix], [], "hexpm", "d0993402844c49539aeadb3fe46a3c9bd190f1ecf86b6f9ebd71957534c95f04"}, "connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"}, "cors_plug": {:hex, :cors_plug, "2.0.2", "2b46083af45e4bc79632bd951550509395935d3e7973275b2b743bd63cc942ce", [:mix], [{:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "f0d0e13f71c51fd4ef8b2c7e051388e4dfb267522a83a22392c856de7e46465f"}, "cowboy": {:hex, :cowboy, "2.8.0", "f3dc62e35797ecd9ac1b50db74611193c29815401e53bac9a5c0577bd7bc667d", [:rebar3], [{:cowlib, "~> 2.9.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "4643e4fba74ac96d4d152c75803de6fad0b3fa5df354c71afdd6cbeeb15fac8a"}, @@ -22,7 +22,7 @@ "credo": {:hex, :credo, "1.5.4", "9914180105b438e378e94a844ec3a5088ae5875626fc945b7c1462b41afc3198", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "cf51af45eadc0a3f39ba13b56fdac415c91b34f7b7533a13dc13550277141bc4"}, "dataloader": {:hex, :dataloader, "1.0.8", "114294362db98a613f231589246aa5b0ce847412e8e75c4c94f31f204d272cbf", [:mix], [{:ecto, ">= 3.4.3 and < 4.0.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "eaf3c2aa2bc9dbd2f1e960561d616b7f593396c4754185b75904f6d66c82a667"}, "db_connection": {:hex, :db_connection, "2.3.1", "4c9f3ed1ef37471cbdd2762d6655be11e38193904d9c5c1c9389f1b891a3088e", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm", "abaab61780dde30301d840417890bd9f74131041afd02174cf4e10635b3a63f5"}, - "decimal": {:hex, :decimal, "1.9.0", "83e8daf59631d632b171faabafb4a9f4242c514b0a06ba3df493951c08f64d07", [:mix], [], "hexpm", "b1f2343568eed6928f3e751cf2dffde95bfaa19dd95d09e8a9ea92ccfd6f7d85"}, + "decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"}, "dialyxir": {:hex, :dialyxir, "1.0.0", "6a1fa629f7881a9f5aaf3a78f094b2a51a0357c843871b8bc98824e7342d00a5", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "aeb06588145fac14ca08d8061a142d52753dbc2cf7f0d00fc1013f53f8654654"}, "earmark": {:hex, :earmark, "1.4.13", "2c6ce9768fc9fdbf4046f457e207df6360ee6c91ee1ecb8e9a139f96a4289d91", [:mix], [{:earmark_parser, ">= 1.4.12", [hex: :earmark_parser, repo: "hexpm", optional: false]}], "hexpm", "a0cf3ed88ef2b1964df408889b5ecb886d1a048edde53497fc935ccd15af3403"}, "earmark_parser": {:hex, :earmark_parser, "1.4.12", "b245e875ec0a311a342320da0551da407d9d2b65d98f7a9597ae078615af3449", [:mix], [], "hexpm", "711e2cc4d64abb7d566d43f54b78f7dc129308a63bc103fbd88550d2174b3160"}, @@ -35,7 +35,7 @@ "elixir_make": {:hex, :elixir_make, "0.6.2", "7dffacd77dec4c37b39af867cedaabb0b59f6a871f89722c25b28fcd4bd70530", [:mix], [], "hexpm", "03e49eadda22526a7e5279d53321d1cced6552f344ba4e03e619063de75348d9"}, "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, "esaml": {:git, "git://github.com/wrren/esaml.git", "2cace5778e4323216bcff2085ca9739e42a68a42", [branch: "ueberauth_saml"]}, - "eternal": {:hex, :eternal, "1.2.1", "d5b6b2499ba876c57be2581b5b999ee9bdf861c647401066d3eeed111d096bc4", [:mix], [], "hexpm", "b14f1dc204321429479c569cfbe8fb287541184ed040956c8862cb7a677b8406"}, + "eternal": {:hex, :eternal, "1.2.2", "d1641c86368de99375b98d183042dd6c2b234262b8d08dfd72b9eeaafc2a1abd", [:mix], [], "hexpm", "2c9fe32b9c3726703ba5e1d43a1d255a4f3f2d8f8f9bc19f094c7cb1a7a9e782"}, "ex_cldr": {:hex, :ex_cldr, "2.18.2", "c0557145c234a4d31ff450a0438c5a70e786ccba9449a9f9f895809be20bed7d", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.5", [hex: :certifi, repo: "hexpm", optional: true]}, {:cldr_utils, "~> 2.12", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.13", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "ac28055ae6df438b72f98703c842c2c0d969af6bd68662a8f586862a9a0ddc79"}, "ex_cldr_calendars": {:hex, :ex_cldr_calendars, "1.12.0", "0cf7c804937a93baa9c3b471667ad05c478942865cc457e8397b5d83fc6f2c7a", [:mix], [{:calendar_interval, "~> 0.2", [hex: :calendar_interval, repo: "hexpm", optional: true]}, {:earmark, "~> 1.0", [hex: :earmark, repo: "hexpm", optional: false]}, {:ex_cldr_numbers, "~> 2.16", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:ex_cldr_units, "~> 3.3", [hex: :ex_cldr_units, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "edcb91ec52ee4e24a928e2bcf6d3354da465eced42887fbdb3f878a7a329963f"}, "ex_cldr_currencies": {:hex, :ex_cldr_currencies, "2.8.0", "b2ecc94e9fa4b8ec07614830f4d6e811e5df5e7679c6d2be92f4fe4f31184913", [:mix], [{:ex_cldr, "~> 2.18", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "a39780667b73bfd3d2bd08e61981bca23a97912b86f3236042850ecb062f48eb"}, @@ -76,7 +76,7 @@ "html_sanitize_ex": {:hex, :html_sanitize_ex, "1.4.0", "0310d27d7bafb662f30bff22ec732a72414799c83eaf44239781fd23b96216c0", [:mix], [{:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm", "c5d79626be0b6e50c19ecdfb783ee26e85bd3a77436b488379ce6dc104ec4593"}, "http_sign": {:hex, :http_sign, "0.1.1", "b16edb83aa282892f3271f9a048c155e772bf36e15700ab93901484c55f8dd10", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "2d4b1c2579d85534035f12c9e1260abdf6d03a9ad4f515b2ee53b50e68c8b787"}, "http_signatures": {:hex, :http_signatures, "0.1.0", "4e4b501a936dbf4cb5222597038a89ea10781776770d2e185849fa829686b34c", [:mix], [], "hexpm", "f8a7b3731e3fd17d38fa6e343fcad7b03d6874a3b0a108c8568a71ed9c2cf824"}, - "httpoison": {:hex, :httpoison, "1.7.0", "abba7d086233c2d8574726227b6c2c4f6e53c4deae7fe5f6de531162ce9929a0", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "975cc87c845a103d3d1ea1ccfd68a2700c211a434d8428b10c323dc95dc5b980"}, + "httpoison": {:hex, :httpoison, "1.8.0", "6b85dea15820b7804ef607ff78406ab449dd78bed923a49c7160e1886e987a3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "28089eaa98cf90c66265b6b5ad87c59a3729bea2e74e9d08f9b51eb9729b3c3a"}, "icalendar": {:git, "https://github.com/tcitworld/icalendar.git", "e16a3a0b74e07ba79044361fbf5014bed344f2da", []}, "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, "inet_cidr": {:hex, :inet_cidr, "1.0.4", "a05744ab7c221ca8e395c926c3919a821eb512e8f36547c062f62c4ca0cf3d6e", [:mix], [], "hexpm", "64a2d30189704ae41ca7dbdd587f5291db5d1dda1414e0774c29ffc81088c1bc"}, @@ -118,8 +118,8 @@ "plug_crypto": {:hex, :plug_crypto, "1.2.0", "1cb20793aa63a6c619dd18bb33d7a3aa94818e5fd39ad357051a67f26dfa2df6", [:mix], [], "hexpm", "a48b538ae8bf381ffac344520755f3007cc10bd8e90b240af98ea29b69683fc2"}, "poison": {:hex, :poison, "4.0.1", "bcb755a16fac91cad79bfe9fc3585bb07b9331e50cfe3420a24bcc2d735709ae", [:mix], [], "hexpm", "ba8836feea4b394bb718a161fc59a288fe0109b5006d6bdf97b6badfcf6f0f25"}, "poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"}, - "postgrex": {:hex, :postgrex, "0.15.7", "724410acd48abac529d0faa6c2a379fb8ae2088e31247687b16cacc0e0883372", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "88310c010ff047cecd73d5ceca1d99205e4b1ab1b9abfdab7e00f5c9d20ef8f9"}, - "progress_bar": {:hex, :progress_bar, "2.0.0", "447285f533b4b8717881fdb7160c7360c2f2ab57276f8904ce6d40482857e573", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "9d8b879f322fd5563e8e7ec39f1d02a9da3ffc36019f05287788744e88260fde"}, + "postgrex": {:hex, :postgrex, "0.15.8", "f5e782bbe5e8fa178d5e3cd1999c857dc48eda95f0a4d7f7bd92a50e84a0d491", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "698fbfacea34c4cf22c8281abeb5cf68d99628d541874f085520ab3b53d356fe"}, + "progress_bar": {:hex, :progress_bar, "2.0.1", "7b40200112ae533d5adceb80ff75fbe66dc753bca5f6c55c073bfc122d71896d", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "2519eb58a2f149a3a094e729378256d8cb6d96a259ec94841bd69fdc71f18f87"}, "ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm", "451d8527787df716d99dc36162fca05934915db0b6141bbdac2ea8d3c7afc7d7"}, "remote_ip": {:hex, :remote_ip, "0.2.1", "cd27cd8ea54ecaaf3532776ff4c5e353b3804e710302e88c01eadeaaf42e7e24", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:inet_cidr, "~> 1.0", [hex: :inet_cidr, repo: "hexpm", optional: false]}, {:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "2e7ab1a461cc3cd5719f37e116a08f45c8b8493923063631b164315d6b7ee8e0"}, "rsa_ex": {:hex, :rsa_ex, "0.4.0", "e28dd7dc5236e156df434af0e4aa822384c8866c928e17b785d4edb7c253b558", [:mix], [], "hexpm", "40e1f08e8401da4be59a6dd0f4da30c42d5bb01703161f0208d839d97db27f4e"}, diff --git a/test/federation/activity_pub/transmogrifier/follow_test.exs b/test/federation/activity_pub/transmogrifier/follow_test.exs index 5c15bd14..db99d54a 100644 --- a/test/federation/activity_pub/transmogrifier/follow_test.exs +++ b/test/federation/activity_pub/transmogrifier/follow_test.exs @@ -3,19 +3,73 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.FollowTest do import Mobilizon.Factory alias Mobilizon.Actors + alias Mobilizon.Actors.Follower alias Mobilizon.Federation.ActivityPub alias Mobilizon.Federation.ActivityPub.{Activity, Transmogrifier} + describe "handle incoming follow requests" do + test "it works for incoming follow requests" do + actor = insert(:actor) + + data = + File.read!("test/fixtures/mastodon-follow-activity.json") + |> Jason.decode!() + |> Map.put("object", actor.url) + + {:ok, %Activity{data: data, local: false}, _} = Transmogrifier.handle_incoming(data) + + assert data["actor"] == "https://social.tcit.fr/users/tcit" + assert data["type"] == "Follow" + assert data["id"] == "https://social.tcit.fr/users/tcit#follows/2" + + actor = Actors.get_actor_with_preload(actor.id) + assert Actors.is_following(Actors.get_actor_by_url!(data["actor"], true), actor) + end + + test "it rejects activities without a valid ID" do + actor = insert(:actor) + + data = + File.read!("test/fixtures/mastodon-follow-activity.json") + |> Jason.decode!() + |> Map.put("object", actor.url) + |> Map.put("id", "") + + :error = Transmogrifier.handle_incoming(data) + end + + # test "it works for incoming follow requests from hubzilla" do + # user = insert(:user) + + # data = + # File.read!("test/fixtures/hubzilla-follow-activity.json") + # |> Jason.decode!() + # |> Map.put("object", user.ap_id) + # |> Utils.normalize_params() + + # {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) + + # assert data["actor"] == "https://hubzilla.example.org/channel/kaniini" + # assert data["type"] == "Follow" + # assert data["id"] == "https://hubzilla.example.org/channel/kaniini#follows/2" + # assert User.is_following(User.get_by_ap_id(data["actor"]), user) + # end + end + describe "handle incoming follow accept activities" do - test "it works for incoming accepts which were pre-accepted" do + test "it works for incoming accepts" do follower = insert(:actor) - followed = insert(:actor) + followed = insert(:actor, manually_approves_followers: false) refute Actors.is_following(follower, followed) {:ok, follow_activity, _} = ActivityPub.follow(follower, followed) assert Actors.is_following(follower, followed) + follow_object_id = follow_activity.data["id"] + + assert %Follower{} = Actors.get_follower_by_url(follow_object_id) + accept_data = File.read!("test/fixtures/mastodon-accept-activity.json") |> Jason.decode!() @@ -24,7 +78,39 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.FollowTest do object = accept_data["object"] |> Map.put("actor", follower.url) - |> Map.put("id", follow_activity.data["id"]) + |> Map.put("id", follow_object_id) + + accept_data = Map.put(accept_data, "object", object) + + :error = Transmogrifier.handle_incoming(accept_data) + + {:ok, follower} = Actors.get_actor_by_url(follower.url) + + assert Actors.is_following(follower, followed) + end + + test "it works for incoming accepts which were pre-accepted" do + follower = insert(:actor) + followed = insert(:actor, manually_approves_followers: true) + + refute Actors.is_following(follower, followed) + + {:ok, follow_activity, _} = ActivityPub.follow(follower, followed) + assert Actors.is_following(follower, followed) + + follow_object_id = follow_activity.data["id"] + + assert %Follower{} = Actors.get_follower_by_url(follow_object_id) + + accept_data = + File.read!("test/fixtures/mastodon-accept-activity.json") + |> Jason.decode!() + |> Map.put("actor", followed.url) + + object = + accept_data["object"] + |> Map.put("actor", follower.url) + |> Map.put("id", follow_object_id) accept_data = Map.put(accept_data, "object", object) @@ -40,7 +126,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.FollowTest do test "it works for incoming accepts which are referenced by IRI only" do follower = insert(:actor) - followed = insert(:actor) + followed = insert(:actor, manually_approves_followers: true) {:ok, follow_activity, _} = ActivityPub.follow(follower, followed) diff --git a/test/federation/activity_pub/transmogrifier_test.exs b/test/federation/activity_pub/transmogrifier_test.exs index 5b176249..f04ad5a7 100644 --- a/test/federation/activity_pub/transmogrifier_test.exs +++ b/test/federation/activity_pub/transmogrifier_test.exs @@ -556,57 +556,6 @@ defmodule Mobilizon.Federation.ActivityPub.TransmogrifierTest do end end - describe "handle incoming follow requests" do - test "it works for incoming follow requests" do - use_cassette "activity_pub/mastodon_follow_activity" do - actor = insert(:actor) - - data = - File.read!("test/fixtures/mastodon-follow-activity.json") - |> Jason.decode!() - |> Map.put("object", actor.url) - - {:ok, %Activity{data: data, local: false}, _} = Transmogrifier.handle_incoming(data) - - assert data["actor"] == "https://social.tcit.fr/users/tcit" - assert data["type"] == "Follow" - assert data["id"] == "https://social.tcit.fr/users/tcit#follows/2" - - actor = Actors.get_actor_with_preload(actor.id) - assert Actors.is_following(Actors.get_actor_by_url!(data["actor"], true), actor) - end - end - - test "it rejects activities without a valid ID" do - actor = insert(:actor) - - data = - File.read!("test/fixtures/mastodon-follow-activity.json") - |> Jason.decode!() - |> Map.put("object", actor.url) - |> Map.put("id", "") - - :error = Transmogrifier.handle_incoming(data) - end - - # test "it works for incoming follow requests from hubzilla" do - # user = insert(:user) - - # data = - # File.read!("test/fixtures/hubzilla-follow-activity.json") - # |> Jason.decode!() - # |> Map.put("object", user.ap_id) - # |> Utils.normalize_params() - - # {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) - - # assert data["actor"] == "https://hubzilla.example.org/channel/kaniini" - # assert data["type"] == "Follow" - # assert data["id"] == "https://hubzilla.example.org/channel/kaniini#follows/2" - # assert User.is_following(User.get_by_ap_id(data["actor"]), user) - # end - end - # test "it works for incoming likes" do # %Comment{url: url} = insert(:comment) diff --git a/test/graphql/resolvers/follower_test.exs b/test/graphql/resolvers/follower_test.exs new file mode 100644 index 00000000..682ef9dd --- /dev/null +++ b/test/graphql/resolvers/follower_test.exs @@ -0,0 +1,275 @@ +defmodule Mobilizon.Web.Resolvers.FollowerTest do + use Mobilizon.Web.ConnCase + use Oban.Testing, repo: Mobilizon.Storage.Repo + + alias Mobilizon.Actors + alias Mobilizon.Actors.{Actor, Follower} + + import Mobilizon.Factory + + alias Mobilizon.GraphQL.AbsintheHelpers + + setup %{conn: conn} do + user = insert(:user) + actor = insert(:actor, user: user) + group = insert(:group) + insert(:member, parent: group, actor: actor, role: :moderator) + follower = insert(:follower, target_actor: group) + + {:ok, conn: conn, actor: actor, user: user, group: group, follower: follower} + end + + @group_followers_query """ + query( + $name: String! + $followersPage: Int + $followersLimit: Int + $approved: Boolean + ) { + group(preferredUsername: $name) { + id + preferredUsername + name + domain + followers( + page: $followersPage + limit: $followersLimit + approved: $approved + ) { + total + elements { + id + actor { + id + preferredUsername + name + domain + avatar { + id + url + } + } + approved + insertedAt + updatedAt + } + } + } + } + """ + + describe "list group followers find_followers_for_group/3" do + test "without being logged-in", %{ + conn: conn, + group: %Actor{preferred_username: preferred_username} + } do + res = + conn + |> AbsintheHelpers.graphql_query( + query: @group_followers_query, + variables: %{name: preferred_username} + ) + + assert hd(res["errors"])["message"] == "unauthenticated" + end + + test "without being a member", %{ + conn: conn, + group: %Actor{preferred_username: preferred_username} + } do + user = insert(:user) + insert(:actor, user: user) + + res = + conn + |> auth_conn(user) + |> AbsintheHelpers.graphql_query( + query: @group_followers_query, + variables: %{name: preferred_username} + ) + + assert hd(res["errors"])["message"] == "unauthorized" + end + + test "without being a moderator", %{ + conn: conn, + group: %Actor{preferred_username: preferred_username} = group + } do + user = insert(:user) + actor = insert(:actor, user: user) + insert(:member, parent: group, actor: actor, role: :member) + + res = + conn + |> auth_conn(user) + |> AbsintheHelpers.graphql_query( + query: @group_followers_query, + variables: %{name: preferred_username} + ) + + assert hd(res["errors"])["message"] == "unauthorized" + end + + test "while being a moderator", %{ + conn: conn, + user: user, + group: %Actor{preferred_username: preferred_username, id: group_id} = group, + follower: %Follower{id: follower_id} + } do + res = + conn + |> auth_conn(user) + |> AbsintheHelpers.graphql_query( + query: @group_followers_query, + variables: %{name: preferred_username} + ) + + assert res["errors"] == nil + assert res["data"]["group"]["id"] == to_string(group_id) + assert res["data"]["group"]["followers"]["total"] == 1 + assert hd(res["data"]["group"]["followers"]["elements"])["id"] == to_string(follower_id) + + Process.sleep(1000) + insert(:follower, target_actor: group) + Process.sleep(1000) + follower3 = insert(:follower, target_actor: group) + + res = + conn + |> auth_conn(user) + |> AbsintheHelpers.graphql_query( + query: @group_followers_query, + variables: %{ + name: preferred_username, + followersLimit: 2, + followersPage: 1 + } + ) + + assert res["errors"] == nil + assert res["data"]["group"]["id"] == to_string(group_id) + assert res["data"]["group"]["followers"]["total"] == 3 + assert hd(res["data"]["group"]["followers"]["elements"])["id"] == to_string(follower3.id) + + res = + conn + |> auth_conn(user) + |> AbsintheHelpers.graphql_query( + query: @group_followers_query, + variables: %{ + name: preferred_username, + followersLimit: 2, + followersPage: 2 + } + ) + + assert res["errors"] == nil + assert res["data"]["group"]["id"] == to_string(group_id) + assert res["data"]["group"]["followers"]["total"] == 3 + assert hd(res["data"]["group"]["followers"]["elements"])["id"] == to_string(follower_id) + end + end + + @update_follower_mutation """ + mutation UpdateFollower($id: ID!, $approved: Boolean) { + updateFollower(id: $id, approved: $approved) { + id + approved + } + } + """ + describe "update a follower update_follower/3" do + test "without being logged-in", %{ + conn: conn, + group: %Actor{} = group + } do + %Follower{id: follower_id} = insert(:follower, target_actor: group) + + res = + conn + |> AbsintheHelpers.graphql_query( + query: @update_follower_mutation, + variables: %{id: follower_id, approved: true} + ) + + assert hd(res["errors"])["message"] == "You need to be logged in" + end + + test "without being a member", %{ + conn: conn, + group: %Actor{} = group + } do + user = insert(:user) + insert(:actor, user: user) + %Follower{id: follower_id} = insert(:follower, target_actor: group) + + res = + conn + |> auth_conn(user) + |> AbsintheHelpers.graphql_query( + query: @update_follower_mutation, + variables: %{id: follower_id, approved: true} + ) + + assert hd(res["errors"])["message"] == "You don't have permission to do this" + end + + test "without being a moderator", %{ + conn: conn, + group: %Actor{} = group + } do + user = insert(:user) + actor = insert(:actor, user: user) + insert(:member, parent: group, actor: actor, role: :member) + %Follower{id: follower_id} = insert(:follower, target_actor: group) + + res = + conn + |> auth_conn(user) + |> AbsintheHelpers.graphql_query( + query: @update_follower_mutation, + variables: %{id: follower_id, approved: true} + ) + + assert hd(res["errors"])["message"] == "You don't have permission to do this" + end + + test "while being a moderator", %{ + conn: conn, + user: user, + follower: %Follower{id: follower_id, approved: false} + } do + res = + conn + |> auth_conn(user) + |> AbsintheHelpers.graphql_query( + query: @update_follower_mutation, + variables: %{id: follower_id, approved: true} + ) + + assert res["errors"] == nil + assert res["data"]["updateFollower"]["id"] == to_string(follower_id) + + assert %Follower{approved: true} = Actors.get_follower(follower_id) + end + + test "reject deletes the follower", %{ + conn: conn, + user: user, + follower: %Follower{id: follower_id, approved: false} + } do + res = + conn + |> auth_conn(user) + |> AbsintheHelpers.graphql_query( + query: @update_follower_mutation, + variables: %{id: follower_id, approved: false} + ) + + assert res["errors"] == nil + assert res["data"]["updateFollower"]["id"] == to_string(follower_id) + + assert is_nil(Actors.get_follower(follower_id)) + end + end +end diff --git a/test/support/factory.ex b/test/support/factory.ex index 82b8205b..09a2f682 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -55,7 +55,8 @@ defmodule Mobilizon.Factory do shared_inbox_url: "#{Endpoint.url()}/inbox", last_refreshed_at: DateTime.utc_now(), user: build(:user), - visibility: :public + visibility: :public, + manually_approves_followers: false } end @@ -108,7 +109,8 @@ defmodule Mobilizon.Factory do target_actor: build(:actor), actor: build(:actor), id: uuid, - url: "#{Endpoint.url()}/follows/#{uuid}" + url: "#{Endpoint.url()}/follows/#{uuid}", + approved: false } end