diff --git a/assets/styles/imports/_toast.scss b/assets/styles/imports/_toast.scss
new file mode 100644
index 000000000..0ef81a5b2
--- /dev/null
+++ b/assets/styles/imports/_toast.scss
@@ -0,0 +1,32 @@
+.iziToast-target, .iziToast {
+ &,
+ &:after,
+ &.iziToast-color-dark:after {
+ box-shadow: none !important;
+ }
+}
+
+.iziToast .iziToast-message {
+ font-weight: 400 !important;
+}
+
+.iziToast.iziToast-color-red {
+ background: $color-danger !important;
+ border-color: $color-danger !important;
+}
+.iziToast.iziToast-color-orange {
+ background: $color-warning !important;
+ border-color: $color-warning !important;
+}
+.iziToast.iziToast-color-yellow {
+ background: $color-yellow !important;
+ border-color: $color-yellow !important;
+}
+.iziToast.iziToast-color-blue {
+ background: $color-secondary !important;
+ border-color: $color-secondary !important;
+}
+.iziToast.iziToast-color-green {
+ background: $color-success !important;
+ border-color: $color-success !important;
+}
diff --git a/assets/styles/main.scss b/assets/styles/main.scss
index e44241d88..e7a456a08 100644
--- a/assets/styles/main.scss
+++ b/assets/styles/main.scss
@@ -1,5 +1,6 @@
@import 'vue-cion-design-system/src/system/tokens/generated/tokens.scss';
@import './imports/_tooltip.scss';
+@import './imports/_toast.scss';
// Transition Easing
$easeOut: cubic-bezier(0.19, 1, 0.22, 1);
diff --git a/components/Author.vue b/components/Author.vue
index ec891f5ae..fc7e01518 100644
--- a/components/Author.vue
+++ b/components/Author.vue
@@ -21,7 +21,22 @@
style="min-width: 250px;"
@mouseover="popoverMouseEnter"
@mouseleave="popoveMouseLeave">
+
+
+
+ {{ fanCount }}
+ Fans
+
+
Kommentare
-
-
- {{ fanCount }}
- Fans
-
-
@@ -100,6 +106,9 @@ export default {
}
},
computed: {
+ itsMe() {
+ return this.author.slug === this.$store.getters['auth/user'].slug
+ },
fanCount() {
let count = Number(this.author.followedByCount) || 0
if (this.voted) {
@@ -145,3 +154,12 @@ export default {
}
}
+
+
diff --git a/components/FollowButton.vue b/components/FollowButton.vue
index a174fac80..790a86d12 100644
--- a/components/FollowButton.vue
+++ b/components/FollowButton.vue
@@ -1,6 +1,7 @@
{
+ this.loading = false
this.disabled = true
this.$emit('update')
})
diff --git a/layouts/default.vue b/layouts/default.vue
index 747a81b49..588cb8e55 100644
--- a/layouts/default.vue
+++ b/layouts/default.vue
@@ -7,6 +7,15 @@
href="/">
+
+
+
@@ -16,3 +25,13 @@
+
+
diff --git a/middleware/authenticated.js b/middleware/authenticated.js
new file mode 100644
index 000000000..af2a7076c
--- /dev/null
+++ b/middleware/authenticated.js
@@ -0,0 +1,26 @@
+import { isEmpty } from 'lodash'
+
+export default async ({ store, env, route, redirect }) => {
+ let publicPages = env.publicPages
+ // only affect non public pages
+ if (publicPages.indexOf(route.name) >= 0) {
+ return true
+ }
+
+ // await store.dispatch('auth/refreshJWT', 'authenticated middleware')
+ const isAuthenticated = await store.dispatch('auth/check')
+ if (isAuthenticated === true) {
+ return true
+ }
+
+ // try to logout user
+ // await store.dispatch('auth/logout', null, { root: true })
+
+ // set the redirect path for after the login
+ let params = {}
+ if (!isEmpty(route.path) && route.path !== '/') {
+ params.path = route.path
+ }
+
+ return redirect('/login', params)
+}
diff --git a/nuxt.config.js b/nuxt.config.js
index 6959ab7e1..832d87e4a 100644
--- a/nuxt.config.js
+++ b/nuxt.config.js
@@ -1,4 +1,17 @@
const pkg = require('./package')
+const envWhitelist = [
+ 'BUILD_COMMIT',
+ 'NODE_ENV',
+ 'WEBAPP_HOST',
+ 'WEBAPP_PORT',
+ 'WEBAPP_BASE_URL',
+ 'API_HOST',
+ 'API_PORT',
+ 'EMBED_API_URL',
+ 'SENTRY_DNS_PUBLIC',
+ 'MAPBOX_TOKEN',
+ 'MAINTENANCE'
+]
module.exports = {
mode: 'universal',
@@ -7,6 +20,19 @@ module.exports = {
name: 'slide-up',
mode: 'out-in'
},
+
+ env: {
+ // pages which do NOT require a login
+ publicPages: [
+ 'login',
+ 'logout',
+ 'register',
+ 'signup',
+ 'reset',
+ 'reset-token',
+ 'pages-slug'
+ ]
+ },
/*
** Headers of the page
*/
@@ -42,15 +68,12 @@ module.exports = {
{ src: '~/plugins/design-system.js', ssr: true },
{ src: '~/plugins/vue-directives.js', ssr: false },
{ src: '~/plugins/v-tooltip.js', ssr: false },
+ { src: '~/plugins/izi-toast.js', ssr: false },
{ src: '~/plugins/vue-filters.js' }
],
router: {
- // middleware: [
- // 'maintenance',
- // 'check-auth',
- // 'authenticated'
- // ],
+ middleware: ['authenticated'],
linkActiveClass: 'router-active-link'
},
/* router: {
@@ -81,14 +104,17 @@ module.exports = {
/*
** Nuxt.js modules
*/
- modules: ['@nuxtjs/apollo'],
+ modules: [
+ '@nuxtjs/apollo',
+ ['@nuxtjs/dotenv', { only: envWhitelist }],
+ ['nuxt-env', { keys: envWhitelist }]
+ ],
// Give apollo module options
apollo: {
- tokenName: 'yourApolloTokenName', // optional, default: apollo-token
- tokenExpires: 10, // optional, default: 7 (days)
- includeNodeModules: true, // optional, default: false (this includes graphql-tag for node_modules folder)
- authenticationType: 'Basic', // optional, default: 'Bearer'
+ // tokenName: 'yourApolloTokenName', // optional, default: apollo-token
+ tokenExpires: 1, // optional, default: 7 (days)
+ // includeNodeModules: true, // optional, default: false (this includes graphql-tag for node_modules folder)
// optional
errorHandler(error) {
console.log(
@@ -97,6 +123,14 @@ module.exports = {
error.message
)
},
+
+ // Watch loading state for all queries
+ // See 'Smart Query > options > watchLoading' for detail
+ // TODO: find a way to get this working
+ // watchLoading(isLoading) {
+ // console.log('Global loading', countModifier)
+ // this.$nuxt.$loading.start()
+ // },
// required
clientConfigs: {
default: {
@@ -107,6 +141,8 @@ module.exports = {
httpLinkOptions: {
credentials: 'same-origin'
},
+ credentials: true,
+
// You can use `wss` for secure connection (recommended in production)
// Use `null` to disable subscriptions
// wsEndpoint: 'ws://localhost:4000', // optional
diff --git a/package.json b/package.json
index 10ab719ce..8b738f630 100644
--- a/package.json
+++ b/package.json
@@ -12,18 +12,22 @@
"generate": "nuxt generate",
"lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
"styleguide": "cd ./styleguide && yarn dev",
- "styleguide:build": "cd ./styleguide && yarn build:lib && cd ../ && yarn upgrade file:./styleguide",
+ "styleguide:build": "cd ./styleguide && yarn build:lib && cd ../ && yarn upgrade --ignore-engines file:./styleguide",
"precommit": "yarn lint"
},
"dependencies": {
"@nuxtjs/apollo": "^4.0.0-rc3",
+ "@nuxtjs/dotenv": "^1.3.0",
"cross-env": "^5.2.0",
"date-fns": "^1.29.0",
"express": "^4.16.3",
"graphql-tag": "^2.10.0",
+ "jsonwebtoken": "^8.3.0",
"nuxt": "^2.0.0",
+ "nuxt-env": "^0.0.4",
"v-tooltip": "^2.0.0-rc.33",
- "vue-cion-design-system": "file:./styleguide"
+ "vue-cion-design-system": "file:./styleguide",
+ "vue-izitoast": "^1.1.0"
},
"devDependencies": {
"babel-eslint": "^10.0.1",
diff --git a/pages/index.vue b/pages/index.vue
index ebcf4666f..1a557c705 100644
--- a/pages/index.vue
+++ b/pages/index.vue
@@ -71,12 +71,7 @@ export default {
shoutedCount
}
}
- `),
- variables() {
- return {
- id: this.$route.query.post || 'p1'
- }
- }
+ `)
}
}
}
diff --git a/pages/login.vue b/pages/login.vue
index 677993048..44a9108c8 100644
--- a/pages/login.vue
+++ b/pages/login.vue
@@ -11,7 +11,7 @@
Wenn Du ein Konto bei Human Connection hast, melde Dich bitte hier an.
-
@@ -49,7 +50,7 @@
Wem folgt {{ user.name | truncate(15) }}?
-
+
-
+
+export default {
+ layout: 'blank',
+ asyncData({ error }) {
+ error({ statusCode: 404, message: 'Profile slug missing' })
+ }
+}
+
diff --git a/plugins/izi-toast.js b/plugins/izi-toast.js
new file mode 100644
index 000000000..5900898ac
--- /dev/null
+++ b/plugins/izi-toast.js
@@ -0,0 +1,13 @@
+import Vue from 'vue'
+import VueIziToast from 'vue-izitoast'
+
+import 'izitoast/dist/css/iziToast.css'
+
+export default ({ app }) => {
+ Vue.use(VueIziToast, {
+ position: 'bottomRight',
+ transitionIn: 'bounceInLeft',
+ layout: 2,
+ theme: 'dark'
+ })
+}
diff --git a/store/auth.js b/store/auth.js
new file mode 100644
index 000000000..c95c0e825
--- /dev/null
+++ b/store/auth.js
@@ -0,0 +1,152 @@
+import gql from 'graphql-tag'
+import jwt from 'jsonwebtoken'
+
+export const state = () => {
+ return {
+ user: null,
+ token: null,
+ pending: false
+ }
+}
+
+export const mutations = {
+ SET_USER(state, user) {
+ state.user = user || null
+ },
+ SET_USER_SETTINGS(state, userSettings) {
+ // state.user = Object.assign(state.user, {
+ // userSettings: Object.assign(this.getters['auth/userSettings'], userSettings)
+ // })
+ },
+ SET_TOKEN(state, token) {
+ state.token = token || null
+ },
+ SET_PENDING(state, pending) {
+ state.pending = pending
+ }
+}
+
+export const getters = {
+ isLoggedIn(state) {
+ return !!(state.user && state.token)
+ },
+ pending(state) {
+ return !!state.pending
+ },
+ isVerified(state) {
+ return !!state.user && state.user.isVerified && !!state.user.name
+ },
+ isAdmin(state) {
+ return !!state.user && state.user.role === 'ADMIN'
+ },
+ isModerator(state) {
+ return (
+ !!state.user &&
+ (state.user.role === 'ADMIN' || state.user.role === 'MODERATOR')
+ )
+ },
+ user(state) {
+ return state.user || {}
+ },
+ token(state) {
+ return state.token
+ }
+ // userSettings(state, getters, rootState, rootGetters) {
+ // const userSettings = (state.user && state.user.userSettings) ? state.user.userSettings : {}
+ //
+ // const defaultLanguage = (state.user && state.user.language) ? state.user.language : rootGetters['i18n/locale']
+ // let contentLanguages = !isEmpty(userSettings.contentLanguages) ? userSettings.contentLanguages : []
+ // if (isEmpty(contentLanguages)) {
+ // contentLanguages = userSettings.uiLanguage ? [userSettings.uiLanguage] : [defaultLanguage]
+ // }
+ //
+ // return Object.assign({
+ // uiLanguage: defaultLanguage,
+ // contentLanguages: contentLanguages
+ // }, userSettings)
+ // }
+}
+
+export const actions = {
+ async init({ commit }) {
+ if (process.client) {
+ return
+ }
+ const token = this.app.$apolloHelpers.getToken()
+ if (!token) {
+ return
+ }
+
+ const user = await jwt.verify(token, 'b/&&7b78BF&fv/Vd')
+ if (user.id) {
+ commit('SET_USER', {
+ id: user.id,
+ name: user.name,
+ slug: user.slug,
+ email: user.email,
+ avatar: user.avatar,
+ role: user.role
+ })
+ commit('SET_TOKEN', token)
+ }
+ },
+ async check({ commit, dispatch, getters }) {
+ if (!this.app.$apolloHelpers.getToken()) {
+ await dispatch('logout')
+ }
+ return getters.isLoggedIn
+ },
+ async login({ commit }, { email, password }) {
+ try {
+ commit('SET_PENDING', true)
+ commit('SET_USER', null)
+ commit('SET_TOKEN', null)
+ const res = await this.app.apolloProvider.defaultClient
+ .mutate({
+ mutation: gql(`
+ mutation($email: String!, $password: String!) {
+ login(email: $email, password: $password) {
+ id
+ name
+ email
+ avatar
+ token
+ }
+ }
+ `),
+ variables: { email, password }
+ })
+ .then(({ data }) => data && data.login)
+
+ if (res && res.token) {
+ await this.app.$apolloHelpers.onLogin(res.token)
+ commit('SET_TOKEN', res.token)
+ delete res.token
+ commit('SET_USER', res)
+ commit('SET_PENDING', false)
+ return true
+ } else {
+ commit('SET_PENDING', false)
+ throw new Error('THERE IS AN ERROR')
+ }
+ } catch (err) {
+ commit('SET_USER', null)
+ commit('SET_TOKEN', null)
+ commit('SET_PENDING', false)
+ throw new Error(err)
+ }
+ },
+ async logout({ commit }) {
+ commit('SET_USER', null)
+ commit('SET_TOKEN', null)
+ return this.app.$apolloHelpers.onLogout()
+ },
+ register(
+ { dispatch, commit },
+ { email, password, inviteCode, invitedByUserId }
+ ) {},
+ async patch({ state, commit, dispatch }, data) {},
+ resendVerifySignup({ state, dispatch }) {},
+ resetPassword({ state }, data) {},
+ setNewPassword({ state }, data) {}
+}
diff --git a/store/index.js b/store/index.js
new file mode 100644
index 000000000..91be021a5
--- /dev/null
+++ b/store/index.js
@@ -0,0 +1,9 @@
+export const state = () => ({})
+
+export const mutations = {}
+
+export const actions = {
+ async nuxtServerInit({ dispatch }) {
+ await dispatch('auth/init')
+ }
+}
diff --git a/yarn.lock b/yarn.lock
index 55c902ca8..42c3fca1b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -708,6 +708,12 @@
babel-helper-vue-jsx-merge-props "^2.0.3"
babel-plugin-transform-vue-jsx "^4.0.1"
+"@nuxtjs/dotenv@^1.3.0":
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/@nuxtjs/dotenv/-/dotenv-1.3.0.tgz#fcfd8fa9da767ce1a79c11104ab998d610e23731"
+ dependencies:
+ dotenv "^6.0.0"
+
"@nuxtjs/friendly-errors-webpack-plugin@^2.0.2":
version "2.0.2"
resolved "http://registry.npmjs.org/@nuxtjs/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-2.0.2.tgz#80fd4c4276e87c09a9157a6f433724235eaaaf6e"
@@ -1696,6 +1702,10 @@ browserslist@^4.0.0, browserslist@^4.1.0, browserslist@^4.1.2:
electron-to-chromium "^1.3.73"
node-releases "^1.0.0-alpha.12"
+buffer-equal-constant-time@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
+
buffer-from@^1.0.0, buffer-from@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
@@ -2676,6 +2686,10 @@ dot-prop@^4.1.0, dot-prop@^4.1.1:
dependencies:
is-obj "^1.0.0"
+dotenv@^6.0.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.1.0.tgz#9853b6ca98292acb7dec67a95018fa40bccff42c"
+
duplexer3@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
@@ -2700,6 +2714,12 @@ ecc-jsbn@~0.1.1:
jsbn "~0.1.0"
safer-buffer "^2.1.0"
+ecdsa-sig-formatter@1.0.10:
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz#1c595000f04a8897dfb85000892a0f4c33af86c3"
+ dependencies:
+ safe-buffer "^5.0.1"
+
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
@@ -4119,6 +4139,10 @@ iterall@^1.1.3, iterall@^1.2.1, iterall@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7"
+izitoast@^1.3.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/izitoast/-/izitoast-1.4.0.tgz#1aa4e3408b7159fba743506af66d8be54fd929fb"
+
js-base64@^2.1.8:
version "2.4.9"
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.9.tgz#748911fb04f48a60c4771b375cac45a80df11c03"
@@ -4196,6 +4220,20 @@ jsonify@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
+jsonwebtoken@^8.3.0:
+ version "8.3.0"
+ resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.3.0.tgz#056c90eee9a65ed6e6c72ddb0a1d325109aaf643"
+ dependencies:
+ jws "^3.1.5"
+ lodash.includes "^4.3.0"
+ lodash.isboolean "^3.0.3"
+ lodash.isinteger "^4.0.4"
+ lodash.isnumber "^3.0.3"
+ lodash.isplainobject "^4.0.6"
+ lodash.isstring "^4.0.1"
+ lodash.once "^4.0.0"
+ ms "^2.1.1"
+
jsprim@^1.2.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
@@ -4205,6 +4243,21 @@ jsprim@^1.2.2:
json-schema "0.2.3"
verror "1.10.0"
+jwa@^1.1.5:
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.1.6.tgz#87240e76c9808dbde18783cf2264ef4929ee50e6"
+ dependencies:
+ buffer-equal-constant-time "1.0.1"
+ ecdsa-sig-formatter "1.0.10"
+ safe-buffer "^5.0.1"
+
+jws@^3.1.5:
+ version "3.1.5"
+ resolved "https://registry.yarnpkg.com/jws/-/jws-3.1.5.tgz#80d12d05b293d1e841e7cb8b4e69e561adcf834f"
+ dependencies:
+ jwa "^1.1.5"
+ safe-buffer "^5.0.1"
+
kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
@@ -4336,10 +4389,30 @@ lodash.debounce@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
+lodash.includes@^4.3.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
+
+lodash.isboolean@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
+
+lodash.isinteger@^4.0.4:
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
+
+lodash.isnumber@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc"
+
lodash.isplainobject@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
+lodash.isstring@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
+
lodash.memoize@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
@@ -4352,6 +4425,10 @@ lodash.mergewith@^4.6.0:
version "4.6.1"
resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927"
+lodash.once@^4.0.0:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
+
lodash.tail@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.tail/-/lodash.tail-4.1.1.tgz#d2333a36d9e7717c8ad2f7cacafec7c32b444664"
@@ -4912,6 +4989,10 @@ number-is-nan@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
+nuxt-env@^0.0.4:
+ version "0.0.4"
+ resolved "https://registry.yarnpkg.com/nuxt-env/-/nuxt-env-0.0.4.tgz#5cc13436d2745da1d180f02910b7a2c7171e540c"
+
nuxt@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/nuxt/-/nuxt-2.1.0.tgz#0875c4c1ce5dbd729d973a5aa0de0ee8aad35a8b"
@@ -7487,6 +7568,12 @@ vue-hot-reload-api@^2.3.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.1.tgz#b2d3d95402a811602380783ea4f566eb875569a2"
+vue-izitoast@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/vue-izitoast/-/vue-izitoast-1.1.0.tgz#4b2b81b91e688eedc95d8f500752ac9ec87d3a8d"
+ dependencies:
+ izitoast "^1.3.0"
+
vue-loader@^15.4.2:
version "15.4.2"
resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.4.2.tgz#812bb26e447dd3b84c485eb634190d914ce125e2"