diff --git a/CHANGELOG.md b/CHANGELOG.md index fb6321786..5c89b2d48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,16 +6,21 @@ **Fixed bugs:** +- πŸ› \[Bug\] Update maintenance page email [\#1731](https://github.com/Human-Connection/Human-Connection/issues/1731) +- πŸ› \[Bug\] Editing comments is not reactive again [\#1718](https://github.com/Human-Connection/Human-Connection/issues/1718) - πŸ› \[Bug\] Comments with mentions in the end not displayed [\#1665](https://github.com/Human-Connection/Human-Connection/issues/1665) - πŸ› \[Bug\] Delete the Sleep Icon [\#1659](https://github.com/Human-Connection/Human-Connection/issues/1659) - πŸ› \[Bug\] Far to less Characters per Contribution \(2000\) [\#1639](https://github.com/Human-Connection/Human-Connection/issues/1639) +- πŸ› \[Bug\] Notifications do just update with page reload [\#1637](https://github.com/Human-Connection/Human-Connection/issues/1637) - πŸ› \[Bug\] Can no users used all hashtags be correct? [\#1632](https://github.com/Human-Connection/Human-Connection/issues/1632) - πŸ› \[Bug\] Create account has no info about email, no localisation, no HC logo [\#1631](https://github.com/Human-Connection/Human-Connection/issues/1631) - πŸ› \[Bug\] Embeds are displayed when creating comments but get removed [\#1547](https://github.com/Human-Connection/Human-Connection/issues/1547) - πŸ› \[Bug\] One cypress test fails but it does not fail the build [\#1312](https://github.com/Human-Connection/Human-Connection/issues/1312) +- πŸ› \[Bug\] TypeError: Cannot read property 'offsetTop' of null [\#1273](https://github.com/Human-Connection/Human-Connection/issues/1273) **Closed issues:** +- πŸš€ \[Feature\] Extend Emoticons [\#1745](https://github.com/Human-Connection/Human-Connection/issues/1745) - πŸš€ \[Feature\] Change slug [\#1650](https://github.com/Human-Connection/Human-Connection/issues/1650) - πŸš€ \[Feature\] Make the slug more visible and usable [\#1486](https://github.com/Human-Connection/Human-Connection/issues/1486) - πŸš€ \[Feature\] Report with reason [\#1469](https://github.com/Human-Connection/Human-Connection/issues/1469) @@ -24,12 +29,57 @@ **Merged pull requests:** +- Bump metascraper-logo from 5.7.5 to 5.7.6 in /backend [\#1783](https://github.com/Human-Connection/Human-Connection/pull/1783) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump metascraper-url from 5.7.5 to 5.7.6 in /backend [\#1782](https://github.com/Human-Connection/Human-Connection/pull/1782) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump graphql-middleware from 3.0.5 to 4.0.1 in /backend [\#1781](https://github.com/Human-Connection/Human-Connection/pull/1781) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump eslint from 6.4.0 to 6.5.1 in /backend [\#1780](https://github.com/Human-Connection/Human-Connection/pull/1780) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump metascraper-audio from 5.7.5 to 5.7.6 in /backend [\#1779](https://github.com/Human-Connection/Human-Connection/pull/1779) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump metascraper-publisher from 5.7.4 to 5.7.6 in /backend [\#1778](https://github.com/Human-Connection/Human-Connection/pull/1778) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump metascraper-youtube from 5.7.5 to 5.7.6 in /backend [\#1777](https://github.com/Human-Connection/Human-Connection/pull/1777) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump @babel/preset-env from 7.6.0 to 7.6.2 in /backend [\#1776](https://github.com/Human-Connection/Human-Connection/pull/1776) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump metascraper-soundcloud from 5.7.4 to 5.7.6 in /backend [\#1775](https://github.com/Human-Connection/Human-Connection/pull/1775) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump metascraper-author from 5.7.4 to 5.7.6 in /backend [\#1774](https://github.com/Human-Connection/Human-Connection/pull/1774) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Fix failing test [\#1772](https://github.com/Human-Connection/Human-Connection/pull/1772) ([aonomike](https://github.com/aonomike)) +- Bump metascraper-date from 5.7.4 to 5.7.6 in /backend [\#1771](https://github.com/Human-Connection/Human-Connection/pull/1771) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump tiptap-extensions from 1.27.0 to 1.28.0 in /webapp [\#1770](https://github.com/Human-Connection/Human-Connection/pull/1770) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump date-fns from 2.3.0 to 2.4.1 in /backend [\#1769](https://github.com/Human-Connection/Human-Connection/pull/1769) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump date-fns from 2.4.0 to 2.4.1 in /webapp [\#1768](https://github.com/Human-Connection/Human-Connection/pull/1768) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump graphql-middleware-sentry from 3.2.0 to 3.2.1 in /backend [\#1767](https://github.com/Human-Connection/Human-Connection/pull/1767) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump metascraper-lang from 5.7.4 to 5.7.6 in /backend [\#1766](https://github.com/Human-Connection/Human-Connection/pull/1766) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump tiptap from 1.25.0 to 1.26.0 in /webapp [\#1765](https://github.com/Human-Connection/Human-Connection/pull/1765) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump metascraper-video from 5.7.5 to 5.7.6 in /backend [\#1764](https://github.com/Human-Connection/Human-Connection/pull/1764) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump apollo-server from 2.9.3 to 2.9.4 in /backend [\#1762](https://github.com/Human-Connection/Human-Connection/pull/1762) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump metascraper-image from 5.7.5 to 5.7.6 in /backend [\#1761](https://github.com/Human-Connection/Human-Connection/pull/1761) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump eslint-loader from 3.0.1 to 3.0.2 in /webapp [\#1760](https://github.com/Human-Connection/Human-Connection/pull/1760) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump metascraper-title from 5.7.5 to 5.7.6 in /backend [\#1759](https://github.com/Human-Connection/Human-Connection/pull/1759) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump nodemon from 1.19.2 to 1.19.3 in /backend [\#1758](https://github.com/Human-Connection/Human-Connection/pull/1758) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- fix email middleware transport config [\#1757](https://github.com/Human-Connection/Human-Connection/pull/1757) ([vbelolapotkov](https://github.com/vbelolapotkov)) +- 1273 fix post page nav suggestions [\#1756](https://github.com/Human-Connection/Human-Connection/pull/1756) ([roschaefer](https://github.com/roschaefer)) +- docs: moves storybook into webapp/README.md [\#1755](https://github.com/Human-Connection/Human-Connection/pull/1755) ([roschaefer](https://github.com/roschaefer)) +- Bump date-fns from 2.2.1 to 2.4.0 in /webapp [\#1752](https://github.com/Human-Connection/Human-Connection/pull/1752) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- fix: Github's security vulnerability warning [\#1751](https://github.com/Human-Connection/Human-Connection/pull/1751) ([roschaefer](https://github.com/roschaefer)) +- update neo4j docker-compose config [\#1750](https://github.com/Human-Connection/Human-Connection/pull/1750) ([vbelolapotkov](https://github.com/vbelolapotkov)) +- 🍰 Try to fix VSCode format works against ESLint [\#1749](https://github.com/Human-Connection/Human-Connection/pull/1749) ([Tirokk](https://github.com/Tirokk)) +- Bump neo4j from 3.5.9 to 3.5.11 in /neo4j [\#1739](https://github.com/Human-Connection/Human-Connection/pull/1739) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump graphql from 14.5.7 to 14.5.8 in /backend [\#1738](https://github.com/Human-Connection/Human-Connection/pull/1738) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump metascraper-youtube from 5.7.4 to 5.7.5 in /backend [\#1737](https://github.com/Human-Connection/Human-Connection/pull/1737) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Update to 0.1.1 [\#1734](https://github.com/Human-Connection/Human-Connection/pull/1734) ([roschaefer](https://github.com/roschaefer)) +- Update maintenance page email to support@... [\#1732](https://github.com/Human-Connection/Human-Connection/pull/1732) ([mattwr18](https://github.com/mattwr18)) - Bump @babel/register from 7.6.0 to 7.6.2 in /backend [\#1730](https://github.com/Human-Connection/Human-Connection/pull/1730) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump graphql from 14.5.7 to 14.5.8 in /webapp [\#1729](https://github.com/Human-Connection/Human-Connection/pull/1729) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump @babel/core from 7.6.0 to 7.6.2 in /backend [\#1728](https://github.com/Human-Connection/Human-Connection/pull/1728) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) - Bump eslint-loader from 3.0.0 to 3.0.1 in /webapp [\#1727](https://github.com/Human-Connection/Human-Connection/pull/1727) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) - Bump apollo-server-express from 2.9.3 to 2.9.4 in /backend [\#1726](https://github.com/Human-Connection/Human-Connection/pull/1726) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump @babel/node from 7.6.1 to 7.6.2 in /backend [\#1725](https://github.com/Human-Connection/Human-Connection/pull/1725) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Fix bug UpdateComment, Fix styling on Comment [\#1719](https://github.com/Human-Connection/Human-Connection/pull/1719) ([mattwr18](https://github.com/mattwr18)) +- Bump apollo-server-testing from 2.9.3 to 2.9.4 in /backend [\#1717](https://github.com/Human-Connection/Human-Connection/pull/1717) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) - Bump metascraper-title from 5.7.4 to 5.7.5 in /backend [\#1715](https://github.com/Human-Connection/Human-Connection/pull/1715) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) - Bump date-fns from 2.2.1 to 2.3.0 in /backend [\#1714](https://github.com/Human-Connection/Human-Connection/pull/1714) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump @babel/cli from 7.6.0 to 7.6.2 in /backend [\#1713](https://github.com/Human-Connection/Human-Connection/pull/1713) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- \[WIP\]1706 refactor shout spec [\#1712](https://github.com/Human-Connection/Human-Connection/pull/1712) ([aonomike](https://github.com/aonomike)) - Remove repetitive labels from emote button [\#1702](https://github.com/Human-Connection/Human-Connection/pull/1702) ([roschaefer](https://github.com/roschaefer)) +- fix the bug with scrolling post comments into view [\#1701](https://github.com/Human-Connection/Human-Connection/pull/1701) ([vbelolapotkov](https://github.com/vbelolapotkov)) +- Bump metascraper-description from 5.7.4 to 5.7.5 in /backend [\#1700](https://github.com/Human-Connection/Human-Connection/pull/1700) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) - Bump metascraper-logo from 5.7.4 to 5.7.5 in /backend [\#1698](https://github.com/Human-Connection/Human-Connection/pull/1698) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) - Bump metascraper-video from 5.7.4 to 5.7.5 in /backend [\#1697](https://github.com/Human-Connection/Human-Connection/pull/1697) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) - Bump @babel/core from 7.6.0 to 7.6.2 in /webapp [\#1696](https://github.com/Human-Connection/Human-Connection/pull/1696) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) @@ -39,6 +89,7 @@ - Bump metascraper-url from 5.7.4 to 5.7.5 in /backend [\#1692](https://github.com/Human-Connection/Human-Connection/pull/1692) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) - Bugfix create user page - missing submit buttons [\#1690](https://github.com/Human-Connection/Human-Connection/pull/1690) ([roschaefer](https://github.com/roschaefer)) - Remove sleep icon from comments list [\#1689](https://github.com/Human-Connection/Human-Connection/pull/1689) ([alina-beck](https://github.com/alina-beck)) +- Configure docker to work with storybook [\#1688](https://github.com/Human-Connection/Human-Connection/pull/1688) ([mattwr18](https://github.com/mattwr18)) - Add Comment story, add spacing above user info [\#1685](https://github.com/Human-Connection/Human-Connection/pull/1685) ([mattwr18](https://github.com/mattwr18)) - Fix create account page has no logo, localisation [\#1681](https://github.com/Human-Connection/Human-Connection/pull/1681) ([roschaefer](https://github.com/roschaefer)) - Fix intermittent backend specs [\#1679](https://github.com/Human-Connection/Human-Connection/pull/1679) ([roschaefer](https://github.com/roschaefer)) @@ -47,11 +98,15 @@ - Bump graphql from 14.5.6 to 14.5.7 in /webapp [\#1676](https://github.com/Human-Connection/Human-Connection/pull/1676) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) - Bump graphql from 14.5.6 to 14.5.7 in /backend [\#1675](https://github.com/Human-Connection/Human-Connection/pull/1675) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) - Bump cookie-universal-nuxt from 2.0.17 to 2.0.18 in /webapp [\#1674](https://github.com/Human-Connection/Human-Connection/pull/1674) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump @hapi/joi from 16.1.2 to 16.1.4 in /backend [\#1673](https://github.com/Human-Connection/Human-Connection/pull/1673) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) - Bump helmet from 3.21.0 to 3.21.1 in /backend [\#1672](https://github.com/Human-Connection/Human-Connection/pull/1672) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) +- Bump cypress-file-upload from 3.3.3 to 3.3.4 [\#1671](https://github.com/Human-Connection/Human-Connection/pull/1671) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) - Bump codecov from 3.6.0 to 3.6.1 [\#1670](https://github.com/Human-Connection/Human-Connection/pull/1670) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) - Make Human Connection a Progressive Web App [\#1668](https://github.com/Human-Connection/Human-Connection/pull/1668) ([roschaefer](https://github.com/roschaefer)) - Remove contentExcerpt from comments [\#1667](https://github.com/Human-Connection/Human-Connection/pull/1667) ([mattwr18](https://github.com/mattwr18)) - Remove follow type enum [\#1660](https://github.com/Human-Connection/Human-Connection/pull/1660) ([vbelolapotkov](https://github.com/vbelolapotkov)) +- 🍰 Notifications self update and refactoring [\#1658](https://github.com/Human-Connection/Human-Connection/pull/1658) ([Tirokk](https://github.com/Tirokk)) +- Bump mustache from 3.0.3 to 3.1.0 in /backend [\#1655](https://github.com/Human-Connection/Human-Connection/pull/1655) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) - Bump @hapi/joi from 16.1.1 to 16.1.2 in /backend [\#1654](https://github.com/Human-Connection/Human-Connection/pull/1654) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) - Bump @nuxtjs/apollo from 4.0.0-rc13 to 4.0.0-rc13.1 in /webapp [\#1653](https://github.com/Human-Connection/Human-Connection/pull/1653) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) - Bump codecov from 3.5.0 to 3.6.0 [\#1652](https://github.com/Human-Connection/Human-Connection/pull/1652) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) diff --git a/VERSION b/VERSION index 17e51c385..d917d3e26 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.1.1 +0.1.2 diff --git a/backend/package.json b/backend/package.json index 5d5f41be3..44f51709f 100644 --- a/backend/package.json +++ b/backend/package.json @@ -41,7 +41,7 @@ ] }, "dependencies": { - "@hapi/joi": "^16.1.4", + "@hapi/joi": "^16.1.5", "@sentry/node": "^5.6.2", "apollo-cache-inmemory": "~1.6.3", "apollo-client": "~2.6.4", @@ -53,7 +53,7 @@ "bcryptjs": "~2.4.3", "cheerio": "~1.0.0-rc.3", "cors": "~2.8.5", - "cross-env": "~6.0.0", + "cross-env": "~6.0.3", "date-fns": "2.4.1", "debug": "~4.1.1", "dotenv": "~8.1.0", @@ -76,7 +76,7 @@ "metascraper-author": "^5.7.6", "metascraper-clearbit-logo": "^5.3.0", "metascraper-date": "^5.7.6", - "metascraper-description": "^5.7.5", + "metascraper-description": "^5.7.6", "metascraper-image": "^5.7.6", "metascraper-lang": "^5.7.6", "metascraper-lang-detector": "^4.8.5", diff --git a/backend/src/middleware/email/emailMiddleware.js b/backend/src/middleware/email/emailMiddleware.js index bea1bf9b3..f92da3368 100644 --- a/backend/src/middleware/email/emailMiddleware.js +++ b/backend/src/middleware/email/emailMiddleware.js @@ -5,7 +5,8 @@ import { signupTemplate, resetPasswordTemplate, wrongAccountTemplate, -} from './templates/templateBuilder' + emailVerificationTemplate, +} from './templateBuilder' const hasEmailConfig = CONFIG.SMTP_HOST && CONFIG.SMTP_PORT const hasAuthData = CONFIG.SMTP_USERNAME && CONFIG.SMTP_PASSWORD @@ -57,8 +58,17 @@ const sendPasswordResetMail = async (resolve, root, args, context, resolveInfo) return true } +const sendEmailVerificationMail = async (resolve, root, args, context, resolveInfo) => { + const response = await resolve(root, args, context, resolveInfo) + const { email, nonce, name } = response + await sendMail(emailVerificationTemplate({ email, nonce, name })) + delete response.nonce + return response +} + export default { Mutation: { + AddEmailAddress: sendEmailVerificationMail, requestPasswordReset: sendPasswordResetMail, Signup: sendSignupMail, SignupByInvitation: sendSignupMail, diff --git a/backend/src/middleware/email/templateBuilder.js b/backend/src/middleware/email/templateBuilder.js new file mode 100644 index 000000000..4b7bcc7cd --- /dev/null +++ b/backend/src/middleware/email/templateBuilder.js @@ -0,0 +1,77 @@ +import mustache from 'mustache' +import CONFIG from '../../config' + +import * as templates from './templates' + +const from = '"Human Connection" ' +const supportUrl = 'https://human-connection.org/en/contact' + +export const signupTemplate = ({ email, nonce }) => { + const subject = 'Willkommen, Bienvenue, Welcome to Human Connection!' + const actionUrl = new URL('/registration/create-user-account', CONFIG.CLIENT_URI) + actionUrl.searchParams.set('nonce', nonce) + actionUrl.searchParams.set('email', email) + + return { + from, + to: email, + subject, + html: mustache.render( + templates.layout, + { actionUrl, supportUrl, subject }, + { content: templates.signup }, + ), + } +} + +export const emailVerificationTemplate = ({ email, nonce, name }) => { + const subject = 'Neue E-Mail Adresse | New E-Mail Address' + const actionUrl = new URL('/settings/my-email-address/verify', CONFIG.CLIENT_URI) + actionUrl.searchParams.set('nonce', nonce) + actionUrl.searchParams.set('email', email) + + return { + from, + to: email, + subject, + html: mustache.render( + templates.layout, + { actionUrl, name, nonce, supportUrl, subject }, + { content: templates.emailVerification }, + ), + } +} + +export const resetPasswordTemplate = ({ email, nonce, name }) => { + const subject = 'Neues Passwort | Reset Password' + const actionUrl = new URL('/password-reset/change-password', CONFIG.CLIENT_URI) + actionUrl.searchParams.set('nonce', nonce) + actionUrl.searchParams.set('email', email) + + return { + from, + to: email, + subject, + html: mustache.render( + templates.layout, + { actionUrl, name, nonce, supportUrl, subject }, + { content: templates.passwordReset }, + ), + } +} + +export const wrongAccountTemplate = ({ email }) => { + const subject = 'Falsche Mailadresse? | Wrong E-mail?' + const actionUrl = new URL('/password-reset/request', CONFIG.CLIENT_URI) + + return { + from, + to: email, + subject, + html: mustache.render( + templates.layout, + { actionUrl, supportUrl }, + { content: templates.wrongAccount }, + ), + } +} diff --git a/backend/src/middleware/email/templates/emailVerification.html b/backend/src/middleware/email/templates/emailVerification.html new file mode 100644 index 000000000..5b5564ebf --- /dev/null +++ b/backend/src/middleware/email/templates/emailVerification.html @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/src/middleware/email/templates/index.js b/backend/src/middleware/email/templates/index.js new file mode 100644 index 000000000..594cae334 --- /dev/null +++ b/backend/src/middleware/email/templates/index.js @@ -0,0 +1,11 @@ +import fs from 'fs' +import path from 'path' + +const readFile = fileName => fs.readFileSync(path.join(__dirname, fileName), 'utf-8') + +export const signup = readFile('./signup.html') +export const passwordReset = readFile('./resetPassword.html') +export const wrongAccount = readFile('./wrongAccount.html') +export const emailVerification = readFile('./emailVerification.html') + +export const layout = readFile('./layout.html') diff --git a/backend/src/middleware/email/templates/layout.html b/backend/src/middleware/email/templates/layout.html new file mode 100644 index 000000000..7e1c39ace --- /dev/null +++ b/backend/src/middleware/email/templates/layout.html @@ -0,0 +1,196 @@ + + + + + + + + + + {{ subject }} + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + diff --git a/backend/src/middleware/email/templates/resetPassword.html b/backend/src/middleware/email/templates/resetPassword.html index e0dde53e5..768051070 100644 --- a/backend/src/middleware/email/templates/resetPassword.html +++ b/backend/src/middleware/email/templates/resetPassword.html @@ -1,448 +1,185 @@ - - + + - - - - - - - Neues Passwort | Reset Password + + + + + - - - - - - - - - - - - - - - - - - - -
- - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - + + + + - + + + + + + +
+ + + +
-

- Human Connection gGmbH
Bahnhofstraße 11, 73235 Weilheim / - Teck
Germany
-

+ style="padding: 20px; padding-top: 0; font-family: Lato, sans-serif; font-size: 16px; line-height: 22px; color: #555555;"> +

+ Hallo {{ name }}!

+

Du hast also dein Passwort vergessen? Kein Problem! Mit Klick auf diesen Button + kannst Du innerhalb der nΓ€chsten 24 Stunden Dein Passwort zurΓΌcksetzen:

+
+ + + + + +
+ Passwort + zurΓΌcksetzen +
+
- +
+ + +
+

Falls Du kein neues Passwort angefordert hast, kannst Du diese E-Mail einfach + ignorieren. Wenn Du noch Fragen hast, melde Dich gerne bei + unserem Support Team!

- - - +
+ + + + + + + +
+

Sollte der Button fΓΌr Dich nicht funktionieren, kannst Du auch folgenden Code in + Dein Browserfenster kopieren: {{{ nonce }}}

+

Bis bald bei Human Connection!

+

– Dein Human Connection Team

+
+

–––––––––––––––––––––––––––––––––––––––––––––––

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/src/middleware/email/templates/signup.html b/backend/src/middleware/email/templates/signup.html index e4be8c02f..79894b584 100644 --- a/backend/src/middleware/email/templates/signup.html +++ b/backend/src/middleware/email/templates/signup.html @@ -1,485 +1,210 @@ - - + + - - - - - - - Willkommen, Bienvenue, Welcome to Human Connection + + + + + - - - - - - - - - - - - - - - - - - - -
- - - -
- Dein Anmeldelink. | Here is your signup link. -
-
- ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ 
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - + + + + - + + + + + + +
+ + + + + + +
-

- Human Connection gGmbH
Bahnhofstraße 11, 73235 Weilheim / - Teck
Germany
-

+ style="padding: 20px; padding-top: 0; font-family: Lato, sans-serif; font-size: 16px; line-height: 22px; color: #555555;"> +

+ Willkommen bei Human Connection!

+

Danke, dass Du dich angemeldet hast – wir freuen uns, Dich dabei zu haben. Jetzt + fehlt nur noch eine Kleinigkeit, bevor wir gemeinsam die Welt verbessern kΓΆnnen ... Bitte bestΓ€tige + Deine E-Mail Adresse:

+
+ + + + + +
+ BestΓ€tige + Deine E-Mail Adresse +
+ +
+

–––––––––––––––––––––––––––––––––––––––––––––––

- +
+ + + + + +
+

Falls Du Dich nicht selbst bei Human Connection angemeldet hast, schau doch mal vorbei! + Wir sind ein gemeinnΓΌtziges Aktionsnetzwerk – von Menschen fΓΌr Menschen.

+

PS: Wenn Du keinen Account bei uns mΓΆchtest, kannst Du diese + E-Mail einfach ignorieren. ;)

+
+

–––––––––––––––––––––––––––––––––––––––––––––––

- - - +
+ + + + + + + +
+

Melde Dich gerne bei + unserem Support Team, wenn Du Fragen hast.

+

Bis bald bei Human Connection!

+

– Dein Human Connection Team

+
+

–––––––––––––––––––––––––––––––––––––––––––––––

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/src/middleware/email/templates/templateBuilder.js b/backend/src/middleware/email/templates/templateBuilder.js deleted file mode 100644 index fdeb47a89..000000000 --- a/backend/src/middleware/email/templates/templateBuilder.js +++ /dev/null @@ -1,48 +0,0 @@ -import fs from 'fs' -import path from 'path' -import mustache from 'mustache' -import CONFIG from '../../../config' - -const from = '"Human Connection" ' -const supportUrl = 'https://human-connection.org/en/contact' - -const signupHtml = fs.readFileSync(path.join(__dirname, './signup.html'), 'utf-8') -const passwordResetHtml = fs.readFileSync(path.join(__dirname, './resetPassword.html'), 'utf-8') -const wrongAccountHtml = fs.readFileSync(path.join(__dirname, './wrongAccount.html'), 'utf-8') - -export const signupTemplate = ({ email, nonce }) => { - const actionUrl = new URL('/registration/create-user-account', CONFIG.CLIENT_URI) - actionUrl.searchParams.set('nonce', nonce) - actionUrl.searchParams.set('email', email) - - return { - from, - to: email, - subject: 'Willkommen, Bienvenue, Welcome to Human Connection!', - html: mustache.render(signupHtml, { actionUrl, supportUrl }), - } -} - -export const resetPasswordTemplate = ({ email, nonce, name }) => { - const actionUrl = new URL('/password-reset/change-password', CONFIG.CLIENT_URI) - actionUrl.searchParams.set('nonce', nonce) - actionUrl.searchParams.set('email', email) - - return { - from, - to: email, - subject: 'Neues Passwort | Reset Password', - html: mustache.render(passwordResetHtml, { actionUrl, name, nonce, supportUrl }), - } -} - -export const wrongAccountTemplate = ({ email }) => { - const actionUrl = new URL('/password-reset/request', CONFIG.CLIENT_URI) - - return { - from, - to: email, - subject: 'Falsche Mailadresse? | Wrong E-mail?', - html: mustache.render(wrongAccountHtml, { actionUrl, supportUrl }), - } -} diff --git a/backend/src/middleware/email/templates/wrongAccount.html b/backend/src/middleware/email/templates/wrongAccount.html index b8e6f6f57..90f8cd357 100644 --- a/backend/src/middleware/email/templates/wrongAccount.html +++ b/backend/src/middleware/email/templates/wrongAccount.html @@ -1,448 +1,185 @@ - - + + - - - - - - - Falsche Mailadresse? | Wrong E-mail? + + + + + - - - - - - - - - - - - - - - - - - - -
- - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - + + + + - + + + + + + +
+ + + +
-

- Human Connection gGmbH
Bahnhofstraße 11, 73235 Weilheim / - Teck
Germany
-

+ style="padding: 20px; padding-top: 0; font-family: Lato, sans-serif; font-size: 16px; line-height: 22px; color: #555555;"> +

+ Hallo!

+

Du hast bei uns ein neues Password angefordert – leider haben wir aber keinen + Account mit Deiner E-Mailadresse gefunden. Kann es sein, dass Du mit einer anderen Adresse bei uns + angemeldet bist?

+
+ + + + + +
+ Versuch' + es mit einer anderen E-Mail +
+
- +
+ + +
+

Wenn Du noch keinen Account bei Human Connection hast oder Dein Password gar nicht Γ€ndern willst, + kannst Du diese E-Mail einfach ignorieren!

- - - +
+ + + + + + + +
+

Ansonsten hilft Dir unser + Support Team gerne weiter.

+

Bis bald bei Human Connection!

+

– Dein Human Connection Team

+
+

–––––––––––––––––––––––––––––––––––––––––––––––

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/src/middleware/permissionsMiddleware.js b/backend/src/middleware/permissionsMiddleware.js index ce98090ad..59ae06c07 100644 --- a/backend/src/middleware/permissionsMiddleware.js +++ b/backend/src/middleware/permissionsMiddleware.js @@ -170,6 +170,8 @@ const permissions = shield( block: isAuthenticated, unblock: isAuthenticated, markAsRead: isAuthenticated, + AddEmailAddress: isAuthenticated, + VerifyEmailAddress: isAuthenticated, }, User: { email: isMyOwn, diff --git a/backend/src/models/UnverifiedEmailAddress.js b/backend/src/models/UnverifiedEmailAddress.js new file mode 100644 index 000000000..7b37b9a39 --- /dev/null +++ b/backend/src/models/UnverifiedEmailAddress.js @@ -0,0 +1,12 @@ +module.exports = { + email: { type: 'string', primary: true, lowercase: true, email: true }, + createdAt: { type: 'string', isoDate: true, default: () => new Date().toISOString() }, + nonce: { type: 'string', token: true }, + belongsTo: { + type: 'relationship', + relationship: 'BELONGS_TO', + target: 'User', + direction: 'out', + eager: true, + }, +} diff --git a/backend/src/models/index.js b/backend/src/models/index.js index a7d3c8252..08362b69f 100644 --- a/backend/src/models/index.js +++ b/backend/src/models/index.js @@ -5,6 +5,7 @@ export default { User: require('./User.js'), InvitationCode: require('./InvitationCode.js'), EmailAddress: require('./EmailAddress.js'), + UnverifiedEmailAddress: require('./UnverifiedEmailAddress.js'), SocialMedia: require('./SocialMedia.js'), Post: require('./Post.js'), Comment: require('./Comment.js'), diff --git a/backend/src/schema/resolvers/emails.js b/backend/src/schema/resolvers/emails.js new file mode 100644 index 000000000..ce93a28e9 --- /dev/null +++ b/backend/src/schema/resolvers/emails.js @@ -0,0 +1,92 @@ +import generateNonce from './helpers/generateNonce' +import Resolver from './helpers/Resolver' +import existingEmailAddress from './helpers/existingEmailAddress' +import { UserInputError } from 'apollo-server' +import Validator from 'neode/build/Services/Validator.js' + +export default { + Mutation: { + AddEmailAddress: async (_parent, args, context, _resolveInfo) => { + let response + try { + const { neode } = context + await new Validator(neode, neode.model('UnverifiedEmailAddress'), args) + } catch (e) { + throw new UserInputError('must be a valid email') + } + + // check email does not belong to anybody + await existingEmailAddress(_parent, args, context) + + const nonce = generateNonce() + const { + user: { id: userId }, + } = context + const { email } = args + const session = context.driver.session() + const writeTxResultPromise = session.writeTransaction(async txc => { + const result = await txc.run( + ` + MATCH (user:User {id: $userId}) + MERGE (user)<-[:BELONGS_TO]-(email:UnverifiedEmailAddress {email: $email, nonce: $nonce}) + SET email.createdAt = toString(datetime()) + RETURN email, user + `, + { userId, email, nonce }, + ) + return result.records.map(record => ({ + name: record.get('user').properties.name, + ...record.get('email').properties, + })) + }) + try { + const txResult = await writeTxResultPromise + response = txResult[0] + } finally { + session.close() + } + return response + }, + VerifyEmailAddress: async (_parent, args, context, _resolveInfo) => { + let response + const { + user: { id: userId }, + } = context + const { nonce, email } = args + const session = context.driver.session() + const writeTxResultPromise = session.writeTransaction(async txc => { + const result = await txc.run( + ` + MATCH (user:User {id: $userId})-[:PRIMARY_EMAIL]->(previous:EmailAddress) + MATCH (user)<-[:BELONGS_TO]-(email:UnverifiedEmailAddress {email: $email, nonce: $nonce}) + MERGE (user)-[:PRIMARY_EMAIL]->(email) + SET email:EmailAddress + SET email.verifiedAt = toString(datetime()) + REMOVE email:UnverifiedEmailAddress + DETACH DELETE previous + RETURN email + `, + { userId, email, nonce }, + ) + return result.records.map(record => record.get('email').properties) + }) + try { + const txResult = await writeTxResultPromise + response = txResult[0] + } catch (e) { + if (e.code === 'Neo.ClientError.Schema.ConstraintValidationFailed') + throw new UserInputError('A user account with this email already exists.') + throw new Error(e) + } finally { + session.close() + } + if (!response) throw new UserInputError('Invalid nonce or no email address found.') + return response + }, + }, + EmailAddress: { + ...Resolver('EmailAddress', { + undefinedToNull: ['verifiedAt'], + }), + }, +} diff --git a/backend/src/schema/resolvers/emails.spec.js b/backend/src/schema/resolvers/emails.spec.js new file mode 100644 index 000000000..ea3491d1e --- /dev/null +++ b/backend/src/schema/resolvers/emails.spec.js @@ -0,0 +1,298 @@ +import Factory from '../../seed/factories' +import { gql } from '../../jest/helpers' +import { getDriver, neode as getNeode } from '../../bootstrap/neo4j' +import createServer from '../../server' +import { createTestClient } from 'apollo-server-testing' + +const factory = Factory() +const neode = getNeode() + +let mutate +let authenticatedUser +let user +let variables +const driver = getDriver() + +beforeEach(async () => { + variables = {} +}) + +beforeAll(() => { + const { server } = createServer({ + context: () => { + return { + driver, + neode, + user: authenticatedUser, + } + }, + }) + mutate = createTestClient(server).mutate +}) + +afterEach(async () => { + await factory.cleanDatabase() +}) + +describe('AddEmailAddress', () => { + const mutation = gql` + mutation($email: String!) { + AddEmailAddress(email: $email) { + email + verifiedAt + createdAt + } + } + ` + beforeEach(() => { + variables = { ...variables, email: 'new-email@example.org' } + }) + + describe('unauthenticated', () => { + beforeEach(() => { + authenticatedUser = null + }) + + it('throws AuthorizationError', async () => { + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { AddEmailAddress: null }, + errors: [{ message: 'Not Authorised!' }], + }) + }) + }) + + describe('authenticated', () => { + beforeEach(async () => { + user = await factory.create('User', { id: '567', email: 'user@example.org' }) + authenticatedUser = await user.toJson() + }) + + describe('email attribute is not a valid email', () => { + beforeEach(() => { + variables = { ...variables, email: 'foobar' } + }) + + it('throws UserInputError', async () => { + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { AddEmailAddress: null }, + errors: [{ message: 'must be a valid email' }], + }) + }) + }) + + describe('email attribute is a valid email', () => { + it('creates a new unverified `EmailAddress` node', async () => { + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { + AddEmailAddress: { + email: 'new-email@example.org', + verifiedAt: null, + createdAt: expect.any(String), + }, + }, + errors: undefined, + }) + }) + + it('connects `UnverifiedEmailAddress` to the authenticated user', async () => { + await mutate({ mutation, variables }) + const result = await neode.cypher(` + MATCH(u:User)-[:PRIMARY_EMAIL]->(:EmailAddress {email: "user@example.org"}) + MATCH(u:User)<-[:BELONGS_TO]-(e:UnverifiedEmailAddress {email: "new-email@example.org"}) + RETURN e + `) + const email = neode.hydrateFirst(result, 'e', neode.model('UnverifiedEmailAddress')) + await expect(email.toJson()).resolves.toMatchObject({ + email: 'new-email@example.org', + nonce: expect.any(String), + }) + }) + + describe('if another `UnverifiedEmailAddress` node already exists with that email', () => { + it('throws no unique constraint violation error', async () => { + await factory.create('UnverifiedEmailAddress', { + createdAt: '2019-09-24T14:00:01.565Z', + email: 'new-email@example.org', + }) + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { + AddEmailAddress: { + email: 'new-email@example.org', + verifiedAt: null, + }, + }, + errors: undefined, + }) + }) + }) + + describe('but if another user owns an `EmailAddress` already with that email', () => { + it('throws UserInputError because of unique constraints', async () => { + await factory.create('User', { email: 'new-email@example.org' }) + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { AddEmailAddress: null }, + errors: [{ message: 'A user account with this email already exists.' }], + }) + }) + }) + }) + }) +}) + +describe('VerifyEmailAddress', () => { + const mutation = gql` + mutation($email: String!, $nonce: String!) { + VerifyEmailAddress(email: $email, nonce: $nonce) { + email + createdAt + verifiedAt + } + } + ` + + beforeEach(() => { + variables = { ...variables, email: 'to-be-verified@example.org', nonce: '123456' } + }) + + describe('unauthenticated', () => { + beforeEach(() => { + authenticatedUser = null + }) + + it('throws AuthorizationError', async () => { + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { VerifyEmailAddress: null }, + errors: [{ message: 'Not Authorised!' }], + }) + }) + }) + + describe('authenticated', () => { + beforeEach(async () => { + user = await factory.create('User', { id: '567', email: 'user@example.org' }) + authenticatedUser = await user.toJson() + }) + + describe('if no unverified `EmailAddress` node exists', () => { + it('throws UserInputError', async () => { + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { VerifyEmailAddress: null }, + errors: [{ message: 'Invalid nonce or no email address found.' }], + }) + }) + }) + + describe('given a `UnverifiedEmailAddress`', () => { + let emailAddress + beforeEach(async () => { + emailAddress = await factory.create('UnverifiedEmailAddress', { + nonce: 'abcdef', + verifiedAt: null, + createdAt: new Date().toISOString(), + email: 'to-be-verified@example.org', + }) + }) + + describe('given invalid nonce', () => { + it('throws UserInputError', async () => { + variables.nonce = 'asdfgh' + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { VerifyEmailAddress: null }, + errors: [{ message: 'Invalid nonce or no email address found.' }], + }) + }) + }) + + describe('given valid nonce for `UnverifiedEmailAddress` node', () => { + beforeEach(() => { + variables = { ...variables, nonce: 'abcdef' } + }) + + describe('but the address does not belong to the authenticated user', () => { + it('throws UserInputError', async () => { + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { VerifyEmailAddress: null }, + errors: [{ message: 'Invalid nonce or no email address found.' }], + }) + }) + }) + + describe('and the `UnverifiedEmailAddress` belongs to the authenticated user', () => { + beforeEach(async () => { + await emailAddress.relateTo(user, 'belongsTo') + }) + + it('adds `verifiedAt`', async () => { + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { + VerifyEmailAddress: { + email: 'to-be-verified@example.org', + verifiedAt: expect.any(String), + createdAt: expect.any(String), + }, + }, + errors: undefined, + }) + }) + + it('connects the new `EmailAddress` as PRIMARY', async () => { + await mutate({ mutation, variables }) + const result = await neode.cypher(` + MATCH(u:User {id: "567"})-[:PRIMARY_EMAIL]->(e:EmailAddress {email: "to-be-verified@example.org"}) + RETURN e + `) + const email = neode.hydrateFirst(result, 'e', neode.model('EmailAddress')) + await expect(email.toJson()).resolves.toMatchObject({ + email: 'to-be-verified@example.org', + }) + }) + + it('removes previous PRIMARY relationship', async () => { + const cypherStatement = ` + MATCH(u:User {id: "567"})-[:PRIMARY_EMAIL]->(e:EmailAddress {email: "user@example.org"}) + RETURN e + ` + let result = await neode.cypher(cypherStatement) + let email = neode.hydrateFirst(result, 'e', neode.model('EmailAddress')) + await expect(email.toJson()).resolves.toMatchObject({ + email: 'user@example.org', + }) + await mutate({ mutation, variables }) + result = await neode.cypher(cypherStatement) + email = neode.hydrateFirst(result, 'e', neode.model('EmailAddress')) + await expect(email).toBe(false) + }) + + it('removes previous `EmailAddress` node', async () => { + const cypherStatement = ` + MATCH(u:User {id: "567"})<-[:BELONGS_TO]-(e:EmailAddress {email: "user@example.org"}) + RETURN e + ` + let result = await neode.cypher(cypherStatement) + let email = neode.hydrateFirst(result, 'e', neode.model('EmailAddress')) + await expect(email.toJson()).resolves.toMatchObject({ + email: 'user@example.org', + }) + await mutate({ mutation, variables }) + result = await neode.cypher(cypherStatement) + email = neode.hydrateFirst(result, 'e', neode.model('EmailAddress')) + await expect(email).toBe(false) + }) + + describe('Edge case: In the meantime someone created an `EmailAddress` node with the given email', () => { + beforeEach(async () => { + await factory.create('EmailAddress', { email: 'to-be-verified@example.org' }) + }) + + it('throws UserInputError because of unique constraints', async () => { + await expect(mutate({ mutation, variables })).resolves.toMatchObject({ + data: { VerifyEmailAddress: null }, + errors: [{ message: 'A user account with this email already exists.' }], + }) + }) + }) + }) + }) + }) + }) +}) diff --git a/backend/src/schema/resolvers/helpers/existingEmailAddress.js b/backend/src/schema/resolvers/helpers/existingEmailAddress.js new file mode 100644 index 000000000..007d2de6b --- /dev/null +++ b/backend/src/schema/resolvers/helpers/existingEmailAddress.js @@ -0,0 +1,26 @@ +import { UserInputError } from 'apollo-server' +export default async function alreadyExistingMail(_parent, args, context) { + let { email } = args + email = email.toLowerCase() + const cypher = ` + MATCH (email:EmailAddress {email: $email}) + OPTIONAL MATCH (email)-[:BELONGS_TO]-(user) + RETURN email, user + ` + let transactionRes + const session = context.driver.session() + try { + transactionRes = await session.run(cypher, { email }) + } finally { + session.close() + } + const [result] = transactionRes.records.map(record => { + return { + alreadyExistingEmail: record.get('email').properties, + user: record.get('user') && record.get('user').properties, + } + }) + const { alreadyExistingEmail, user } = result || {} + if (user) throw new UserInputError('A user account with this email already exists.') + return alreadyExistingEmail +} diff --git a/backend/src/schema/resolvers/helpers/generateNonce.js b/backend/src/schema/resolvers/helpers/generateNonce.js new file mode 100644 index 000000000..4dde1df04 --- /dev/null +++ b/backend/src/schema/resolvers/helpers/generateNonce.js @@ -0,0 +1,4 @@ +import uuid from 'uuid/v4' +export default function generateNonce() { + return uuid().substring(0, 6) +} diff --git a/backend/src/schema/resolvers/registration.js b/backend/src/schema/resolvers/registration.js index 72e499038..bd62b32c3 100644 --- a/backend/src/schema/resolvers/registration.js +++ b/backend/src/schema/resolvers/registration.js @@ -1,41 +1,16 @@ import { UserInputError } from 'apollo-server' -import uuid from 'uuid/v4' import { neode } from '../../bootstrap/neo4j' import fileUpload from './fileUpload' import encryptPassword from '../../helpers/encryptPassword' +import generateNonce from './helpers/generateNonce' +import existingEmailAddress from './helpers/existingEmailAddress' const instance = neode() -const alreadyExistingMail = async (_parent, args, context) => { - let { email } = args - email = email.toLowerCase() - const cypher = ` - MATCH (email:EmailAddress {email: $email}) - OPTIONAL MATCH (email)-[:PRIMARY_EMAIL]-(user) - RETURN email, user - ` - let transactionRes - const session = context.driver.session() - try { - transactionRes = await session.run(cypher, { email }) - } finally { - session.close() - } - const [result] = transactionRes.records.map(record => { - return { - alreadyExistingEmail: record.get('email').properties, - user: record.get('user') && record.get('user').properties, - } - }) - const { alreadyExistingEmail, user } = result || {} - if (user) throw new UserInputError('User account with this email already exists.') - return alreadyExistingEmail -} - export default { Mutation: { CreateInvitationCode: async (_parent, args, context, _resolveInfo) => { - args.token = uuid().substring(0, 6) + args.token = generateNonce() const { user: { id: userId }, } = context @@ -54,9 +29,9 @@ export default { return response }, Signup: async (_parent, args, context) => { - const nonce = uuid().substring(0, 6) + const nonce = generateNonce() args.nonce = nonce - let emailAddress = await alreadyExistingMail(_parent, args, context) + let emailAddress = await existingEmailAddress(_parent, args, context) if (emailAddress) return emailAddress try { emailAddress = await instance.create('EmailAddress', args) @@ -67,9 +42,9 @@ export default { }, SignupByInvitation: async (_parent, args, context) => { const { token } = args - const nonce = uuid().substring(0, 6) + const nonce = generateNonce() args.nonce = nonce - let emailAddress = await alreadyExistingMail(_parent, args, context) + let emailAddress = await existingEmailAddress(_parent, args, context) if (emailAddress) return emailAddress try { const result = await instance.cypher( diff --git a/backend/src/schema/resolvers/registration.spec.js b/backend/src/schema/resolvers/registration.spec.js index 81326004d..0f3af5a8d 100644 --- a/backend/src/schema/resolvers/registration.spec.js +++ b/backend/src/schema/resolvers/registration.spec.js @@ -257,7 +257,7 @@ describe('SignupByInvitation', () => { it('throws unique violation error', async () => { await expect(mutate({ mutation, variables })).resolves.toMatchObject({ - errors: [{ message: 'User account with this email already exists.' }], + errors: [{ message: 'A user account with this email already exists.' }], }) }) }) @@ -307,6 +307,7 @@ describe('Signup', () => { it('is allowed to signup users by email', async () => { await expect(mutate({ mutation, variables })).resolves.toMatchObject({ data: { Signup: { email: 'someuser@example.org' } }, + errors: undefined, }) }) @@ -342,7 +343,7 @@ describe('Signup', () => { it('throws UserInputError error because of unique constraint violation', async () => { await expect(mutate({ mutation, variables })).resolves.toMatchObject({ - errors: [{ message: 'User account with this email already exists.' }], + errors: [{ message: 'A user account with this email already exists.' }], }) }) }) @@ -351,6 +352,7 @@ describe('Signup', () => { it('resolves with the already existing email', async () => { await expect(mutate({ mutation, variables })).resolves.toMatchObject({ data: { Signup: { email: 'someuser@example.org' } }, + errors: undefined, }) }) @@ -359,6 +361,7 @@ describe('Signup', () => { await expect(neode.all('EmailAddress')).resolves.toHaveLength(2) await expect(mutate({ mutation, variables })).resolves.toMatchObject({ data: { Signup: { email: 'someuser@example.org' } }, + errors: undefined, }) await expect(neode.all('EmailAddress')).resolves.toHaveLength(2) }) diff --git a/backend/src/schema/resolvers/statistics.js b/backend/src/schema/resolvers/statistics.js index 466c1ef70..7b06f8705 100644 --- a/backend/src/schema/resolvers/statistics.js +++ b/backend/src/schema/resolvers/statistics.js @@ -9,7 +9,7 @@ export default { countPosts: 'Post', countComments: 'Comment', countNotifications: 'NOTIFIED', - countInvites: 'InvitationCode', + countEmails: 'EmailAddress', countFollows: 'FOLLOWS', countShouts: 'SHOUTED', } @@ -28,6 +28,11 @@ export default { const stat = statistics[mapping[key]] response[key] = stat ? stat.toNumber() : 0 }) + + /* + * Note: invites count is calculated this way because invitation codes are not in use yet + */ + response.countInvites = response.countEmails - response.countUsers } finally { session.close() } diff --git a/backend/src/schema/resolvers/users.js b/backend/src/schema/resolvers/users.js index ea9220d5e..b5df8111e 100644 --- a/backend/src/schema/resolvers/users.js +++ b/backend/src/schema/resolvers/users.js @@ -22,6 +22,7 @@ export const getBlockedUsers = async context => { } export const getBlockedByUsers = async context => { + if (context.user.role === 'moderator' || context.user.role === 'admin') return [] const { neode } = context const userModel = neode.model('User') let blockedByUsers = neode diff --git a/backend/src/schema/types/type/EmailAddress.gql b/backend/src/schema/types/type/EmailAddress.gql index 4bf8ff724..1748139bd 100644 --- a/backend/src/schema/types/type/EmailAddress.gql +++ b/backend/src/schema/types/type/EmailAddress.gql @@ -20,4 +20,9 @@ type Mutation { about: String termsAndConditionsAgreedVersion: String! ): User + AddEmailAddress(email: String!): EmailAddress + VerifyEmailAddress( + nonce: String! + email: String! + ): EmailAddress } diff --git a/backend/src/seed/factories/emailAddresses.js b/backend/src/seed/factories/emailAddresses.js index 0212dca53..41b1fe96c 100644 --- a/backend/src/seed/factories/emailAddresses.js +++ b/backend/src/seed/factories/emailAddresses.js @@ -1,16 +1,21 @@ import faker from 'faker' +export function defaults({ args }) { + const defaults = { + email: faker.internet.email(), + verifiedAt: new Date().toISOString(), + } + args = { + ...defaults, + ...args, + } + return args +} + export default function create() { return { factory: async ({ args, neodeInstance }) => { - const defaults = { - email: faker.internet.email(), - verifiedAt: new Date().toISOString(), - } - args = { - ...defaults, - ...args, - } + args = defaults({ args }) return neodeInstance.create('EmailAddress', args) }, } diff --git a/backend/src/seed/factories/index.js b/backend/src/seed/factories/index.js index ab09b438d..5fd6f2d82 100644 --- a/backend/src/seed/factories/index.js +++ b/backend/src/seed/factories/index.js @@ -9,6 +9,7 @@ import createTag from './tags.js' import createSocialMedia from './socialMedia.js' import createLocation from './locations.js' import createEmailAddress from './emailAddresses.js' +import createUnverifiedEmailAddresss from './unverifiedEmailAddresses.js' export const seedServerHost = 'http://127.0.0.1:4001' @@ -32,6 +33,7 @@ const factories = { SocialMedia: createSocialMedia, Location: createLocation, EmailAddress: createEmailAddress, + UnverifiedEmailAddress: createUnverifiedEmailAddresss, } export const cleanDatabase = async (options = {}) => { diff --git a/backend/src/seed/factories/unverifiedEmailAddresses.js b/backend/src/seed/factories/unverifiedEmailAddresses.js new file mode 100644 index 000000000..94e32af6e --- /dev/null +++ b/backend/src/seed/factories/unverifiedEmailAddresses.js @@ -0,0 +1,10 @@ +import { defaults } from './emailAddresses.js' + +export default function create() { + return { + factory: async ({ args, neodeInstance }) => { + args = defaults({ args }) + return neodeInstance.create('UnverifiedEmailAddress', args) + }, + } +} diff --git a/backend/yarn.lock b/backend/yarn.lock index d1f0baf95..990464fdb 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -689,9 +689,9 @@ regenerator-runtime "^0.13.2" "@babel/runtime@^7.0.0", "@babel/runtime@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" - integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.2.tgz#c3d6e41b304ef10dcf13777a33e7694ec4a9a6dd" + integrity sha512-EXxN64agfUqqIGeEjI5dL5z0Sw0ZwWo1mLTi4mQowCZ42O59b7DRpZAnTC6OqdF28wMBMFKNb/4uFGrVaigSpg== dependencies: regenerator-runtime "^0.13.2" @@ -766,10 +766,10 @@ "@hapi/hoek" "8.x.x" "@hapi/topo" "3.x.x" -"@hapi/joi@^16.1.4": - version "16.1.4" - resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-16.1.4.tgz#b039fe474a0ab838c1a90620c53a208fcef75d99" - integrity sha512-m7ctezhxjob+dSpXnCNlgAj6rrEpdSsaWu3GWL3g1AybQCU36mlAo9IwGFJwIxD+oHgdO6mYyviYlaejX+qN6g== +"@hapi/joi@^16.1.5": + version "16.1.5" + resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-16.1.5.tgz#06bdfec1084f46bff6be8f6b4076d8314c81cea2" + integrity sha512-FnVe0t1YQbF0H4fhFM6qBL7lIP4wdVHdFFBkloxgCkpKKdaCB6Z2UaNI0UalaDRHbRM9BvfTfyUKJg7tGtBSXg== dependencies: "@hapi/address" "^2.1.2" "@hapi/formula" "^1.2.0" @@ -971,7 +971,7 @@ url-regex "~4.1.1" video-extensions "~1.1.0" -"@metascraper/helpers@^5.7.5", "@metascraper/helpers@^5.7.6": +"@metascraper/helpers@^5.7.6": version "5.7.6" resolved "https://registry.yarnpkg.com/@metascraper/helpers/-/helpers-5.7.6.tgz#84007215d3b31525995fd85cf0d28bf6a12bf7bb" integrity sha512-AD2VTQmMWl/KCUXl9h0fP84VacoiTI/8y8CBgErmYZnm+sliKGedQrDZO3JmzNg73Z5z08GQTjME1WHIDiIQDw== @@ -2626,10 +2626,10 @@ create-error-class@^3.0.0: dependencies: capture-stack-trace "^1.0.0" -cross-env@~6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-6.0.0.tgz#3c8e71440ea20aa6faaf5aec541235efc565dac6" - integrity sha512-G/B6gtkjgthT8AP/xN1wdj5Xe18fVyk58JepK8GxpUbqcz3hyWxegocMbvnZK+KoTslwd0ACZ3woi/DVUdVjyQ== +cross-env@~6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-6.0.3.tgz#4256b71e49b3a40637a0ce70768a6ef5c72ae941" + integrity sha512-+KqxF6LCvfhWvADcDPqo64yVIB31gv/jQulX2NGzKS/g3GEVz6/pt4wjHFtFWsHMddebWD/sDthJemzM4MaAag== dependencies: cross-spawn "^7.0.0" @@ -5754,12 +5754,12 @@ metascraper-date@^5.7.6: dependencies: "@metascraper/helpers" "^5.7.6" -metascraper-description@^5.7.5: - version "5.7.5" - resolved "https://registry.yarnpkg.com/metascraper-description/-/metascraper-description-5.7.5.tgz#b19be853f7f712d2c388cb0c4086b3b38f6e603b" - integrity sha512-9WHt9XRIj7OCS1wkFbvFI4dOkdgc6I74dC78UcVlwJYJKpRRonm83i5opev4chG4psOwbUhZUhKS3n+Rb8khCg== +metascraper-description@^5.7.6: + version "5.7.6" + resolved "https://registry.yarnpkg.com/metascraper-description/-/metascraper-description-5.7.6.tgz#3a26b8bb8f325b1e959864f2c983ad4ef6050c24" + integrity sha512-DtcIRTwI2RFdy2NBSYCUpekNSqMH4BVNjAJNpWWYsDJZbk5rw6w2gOgzJH4HUM4eYKDkd0/tVd+HZYz57xxYBQ== dependencies: - "@metascraper/helpers" "^5.7.5" + "@metascraper/helpers" "^5.7.6" metascraper-image@^5.7.6: version "5.7.6" diff --git a/cypress/integration/common/report.js b/cypress/integration/common/report.js index fb395d361..c51c6b42e 100644 --- a/cypress/integration/common/report.js +++ b/cypress/integration/common/report.js @@ -5,7 +5,7 @@ import { Given, When, Then } from 'cypress-cucumber-preprocessor/steps' let lastReportTitle let davidIrvingPostTitle = 'The Truth about the Holocaust' let davidIrvingPostSlug = 'the-truth-about-the-holocaust' -let davidIrvingName = 'David Irving' +let annoyingUserWhoBlockedModeratorTitle = 'Fake news' const savePostTitle = $post => { return $post @@ -116,7 +116,7 @@ When(/^I confirm the reporting dialog .*:$/, message => { Given('somebody reported the following posts:', table => { table.hashes().forEach(({ id }) => { const submitter = { - email: `submitter${id}@example.org`, + email: `submitter${id}@example.org`, password: '1234' } cy.factory() @@ -139,7 +139,28 @@ Then('I see all the reported posts including the one from above', () => { }) }) +Then('I see all the reported posts including from the user who blocked me', () => { + cy.get('table tbody').within(() => { + cy.contains('tr', annoyingUserWhoBlockedModeratorTitle) + }) +}) + Then('each list item links to the post page', () => { cy.contains(davidIrvingPostTitle).click() cy.location('pathname').should('contain', '/post') }) + +Then('I can visit the post page', () => { + cy.contains(annoyingUserWhoBlockedModeratorTitle).click() + cy.location('pathname').should('contain', '/post') + .get('h3').should('contain', annoyingUserWhoBlockedModeratorTitle) +}) + +When("they have a post someone has reported", () => { + cy.factory() + .create("Post", { + authorId: 'annnoying-user', + title, + }); + +}) diff --git a/cypress/integration/common/steps.js b/cypress/integration/common/steps.js index a25200667..ab1790756 100644 --- a/cypress/integration/common/steps.js +++ b/cypress/integration/common/steps.js @@ -410,6 +410,20 @@ Given("there is an annoying user called {string}", name => { }); }); +Given("there is an annoying user who has blocked me", () => { + cy.neode() + .first("User", { + role: 'moderator' + }) + .then(blocked => { + cy.neode() + .first("User", { + id: 'annoying-user' + }) + .relateTo(blocked, "blocked"); + }); +}); + Given("I am on the profile page of the annoying user", name => { cy.openPage("/profile/annoying-user/spammy-spammer"); }); diff --git a/cypress/integration/moderation/ReportContent.feature b/cypress/integration/moderation/ReportContent.feature index 0181dc7a6..0f8eec0e3 100644 --- a/cypress/integration/moderation/ReportContent.feature +++ b/cypress/integration/moderation/ReportContent.feature @@ -8,13 +8,15 @@ Feature: Report and Moderate So I can look into it and decide what to do Background: - Given we have this user in our database: - | id | name | - | u67 | David Irving| + Given we have the following user accounts: + | id | name | + | u67 | David Irving | + | annoying-user | I'm gonna block Moderators and Admins HA HA HA | + Given we have the following posts in our database: - | authorId | id | title | content | - | u67 | p1 | The Truth about the Holocaust | It never existed! | - + | authorId | id | title | content | + | u67 | p1 | The Truth about the Holocaust | It never existed! | + | annoying-user | p2 | Fake news | This content is demonstratably infactual in some way | Scenario Outline: Report a post from various pages Given I am logged in with a "user" role When I see David Irving's post on the @@ -56,6 +58,18 @@ Feature: Report and Moderate Then I see all the reported posts including the one from above And each list item links to the post page + Scenario: Review reported posts of a user who's blocked a moderator + Given somebody reported the following posts: + | id | + | p2 | + And my user account has the role "moderator" + And there is an annoying user who has blocked me + And I am logged in + When I click on the avatar menu in the top right corner + And I click on "Moderation" + Then I see all the reported posts including from the user who blocked me + And I can visit the post page + Scenario: Normal user can't see the moderation page Given I am logged in with a "user" role When I click on the avatar menu in the top right corner diff --git a/deployment/volumes/neo4j-online-backup/README.md b/deployment/volumes/neo4j-online-backup/README.md new file mode 100644 index 000000000..f096c769f --- /dev/null +++ b/deployment/volumes/neo4j-online-backup/README.md @@ -0,0 +1,57 @@ +# Backup (online) + +## Online backups are only avaible with a Neo4j Enterprise and a license, see https://neo4j.com/licensing/ for the different licenses available + +This tutorial explains how to carry out an online backup of your Neo4J +database in a kubernetes cluster. + +One of the benefits of doing an online backup is that the Neo4j database does not need to be stopped, so there is no downtime. Read [the docs](https://neo4j.com/docs/operations-manual/current/backup/performing/) + +To use Neo4j Enterprise you must add this line to your configmap, if using, or your deployment `nitro-neo4j` env. + +``` +NEO4J_ACCEPT_LICENSE_AGREEMENT: "yes" +``` +## Create a Backup in Kubernetes + +```sh +# Backup the database with one command, this will get the nitro-neo4j pod, ssh into it, and run the backup command +kubectl -n=human-connection exec -it $(kubectl -n=human-connection get pods | grep nitro-neo4j | awk '{ print $1 }') -- neo4j-admin backup --backup-dir=/var/lib/neo4j --name=neo4j-backup +# Download the file from the pod to your computer. +kubectl cp human-connection/$(kubectl -n=human-connection get pods | grep nitro-neo4j | awk '{ print $1 }'):/var/lib/neo4j/neo4j-backup ./neo4j-backup/ +``` + +You should now have a backup of the database locally. If you want, you can simulate disaster recovery by sshing into the nitro-neo4j pod, deleting all data and restoring from backup + +## Disaster where database data is gone somehow + +```sh +kubectl -n=human-connection exec -it $(kubectl -n=human-connection get pods | grep nitro-neo4j |awk '{ print $1 }') bash +# Enter cypher-shell +cypher-shell +# Delete all data +> MATCH (n) DETACH DELETE (n); + +exit +``` + +## Restore a backup in Kubernetes + +Restoration must be done while the database is not running, see [our docs](https://docs.human-connection.org/human-connection/deployment/volumes/neo4j-offline-backup#stop-and-restart-neo-4-j-database-in-kubernetes) for how to stop the database, but keep the container running + +After, you have stopped the database, and have the pod running, you can restore the database by running these commands: + +```sh +kubectl --namespace=human-connection get pods +# Copy the ID of the pod running Neo4J. +# Then upload your local backup to the pod. Note that once the pod gets deleted +# e.g. if you change the deployment, the backup file is gone with it. +kubectl cp ./neo4j-backup/ human-connection/:/root/ +kubectl --namespace=human-connection exec -it bash +# Once you're in the pod restore the backup and overwrite the default database +# called `graph.db` with `--force`. +# This will delete all existing data in database `graph.db`! +neo4j-admin restore --from=/root/neo4j-backup --force +exit +``` +Revert your changes to deployment `nitro-neo4j` which will restart the database. \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index e937feeed..c5ce3a20f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -57,6 +57,7 @@ services: environment: - NEO4J_AUTH=none - NEO4J_dbms_security_procedures_unrestricted=algo.*,apoc.* + - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes ports: - 7687:7687 - 7474:7474 diff --git a/neo4j/Dockerfile b/neo4j/Dockerfile index 597ed50b7..7c0e83ea7 100644 --- a/neo4j/Dockerfile +++ b/neo4j/Dockerfile @@ -1,4 +1,4 @@ -FROM neo4j:3.5.11 +FROM neo4j:3.5.11-enterprise LABEL Description="Neo4J database of the Social Network Human-Connection.org with preinstalled database constraints and indices" Vendor="Human Connection gGmbH" Version="0.0.1" Maintainer="Human Connection gGmbH (developer@human-connection.org)" ARG BUILD_COMMIT diff --git a/package.json b/package.json index 94e567787..62020c4e4 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "devDependencies": { "bcryptjs": "^2.4.3", "codecov": "^3.6.1", - "cross-env": "^6.0.0", + "cross-env": "^6.0.3", "cypress": "^3.4.1", "cypress-cucumber-preprocessor": "^1.16.0", "cypress-file-upload": "^3.3.4", diff --git a/webapp/components/Registration/Signup.spec.js b/webapp/components/Registration/Signup.spec.js index afcf94c37..ed78d47a2 100644 --- a/webapp/components/Registration/Signup.spec.js +++ b/webapp/components/Registration/Signup.spec.js @@ -115,7 +115,7 @@ describe('Signup', () => { mocks.$apollo.mutate = jest .fn() .mockRejectedValue( - new Error('UserInputError: User account with this email already exists.'), + new Error('UserInputError: A user account with this email already exists.'), ) }) diff --git a/webapp/components/Registration/Signup.vue b/webapp/components/Registration/Signup.vue index dcf4f0e88..36a43f180 100644 --- a/webapp/components/Registration/Signup.vue +++ b/webapp/components/Registration/Signup.vue @@ -128,7 +128,7 @@ export default { } catch (err) { const { message } = err const mapping = { - 'User account with this email already exists': 'email-exists', + 'A user account with this email already exists': 'email-exists', 'Invitation code already used or does not exist': 'invalid-invitation-token', } for (const [pattern, key] of Object.entries(mapping)) { diff --git a/webapp/graphql/EmailAddress.js b/webapp/graphql/EmailAddress.js new file mode 100644 index 000000000..675ec6bed --- /dev/null +++ b/webapp/graphql/EmailAddress.js @@ -0,0 +1,20 @@ +import gql from 'graphql-tag' + +export const AddEmailAddressMutation = gql` + mutation($email: String!) { + AddEmailAddress(email: $email) { + email + createdAt + } + } +` + +export const VerifyEmailAddressMutation = gql` + mutation($email: String!, $nonce: String!) { + VerifyEmailAddress(email: $email, nonce: $nonce) { + email + verifiedAt + createdAt + } + } +` diff --git a/webapp/locales/de.json b/webapp/locales/de.json index 7b7bc3ec1..c547e063f 100644 --- a/webapp/locales/de.json +++ b/webapp/locales/de.json @@ -158,6 +158,27 @@ "labelBio": "Über dich", "success": "Deine Daten wurden erfolgreich aktualisiert!" }, + "email": { + "validation": { + "same-email": "Das ist deine aktuelle E-Mail Addresse" + }, + "name": "Deine E-Mail", + "labelEmail": "E-Mail Adresse Γ€ndern", + "labelNewEmail": "Neue E-Mail Adresse", + "labelNonce": "BestΓ€tigungscode eingeben", + "success": "Eine neue E-Mail Addresse wurde registriert.", + "submitted": "Eine E-Mail zur BestΓ€tigung deiner Adresse wurde an {email} gesendet.", + "change-successful": "Deine E-Mail Adresse wurde erfolgreich geΓ€ndert.", + "verification-error": { + "message": "Deine E-Mail Adresse konnte nicht verifiziert werden.", + "support": "Wenn das Problem weiterhin besteht, kontaktiere uns gerne per E-Mail an", + "explanation": "Das kann verschiedene Ursachen haben:", + "reason": { + "invalid-nonce": "Ist der BestΓ€tigungscode falsch?", + "no-email-request": "Bist du dir sicher, dass du eine Γ„nderung deiner E-Mail Adresse angefragt hattest?" + } + } + }, "validation": { "slug": { "regex": "Es sind nur Kleinbuchstaben, Zahlen, Unterstriche oder Bindestriche erlaubt.", diff --git a/webapp/locales/en.json b/webapp/locales/en.json index 49cb35210..ef623050f 100644 --- a/webapp/locales/en.json +++ b/webapp/locales/en.json @@ -159,6 +159,27 @@ "labelBio": "About You", "success": "Your data was successfully updated!" }, + "email": { + "validation": { + "same-email": "This is your current email address" + }, + "name": "Your email", + "labelEmail": "Change your email address", + "labelNewEmail": "New email Address", + "labelNonce": "Enter your code", + "success": "A new email address has been registered.", + "submitted": "An email to verify your address has been sent to {email}.", + "change-successful": "Your email address has been changed successfully.", + "verification-error": { + "message": "Your email could not be changed.", + "explanation": "This can have different causes:", + "reason": { + "invalid-nonce": "Is the confirmation code invalid?", + "no-email-request": "Are you certain that you requested a change of your email address?" + }, + "support": "If the problem persists, please contact us by email at" + } + }, "validation": { "slug": { "regex": "Allowed characters are only lowercase letters, numbers, underscores and hyphens.", @@ -254,7 +275,7 @@ "users": { "name": "Users", "form": { - "placeholder": "E-Mail, name or description" + "placeholder": "email, name or description" }, "table": { "columns": { diff --git a/webapp/package.json b/webapp/package.json index 97b00e0c0..be343570e 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -52,7 +52,7 @@ }, "dependencies": { "@human-connection/styleguide": "0.5.21", - "@nuxtjs/apollo": "^4.0.0-rc13.1", + "@nuxtjs/apollo": "^4.0.0-rc14", "@nuxtjs/axios": "~5.6.0", "@nuxtjs/dotenv": "~1.4.1", "@nuxtjs/pwa": "^3.0.0-beta.19", @@ -62,7 +62,7 @@ "apollo-cache-inmemory": "~1.6.3", "apollo-client": "~2.6.4", "cookie-universal-nuxt": "~2.0.18", - "cross-env": "~6.0.0", + "cross-env": "~6.0.3", "date-fns": "2.4.1", "express": "~4.17.1", "graphql": "~14.5.8", @@ -70,7 +70,7 @@ "jsonwebtoken": "~8.5.1", "linkify-it": "~2.2.0", "node-fetch": "^2.6.0", - "nuxt": "~2.9.2", + "nuxt": "~2.10.0", "nuxt-dropzone": "^1.0.4", "nuxt-env": "~0.1.0", "stack-utils": "^1.0.2", diff --git a/webapp/pages/settings.vue b/webapp/pages/settings.vue index 67493c333..5795792f9 100644 --- a/webapp/pages/settings.vue +++ b/webapp/pages/settings.vue @@ -23,6 +23,10 @@ export default { name: this.$t('settings.data.name'), path: `/settings`, }, + { + name: this.$t('settings.email.name'), + path: `/settings/my-email-address`, + }, { name: this.$t('settings.security.name'), path: `/settings/security`, diff --git a/webapp/pages/settings/index.vue b/webapp/pages/settings/index.vue index d32d9a91b..934b10558 100644 --- a/webapp/pages/settings/index.vue +++ b/webapp/pages/settings/index.vue @@ -31,14 +31,7 @@ :placeholder="$t('settings.data.labelBio')" /> diff --git a/webapp/pages/settings/my-email-address/enter-nonce.spec.js b/webapp/pages/settings/my-email-address/enter-nonce.spec.js new file mode 100644 index 000000000..abb6a71bf --- /dev/null +++ b/webapp/pages/settings/my-email-address/enter-nonce.spec.js @@ -0,0 +1,53 @@ +import { mount, createLocalVue } from '@vue/test-utils' +import EnterNoncePage from './enter-nonce.vue' +import Styleguide from '@human-connection/styleguide' + +const localVue = createLocalVue() + +localVue.use(Styleguide) + +describe('EnterNoncePage', () => { + let mocks + let wrapper + + beforeEach(() => { + wrapper = null + mocks = { + $t: jest.fn(t => t), + $route: { + query: {}, + }, + $router: { + replace: jest.fn(), + }, + } + }) + + describe('mount', () => { + const Wrapper = () => { + return mount(EnterNoncePage, { + mocks, + localVue, + }) + } + + describe('form', () => { + describe('submit', () => { + it('renders form errors', () => { + wrapper = Wrapper() + wrapper.find('form').trigger('submit') + expect(mocks.$router.replace).not.toHaveBeenCalled() + }) + + describe('entering a nonce', () => { + it('redirects to my-email-address/verify', () => { + wrapper = Wrapper() + wrapper.find('#nonce').setValue('foobar') + wrapper.find('form').trigger('submit') + expect(mocks.$router.replace).toHaveBeenCalled() + }) + }) + }) + }) + }) +}) diff --git a/webapp/pages/settings/my-email-address/enter-nonce.vue b/webapp/pages/settings/my-email-address/enter-nonce.vue new file mode 100644 index 000000000..85755953a --- /dev/null +++ b/webapp/pages/settings/my-email-address/enter-nonce.vue @@ -0,0 +1,59 @@ + + + diff --git a/webapp/pages/settings/my-email-address/index.spec.js b/webapp/pages/settings/my-email-address/index.spec.js new file mode 100644 index 000000000..8bf1bb986 --- /dev/null +++ b/webapp/pages/settings/my-email-address/index.spec.js @@ -0,0 +1,116 @@ +import { config, mount, createLocalVue } from '@vue/test-utils' +import EmailSettingsIndexPage from './index.vue' +import Vuex from 'vuex' +import Styleguide from '@human-connection/styleguide' + +const localVue = createLocalVue() + +localVue.use(Vuex) +localVue.use(Styleguide) + +config.stubs['sweetalert-icon'] = '' + +describe('EmailSettingsIndexPage', () => { + let store + let mocks + let wrapper + + beforeEach(() => { + wrapper = null + store = new Vuex.Store({ + getters: { + 'auth/user': () => { + return { id: 'u23', email: 'some-mail@example.org' } + }, + }, + }) + mocks = { + $t: jest.fn(t => t), + $toast: { + success: jest.fn(), + error: jest.fn(), + }, + $apollo: { + mutate: jest.fn().mockResolvedValue(), + }, + $router: { + push: jest.fn(), + }, + } + }) + + describe('mount', () => { + const Wrapper = () => { + return mount(EmailSettingsIndexPage, { + store, + mocks, + localVue, + }) + } + + describe('form', () => { + describe('submit', () => { + beforeEach(jest.useFakeTimers) + + describe('email unchanged', () => { + beforeEach(() => { + wrapper = Wrapper() + wrapper.find('form').trigger('submit') + }) + + it('displays form errors', () => { + expect(wrapper.text()).not.toContain('settings.email.submitted') + expect(wrapper.text()).toContain('settings.email.validation.same-email') + }) + + it('does not call $apollo.mutate', () => { + expect(mocks.$apollo.mutate).not.toHaveBeenCalled() + }) + }) + + describe('enter another email', () => { + beforeEach(() => { + wrapper = Wrapper() + wrapper.find('#email').setValue('yet-another-email@example.org') + wrapper.find('form').trigger('submit') + }) + + it('calls $apollo.mutate', () => { + expect(mocks.$apollo.mutate).toHaveBeenCalled() + }) + + it('no form errors', () => { + expect(wrapper.text()).not.toContain('settings.email.validation.same-email') + expect(wrapper.text()).toContain('settings.email.submitted') + }) + + describe('after timeout', () => { + beforeEach(jest.runAllTimers) + + it('redirects to `my-email-address/enter-nonce`', () => { + expect(mocks.$router.push).toHaveBeenCalledWith({ + path: 'my-email-address/enter-nonce', + query: { email: 'yet-another-email@example.org' }, + }) + }) + }) + }) + + describe('if backend responds with unique constraint violation', () => { + beforeEach(() => { + mocks.$apollo.mutate = jest.fn().mockRejectedValue({ + message: 'User account already exists', + }) + wrapper = Wrapper() + wrapper.find('#email').setValue('already-taken@example.org') + wrapper.find('form').trigger('submit') + }) + + it('translates error message', () => { + expect(wrapper.text()).toContain('registration.signup.form.errors.email-exists') + }) + }) + }) + }) + }) +}) diff --git a/webapp/pages/settings/my-email-address/index.vue b/webapp/pages/settings/my-email-address/index.vue new file mode 100644 index 000000000..fcfeb941d --- /dev/null +++ b/webapp/pages/settings/my-email-address/index.vue @@ -0,0 +1,113 @@ + + + diff --git a/webapp/pages/settings/my-email-address/verify.spec.js b/webapp/pages/settings/my-email-address/verify.spec.js new file mode 100644 index 000000000..d0f098bb0 --- /dev/null +++ b/webapp/pages/settings/my-email-address/verify.spec.js @@ -0,0 +1,164 @@ +import { config, mount, createLocalVue } from '@vue/test-utils' +import EmailVerifyPage from './verify.vue' +import Vuex from 'vuex' +import Styleguide from '@human-connection/styleguide' + +const localVue = createLocalVue() + +localVue.use(Vuex) +localVue.use(Styleguide) + +config.stubs['client-only'] = '' +config.stubs['sweetalert-icon'] = '' + +describe('EmailVerifyPage', () => { + let store + let mocks + let wrapper + let setUser + + beforeEach(() => { + setUser = jest.fn() + wrapper = null + store = new Vuex.Store({ + getters: { + 'auth/user': () => { + return { id: 'u23', email: 'some-mail@example.org' } + }, + }, + mutations: { + 'auth/SET_USER': setUser, + }, + }) + mocks = { + $t: jest.fn(t => t), + $toast: { + success: jest.fn(), + error: jest.fn(), + }, + $router: { + replace: jest.fn(), + }, + store, + } + }) + + describe('asyncData', () => { + const asyncDataAction = () => { + const context = { + store: mocks.store, + query: {}, + app: { + apolloProvider: { + defaultClient: mocks.$apollo, + }, + }, + } + return EmailVerifyPage.asyncData(context) + } + + describe('backend sends successful response', () => { + beforeEach(() => { + mocks = { + ...mocks, + $apollo: { + mutate: jest.fn().mockResolvedValue({ + data: { + VerifyEmailAddress: { + email: 'verified-email@example.org', + }, + }, + }), + }, + } + }) + + it('sets `success` to true', async () => { + await expect(asyncDataAction()).resolves.toEqual({ + success: true, + }) + }) + + it("updates current user's email", async () => { + await asyncDataAction() + expect(setUser).toHaveBeenCalledWith({}, { id: 'u23', email: 'verified-email@example.org' }) + }) + }) + + describe('backend sends unsuccessful response', () => { + beforeEach(() => { + mocks = { + ...mocks, + $apollo: { + mutate: jest.fn().mockRejectedValue({ + data: { VerifyEmailAddress: null }, + errors: [{ message: 'User account already exists with that email' }], + }), + }, + } + }) + + it('sets `success` to false', async () => { + await expect(asyncDataAction()).resolves.toEqual({ + success: false, + }) + }) + + it('does not updates current user', async () => { + await asyncDataAction() + expect(setUser).not.toHaveBeenCalled() + }) + }) + }) + + describe('mount', () => { + beforeEach(jest.useFakeTimers) + const Wrapper = () => { + return mount(EmailVerifyPage, { + store, + mocks, + localVue, + }) + } + + describe('given successful verification', () => { + beforeEach(() => { + mocks = { ...mocks, success: true } + wrapper = Wrapper() + }) + + it('shows success message', () => { + expect(wrapper.text()).toContain('settings.email.change-successful') + }) + + describe('after timeout', () => { + beforeEach(jest.runAllTimers) + + it('redirects to email settings page', () => { + expect(mocks.$router.replace).toHaveBeenCalledWith({ + name: 'settings-my-email-address', + }) + }) + }) + }) + + describe('given unsuccessful verification', () => { + beforeEach(() => { + mocks = { ...mocks, success: false } + wrapper = Wrapper() + }) + + it('shows success message', () => { + expect(wrapper.text()).toContain('settings.email.verification-error') + }) + + describe('after timeout', () => { + beforeEach(jest.runAllTimers) + + it('does not redirect', () => { + expect(mocks.$router.replace).not.toHaveBeenCalledWith() + }) + }) + }) + }) +}) diff --git a/webapp/pages/settings/my-email-address/verify.vue b/webapp/pages/settings/my-email-address/verify.vue new file mode 100644 index 000000000..21e4fd775 --- /dev/null +++ b/webapp/pages/settings/my-email-address/verify.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/webapp/yarn.lock b/webapp/yarn.lock index cf0c4095d..6e0fc69b8 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -"@apollographql/apollo-tools@0.4.0", "@apollographql/apollo-tools@^0.4.0": +"@apollographql/apollo-tools@^0.4.0": version "0.4.0" resolved "https://registry.yarnpkg.com/@apollographql/apollo-tools/-/apollo-tools-0.4.0.tgz#8a1a0ab7a0bb12ccc03b72e4a104cfa5d969fd5f" integrity sha512-7wEO+S+zgz/wVe3ilFQqICufRBYYDSNUkd1V03JWvXuSydbYq2SM5EgvWmFF+04iadt+aQ0XCCsRzCzRPQODfQ== @@ -56,7 +56,7 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@^7.1.0", "@babel/core@^7.5.5", "@babel/core@~7.6.2": +"@babel/core@^7.1.0", "@babel/core@^7.6.2", "@babel/core@~7.6.2": version "7.6.2" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.2.tgz#069a776e8d5e9eefff76236bc8845566bd31dd91" integrity sha512-l8zto/fuoZIbncm+01p8zPSDZu/VuuJhAfA7d/AbzM09WR7iVhavvfNDYCNpo1VvLk6E6xgAoP9P+/EMJHuRkQ== @@ -121,18 +121,6 @@ "@babel/traverse" "^7.4.4" "@babel/types" "^7.4.4" -"@babel/helper-create-class-features-plugin@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.4.4.tgz#fc3d690af6554cc9efc607364a82d48f58736dba" - integrity sha512-UbBHIa2qeAGgyiNR9RszVF7bUHEdgS4JAUNT8SiqrAN6YJVxlOxeLr5pBzb5kan302dejJ9nla4RyKcR1XT6XA== - dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-member-expression-to-functions" "^7.0.0" - "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.4.4" - "@babel/helper-split-export-declaration" "^7.4.4" - "@babel/helper-create-class-features-plugin@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.5.tgz#401f302c8ddbc0edd36f7c6b2887d8fa1122e5a4" @@ -145,6 +133,18 @@ "@babel/helper-replace-supers" "^7.5.5" "@babel/helper-split-export-declaration" "^7.4.4" +"@babel/helper-create-class-features-plugin@^7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.6.0.tgz#769711acca889be371e9bc2eb68641d55218021f" + integrity sha512-O1QWBko4fzGju6VoVvrZg0RROCVifcLxiApnGP3OWfWzvxRZFCoBD81K5ur5e3bVY2Vf/5rIJm8cqPKn8HUJng== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-member-expression-to-functions" "^7.5.5" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.5.5" + "@babel/helper-split-export-declaration" "^7.4.4" + "@babel/helper-define-map@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz#3dec32c2046f37e09b28c93eb0b103fd2a25d369" @@ -185,13 +185,6 @@ dependencies: "@babel/types" "^7.4.4" -"@babel/helper-member-expression-to-functions@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz#8cd14b0a0df7ff00f009e7d7a436945f47c7a16f" - integrity sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg== - dependencies: - "@babel/types" "^7.0.0" - "@babel/helper-member-expression-to-functions@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz#1fb5b8ec4453a93c439ee9fe3aeea4a84b76b590" @@ -248,16 +241,6 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.0.0" -"@babel/helper-replace-supers@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.4.4.tgz#aee41783ebe4f2d3ab3ae775e1cc6f1a90cefa27" - integrity sha512-04xGEnd+s01nY1l15EuMS1rfKktNF+1CkKmHoErDppjAAZL+IUBZpzT748x262HF7fibaQPhbvWUl5HeSt1EXg== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.0.0" - "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/traverse" "^7.4.4" - "@babel/types" "^7.4.4" - "@babel/helper-replace-supers@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz#f84ce43df031222d2bad068d2626cb5799c34bc2" @@ -333,12 +316,12 @@ "@babel/helper-create-class-features-plugin" "^7.5.5" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-proposal-decorators@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.4.4.tgz#de9b2a1a8ab0196f378e2a82f10b6e2a36f21cc0" - integrity sha512-z7MpQz3XC/iQJWXH9y+MaWcLPNSMY9RQSthrLzak8R8hCj0fuyNk+Dzi9kfNe/JxxlWQ2g7wkABbgWjW36MTcw== +"@babel/plugin-proposal-decorators@^7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.6.0.tgz#6659d2572a17d70abd68123e89a12a43d90aa30c" + integrity sha512-ZSyYw9trQI50sES6YxREXKu+4b7MAg6Qx2cvyDDYjP2Hpzd3FleOUwC9cqn1+za8d0A2ZU8SHujxFao956efUg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.4.4" + "@babel/helper-create-class-features-plugin" "^7.6.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-decorators" "^7.2.0" @@ -640,10 +623,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-runtime@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz#a6331afbfc59189d2135b2e09474457a8e3d28bc" - integrity sha512-6Xmeidsun5rkwnGfMOp6/z9nSzWpHFNVr2Jx7kwoq4mVatQfQx5S56drBgEHF+XQbKOdIaOiMIINvp/kAwMN+w== +"@babel/plugin-transform-runtime@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.6.2.tgz#2669f67c1fae0ae8d8bf696e4263ad52cb98b6f8" + integrity sha512-cqULw/QB4yl73cS5Y0TZlQSjDvNkzDbu0FurTZyHlJpWE5T3PCMdnyV+xXoH1opr1ldyHODe3QAX3OMAii5NxA== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -696,7 +679,7 @@ "@babel/helper-regex" "^7.4.4" regexpu-core "^4.6.0" -"@babel/preset-env@^7.4.5", "@babel/preset-env@^7.5.5", "@babel/preset-env@~7.6.2": +"@babel/preset-env@^7.4.5", "@babel/preset-env@^7.6.2", "@babel/preset-env@~7.6.2": version "7.6.2" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.6.2.tgz#abbb3ed785c7fe4220d4c82a53621d71fc0c75d3" integrity sha512-Ru7+mfzy9M1/YTEtlDS8CD45jd22ngb9tXnn64DvQK3ooyqSw9K4K9DUWmYknTTVk4TqygL9dqCrZgm1HMea/Q== @@ -767,24 +750,10 @@ dependencies: regenerator-runtime "^0.12.0" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.3", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" - integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== - dependencies: - regenerator-runtime "^0.13.2" - -"@babel/runtime@^7.4.4": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.0.tgz#4fc1d642a9fd0299754e8b5de62c631cf5568205" - integrity sha512-89eSBLJsxNxOERC0Op4vd+0Bqm6wRMqMbFtV3i0/fbaWw/mJ8Q3eBvgX0G4SyrOOLCtbu98HspF8o09MRT+KzQ== - dependencies: - regenerator-runtime "^0.13.2" - -"@babel/runtime@^7.4.5": - version "7.4.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.5.tgz#582bb531f5f9dc67d2fcb682979894f75e253f12" - integrity sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ== +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.3", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.2.tgz#c3d6e41b304ef10dcf13777a33e7694ec4a9a6dd" + integrity sha512-EXxN64agfUqqIGeEjI5dL5z0Sw0ZwWo1mLTi4mQowCZ42O59b7DRpZAnTC6OqdF28wMBMFKNb/4uFGrVaigSpg== dependencies: regenerator-runtime "^0.13.2" @@ -812,16 +781,7 @@ globals "^11.1.0" lodash "^4.17.13" -"@babel/types@7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.5.tgz#97b9f728e182785909aa4ab56264f090a028d18a" - integrity sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw== - dependencies: - esutils "^2.0.2" - lodash "^4.17.13" - to-fast-properties "^2.0.0" - -"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5", "@babel/types@^7.6.0": +"@babel/types@7.6.1", "@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5", "@babel/types@^7.6.0": version "7.6.1" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.6.1.tgz#53abf3308add3ac2a2884d539151c57c4b3ac648" integrity sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g== @@ -1216,29 +1176,29 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== -"@nuxt/babel-preset-app@2.9.2": - version "2.9.2" - resolved "https://registry.yarnpkg.com/@nuxt/babel-preset-app/-/babel-preset-app-2.9.2.tgz#e8d2ac841db845ef88ca2687093a95a480106e5d" - integrity sha512-s4423c5Pvl3aCmD8KoDdit1XZuZig0sCwop5KV3kn0/KfEru+jFWbQ3pTssCV8XTR9Am2BV0UIQ0hoCMdnvdfw== +"@nuxt/babel-preset-app@2.10.0": + version "2.10.0" + resolved "https://registry.yarnpkg.com/@nuxt/babel-preset-app/-/babel-preset-app-2.10.0.tgz#5f3cd3ef7dbd851d8120c28866f29ede7e64a43d" + integrity sha512-G+HY00F1e80ic2CwGMCA4FNAY1PcKMi/WshYOus8ObZxuHvlvsObKVilZq5l9P1xQqgcCoRyetEnhfMnpxqt7Q== dependencies: - "@babel/core" "^7.5.5" + "@babel/core" "^7.6.2" "@babel/plugin-proposal-class-properties" "^7.5.5" - "@babel/plugin-proposal-decorators" "^7.4.4" - "@babel/plugin-transform-runtime" "^7.5.5" - "@babel/preset-env" "^7.5.5" - "@babel/runtime" "^7.5.5" + "@babel/plugin-proposal-decorators" "^7.6.0" + "@babel/plugin-transform-runtime" "^7.6.2" + "@babel/preset-env" "^7.6.2" + "@babel/runtime" "^7.6.2" "@vue/babel-preset-jsx" "^1.1.0" core-js "^2.6.5" -"@nuxt/builder@2.9.2": - version "2.9.2" - resolved "https://registry.yarnpkg.com/@nuxt/builder/-/builder-2.9.2.tgz#57c515efc446c02e4062ebdb6cd735ea456df4dd" - integrity sha512-egDjm2AnaKjeAlZ0yNAooP+Xd/fKIvhK66qNyd+ekvzutSkbSkKtB/udNxyHcBnjg8GOB4KayIXvBX0K1TS/vg== +"@nuxt/builder@2.10.0": + version "2.10.0" + resolved "https://registry.yarnpkg.com/@nuxt/builder/-/builder-2.10.0.tgz#3f59fe06c1bde1af25c969ca85ebfee7201d1151" + integrity sha512-c8NgfILAvFRBwstUu8x9l8TZUUM0FiDB8gPewvYPsP2uEuy5HEglhGzj8+/NDU/lgvHh2a9jToDjTX1LpYYHuQ== dependencies: "@nuxt/devalue" "^1.2.4" - "@nuxt/utils" "2.9.2" - "@nuxt/vue-app" "2.9.2" - chokidar "^3.0.2" + "@nuxt/utils" "2.10.0" + "@nuxt/vue-app" "2.10.0" + chokidar "^3.2.1" consola "^2.10.1" fs-extra "^8.1.0" glob "^7.1.4" @@ -1247,16 +1207,16 @@ lodash "^4.17.15" pify "^4.0.1" semver "^6.3.0" - serialize-javascript "^1.8.0" - upath "^1.1.2" + serialize-javascript "^2.1.0" + upath "^1.2.0" -"@nuxt/cli@2.9.2": - version "2.9.2" - resolved "https://registry.yarnpkg.com/@nuxt/cli/-/cli-2.9.2.tgz#d56540f95b58afa7c7073c166d6f624b78024fca" - integrity sha512-9Pxavn/w/K4uUItXPNmKyT1aBoGlJPqTdpr3nlXRX00JSU1OKd2fTNL3RlaN+xXtlYh2XoZo2roGHAFX1CyKrw== +"@nuxt/cli@2.10.0": + version "2.10.0" + resolved "https://registry.yarnpkg.com/@nuxt/cli/-/cli-2.10.0.tgz#48c90a7c3d3be5d40b70daf8f2280f1865ccc2fe" + integrity sha512-nmARLjlBLWwWtWsgmyWTk4YGEkkUQvOqJS1YZlQy6CPU/itRdIDv9D/vbZZv2NkWegXQJOQ8UUv9iCue9g06bw== dependencies: - "@nuxt/config" "2.9.2" - "@nuxt/utils" "2.9.2" + "@nuxt/config" "2.10.0" + "@nuxt/utils" "2.10.0" boxen "^4.1.0" chalk "^2.4.2" consola "^2.10.1" @@ -1264,37 +1224,37 @@ execa "^2.0.4" exit "^0.1.2" fs-extra "^8.1.0" - hable "^2.2.1" + hable "^2.3.2" minimist "^1.2.0" opener "1.5.1" pretty-bytes "^5.3.0" std-env "^2.2.1" wrap-ansi "^6.0.0" -"@nuxt/config@2.9.2": - version "2.9.2" - resolved "https://registry.yarnpkg.com/@nuxt/config/-/config-2.9.2.tgz#8976da395cc9f9971f48890ecaff9991d011578a" - integrity sha512-FjBPZNE2vUh7UsJ4GdiEYcgr3umvAxSKU2xvbBQpBGk8mItPyt8k/1LmrRSvImkno4j1IBKp4VehSBZYEczJdQ== +"@nuxt/config@2.10.0": + version "2.10.0" + resolved "https://registry.yarnpkg.com/@nuxt/config/-/config-2.10.0.tgz#72c1713d57b8e50b4f08c1abe6b816a64f7d2e28" + integrity sha512-avDv8sNBhffok7tJXE9bUQm7wcSGcN0ZQdM9N/PFNbHfROZ6wm8umsotQaQbg2XVJQZ2k2PNKCEN+hNKcFmrNw== dependencies: - "@nuxt/utils" "2.9.2" + "@nuxt/utils" "2.10.0" consola "^2.10.1" std-env "^2.2.1" -"@nuxt/core@2.9.2": - version "2.9.2" - resolved "https://registry.yarnpkg.com/@nuxt/core/-/core-2.9.2.tgz#1ab1d5c1928c37100a680241f23fe6ebe230d9f9" - integrity sha512-OtjLLutaMsYP6/EYXD96i/J79GSrjHlxfHbBaqHjIxnHdDnzZlsvA13EjULJ9mhumw3fvOPi12AEqqNpBHXqUg== +"@nuxt/core@2.10.0": + version "2.10.0" + resolved "https://registry.yarnpkg.com/@nuxt/core/-/core-2.10.0.tgz#71479a2f87160309486be5de358fea97b98cf072" + integrity sha512-Frhyoqz+uGVOvTXA3S1mTguOZVqxJFCbcx+FksC49WCR7q5OdrD8Z6mQeUmUW9dBa2l+p7hj9LCTa6ECf1wwvw== dependencies: - "@nuxt/config" "2.9.2" + "@nuxt/config" "2.10.0" "@nuxt/devalue" "^1.2.4" - "@nuxt/server" "2.9.2" - "@nuxt/utils" "2.9.2" - "@nuxt/vue-renderer" "2.9.2" + "@nuxt/server" "2.10.0" + "@nuxt/utils" "2.10.0" + "@nuxt/vue-renderer" "2.10.0" consola "^2.10.1" debug "^4.1.1" esm "^3.2.25" fs-extra "^8.1.0" - hable "^2.2.1" + hable "^2.3.2" hash-sum "^2.0.0" std-env "^2.2.1" @@ -1315,21 +1275,21 @@ error-stack-parser "^2.0.0" string-width "^2.0.0" -"@nuxt/generator@2.9.2": - version "2.9.2" - resolved "https://registry.yarnpkg.com/@nuxt/generator/-/generator-2.9.2.tgz#5fd8e1af5217b3c7049ef89af4a8568b3d34a437" - integrity sha512-54bp94eel5vAxUQPKP8YU3uxPmaqSb0EwXXY+712LS2kZ2HELR/YpuATOH2wS3IUfpc0x9Zu6O/nPkjYo+635Q== +"@nuxt/generator@2.10.0": + version "2.10.0" + resolved "https://registry.yarnpkg.com/@nuxt/generator/-/generator-2.10.0.tgz#614ff34776f1796cbbd22c46dfcbbe7ad7e0ee60" + integrity sha512-5R6yuexDSSMXP5gGAnIZOJIBjfpmFXdaj8PsKkYjN3PNESVXTlJ8quBefV39QbCnyQgvNusOKppN3KmtpbDkdg== dependencies: - "@nuxt/utils" "2.9.2" + "@nuxt/utils" "2.10.0" chalk "^2.4.2" consola "^2.10.1" fs-extra "^8.1.0" html-minifier "^4.0.0" -"@nuxt/loading-screen@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@nuxt/loading-screen/-/loading-screen-1.0.1.tgz#fca2483c30545c5ab98f9547327d0e81cf4b9ebc" - integrity sha512-uvFYSHG1H8sN5F61/JWPy6aZGQKYXcpVkrwv10HaXsm+INXrC9zGin4+WtRl9LA+3MMIoPqiJ6NZSwD3LqzNRA== +"@nuxt/loading-screen@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@nuxt/loading-screen/-/loading-screen-1.2.0.tgz#9cfab1e5e421bbaedadb26f7f27a68bcde313c24" + integrity sha512-l7nXgwkuX2/lDxEDAyIe3013MS8Jhja29uDVka21gyEbRnL68XOkoV3ws4dkk6QfhT2bcPwtu2C8tYvAhhhUzA== dependencies: connect "^3.7.0" fs-extra "^8.1.0" @@ -1345,13 +1305,13 @@ consola "^2.10.1" node-fetch "^2.6.0" -"@nuxt/server@2.9.2": - version "2.9.2" - resolved "https://registry.yarnpkg.com/@nuxt/server/-/server-2.9.2.tgz#ef6f45b57b2f873c48ddb3cb1c593f56052dc186" - integrity sha512-If9Yu1pCah3d9l1AmyZ6hyfJ4+3RTekAdB9lMyHskIFGR4DCoTx2cd8oJ0VOv9CgQz90j/1Wi/SdeHy22Hy9Fg== +"@nuxt/server@2.10.0": + version "2.10.0" + resolved "https://registry.yarnpkg.com/@nuxt/server/-/server-2.10.0.tgz#354f9f7fec04c8544791331194aba60eb0631a32" + integrity sha512-K3317JyzvQe7lhVtveOb56k+L9NlFt1I2BgSg5GDt0lp21Rpf+qGUK53GQBXIpvWc9P5VT5hr8m+nxEdZZQYpA== dependencies: - "@nuxt/config" "2.9.2" - "@nuxt/utils" "2.9.2" + "@nuxt/config" "2.10.0" + "@nuxt/utils" "2.10.0" "@nuxtjs/youch" "^4.2.3" chalk "^2.4.2" compression "^1.7.4" @@ -1368,61 +1328,61 @@ serve-static "^1.14.1" server-destroy "^1.0.1" -"@nuxt/utils@2.9.2": - version "2.9.2" - resolved "https://registry.yarnpkg.com/@nuxt/utils/-/utils-2.9.2.tgz#b6ced2abe8ada3f8d5ec03dd1a5e8053c9b4a66c" - integrity sha512-qmXbRNNJtdT4cr1t66ayaUFx9rQ9aOiLPHM/J69/uw/TKiy/j3WgX1YHE6TRAfIpg0eb68nDzHGM40T3XJ+jsg== +"@nuxt/utils@2.10.0": + version "2.10.0" + resolved "https://registry.yarnpkg.com/@nuxt/utils/-/utils-2.10.0.tgz#7e1e618312c4048238050d97bf7ac61d1ce71804" + integrity sha512-DcBcUOf9qhVnaR0RqE/Ft+IbTgCQCttn4DM3CBRJJCQ9RV8CpLG8mfFsNtgnPTYrgDrUet67YrL5JcM9Ok02aw== dependencies: consola "^2.10.1" fs-extra "^8.1.0" hash-sum "^2.0.0" proper-lockfile "^4.1.1" semver "^6.3.0" - serialize-javascript "^1.8.0" + serialize-javascript "^2.1.0" signal-exit "^3.0.2" ua-parser-js "^0.7.20" -"@nuxt/vue-app@2.9.2": - version "2.9.2" - resolved "https://registry.yarnpkg.com/@nuxt/vue-app/-/vue-app-2.9.2.tgz#725b1f6c4ac955b990ce3db68f9ae19a8d578c5b" - integrity sha512-zLoCvA3+UVfdikfol7plPukP0GddU1LdgkV+1EDeVUm22PNgt/OdYN3z5kJIZEfZoLpfMbtF8NsBVWrehPuoFQ== +"@nuxt/vue-app@2.10.0": + version "2.10.0" + resolved "https://registry.yarnpkg.com/@nuxt/vue-app/-/vue-app-2.10.0.tgz#fd5616d91c543ae0dfdf745167c481d8932381ec" + integrity sha512-63tnJCv5IReW9wJh63IHgw/F09hqkQ1ot+u8+umTsk45awYWE39VrwdNOkRdy2IHygIH2xxXIhtYkwZuX8xFhg== dependencies: node-fetch "^2.6.0" unfetch "^4.1.0" vue "^2.6.10" vue-client-only "^2.0.0" - vue-meta "^2.2.1" + vue-meta "^2.2.2" vue-no-ssr "^1.1.1" vue-router "~3.0.7" vue-template-compiler "^2.6.10" vuex "^3.1.1" -"@nuxt/vue-renderer@2.9.2": - version "2.9.2" - resolved "https://registry.yarnpkg.com/@nuxt/vue-renderer/-/vue-renderer-2.9.2.tgz#5118ba5caa894d94b272ad4665f88837ab2359ef" - integrity sha512-bLUnYEj2PHs07K7EAH+a3Nhg9ZK4WRsbG9q5eYNF3CD0O10CzNOR6/8qqqbFYj8hFrP76EOf0P/5CAJcWvRtPg== +"@nuxt/vue-renderer@2.10.0": + version "2.10.0" + resolved "https://registry.yarnpkg.com/@nuxt/vue-renderer/-/vue-renderer-2.10.0.tgz#1e467d6b146670311cfb23e7e6f3933d2c58a296" + integrity sha512-uTkBDZUUJWi87RnViyC6x252NwQ9w3GuZMuN0Mv0v42+8S+BQ1/0bN84X2d5imdZz3kAlhsLJQ69GKrI75dCAA== dependencies: "@nuxt/devalue" "^1.2.4" - "@nuxt/utils" "2.9.2" + "@nuxt/utils" "2.10.0" consola "^2.10.1" fs-extra "^8.1.0" lru-cache "^5.1.1" vue "^2.6.10" - vue-meta "^2.2.1" + vue-meta "^2.2.2" vue-server-renderer "^2.6.10" -"@nuxt/webpack@2.9.2": - version "2.9.2" - resolved "https://registry.yarnpkg.com/@nuxt/webpack/-/webpack-2.9.2.tgz#4db33ddcb6805d5fed06a67515e542ca54ffa75d" - integrity sha512-M+j3Ceo6BcBSz4eIXqMP+Owcp2f78Dco+KGHJuUuCxWRNJjVdJAo1RHa2sMVDezdQgiDJQzgChwORU2mjN6rEw== +"@nuxt/webpack@2.10.0": + version "2.10.0" + resolved "https://registry.yarnpkg.com/@nuxt/webpack/-/webpack-2.10.0.tgz#c71f54994dbba52f24849f55eb275d87667f2da7" + integrity sha512-ah1G6nIP3PJaeS5oQXrAUyPwmeWos1ycgZXvADN2rkXP4I2hdpdRuFBVrl1NfNoCNq+Hw0hZeEL9vgN4SbbPXQ== dependencies: - "@babel/core" "^7.5.5" - "@nuxt/babel-preset-app" "2.9.2" + "@babel/core" "^7.6.2" + "@nuxt/babel-preset-app" "2.10.0" "@nuxt/friendly-errors-webpack-plugin" "^2.5.0" - "@nuxt/utils" "2.9.2" + "@nuxt/utils" "2.10.0" babel-loader "^8.0.6" cache-loader "^4.1.0" - caniuse-lite "^1.0.30000989" + caniuse-lite "^1.0.30000997" chalk "^2.4.2" consola "^2.10.1" css-loader "^3.2.0" @@ -1437,35 +1397,36 @@ memory-fs "^0.4.1" optimize-css-assets-webpack-plugin "^5.0.3" pify "^4.0.1" - postcss "^7.0.17" + postcss "^7.0.18" postcss-import "^12.0.1" postcss-import-resolver "^1.2.3" postcss-loader "^3.0.0" postcss-preset-env "^6.7.0" postcss-url "^8.0.0" + semver "^6.3.0" std-env "^2.2.1" style-resources-loader "^1.2.1" - terser-webpack-plugin "^1.4.1" + terser-webpack-plugin "^2.1.2" thread-loader "^2.1.3" time-fix-plugin "^2.0.6" url-loader "^2.1.0" vue-loader "^15.7.1" - webpack "^4.39.3" - webpack-bundle-analyzer "^3.4.1" - webpack-dev-middleware "^3.7.0" + webpack "^4.41.0" + webpack-bundle-analyzer "^3.5.2" + webpack-dev-middleware "^3.7.2" webpack-hot-middleware "^2.25.0" webpack-node-externals "^1.7.2" webpackbar "^4.0.0" -"@nuxtjs/apollo@^4.0.0-rc13.1": - version "4.0.0-rc13.1" - resolved "https://registry.yarnpkg.com/@nuxtjs/apollo/-/apollo-4.0.0-rc13.1.tgz#35c9ffae5f0a8f94add1bf0480e67a54bd1fca5b" - integrity sha512-a39GSehrJlCB236oEHa3lTwFSHvMWq+0LFosM8UXYMReZPDSNnxtEzfQlRrXsav9iKXcELw31e8sisRB+LcMdQ== +"@nuxtjs/apollo@^4.0.0-rc14": + version "4.0.0-rc14" + resolved "https://registry.yarnpkg.com/@nuxtjs/apollo/-/apollo-4.0.0-rc14.tgz#b589e72c6e6b36c93154b07c12a5ce59cc350942" + integrity sha512-ap/oiF/0i/EdeeFWnj8IkoHPTjqut6CW46sshdtanZxrGEmYody0Qi98KfQnoO7mYrQg7dbfHHNh1xCPhGYQ7A== dependencies: cross-fetch "^3.0.4" universal-cookie "^4.0.2" - vue-apollo "^3.0.0-rc.5" - vue-cli-plugin-apollo "^0.21.0" + vue-apollo "^3.0.0-rc.7" + vue-cli-plugin-apollo "^0.21.1" webpack-node-externals "^1.7.2" "@nuxtjs/axios@~5.6.0": @@ -1545,17 +1506,7 @@ supports-color "^5.4.0" tslib "^1" -"@oclif/command@1.5.16": - version "1.5.16" - resolved "https://registry.yarnpkg.com/@oclif/command/-/command-1.5.16.tgz#88b578d37e981034303effbcbdd73c332a6f5543" - integrity sha512-bzqNz9/EblkohokXbico/14r05oRe8aa06S3MLEo4GlmyOce2abIOx1oZfUDl8ekQuKO+Ycw9Jco+hN2aL423A== - dependencies: - "@oclif/errors" "^1.2.2" - "@oclif/parser" "^3.7.3" - debug "^4.1.1" - semver "^5.6.0" - -"@oclif/command@^1.4.31", "@oclif/command@^1.5.1", "@oclif/command@^1.5.10", "@oclif/command@^1.5.12", "@oclif/command@^1.5.13", "@oclif/command@^1.5.3": +"@oclif/command@1.5.18", "@oclif/command@^1.4.31", "@oclif/command@^1.5.1", "@oclif/command@^1.5.10", "@oclif/command@^1.5.12", "@oclif/command@^1.5.13", "@oclif/command@^1.5.3": version "1.5.18" resolved "https://registry.yarnpkg.com/@oclif/command/-/command-1.5.18.tgz#57125b501fafa155ad280bf8dc9f36a911c44f11" integrity sha512-sfLb5UUCwyQ0w9LyQ1/3DUuD/RWnPZk6uvcK5P7pqD65WgRJaOPCqzuNZyb56kPsj6FftRp1UudApNKd7U0KBQ== @@ -1567,7 +1518,16 @@ debug "^4.1.1" semver "^5.6.0" -"@oclif/config@1.13.2", "@oclif/config@^1", "@oclif/config@^1.12.8", "@oclif/config@^1.6.22": +"@oclif/config@1.13.3": + version "1.13.3" + resolved "https://registry.yarnpkg.com/@oclif/config/-/config-1.13.3.tgz#1b13e18d0e4242ddbd9cbd100f0eec819aa2bf8c" + integrity sha512-qs5XvGRw+1M41abOKCjd0uoeHCgsMxa2MurD2g2K8CtQlzlMXl0rW5idVeimIg5208LLuxkfzQo8TKAhhRCWLg== + dependencies: + "@oclif/parser" "^3.8.0" + debug "^4.1.1" + tslib "^1.9.3" + +"@oclif/config@^1", "@oclif/config@^1.12.8", "@oclif/config@^1.6.22": version "1.13.2" resolved "https://registry.yarnpkg.com/@oclif/config/-/config-1.13.2.tgz#c1dc25296bf06c039fd5fb0b90e4132be2213b2a" integrity sha512-RUOKeuAaopo3zrA5hcgE0PT2lbAUT72+eJdqTlWyI9sbPrGHZgUwV+vrL6Qal7ywWYDkL0vrKd1YS4yXtKIDKw== @@ -1592,7 +1552,7 @@ resolved "https://registry.yarnpkg.com/@oclif/linewrap/-/linewrap-1.0.0.tgz#aedcb64b479d4db7be24196384897b5000901d91" integrity sha512-Ups2dShK52xXa8w6iBWLgcjPJWjais6KPJQq3gQ/88AY6BXoTX+MIGFPrWQO1KLMiQfoTpcLnUwloN4brrVUHw== -"@oclif/parser@^3.7.3", "@oclif/parser@^3.8.0", "@oclif/parser@^3.8.3": +"@oclif/parser@^3.8.0", "@oclif/parser@^3.8.3": version "3.8.3" resolved "https://registry.yarnpkg.com/@oclif/parser/-/parser-3.8.3.tgz#717fbbe5bfafef4270224b8bd41a2d3c80b9554e" integrity sha512-zN+3oGuv9Lg8NjFvxZTDKFEmhAMfAvd/JWeQp3Ri8pDezoyJQi4OSHHLM8sdHjBh8sePewfWI7+fDUXdrVbrqg== @@ -1601,10 +1561,10 @@ chalk "^2.4.2" tslib "^1.9.3" -"@oclif/plugin-autocomplete@0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@oclif/plugin-autocomplete/-/plugin-autocomplete-0.1.2.tgz#18febb452935adfc97882c2c249fa4e45fc77652" - integrity sha512-n6SVOJVVxGkDbU2eu5cU5fTBJIF9hJj3t5Lk/Io8VYnLOPd3TBYrpWBbBhYvVecvqUQ2SxHNDw3CcSjaLsyHBg== +"@oclif/plugin-autocomplete@0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@oclif/plugin-autocomplete/-/plugin-autocomplete-0.1.3.tgz#c0dfb09aba9ed8c5149db5f7ac1f3d2d6917c0fc" + integrity sha512-gObSl+GOwhTuzJJh1vKocsTVAU/VX1V1MNnM+evb4c2z33KZeWiM+DanxXvM7JGDSKKaSE55Q2CXsAQnIuDi2w== dependencies: "@oclif/command" "^1.4.31" "@oclif/config" "^1.6.22" @@ -1615,7 +1575,21 @@ fs-extra "^6.0.1" moment "^2.22.1" -"@oclif/plugin-help@2.2.0", "@oclif/plugin-help@^2": +"@oclif/plugin-help@2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@oclif/plugin-help/-/plugin-help-2.2.1.tgz#cb4d23e453b19340b07c48fb299948b7c74366d3" + integrity sha512-psEA3t41MSGBErLk6xCaAq2jKrRtx3Br+kHpd43vZeGEeZ7Gos4wgK0JAaHBbvhvUQskCHg8dzoqv4XEeTWeVQ== + dependencies: + "@oclif/command" "^1.5.13" + chalk "^2.4.1" + indent-string "^3.2.0" + lodash.template "^4.4.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + widest-line "^2.0.1" + wrap-ansi "^4.0.0" + +"@oclif/plugin-help@^2": version "2.2.0" resolved "https://registry.yarnpkg.com/@oclif/plugin-help/-/plugin-help-2.2.0.tgz#8dfc1c80deae47a205fbc70b018747ba93f31cc3" integrity sha512-56iIgE7NQfwy/ZrWrvrEfJGb5rrMUt409yoQGw4feiU101UudA1btN1pbUbcKBr7vY9KFeqZZcftXEGxOp7zBg== @@ -1629,16 +1603,16 @@ widest-line "^2.0.1" wrap-ansi "^4.0.0" -"@oclif/plugin-not-found@1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@oclif/plugin-not-found/-/plugin-not-found-1.2.2.tgz#3e601f6e4264d7a0268cd03c152d90aa9c0cec6d" - integrity sha512-SPlmiJFmTFltQT/owdzQwKgq6eq5AEKVwVK31JqbzK48bRWvEL1Ye60cgztXyZ4bpPn2Fl+KeL3FWFQX41qJuA== +"@oclif/plugin-not-found@1.2.3": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@oclif/plugin-not-found/-/plugin-not-found-1.2.3.tgz#00f9e7a0a793a5e2f616d8280075f4592de8f079" + integrity sha512-Igbw2T4gLrb/f28Llr730FeMXBSI2PXdky2YvQfsZeQGDsyBZmC4gprJJtmrMWQcjz0B51IInRBnZYERvwfIpw== dependencies: "@oclif/color" "^0.0.0" "@oclif/command" "^1.5.3" cli-ux "^4.9.0" fast-levenshtein "^2.0.6" - lodash "^4.17.11" + lodash "^4.17.13" "@oclif/plugin-plugins@1.7.8": version "1.7.8" @@ -2237,7 +2211,7 @@ dependencies: "@babel/types" "^7.3.0" -"@types/body-parser@*", "@types/body-parser@1.17.0": +"@types/body-parser@*": version "1.17.0" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.0.tgz#9f5c9d9bd04bb54be32d5eb9fc0d8c974e6cf58c" integrity sha512-a2+YeUjPkztKJu5aIF2yArYFQQp8d51wZ7DavSHjFuY1mqVgidGyzEQ41JIVNy82fXj8yPgy2vJmfIywgESW6w== @@ -2245,6 +2219,14 @@ "@types/connect" "*" "@types/node" "*" +"@types/body-parser@1.17.1": + version "1.17.1" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.1.tgz#18fcf61768fb5c30ccc508c21d6fd2e8b3bf7897" + integrity sha512-RoX2EZjMiFMjZh9lmYrwgoP9RTpAjSHiJxdp4oidAQVO02T7HER3xj9UKue5534ULWeqVEkujhWcyvUce+d68w== + dependencies: + "@types/connect" "*" + "@types/node" "*" + "@types/connect@*": version "3.4.32" resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.32.tgz#aa0e9616b9435ccad02bc52b5b454ffc2c70ba28" @@ -2296,10 +2278,10 @@ "@types/express-serve-static-core" "*" "@types/serve-static" "*" -"@types/express@4.17.0": - version "4.17.0" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.0.tgz#49eaedb209582a86f12ed9b725160f12d04ef287" - integrity sha512-CjaMu57cjgjuZbh9DpkloeGxV45CnMGlVd+XpG7Gm9QgVrd7KFq+X4HY0vM+2v0bczS48Wg7bvnMY5TN+Xmcfw== +"@types/express@4.17.1": + version "4.17.1" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.1.tgz#4cf7849ae3b47125a567dfee18bfca4254b88c5c" + integrity sha512-VfH/XCP0QbQk5B5puLqTLEeFgR8lfCJHZJKkInZ9mkYd+u8byX0kztXEQxEk4wZXJs8HI+7km2ALXjn4YKcX9w== dependencies: "@types/body-parser" "*" "@types/express-serve-static-core" "*" @@ -2881,6 +2863,14 @@ agent-base@^4.1.0, agent-base@^4.3.0: dependencies: es6-promisify "^5.0.0" +aggregate-error@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.0.tgz#5b5a3c95e9095f311c9ab16c19fb4f3527cd3f79" + integrity sha512-yKD9kEoJIR+2IFqhMwayIBgheLYbB3PS2OBhWae1L/ODTd/JF/30cW0bc9TqzRL3k4U41Dieu3BF4I29p8xesA== + dependencies: + clean-stack "^2.0.0" + indent-string "^3.2.0" + "airbnb-js-shims@^1 || ^2": version "2.2.0" resolved "https://registry.yarnpkg.com/airbnb-js-shims/-/airbnb-js-shims-2.2.0.tgz#46e1d9d9516f704ef736de76a3b6d484df9a96d8" @@ -3044,23 +3034,23 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -anymatch@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.0.2.tgz#ddb3a8495d44875423af7b919aace11e91732a41" - integrity sha512-rUe9SxpRQlVg4EM8It7JMNWWYHAirTPpbTuvaSKybb5IejNgWB3PGBBX9rrPKDx2pM/p3Wh+7+ASaWRyyAbxmQ== +anymatch@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" -apollo-cache-control@0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.8.1.tgz#707c0b958c02c5b47ddf49a02f60ea88a64783fb" - integrity sha512-yQy5KB/OuX90PsdztWc4vfc4R//ZmW/AxNgXKWga0xW5OzEsysdJWHAsTzb40/rkJ9VNeQ+0N5wGikiS+jSCzg== +apollo-cache-control@^0.8.4: + version "0.8.4" + resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.8.4.tgz#a3650d5e4173953e2a3af995bea62147f1ffe4d7" + integrity sha512-IZ1d3AXZtkZhLYo0kWqTbZ6nqLFaeUvLdMESs+9orMadBZ7mvzcAfBwrhKyCWPGeAAZ/jKv8FtYHybpchHgFAg== dependencies: - apollo-server-env "2.4.1" - graphql-extensions "0.8.1" + apollo-server-env "^2.4.3" + graphql-extensions "^0.10.3" -apollo-cache-inmemory@^1.6.2, apollo-cache-inmemory@~1.6.3: +apollo-cache-inmemory@^1.6.3, apollo-cache-inmemory@~1.6.3: version "1.6.3" resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.6.3.tgz#826861d20baca4abc45f7ca7a874105905b8525d" integrity sha512-S4B/zQNSuYc0M/1Wq8dJDTIO9yRgU0ZwDGnmlqxGGmFombOZb9mLjylewSfQKmjNpciZ7iUIBbJ0mHlPJTzdXg== @@ -3079,7 +3069,7 @@ apollo-cache@1.3.2, apollo-cache@^1.3.2: apollo-utilities "^1.3.2" tslib "^1.9.3" -apollo-client@^2.6.3, apollo-client@~2.6.4: +apollo-client@^2.6.4, apollo-client@~2.6.4: version "2.6.4" resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.6.4.tgz#872c32927263a0d34655c5ef8a8949fbb20b6140" integrity sha512-oWOwEOxQ9neHHVZrQhHDbI6bIibp9SHgxaLRVPoGvOFy7OH5XUykZE7hBQAVxq99tQjBzgytaZffQkeWo1B4VQ== @@ -3093,69 +3083,69 @@ apollo-client@^2.6.3, apollo-client@~2.6.4: tslib "^1.9.3" zen-observable "^0.8.0" -apollo-codegen-core@0.34.12: - version "0.34.12" - resolved "https://registry.yarnpkg.com/apollo-codegen-core/-/apollo-codegen-core-0.34.12.tgz#3726fa352e90c701bc35927e58c91eea8db14a71" - integrity sha512-AlpR5HyM1S2WLIfBFEOI+0ezXO0mup8BRSOqyDs1Z0LK3J4ft/gEe5JuqnAfPi/k0YKfpeXTc+rkT3p6+TyQ1A== +apollo-codegen-core@^0.35.3: + version "0.35.3" + resolved "https://registry.yarnpkg.com/apollo-codegen-core/-/apollo-codegen-core-0.35.3.tgz#be8e79d0a49c9707a209e9448cfc448a38e36a25" + integrity sha512-mSj9+wOogyd3rkt766Gnds4ZHcjqE6mcV6rYmAKoq2kUA19GsXfoMrD7vJK1AjWNgp7Q5EpSwHrfxlxtptjwjQ== dependencies: "@babel/generator" "7.5.5" "@babel/parser" "^7.1.3" - "@babel/types" "7.5.5" - apollo-env "0.5.1" - apollo-language-server "1.14.1" + "@babel/types" "7.6.1" + apollo-env "^0.5.1" + apollo-language-server "^1.15.3" ast-types "^0.13.0" common-tags "^1.5.1" recast "^0.18.0" -apollo-codegen-flow@0.33.22: - version "0.33.22" - resolved "https://registry.yarnpkg.com/apollo-codegen-flow/-/apollo-codegen-flow-0.33.22.tgz#475670b153b2785e562d7564acbaa85470927b34" - integrity sha512-VS7DHtVEO/DtnvAmQsuI2zBH6H1np2w0vpl4ZsUmDd+kzMKr+/oTrbOj6VRs1IYvlRvugWFmfGINUDNLcCUhHQ== +apollo-codegen-flow@^0.33.28: + version "0.33.28" + resolved "https://registry.yarnpkg.com/apollo-codegen-flow/-/apollo-codegen-flow-0.33.28.tgz#abaa3c1bd479148f47322e07ac2bbe9dbedf4153" + integrity sha512-PUQQC0og6a6pn4QsT2/9dd97eKRelM2xz3d2xydB2ZnFS3hb7p6giaVC4aeahQS8FeKi9Yf8qT2X0s8RYsWdPA== dependencies: "@babel/generator" "7.5.5" - "@babel/types" "7.5.5" - apollo-codegen-core "0.34.12" - apollo-env "0.5.1" + "@babel/types" "7.6.1" + apollo-codegen-core "^0.35.3" + apollo-env "^0.5.1" change-case "^3.0.1" common-tags "^1.5.1" inflected "^2.0.3" -apollo-codegen-scala@0.34.22: - version "0.34.22" - resolved "https://registry.yarnpkg.com/apollo-codegen-scala/-/apollo-codegen-scala-0.34.22.tgz#03c4fcf18e8c2bf6c30584103e25abc8a120fd01" - integrity sha512-AGknf1+Qa2975gTWLgs+pGRDtSy9Mx1zw+hoHQyJdUJ9fi2F9jZpYRU015M1GhfzTJb0vn8NSr3JUWODOTE1kw== +apollo-codegen-scala@^0.34.28: + version "0.34.28" + resolved "https://registry.yarnpkg.com/apollo-codegen-scala/-/apollo-codegen-scala-0.34.28.tgz#b465a6d1918bfbd9af735f0aaf5380140169538f" + integrity sha512-9kMy8d7Bj5NTx6YBgHxIF/75MDa4c31DKPewVAmwRJ7PyiU0nKb7p6Snp45TJ1Lj0cgqCYLGQlodt0e2GdhIqw== dependencies: - apollo-codegen-core "0.34.12" - apollo-env "0.5.1" + apollo-codegen-core "^0.35.3" + apollo-env "^0.5.1" change-case "^3.0.1" common-tags "^1.5.1" inflected "^2.0.3" -apollo-codegen-swift@0.34.3: - version "0.34.3" - resolved "https://registry.yarnpkg.com/apollo-codegen-swift/-/apollo-codegen-swift-0.34.3.tgz#e6943a447024ab09c1be40579fb48b2d94c5df3a" - integrity sha512-PDEh/TyzBxk5RF5U0dV/m6I8bHvz7CzgJlU7pyCRZYe3C1BU7Mp9SJk0a4ktxYJFwNjiPsCmvsA2b3aT1W3ZgQ== +apollo-codegen-swift@^0.35.8: + version "0.35.8" + resolved "https://registry.yarnpkg.com/apollo-codegen-swift/-/apollo-codegen-swift-0.35.8.tgz#c3afff793f594104eca1603fcbf0d9dbc1852c19" + integrity sha512-VBQu2Xef5nB4Io2e4EnhceQxJQTgqxjKX0aHvBEXTXYoyBKhLzCuF75BKTw1nltrpX2wAmMmjO6ufwZ9AIUBLA== dependencies: - apollo-codegen-core "0.34.12" - apollo-env "0.5.1" + apollo-codegen-core "^0.35.3" + apollo-env "^0.5.1" change-case "^3.0.1" common-tags "^1.5.1" inflected "^2.0.3" -apollo-codegen-typescript@0.34.12: - version "0.34.12" - resolved "https://registry.yarnpkg.com/apollo-codegen-typescript/-/apollo-codegen-typescript-0.34.12.tgz#82657932027ed2484555ad0e489d2ca62d96c716" - integrity sha512-GdfmQEmlbvuWK1SOpKgk/gN2nLtqV8SrDBLjf+U54QGHOqL8St0u8DR6a60/6nIy+xGrJoCDN1vVz3IPLdzaDA== +apollo-codegen-typescript@^0.35.3: + version "0.35.3" + resolved "https://registry.yarnpkg.com/apollo-codegen-typescript/-/apollo-codegen-typescript-0.35.3.tgz#b033e8ae7fe84637d2a577b4158bcb014569f047" + integrity sha512-QwZm2WaNtuDi65bqRETNwpeb/ol9nPsem237WlzfW7WoznNyNGIC47Z+61fQDU+HyK/xlFdFLA5uPS59412jTA== dependencies: "@babel/generator" "7.5.5" - "@babel/types" "7.5.5" - apollo-codegen-core "0.34.12" - apollo-env "0.5.1" + "@babel/types" "7.6.1" + apollo-codegen-core "^0.35.3" + apollo-env "^0.5.1" change-case "^3.0.1" common-tags "^1.5.1" inflected "^2.0.3" -apollo-datasource@0.6.1, apollo-datasource@^0.6.0: +apollo-datasource@^0.6.0: version "0.6.1" resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.6.1.tgz#697870f564da90bee53fa30d07875cb46c4d6b06" integrity sha512-oy7c+9Up8PSZwJ1qTK9Idh1acDpIocvw+C0zcHg14ycvNz7qWHSwLUSaAjuQMd9SYFzB3sxfyEhyfyhIogT2+Q== @@ -3163,27 +3153,35 @@ apollo-datasource@0.6.1, apollo-datasource@^0.6.0: apollo-server-caching "0.5.0" apollo-server-env "2.4.1" -apollo-engine-reporting-protobuf@0.4.0: +apollo-datasource@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.6.3.tgz#b31e089e52adb92fabb536ab8501c502573ffe13" + integrity sha512-gRYyFVpJgHE2hhS+VxMeOerxXQ/QYxWG7T6QddfugJWYAG9DRCl65e2b7txcGq2NP3r+O1iCm4GNwhRBDJbd8A== + dependencies: + apollo-server-caching "^0.5.0" + apollo-server-env "^2.4.3" + +apollo-engine-reporting-protobuf@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.4.0.tgz#e34c192d86493b33a73181fd6be75721559111ec" integrity sha512-cXHZSienkis8v4RhqB3YG3DkaksqLpcxApRLTpRMs7IXNozgV7CUPYGFyFBEra1ZFgUyHXx4G9MpelV+n2cCfA== dependencies: protobufjs "^6.8.6" -apollo-engine-reporting@1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.4.3.tgz#0fcb67de7a24bef4e7e59990981f923267ffdd00" - integrity sha512-xv27qfc9dhi1yaWOhNQRmfF+SoLy74hl+M42arpIWdkoDe22fVTmTIqxqGwo4TFR3Z2OkAV5tNzuuOI/icd0Rg== +apollo-engine-reporting@^1.4.6: + version "1.4.6" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.4.6.tgz#83af6689c4ab82d1c62c3f5dde7651975508114f" + integrity sha512-acfb7oFnru/8YQdY4x6+7WJbZfzdVETI8Cl+9ImgUrvUnE8P+f2SsGTKXTC1RuUvve4c56PAvaPgE+z8X1a1Mw== dependencies: - apollo-engine-reporting-protobuf "0.4.0" + apollo-engine-reporting-protobuf "^0.4.0" apollo-graphql "^0.3.3" - apollo-server-caching "0.5.0" - apollo-server-env "2.4.1" - apollo-server-types "0.2.1" + apollo-server-caching "^0.5.0" + apollo-server-env "^2.4.3" + apollo-server-types "^0.2.4" async-retry "^1.2.1" - graphql-extensions "0.9.1" + graphql-extensions "^0.10.3" -apollo-env@0.5.1: +apollo-env@0.5.1, apollo-env@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/apollo-env/-/apollo-env-0.5.1.tgz#b9b0195c16feadf0fe9fd5563edb0b9b7d9e97d3" integrity sha512-fndST2xojgSdH02k5hxk1cbqA9Ti8RX4YzzBoAB4oIe1Puhq7+YlhXGXfXB5Y4XN0al8dLg+5nAkyjNAR2qZTw== @@ -3192,7 +3190,7 @@ apollo-env@0.5.1: node-fetch "^2.2.0" sha.js "^2.4.11" -apollo-graphql@0.3.3, apollo-graphql@^0.3.3: +apollo-graphql@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/apollo-graphql/-/apollo-graphql-0.3.3.tgz#ce1df194f6e547ad3ce1e35b42f9c211766e1658" integrity sha512-t3CO/xIDVsCG2qOvx2MEbuu4b/6LzQjcBBwiVnxclmmFyAxYCIe7rpPlnLHSq7HyOMlCWDMozjoeWfdqYSaLqQ== @@ -3200,16 +3198,17 @@ apollo-graphql@0.3.3, apollo-graphql@^0.3.3: apollo-env "0.5.1" lodash.sortby "^4.7.0" -apollo-language-server@1.14.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/apollo-language-server/-/apollo-language-server-1.14.1.tgz#c9dc5147c5f3528d8ba39bc1748a7736a3d04678" - integrity sha512-oCycMdsG6Qm0V8lk1pwzpUQt4LK9hdusFl9pQkfWGUAGqt4KA0qbI5F4vErqCOMvqoiZ0v2jCh9tw+KOEWP9CQ== +apollo-language-server@^1.15.3: + version "1.15.3" + resolved "https://registry.yarnpkg.com/apollo-language-server/-/apollo-language-server-1.15.3.tgz#51c8cab4f2b70b2a158fff14c9edd7a2336c6a6a" + integrity sha512-/e3bzTepAW157z1fnw/73aL9CuVsDDSlAiAzMaqIYpx4RHHAJRI73Eg1+JjEvphr+CZPasA8oBmczHyBcOgCOA== dependencies: - "@apollographql/apollo-tools" "0.4.0" + "@apollographql/apollo-tools" "^0.4.0" "@apollographql/graphql-language-service-interface" "^2.0.2" "@endemolshinegroup/cosmiconfig-typescript-loader" "^1.0.0" apollo-datasource "^0.6.0" - apollo-env "0.5.1" + apollo-env "^0.5.1" + apollo-graphql "^0.3.3" apollo-link "^1.2.3" apollo-link-context "^1.0.9" apollo-link-error "^1.1.1" @@ -3229,7 +3228,15 @@ apollo-language-server@1.14.1: vscode-languageserver "^5.1.0" vscode-uri "1.0.6" -apollo-link-context@^1.0.18, apollo-link-context@^1.0.9: +apollo-link-context@^1.0.19: + version "1.0.19" + resolved "https://registry.yarnpkg.com/apollo-link-context/-/apollo-link-context-1.0.19.tgz#3c9ba5bf75ed5428567ce057b8837ef874a58987" + integrity sha512-TUi5TyufU84hEiGkpt+5gdH5HkB3Gx46npNfoxR4of3DKBCMuItGERt36RCaryGcU/C3u2zsICU3tJ+Z9LjFoQ== + dependencies: + apollo-link "^1.2.13" + tslib "^1.9.3" + +apollo-link-context@^1.0.9: version "1.0.18" resolved "https://registry.yarnpkg.com/apollo-link-context/-/apollo-link-context-1.0.18.tgz#9e700e3314da8ded50057fee0a18af2bfcedbfc3" integrity sha512-aG5cbUp1zqOHHQjAJXG7n/izeMQ6LApd/whEF5z6qZp5ATvcyfSNkCfy3KRJMMZZ3iNfVTs6jF+IUA8Zvf+zeg== @@ -3246,15 +3253,6 @@ apollo-link-error@^1.1.1: apollo-link-http-common "^0.2.14" tslib "^1.9.3" -apollo-link-http-common@^0.2.13: - version "0.2.13" - resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.13.tgz#c688f6baaffdc7b269b2db7ae89dae7c58b5b350" - integrity sha512-Uyg1ECQpTTA691Fwx5e6Rc/6CPSu4TB4pQRTGIpwZ4l5JDOQ+812Wvi/e3IInmzOZpwx5YrrOfXrtN8BrsDXoA== - dependencies: - apollo-link "^1.2.11" - ts-invariant "^0.3.2" - tslib "^1.9.3" - apollo-link-http-common@^0.2.14: version "0.2.14" resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.14.tgz#d3a195c12e00f4e311c417f121181dcc31f7d0c8" @@ -3264,7 +3262,25 @@ apollo-link-http-common@^0.2.14: ts-invariant "^0.4.0" tslib "^1.9.3" -apollo-link-http@^1.5.15, apollo-link-http@^1.5.5: +apollo-link-http-common@^0.2.15: + version "0.2.15" + resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.15.tgz#304e67705122bf69a9abaded4351b10bc5efd6d9" + integrity sha512-+Heey4S2IPsPyTf8Ag3PugUupASJMW894iVps6hXbvwtg1aHSNMXUYO5VG7iRHkPzqpuzT4HMBanCTXPjtGzxg== + dependencies: + apollo-link "^1.2.13" + ts-invariant "^0.4.0" + tslib "^1.9.3" + +apollo-link-http@^1.5.16: + version "1.5.16" + resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.16.tgz#44fe760bcc2803b8a7f57fc9269173afb00f3814" + integrity sha512-IA3xA/OcrOzINRZEECI6IdhRp/Twom5X5L9jMehfzEo2AXdeRwAMlH5LuvTZHgKD8V1MBnXdM6YXawXkTDSmJw== + dependencies: + apollo-link "^1.2.13" + apollo-link-http-common "^0.2.15" + tslib "^1.9.3" + +apollo-link-http@^1.5.5: version "1.5.15" resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.15.tgz#106ab23bb8997bd55965d05855736d33119652cf" integrity sha512-epZFhCKDjD7+oNTVK3P39pqWGn4LEhShAoA1Q9e2tDrBjItNfviiE33RmcLcCURDYyW5JA6SMgdODNI4Is8tvQ== @@ -3289,15 +3305,15 @@ apollo-link-state@^0.4.2: apollo-utilities "^1.0.8" graphql-anywhere "^4.1.0-alpha.0" -apollo-link-ws@^1.0.18: - version "1.0.18" - resolved "https://registry.yarnpkg.com/apollo-link-ws/-/apollo-link-ws-1.0.18.tgz#281b9b0826d5fc7e2aa14d2784c5193d8b761112" - integrity sha512-nrWh9m7k1FQw1AK1GB1VTJS0o01cpsP2RYmTAh2j+P4lL2/72WgsblhbuF+yA1/jsgVrzg6xa+TNw3UwgGp3+g== +apollo-link-ws@^1.0.19: + version "1.0.19" + resolved "https://registry.yarnpkg.com/apollo-link-ws/-/apollo-link-ws-1.0.19.tgz#dfa871d4df883a8777c9556c872fc892e103daa5" + integrity sha512-mRXmeUkc55ixOdYRtfq5rq3o9sboKghKABKroDVhJnkdS56zthBEWMAD+phajujOUbqByxjok0te8ABqByBdeQ== dependencies: - apollo-link "^1.2.12" + apollo-link "^1.2.13" tslib "^1.9.3" -apollo-link@^1.0.0, apollo-link@^1.2.1, apollo-link@^1.2.11, apollo-link@^1.2.12, apollo-link@^1.2.3: +apollo-link@^1.0.0, apollo-link@^1.2.1, apollo-link@^1.2.12, apollo-link@^1.2.3: version "1.2.12" resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.12.tgz#014b514fba95f1945c38ad4c216f31bcfee68429" integrity sha512-fsgIAXPKThyMVEMWQsUN22AoQI+J/pVXcjRGAShtk97h7D8O+SPskFinCGEkxPeQpE83uKaqafB2IyWdjN+J3Q== @@ -3307,33 +3323,43 @@ apollo-link@^1.0.0, apollo-link@^1.2.1, apollo-link@^1.2.11, apollo-link@^1.2.12 tslib "^1.9.3" zen-observable-ts "^0.8.19" -apollo-server-caching@0.5.0: +apollo-link@^1.2.13: + version "1.2.13" + resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.13.tgz#dff00fbf19dfcd90fddbc14b6a3f9a771acac6c4" + integrity sha512-+iBMcYeevMm1JpYgwDEIDt/y0BB7VWyvlm/7x+TIPNLHCTCMgcEgDuW5kH86iQZWo0I7mNwQiTOz+/3ShPFmBw== + dependencies: + apollo-utilities "^1.3.0" + ts-invariant "^0.4.0" + tslib "^1.9.3" + zen-observable-ts "^0.8.20" + +apollo-server-caching@0.5.0, apollo-server-caching@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.5.0.tgz#446a37ce2d4e24c81833e276638330a634f7bd46" integrity sha512-l7ieNCGxUaUAVAAp600HjbUJxVaxjJygtPV0tPTe1Q3HkPy6LEWoY6mNHV7T268g1hxtPTxcdRu7WLsJrg7ufw== dependencies: lru-cache "^5.0.0" -apollo-server-core@2.8.1: - version "2.8.1" - resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.8.1.tgz#e5fadb3fe1fadd009d1b06a46cb44ec8692bf3fb" - integrity sha512-BpvhKdycTI1v5n8biJ5c/DVF7MCbTL3JtB9llHGkqYgHaTH1gXguh2qD8Vcki+rpUNO5P1lcj5V6oVXoSUFXlA== +apollo-server-core@^2.9.4: + version "2.9.4" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.9.4.tgz#0404455884951804d23ea64e45514c73afd34e5e" + integrity sha512-6mzipnn9woJxgo/JQFWTlY13svS7HCr0ZsN035eRmKOsXzROfB9ugXcTuc6MP94ICM7TlB/DtJOP+bLX53mijw== dependencies: "@apollographql/apollo-tools" "^0.4.0" "@apollographql/graphql-playground-html" "1.6.24" "@types/graphql-upload" "^8.0.0" "@types/ws" "^6.0.0" - apollo-cache-control "0.8.1" - apollo-datasource "0.6.1" - apollo-engine-reporting "1.4.3" - apollo-server-caching "0.5.0" - apollo-server-env "2.4.1" - apollo-server-errors "2.3.1" - apollo-server-plugin-base "0.6.1" - apollo-server-types "0.2.1" - apollo-tracing "0.8.1" + apollo-cache-control "^0.8.4" + apollo-datasource "^0.6.3" + apollo-engine-reporting "^1.4.6" + apollo-server-caching "^0.5.0" + apollo-server-env "^2.4.3" + apollo-server-errors "^2.3.3" + apollo-server-plugin-base "^0.6.4" + apollo-server-types "^0.2.4" + apollo-tracing "^0.8.4" fast-json-stable-stringify "^2.0.0" - graphql-extensions "0.9.1" + graphql-extensions "^0.10.3" graphql-tag "^2.9.2" graphql-tools "^4.0.0" graphql-upload "^8.0.2" @@ -3349,62 +3375,78 @@ apollo-server-env@2.4.1: node-fetch "^2.1.2" util.promisify "^1.0.0" -apollo-server-errors@2.3.1, apollo-server-errors@^2.0.2: +apollo-server-env@^2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-2.4.3.tgz#9bceedaae07eafb96becdfd478f8d92617d825d2" + integrity sha512-23R5Xo9OMYX0iyTu2/qT0EUb+AULCBriA9w8HDfMoChB8M+lFClqUkYtaTTHDfp6eoARLW8kDBhPOBavsvKAjA== + dependencies: + node-fetch "^2.1.2" + util.promisify "^1.0.0" + +apollo-server-errors@^2.0.2: version "2.3.1" resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.3.1.tgz#033cf331463ebb99a563f8354180b41ac6714eb6" integrity sha512-errZvnh0vUQChecT7M4A/h94dnBSRL213dNxpM5ueMypaLYgnp4hiCTWIEaooo9E4yMGd1qA6WaNbLDG2+bjcg== -apollo-server-express@^2.6.7: - version "2.8.1" - resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.8.1.tgz#955708efdcae8201b7941f0b5c5895e76997b4a3" - integrity sha512-XoWqSuNQkL8ivBq5LXJW6wV0/Ef+m8w4fAK/7PBspLHVfDAbHRyRr6zraotim2Kl7NOnzcqHtb6sB9yozjL0hA== +apollo-server-errors@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.3.3.tgz#83763b00352c10dc68fbb0d41744ade66de549ff" + integrity sha512-MO4oJ129vuCcbqwr5ZwgxqGGiLz3hCyowz0bstUF7MR+vNGe4oe3DWajC9lv4CxrhcqUHQOeOPViOdIo1IxE3g== + +apollo-server-express@^2.9.4: + version "2.9.4" + resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.9.4.tgz#ae7ca0b70a644ba9fa5e3ac395d1e2d9a4b23522" + integrity sha512-diX9n81E0tIJ0Sy2bHvDGPM9QsFBsZ76Nx/dszinY00ViyWG0yIAYEYWeRbsoKTeNDWWTvlMrh/3Eu2oaCIEhQ== dependencies: "@apollographql/graphql-playground-html" "1.6.24" "@types/accepts" "^1.3.5" - "@types/body-parser" "1.17.0" + "@types/body-parser" "1.17.1" "@types/cors" "^2.8.4" - "@types/express" "4.17.0" + "@types/express" "4.17.1" accepts "^1.3.5" - apollo-server-core "2.8.1" - apollo-server-types "0.2.1" + apollo-server-core "^2.9.4" + apollo-server-types "^0.2.4" body-parser "^1.18.3" cors "^2.8.4" + express "^4.17.1" graphql-subscriptions "^1.0.0" graphql-tools "^4.0.0" + parseurl "^1.3.2" subscriptions-transport-ws "^0.9.16" type-is "^1.6.16" -apollo-server-plugin-base@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.6.1.tgz#b9c209aa2102a26c6134f51bfa1e4a8307b63b11" - integrity sha512-gLLF0kz4QOOyczDGWuR2ZNDfa1nHfyFNG76ue8Es0/0ujnMT9KoSokXkx1hDh0X7FFTMj/MelYYoNEqgTH88zw== +apollo-server-plugin-base@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.6.4.tgz#63ea4fd0bbb6c4510bc8d0d2ad0a0684c8d0da8c" + integrity sha512-4rY+cBAIpQomGWYBtk8hHkLQWHrh5hgIBPQqmhXh00YFdcY+Ob1/cU2/2iqTcIzhtcaezsc8OZ63au6ahSBQqg== dependencies: - apollo-server-types "0.2.1" + apollo-server-types "^0.2.4" -apollo-server-types@0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/apollo-server-types/-/apollo-server-types-0.2.1.tgz#553da40ea1ad779ef0390c250ddad7eb782fdf64" - integrity sha512-ls26d6jjY7x91ctLWtbpQHGW0lcFR1LcOpDvBQUC2aCwQzuW/6yV7F3hfcEdLR9pjIxcA4yAtFQcKf5olDWVkA== +apollo-server-types@^0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/apollo-server-types/-/apollo-server-types-0.2.4.tgz#28864900ffc7f9711a859297c143a833fdb6aa43" + integrity sha512-G4FvBVgGQcTW6ZBS2+hvcDQkSfdOIKV+cHADduXA275v+5zl42g+bCaGd/hCCKTDRjmQvObLiMxH/BJ6pDMQgA== dependencies: - apollo-engine-reporting-protobuf "0.4.0" - apollo-server-caching "0.5.0" - apollo-server-env "2.4.1" + apollo-engine-reporting-protobuf "^0.4.0" + apollo-server-caching "^0.5.0" + apollo-server-env "^2.4.3" -apollo-tracing@0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.8.1.tgz#220aeac6ad598c67f9333739155b7a56bd63ccab" - integrity sha512-zhVNC7N6hg9IJEeSEXFDxcnXD5GJQAbHxaoKVBKEolcIIsz6EGd700ORdagJgFKLReVp9O65HPrZJCg66sVx7g== +apollo-tracing@^0.8.4: + version "0.8.4" + resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.8.4.tgz#0117820c3f0ad3aa6daf7bf13ddbb923cbefa6de" + integrity sha512-DjbFW0IvHicSlTVG+vK+1WINfBMRCdPPHJSW/j65JMir9Oe56WGeqL8qz8hptdUUmLYEb+azvcyyGsJsiR3zpQ== dependencies: - apollo-server-env "2.4.1" - graphql-extensions "0.8.1" + apollo-server-env "^2.4.3" + graphql-extensions "^0.10.3" -apollo-upload-client@^10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/apollo-upload-client/-/apollo-upload-client-10.0.1.tgz#e8446288d03edb1c582c91c26a18b27533f85013" - integrity sha512-K6WnuYQi0RRTNO+aSPVjoUWXp4QSr+eoKU4fE0OKQp25XRF2oXl2cTLs+Q4Nk0wOIHM76YGdo/IHtzuNR7jO+A== +apollo-upload-client@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/apollo-upload-client/-/apollo-upload-client-11.0.0.tgz#465a2ed5756e6155f53befaf82d17bdb08c82060" + integrity sha512-JChTrBi1VSF8u6OPrkWUApJlyUvzwhw98kqRB3fSi7/CU6z0OUD42Mee9s5h8mfjKEfOanK6GNZhF4t2tIPXSw== dependencies: - apollo-link "^1.2.11" - apollo-link-http-common "^0.2.13" + "@babel/runtime" "^7.5.4" + apollo-link "^1.2.12" + apollo-link-http-common "^0.2.14" extract-files "^5.0.1" apollo-utilities@1.3.2, apollo-utilities@^1.0.1, apollo-utilities@^1.0.8, apollo-utilities@^1.2.1, apollo-utilities@^1.3.0, apollo-utilities@^1.3.2: @@ -3417,28 +3459,28 @@ apollo-utilities@1.3.2, apollo-utilities@^1.0.1, apollo-utilities@^1.0.8, apollo ts-invariant "^0.4.0" tslib "^1.9.3" -apollo@^2.15.0: - version "2.16.3" - resolved "https://registry.yarnpkg.com/apollo/-/apollo-2.16.3.tgz#6f4e3681480db0286832427b566e581dab97f907" - integrity sha512-Y2AcawM/NYdeee/jUcVS8hzIYblc9T4gIiCMgR0a7/vQGOX3eGp4IgLvr3ICiPogANZDFOMJODJ/1N8tXmk0WA== +apollo@^2.18.3: + version "2.18.3" + resolved "https://registry.yarnpkg.com/apollo/-/apollo-2.18.3.tgz#a06d8e2f3096e235ca20ec98c8e14bf5131f053a" + integrity sha512-NxlW4WprImYQcQvBCM87nrMV5RuhF7cynlFxnk8QIYhxVb+o79/h/b6Cs6jR3+LGrBPkY+GUKz04aO79RgHP4Q== dependencies: - "@apollographql/apollo-tools" "0.4.0" - "@oclif/command" "1.5.16" - "@oclif/config" "1.13.2" + "@apollographql/apollo-tools" "^0.4.0" + "@oclif/command" "1.5.18" + "@oclif/config" "1.13.3" "@oclif/errors" "1.2.2" - "@oclif/plugin-autocomplete" "0.1.2" - "@oclif/plugin-help" "2.2.0" - "@oclif/plugin-not-found" "1.2.2" + "@oclif/plugin-autocomplete" "0.1.3" + "@oclif/plugin-help" "2.2.1" + "@oclif/plugin-not-found" "1.2.3" "@oclif/plugin-plugins" "1.7.8" "@oclif/plugin-warn-if-update-available" "1.7.0" - apollo-codegen-core "0.34.12" - apollo-codegen-flow "0.33.22" - apollo-codegen-scala "0.34.22" - apollo-codegen-swift "0.34.3" - apollo-codegen-typescript "0.34.12" - apollo-env "0.5.1" - apollo-graphql "0.3.3" - apollo-language-server "1.14.1" + apollo-codegen-core "^0.35.3" + apollo-codegen-flow "^0.33.28" + apollo-codegen-scala "^0.34.28" + apollo-codegen-swift "^0.35.8" + apollo-codegen-typescript "^0.35.3" + apollo-env "^0.5.1" + apollo-graphql "^0.3.3" + apollo-language-server "^1.15.3" chalk "2.4.2" env-ci "3.2.2" gaze "1.1.3" @@ -4378,7 +4420,7 @@ braces@^2.3.1, braces@^2.3.2: split-string "^3.0.2" to-regex "^3.0.1" -braces@^3.0.2: +braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -4563,6 +4605,30 @@ cacache@^12.0.2: unique-filename "^1.1.1" y18n "^4.0.0" +cacache@^13.0.0: + version "13.0.1" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-13.0.1.tgz#a8000c21697089082f85287a1aec6e382024a71c" + integrity sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w== + dependencies: + chownr "^1.1.2" + figgy-pudding "^3.5.1" + fs-minipass "^2.0.0" + glob "^7.1.4" + graceful-fs "^4.2.2" + infer-owner "^1.0.4" + lru-cache "^5.1.1" + minipass "^3.0.0" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.2" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + p-map "^3.0.0" + promise-inflight "^1.0.1" + rimraf "^2.7.1" + ssri "^7.0.0" + unique-filename "^1.1.1" + cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" @@ -4693,11 +4759,16 @@ caniuse-lite@^1.0.30000955: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000988.tgz#742f35ec1b8b75b9628d705d7652eea1fef983db" integrity sha512-lPj3T8poYrRc/bniW5SQPND3GRtSrQdUM/R4mCYTbZxyi3jQiggLvZH4+BYUuX0t4TXjU+vMM7KFDQg+rSzZUQ== -caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30000984, caniuse-lite@^1.0.30000989: +caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30000984: version "1.0.30000989" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw== +caniuse-lite@^1.0.30000997: + version "1.0.30000998" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000998.tgz#7227a8046841e7d01e156ae7227a504d065f6744" + integrity sha512-8Tj5sPZR9kMHeDD9SZXIVr5m9ofufLLCG2Y4QwQrH18GIwG+kCc+zYdlR036ZRkuKjVVetyxeAgGA1xF7XdmzQ== + capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -4828,26 +4899,31 @@ chokidar@^2.0.2, chokidar@^2.0.4, chokidar@^2.1.5: optionalDependencies: fsevents "^1.2.7" -chokidar@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.0.2.tgz#0d1cd6d04eb2df0327446188cd13736a3367d681" - integrity sha512-c4PR2egjNjI1um6bamCQ6bUNPDiyofNQruHvKgHQ4gDUP/ITSVSzNsiI5OWtHOsX323i5ha/kk4YmOZ1Ktg7KA== +chokidar@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.2.1.tgz#4634772a1924512d990d4505957bf3a510611387" + integrity sha512-/j5PPkb5Feyps9e+jo07jUZGvkB5Aj953NrI4s8xSVScrAo/RHeILrtdb4uzR7N6aaFFxxJ+gt8mA8HfNpw76w== dependencies: - anymatch "^3.0.1" - braces "^3.0.2" - glob-parent "^5.0.0" - is-binary-path "^2.1.0" - is-glob "^4.0.1" - normalize-path "^3.0.0" - readdirp "^3.1.1" + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.1.3" optionalDependencies: - fsevents "^2.0.6" + fsevents "~2.1.0" chownr@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== +chownr@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" + integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw== + chrome-trace-event@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" @@ -5494,10 +5570,10 @@ create-react-context@^0.2.1: fbjs "^0.8.0" gud "^1.0.0" -cross-env@~6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-6.0.0.tgz#3c8e71440ea20aa6faaf5aec541235efc565dac6" - integrity sha512-G/B6gtkjgthT8AP/xN1wdj5Xe18fVyk58JepK8GxpUbqcz3hyWxegocMbvnZK+KoTslwd0ACZ3woi/DVUdVjyQ== +cross-env@~6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-6.0.3.tgz#4256b71e49b3a40637a0ce70768a6ef5c72ae941" + integrity sha512-+KqxF6LCvfhWvADcDPqo64yVIB31gv/jQulX2NGzKS/g3GEVz6/pt4wjHFtFWsHMddebWD/sDthJemzM4MaAag== dependencies: cross-spawn "^7.0.0" @@ -5912,11 +5988,6 @@ deepmerge@^3.2.0: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-3.2.0.tgz#58ef463a57c08d376547f8869fdc5bcee957f44e" integrity sha512-6+LuZGU7QCNUnAJyX8cIrlzoEgggTM6B7mm+znKOX4t5ltluT9KLjN6g61ECMS0LTsLW7yDpNoxhix5FZcrIow== -deepmerge@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-3.3.0.tgz#d3c47fd6f3a93d517b14426b0628a17b0125f5f7" - integrity sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA== - deepmerge@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.0.0.tgz#3e3110ca29205f120d7cb064960a39c3d2087c09" @@ -6777,7 +6848,7 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -execa@^2.0.1, execa@^2.0.4: +execa@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/execa/-/execa-2.0.4.tgz#2f5cc589c81db316628627004ea4e37b93391d8e" integrity sha512-VcQfhuGD51vQUQtKIq2fjGDLDbL6N1DTQVpYzxZ7LPIXw3HqTuIz6uxRmpV1qf8i31LHf2kjiaGI+GdHwRgbnQ== @@ -7338,6 +7409,13 @@ fs-minipass@^1.2.5: dependencies: minipass "^2.2.1" +fs-minipass@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.0.0.tgz#a6415edab02fae4b9e9230bc87ee2e4472003cd1" + integrity sha512-40Qz+LFXmd9tzYVnnBmZvFfvAADfUA14TXPK1s7IfElJTIZ97rA8w4Kin7Wt5JBrC3ShnnFJO/5vPjPEeJIq9A== + dependencies: + minipass "^3.0.0" + fs-write-stream-atomic@^1.0.8: version "1.0.10" resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" @@ -7361,10 +7439,10 @@ fsevents@^1.2.7: nan "^2.12.1" node-pre-gyp "^0.12.0" -fsevents@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.0.6.tgz#87b19df0bfb4a1a51d7ddb51b01b5f3bedb40c33" - integrity sha512-vfmKZp3XPM36DNF0qhW+Cdxk7xm7gTEHY1clv1Xq1arwRQuKZgAhw+NZNWbJBtuaNxzNXwhfdPYRrvIbjfS33A== +fsevents@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.0.tgz#ce1a5f9ac71c6d75278b0c5bd236d7dfece4cbaa" + integrity sha512-+iXhW3LuDQsno8dOIrCIT/CBjeBWuP7PXe8w9shnj9Lebny/Gx1ZjVBYwexLz36Ri2jKuXMNpV6CYNh8lHHgrQ== fstream@^1.0.0, fstream@^1.0.12: version "1.0.12" @@ -7512,10 +7590,10 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob-parent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.0.0.tgz#1dc99f0f39b006d3e92c2c284068382f0c20e954" - integrity sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg== +glob-parent@~5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.0.tgz#5f4c1d1e748d30cd73ad2944b3577a81b081e8c2" + integrity sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw== dependencies: is-glob "^4.0.1" @@ -7670,7 +7748,7 @@ graceful-fs@^4.1.9: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.0.tgz#8d8fdc73977cb04104721cb53666c1ca64cd328b" integrity sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg== -graceful-fs@^4.2.0: +graceful-fs@^4.2.0, graceful-fs@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02" integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q== @@ -7683,23 +7761,14 @@ graphql-anywhere@^4.1.0-alpha.0: apollo-utilities "^1.2.1" tslib "^1.9.3" -graphql-extensions@0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.8.1.tgz#f5f1fed5fe49620c4e70c5d08bdbd0039e91c402" - integrity sha512-d/L4x7/PPWhviJqi7jIWOVJPzfzagYgPizSQUpa+3hozbWhwpWEnfxwgL5/If5MnPUikBnqlkOLCyjHMNdipYA== +graphql-extensions@^0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.10.3.tgz#9e37f3bd26309c40b03a0be0e63e02b3f99d52ea" + integrity sha512-kwU0gUe+Qdfr8iZYT91qrPSwQNgPhB/ClF1m1LEPdxlptk5FhFmjpxAcbMZ8q7j0kjfnbp2IeV1OhRDCEPqz2w== dependencies: "@apollographql/apollo-tools" "^0.4.0" - apollo-server-env "2.4.1" - apollo-server-types "0.2.1" - -graphql-extensions@0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.9.1.tgz#5d40b2c2cf57a35b686121d5e63783369dade5ef" - integrity sha512-JR/KStdwALd48B/xSG/Mi85zamuJd8THvVlzGM5juznPDN0wTYG5SARGzzvoqHxgxuUHYdzpvESwMAisORJdCQ== - dependencies: - "@apollographql/apollo-tools" "^0.4.0" - apollo-server-env "2.4.1" - apollo-server-types "0.2.1" + apollo-server-env "^2.4.3" + apollo-server-types "^0.2.4" graphql-subscriptions@^1.0.0, graphql-subscriptions@^1.1.0: version "1.1.0" @@ -7745,7 +7814,7 @@ graphql-upload@^8.0.2: http-errors "^1.7.2" object-path "^0.11.4" -"graphql@14.0.2 - 14.2.0 || ^14.3.1", graphql@^14.4.0, graphql@~14.5.8: +"graphql@14.0.2 - 14.2.0 || ^14.3.1", graphql@^14.5.8, graphql@~14.5.8: version "14.5.8" resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.5.8.tgz#504f3d3114cb9a0a3f359bbbcf38d9e5bf6a6b3c" integrity sha512-MMwmi0zlVLQKLdGiMfWkgQD7dY/TUKt4L+zgJ/aR0Howebod3aNgP5JkgvAULiR2HPVZaP2VEElqtdidHweLkg== @@ -7778,10 +7847,10 @@ gzip-size@^5.0.0: duplexer "^0.1.1" pify "^4.0.1" -hable@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/hable/-/hable-2.2.1.tgz#714ef141a7eda5bd8530d6e4e3b37c6807716290" - integrity sha512-CuGRGMNnCp8RJ70zeoTX37sX4ctoT8BpmkStI2TYQwBBtWzQQFXQ/jsBUCqd34grt3IJQ+hkUXAU84/IuErVLQ== +hable@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/hable/-/hable-2.3.2.tgz#7867ffec0b67e63136937613d9a0bc646ac9d7fe" + integrity sha512-qJ9WoXl/15LNlG1KeAuBjCNGStUb+MCQ5biPxOmwRyESH8CSWwZB4xEnzCduuQ3I/mlgui28t8/oMAGT1Rpb2g== handlebars@^4.1.2: version "4.1.2" @@ -8348,7 +8417,7 @@ indexes-of@^1.0.1: resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= -infer-owner@^1.0.3: +infer-owner@^1.0.3, infer-owner@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== @@ -8530,7 +8599,7 @@ is-binary-path@^1.0.0: dependencies: binary-extensions "^1.0.0" -is-binary-path@^2.1.0: +is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== @@ -8691,7 +8760,7 @@ is-glob@^3.1.0: dependencies: is-extglob "^2.1.0" -is-glob@^4.0.0, is-glob@^4.0.1: +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== @@ -10331,6 +10400,27 @@ minimist@~0.0.1: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= +minipass-collect@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" + integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== + dependencies: + minipass "^3.0.0" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-pipeline@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.2.tgz#3dcb6bb4a546e32969c7ad710f2c79a86abba93a" + integrity sha512-3JS5A2DKhD2g0Gg8x3yamO0pj7YeKGwVlDS90pF++kxptwx/F+B//roxf9SqYil5tQo65bijy+dAuAFZmYOouA== + dependencies: + minipass "^3.0.0" + minipass@^2.2.1, minipass@^2.3.4: version "2.3.5" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" @@ -10339,6 +10429,13 @@ minipass@^2.2.1, minipass@^2.3.4: safe-buffer "^5.1.2" yallist "^3.0.0" +minipass@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.0.1.tgz#b4fec73bd61e8a40f0b374ddd04260ade2c8ec20" + integrity sha512-2y5okJ4uBsjoD2vAbLKL9EUQPPkC0YMIp+2mZOXG3nBba++pdfJWRxx2Ewirc0pwAJYu4XtWg2EkVo1nRXuO/w== + dependencies: + yallist "^4.0.0" + minizlib@^1.1.1: version "1.2.1" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" @@ -10662,10 +10759,10 @@ node-sass@^4.12.0, node-sass@~4.12.0: stdout-stream "^1.4.0" "true-case-path" "^1.0.2" -nodemon@^1.19.1: - version "1.19.2" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.19.2.tgz#b0975147dc99b3761ceb595b3f9277084931dcc0" - integrity sha512-hRLYaw5Ihyw9zK7NF+9EUzVyS6Cvgc14yh8CAYr38tPxJa6UrOxwAQ351GwrgoanHCF0FalQFn6w5eoX/LGdJw== +nodemon@^1.19.3: + version "1.19.3" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.19.3.tgz#db71b3e62aef2a8e1283a9fa00164237356102c0" + integrity sha512-TBNKRmJykEbxpTniZBusqRrUTHIEqa2fpecbTQDQj1Gxjth7kKAPP296ztR0o5gPUWsiYbuEbt73/+XMYab1+w== dependencies: chokidar "^2.1.5" debug "^3.1.0" @@ -10717,7 +10814,7 @@ normalize-path@^2.1.1: dependencies: remove-trailing-separator "^1.0.1" -normalize-path@^3.0.0: +normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== @@ -10817,18 +10914,18 @@ nuxt-env@~0.1.0: resolved "https://registry.yarnpkg.com/nuxt-env/-/nuxt-env-0.1.0.tgz#8ac50b9ff45391ad3044ea932cbd05f06a585f87" integrity sha512-7mTao3qG0zfN0hahk3O6SuDy0KEwYmNojammWQsMwhqMn3aUjX4nMYnWDa0pua+2/rwAY9oG53jQtLgJdG7f9w== -nuxt@~2.9.2: - version "2.9.2" - resolved "https://registry.yarnpkg.com/nuxt/-/nuxt-2.9.2.tgz#3c190fe79dcb00550029d065bb9505caffd02bbb" - integrity sha512-PQjHQfh567g9J+SdbiZPWUZ9FXKWDONE9kB6/H9O9reWcac+jwD/uwWzZrgt+W6AiphHmbfwyGGLwCLv5hrQBg== +nuxt@~2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/nuxt/-/nuxt-2.10.0.tgz#854c21e87c8b237359253b9419f05149b6214b63" + integrity sha512-Hl5hbT6gbfNXinY74oFvYroa0d0rCKpJQgJaLDN57e8CZu9kCe/90Gr21BX1+npcguIicjup5EXZ4GwzlcXKDA== dependencies: - "@nuxt/builder" "2.9.2" - "@nuxt/cli" "2.9.2" - "@nuxt/core" "2.9.2" - "@nuxt/generator" "2.9.2" - "@nuxt/loading-screen" "^1.0.1" + "@nuxt/builder" "2.10.0" + "@nuxt/cli" "2.10.0" + "@nuxt/core" "2.10.0" + "@nuxt/generator" "2.10.0" + "@nuxt/loading-screen" "^1.2.0" "@nuxt/opencollective" "^0.3.0" - "@nuxt/webpack" "2.9.2" + "@nuxt/webpack" "2.10.0" nwsapi@^2.0.7: version "2.1.4" @@ -11146,6 +11243,13 @@ p-map@^2.0.0: resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== +p-map@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" + integrity sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ== + dependencies: + aggregate-error "^3.0.0" + p-reduce@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" @@ -11257,7 +11361,7 @@ parse5@^3.0.1: dependencies: "@types/node" "*" -parseurl@~1.3.2, parseurl@~1.3.3: +parseurl@^1.3.2, parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== @@ -12154,6 +12258,15 @@ postcss@^7.0.17: source-map "^0.6.1" supports-color "^6.1.0" +postcss@^7.0.18: + version "7.0.18" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.18.tgz#4b9cda95ae6c069c67a4d933029eddd4838ac233" + integrity sha512-/7g1QXXgegpF+9GJj4iN7ChGF40sYuGYJ8WZu8DZWnmhQ/G36hfdk3q9LBJmoK+lZ+yzZ5KYpOoxq7LF1BxE8g== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -12970,10 +13083,10 @@ readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" -readdirp@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.1.2.tgz#fa85d2d14d4289920e4671dead96431add2ee78a" - integrity sha512-8rhl0xs2cxfVsqzreYCvs8EwBfn/DhVdqtoLmw19uI3SC5avYX9teCurlErfpPXGmYtMHReGaP2RsLnFvz/lnw== +readdirp@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.1.3.tgz#d6e011ed5b9240a92f08651eeb40f7942ceb6cc1" + integrity sha512-ZOsfTGkjO2kqeR5Mzr5RYDbTGYneSkdNKX2fOX2P5jF7vMrd/GNnIAUtDldeHHumHUCQ3V05YfWUdxMPAsRu9Q== dependencies: picomatch "^2.0.4" @@ -13334,6 +13447,13 @@ rimraf@2, rimraf@2.6.3, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6 dependencies: glob "^7.1.3" +rimraf@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" @@ -13494,6 +13614,14 @@ schema-utils@^2.0.0, schema-utils@^2.1.0, schema-utils@^2.2.0: ajv "^6.10.2" ajv-keywords "^3.4.1" +schema-utils@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.4.1.tgz#e89ade5d056dc8bcaca377574bb4a9c4e1b8be56" + integrity sha512-RqYLpkPZX5Oc3fw/kHHHyP56fg5Y+XBpIpV8nCg0znIALfq3OH+Ea9Hfeac9BAMwG5IICltiZ0vxFvJQONfA5w== + dependencies: + ajv "^6.10.2" + ajv-keywords "^3.4.1" + scriptjs@^2.5.9: version "2.5.9" resolved "https://registry.yarnpkg.com/scriptjs/-/scriptjs-2.5.9.tgz#343915cd2ec2ed9bfdde2b9875cd28f59394b35f" @@ -13571,10 +13699,10 @@ serialize-javascript@^1.3.0, serialize-javascript@^1.7.0: resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.7.0.tgz#d6e0dfb2a3832a8c94468e6eb1db97e55a192a65" integrity sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA== -serialize-javascript@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.8.0.tgz#9515fc687232e2321aea1ca7a529476eb34bb480" - integrity sha512-3tHgtF4OzDmeKYj6V9nSyceRS0UJ3C7VqyD2Yj28vC/z2j6jG5FmFGahOKMD9CrglxTm3tETr87jEypaYV8DUg== +serialize-javascript@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.0.tgz#9310276819efd0eb128258bb341957f6eb2fc570" + integrity sha512-a/mxFfU00QT88umAJQsNWOnUKckhNCqOl028N48e7wFmo2/EHpTo9Wso+iJJCMrQnmFvcjto5RJdAHEvVhcyUQ== serve-favicon@^2.5.0: version "2.5.0" @@ -13967,6 +14095,14 @@ ssri@^6.0.1: dependencies: figgy-pudding "^3.5.1" +ssri@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-7.0.1.tgz#b0cab7bbb11ac9ea07f003453e2011f8cbed9f34" + integrity sha512-FfndBvkXL9AHyGLNzU3r9AvYIBBZ7gm+m+kd0p8cT3/v4OliMAyipZAhLVEv1Zi/k4QFq9CstRGVd9pW/zcHFQ== + dependencies: + figgy-pudding "^3.5.1" + minipass "^3.0.0" + stable@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" @@ -14417,6 +14553,20 @@ terser-webpack-plugin@^1.2.4, terser-webpack-plugin@^1.4.1: webpack-sources "^1.4.0" worker-farm "^1.7.0" +terser-webpack-plugin@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-2.1.2.tgz#2b9b8147a6f18918348200800cf9560c50f701bb" + integrity sha512-MF/C4KABwqYOfRDi87f7gG07GP7Wj/kyiX938UxIGIO6l5mkh8XJL7xtS0hX/CRdVQaZI7ThGUPZbznrCjsGpg== + dependencies: + cacache "^13.0.0" + find-cache-dir "^3.0.0" + jest-worker "^24.9.0" + schema-utils "^2.4.1" + serialize-javascript "^2.1.0" + source-map "^0.6.1" + terser "^4.3.4" + webpack-sources "^1.4.3" + terser@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/terser/-/terser-4.1.2.tgz#b2656c8a506f7ce805a3f300a2ff48db022fa391" @@ -14426,6 +14576,15 @@ terser@^4.1.2: source-map "~0.6.1" source-map-support "~0.5.12" +terser@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.3.4.tgz#ad91bade95619e3434685d69efa621a5af5f877d" + integrity sha512-Kcrn3RiW8NtHBP0ssOAzwa2MsIRQ8lJWiBG/K7JgqPlomA3mtb2DEmp4/hrUA+Jujx+WZ02zqd7GYD+QRBB/2Q== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + test-exclude@^5.2.3: version "5.2.3" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.2.3.tgz#c3d3e1e311eb7ee405e092dac10aefd09091eac0" @@ -14722,13 +14881,6 @@ tryer@^1.0.0: resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== -ts-invariant@^0.3.2: - version "0.3.3" - resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.3.3.tgz#b5742b1885ecf9e29c31a750307480f045ec0b16" - integrity sha512-UReOKsrJFGC9tUblgSRWo+BsVNbEd77Cl6WiV/XpMlkifXwNIJbknViCucHvVZkXSC/mcWeRnIGdY7uprcwvdQ== - dependencies: - tslib "^1.9.3" - ts-invariant@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.4.2.tgz#8685131b8083e67c66d602540e78763408be9113" @@ -14736,7 +14888,7 @@ ts-invariant@^0.4.0: dependencies: tslib "^1.9.3" -ts-node@^8, ts-node@^8.3.0: +ts-node@^8: version "8.3.0" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.3.0.tgz#e4059618411371924a1fb5f3b125915f324efb57" integrity sha512-dyNS/RqyVTDcmNM4NIBAeDMpsAdaQ+ojdf0GOLqE6nwJOgzEkdRNzJywhDfwnuvB10oa6NLVG1rUJQCpRN7qoQ== @@ -14747,6 +14899,17 @@ ts-node@^8, ts-node@^8.3.0: source-map-support "^0.5.6" yn "^3.0.0" +ts-node@^8.4.1: + version "8.4.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.4.1.tgz#270b0dba16e8723c9fa4f9b4775d3810fd994b4f" + integrity sha512-5LpRN+mTiCs7lI5EtbXmF/HfMeCjzt7DH9CZwtkr6SywStrNQC723wG+aOWFiLNn7zT3kD/RnFqi3ZUfr4l5Qw== + dependencies: + arg "^4.1.0" + diff "^4.0.1" + make-error "^1.1.1" + source-map-support "^0.5.6" + yn "^3.0.0" + ts-pnp@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.1.2.tgz#be8e4bfce5d00f0f58e0666a82260c34a57af552" @@ -14969,11 +15132,16 @@ unzip-response@^2.0.1: resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= -upath@^1.1.1, upath@^1.1.2: +upath@^1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068" integrity sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q== +upath@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + update-notifier@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" @@ -15182,47 +15350,47 @@ vscode-uri@^1.0.6: resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.8.tgz#9769aaececae4026fb6e22359cb38946580ded59" integrity sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ== -vue-apollo@^3.0.0-rc.5: - version "3.0.0-rc.5" - resolved "https://registry.yarnpkg.com/vue-apollo/-/vue-apollo-3.0.0-rc.5.tgz#0280c0855318ca89439014c24f3a693a301fa25d" - integrity sha512-FuVP93Zq0cglj/S7xRJtmeuGa47BuE7PVEuEbmpGObhEu6sV8TzUMVI6UUTiOHMXYS02NvCAazyy4GAh8Duz8A== +vue-apollo@^3.0.0-rc.7: + version "3.0.0-rc.7" + resolved "https://registry.yarnpkg.com/vue-apollo/-/vue-apollo-3.0.0-rc.7.tgz#4b603a9080acddf79d41d130609b5c66b7ded2eb" + integrity sha512-YbE4cVKuIOowhOVhMOLrvReELXZc1l7bKGNKQXYv3H1xRMYaz5U0KhXjgO16UCnYvygAG1jRKbkgSoHwaXmlDA== dependencies: chalk "^2.4.2" - serialize-javascript "^1.7.0" + serialize-javascript "^2.1.0" throttle-debounce "^2.1.0" -vue-cli-plugin-apollo@^0.21.0: - version "0.21.0" - resolved "https://registry.yarnpkg.com/vue-cli-plugin-apollo/-/vue-cli-plugin-apollo-0.21.0.tgz#51249d76827db2684d23342ddc70017e5baba76b" - integrity sha512-UUEmwwxcx06our1s0Ln3i898wi5e/lxMid1+8Y6y+iL2qeaDKAhm8QjM5SljLpA6u8orCzjpj3+/XRMPLazseQ== +vue-cli-plugin-apollo@^0.21.1: + version "0.21.1" + resolved "https://registry.yarnpkg.com/vue-cli-plugin-apollo/-/vue-cli-plugin-apollo-0.21.1.tgz#ce61b035c5205d76ad486ef946b71de51c735421" + integrity sha512-4Ym0aKoOWDSAtuNrlGkbiPzOOf/5boxTuo62xKYVaN2Sak1TZSRP+FnD49f8LcWBA/JPKemlxjGUPFqLC45GmQ== dependencies: - apollo "^2.15.0" - apollo-cache-inmemory "^1.6.2" - apollo-client "^2.6.3" - apollo-link "^1.2.12" - apollo-link-context "^1.0.18" - apollo-link-http "^1.5.15" + apollo "^2.18.3" + apollo-cache-inmemory "^1.6.3" + apollo-client "^2.6.4" + apollo-link "^1.2.13" + apollo-link-context "^1.0.19" + apollo-link-http "^1.5.16" apollo-link-persisted-queries "^0.2.2" apollo-link-state "^0.4.2" - apollo-link-ws "^1.0.18" - apollo-server-express "^2.6.7" - apollo-upload-client "^10.0.1" + apollo-link-ws "^1.0.19" + apollo-server-express "^2.9.4" + apollo-upload-client "^11.0.0" apollo-utilities "^1.3.2" chalk "^2.4.2" - deepmerge "^3.3.0" - dotenv "^8.0.0" + deepmerge "^4.0.0" + dotenv "^8.1.0" esm "^3.2.25" - execa "^2.0.1" + execa "^2.0.4" express "^4.17.1" - fs-extra "^8.0.1" - graphql "^14.4.0" + fs-extra "^8.1.0" + graphql "^14.5.8" graphql-subscriptions "^1.1.0" graphql-tag "^2.10.1" graphql-tools "^4.0.5" node-fetch "^2.6.0" - nodemon "^1.19.1" + nodemon "^1.19.3" subscriptions-transport-ws "^0.9.16" - ts-node "^8.3.0" + ts-node "^8.4.1" vue-client-only@^2.0.0: version "2.0.0" @@ -15290,10 +15458,10 @@ vue-loader@^15.7.1, vue-loader@~15.7.0: vue-hot-reload-api "^2.3.0" vue-style-loader "^4.1.0" -vue-meta@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/vue-meta/-/vue-meta-2.2.1.tgz#30c2ff8b806f67eb2079734883c586295761b086" - integrity sha512-S0setu909L+jQNI4wa/WUMMJQSHIOU13eQZVIIBT1sCEH7g91AWwNA347//5lbWoNvyr3EQPk/kPMuPnhEbL1w== +vue-meta@^2.2.2: + version "2.3.0" + resolved "https://registry.yarnpkg.com/vue-meta/-/vue-meta-2.3.0.tgz#7f4af99b02c7a1811ad332110839f0c8ab1c4ea3" + integrity sha512-pLfbtVco5HXWQ6byjK+KdmGZJFaXcE441Dt1UmuQmT1lyX05QLRZo5laDYSHZdgGyHyiUsykZAKVBRXBCvDa6w== dependencies: deepmerge "^4.0.0" @@ -15446,10 +15614,10 @@ webidl-conversions@^4.0.2: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== -webpack-bundle-analyzer@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.4.1.tgz#430544c7ba1631baccf673475ca8300cb74a3c47" - integrity sha512-Bs8D/1zF+17lhqj2OYmzi7HEVYqEVxu7lCO9Ff8BwajenOU0vAwEoV8e4ICCPNZAcqR1PCR/7o2SkW+cnCmF0A== +webpack-bundle-analyzer@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.5.2.tgz#ac02834f4b31de8e27d71e6c7a612301ebddb79f" + integrity sha512-g9spCNe25QYUVqHRDkwG414GTok2m7pTTP0wr6l0J50Z3YLS04+BGodTqqoVBL7QfU/U/9p/oiI5XFOyfZ7S/A== dependencies: acorn "^6.0.7" acorn-walk "^6.1.1" @@ -15475,6 +15643,17 @@ webpack-dev-middleware@^3.7.0: range-parser "^1.2.1" webpack-log "^2.0.0" +webpack-dev-middleware@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz#0019c3db716e3fa5cecbf64f2ab88a74bab331f3" + integrity sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw== + dependencies: + memory-fs "^0.4.1" + mime "^2.4.4" + mkdirp "^0.5.1" + range-parser "^1.2.1" + webpack-log "^2.0.0" + webpack-external-import@^0.0.1-beta.19: version "0.0.1-beta.19" resolved "https://registry.yarnpkg.com/webpack-external-import/-/webpack-external-import-0.0.1-beta.19.tgz#505c2bf1bf43bf6be96e25ac1e586ab0b46aa87f" @@ -15524,7 +15703,15 @@ webpack-sources@^1.4.0, webpack-sources@^1.4.1: source-list-map "^2.0.0" source-map "~0.6.1" -webpack@^4.33.0, webpack@^4.38.0, webpack@^4.39.3: +webpack-sources@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack@^4.33.0, webpack@^4.38.0: version "4.39.3" resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.39.3.tgz#a02179d1032156b713b6ec2da7e0df9d037def50" integrity sha512-BXSI9M211JyCVc3JxHWDpze85CvjC842EvpRsVTc/d15YJGlox7GIDd38kJgWrb3ZluyvIjgenbLDMBQPDcxYQ== @@ -15553,6 +15740,35 @@ webpack@^4.33.0, webpack@^4.38.0, webpack@^4.39.3: watchpack "^1.6.0" webpack-sources "^1.4.1" +webpack@^4.41.0: + version "4.41.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.41.0.tgz#db6a254bde671769f7c14e90a1a55e73602fc70b" + integrity sha512-yNV98U4r7wX1VJAj5kyMsu36T8RPPQntcb5fJLOsMz/pt/WrKC0Vp1bAlqPLkA1LegSwQwf6P+kAbyhRKVQ72g== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-module-context" "1.8.5" + "@webassemblyjs/wasm-edit" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + acorn "^6.2.1" + ajv "^6.10.2" + ajv-keywords "^3.4.1" + chrome-trace-event "^1.0.2" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.3" + json-parse-better-errors "^1.0.2" + loader-runner "^2.4.0" + loader-utils "^1.2.3" + memory-fs "^0.4.1" + micromatch "^3.1.10" + mkdirp "^0.5.1" + neo-async "^2.6.1" + node-libs-browser "^2.2.1" + schema-utils "^1.0.0" + tapable "^1.1.3" + terser-webpack-plugin "^1.4.1" + watchpack "^1.6.0" + webpack-sources "^1.4.1" + webpackbar@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/webpackbar/-/webpackbar-4.0.0.tgz#ee7a87f16077505b5720551af413c8ecd5b1f780" @@ -15836,6 +16052,11 @@ yallist@^3.0.0, yallist@^3.0.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + yargs-parser@^13.1.1: version "13.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" @@ -15911,6 +16132,14 @@ zen-observable-ts@^0.8.19: tslib "^1.9.3" zen-observable "^0.8.0" +zen-observable-ts@^0.8.20: + version "0.8.20" + resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.20.tgz#44091e335d3fcbc97f6497e63e7f57d5b516b163" + integrity sha512-2rkjiPALhOtRaDX6pWyNqK1fnP5KkJJybYebopNSn6wDG1lxBoFs2+nwwXKoA6glHIrtwrfBBy6da0stkKtTAA== + dependencies: + tslib "^1.9.3" + zen-observable "^0.8.0" + zen-observable@^0.8.0: version "0.8.14" resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.14.tgz#d33058359d335bc0db1f0af66158b32872af3bf7" diff --git a/yarn.lock b/yarn.lock index 54937694e..e5b36f7f3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -741,9 +741,9 @@ regenerator-runtime "^0.12.0" "@babel/runtime@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" - integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.2.tgz#c3d6e41b304ef10dcf13777a33e7694ec4a9a6dd" + integrity sha512-EXxN64agfUqqIGeEjI5dL5z0Sw0ZwWo1mLTi4mQowCZ42O59b7DRpZAnTC6OqdF28wMBMFKNb/4uFGrVaigSpg== dependencies: regenerator-runtime "^0.13.2" @@ -1772,10 +1772,10 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: safe-buffer "^5.0.1" sha.js "^2.4.8" -cross-env@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-6.0.0.tgz#3c8e71440ea20aa6faaf5aec541235efc565dac6" - integrity sha512-G/B6gtkjgthT8AP/xN1wdj5Xe18fVyk58JepK8GxpUbqcz3hyWxegocMbvnZK+KoTslwd0ACZ3woi/DVUdVjyQ== +cross-env@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-6.0.3.tgz#4256b71e49b3a40637a0ce70768a6ef5c72ae941" + integrity sha512-+KqxF6LCvfhWvADcDPqo64yVIB31gv/jQulX2NGzKS/g3GEVz6/pt4wjHFtFWsHMddebWD/sDthJemzM4MaAag== dependencies: cross-spawn "^7.0.0"