refactor: deps update + 2FA setup + verify
This commit is contained in:
1 parent
29afc61abf
commit
f72530bf84
58 files changed
+481
-391
No files matched your search
@@ -64,7 +64,7 @@ const graphQLLink = ApolloLink.from([
|
||||
})
|
||||
store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: isAuthError ? `You are not authorized to access this resource.` : `An unexpected error occured.`,
|
||||
message: isAuthError ? `You are not authorized to access this resource.` : `An unexpected error occurred.`,
|
||||
icon: 'alert'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -309,6 +309,21 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
.admin-providerlogo {
|
||||
width: 250px;
|
||||
height: 50px;
|
||||
float: right;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
margin-left: 16px;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.v-application.admin {
|
||||
code {
|
||||
box-shadow: none;
|
||||
|
||||
@@ -46,14 +46,16 @@
|
||||
hide-details
|
||||
inset
|
||||
)
|
||||
v-card-info(color='blue')
|
||||
div
|
||||
div {{provider.description}}
|
||||
span.caption: a(:href='provider.website') {{provider.website}}
|
||||
v-spacer
|
||||
.admin-providerlogo
|
||||
img(:src='provider.logo', :alt='provider.title')
|
||||
v-card-text
|
||||
v-form
|
||||
.analytic-provider-logo
|
||||
img(:src='provider.logo', :alt='provider.title')
|
||||
.body-2.pt-3 {{provider.description}}
|
||||
.body-2.pt-3: a(:href='provider.website') {{provider.website}}
|
||||
v-divider.mt-5
|
||||
.overline.py-5 {{$t('admin:analytics.providerConfiguration')}}
|
||||
.overline.pb-5 {{$t('admin:analytics.providerConfiguration')}}
|
||||
.body-1.ml-3(v-if='!provider.config || provider.config.length < 1'): em {{$t('admin:analytics.providerNoConfiguration')}}
|
||||
template(v-else, v-for='cfg in provider.config')
|
||||
v-select(
|
||||
@@ -177,21 +179,3 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
|
||||
.analytic-provider-logo {
|
||||
width: 250px;
|
||||
height: 85px;
|
||||
float:right;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -211,7 +211,7 @@ export default {
|
||||
} else {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: _.get(resp, 'data.authentication.createApiKey.responseResult.message', 'An unexpected error occured.'),
|
||||
message: _.get(resp, 'data.authentication.createApiKey.responseResult.message', 'An unexpected error occurred.'),
|
||||
icon: 'alert'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ export default {
|
||||
} else {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: _.get(resp, 'data.authentication.setApiState.responseResult.message', 'An unexpected error occured.'),
|
||||
message: _.get(resp, 'data.authentication.setApiState.responseResult.message', 'An unexpected error occurred.'),
|
||||
icon: 'alert'
|
||||
})
|
||||
}
|
||||
@@ -182,7 +182,7 @@ export default {
|
||||
} else {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: _.get(resp, 'data.authentication.revokeApiKey.responseResult.message', 'An unexpected error occured.'),
|
||||
message: _.get(resp, 'data.authentication.revokeApiKey.responseResult.message', 'An unexpected error occurred.'),
|
||||
icon: 'alert'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
span {{strategy.strategy.description}}
|
||||
.caption: a(:href='strategy.strategy.website') {{strategy.strategy.website}}
|
||||
v-spacer
|
||||
.authlogo
|
||||
.admin-providerlogo
|
||||
img(:src='strategy.strategy.logo', :alt='strategy.strategy.title')
|
||||
v-card-text
|
||||
.overline.mb-5 {{$t('admin:auth.strategyConfiguration')}}
|
||||
@@ -423,22 +423,3 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
|
||||
.authlogo {
|
||||
width: 250px;
|
||||
height: 60px;
|
||||
float:right;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
margin-left: 16px;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -38,12 +38,14 @@
|
||||
v-card.animated.fadeInUp.wait-p2s
|
||||
v-toolbar(color='primary', dense, flat, dark)
|
||||
.subtitle-1 {{provider.title}}
|
||||
v-card-text
|
||||
.providerlogo
|
||||
v-card-info(color='blue')
|
||||
div
|
||||
div {{provider.description}}
|
||||
span.caption: a(:href='provider.website') {{provider.website}}
|
||||
v-spacer
|
||||
.admin-providerlogo
|
||||
img(:src='provider.logo', :alt='provider.title')
|
||||
.caption.pt-3 {{provider.description}}
|
||||
.caption.pb-3: a(:href='provider.website') {{provider.website}}
|
||||
v-divider.mt-3
|
||||
v-card-text
|
||||
.overline.my-5 {{$t('admin:comments.providerConfig')}}
|
||||
.body-2.ml-3(v-if='!provider.config || provider.config.length < 1'): em {{$t('admin:comments.providerNoConfig')}}
|
||||
template(v-else, v-for='cfg in provider.config')
|
||||
@@ -202,21 +204,3 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
|
||||
.providerlogo {
|
||||
width: 250px;
|
||||
height: 85px;
|
||||
float:right;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -226,7 +226,7 @@ export default {
|
||||
}
|
||||
})
|
||||
if (!_.get(resp, 'data.mail.sendTest.responseResult.succeeded', false)) {
|
||||
throw new Error(_.get(resp, 'data.mail.sendTest.responseResult.message', 'An unexpected error occured.'))
|
||||
throw new Error(_.get(resp, 'data.mail.sendTest.responseResult.message', 'An unexpected error occurred.'))
|
||||
}
|
||||
|
||||
this.testEmail = ''
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
.headline.primary--text.animated.fadeInLeft {{$t('navigation.title')}}
|
||||
.subtitle-1.grey--text.animated.fadeInLeft.wait-p4s {{$t('navigation.subtitle')}}
|
||||
v-spacer
|
||||
v-btn.animated.fadeInDown.wait-p2s.mr-3(icon, outlined, color='grey', @click='refresh')
|
||||
v-btn.animated.fadeInDown.wait-p3s(icon, outlined, color='grey', href='https://docs.requarks.io/navigation', target='_blank')
|
||||
v-icon mdi-help-circle
|
||||
v-btn.mx-3.animated.fadeInDown.wait-p2s.mr-3(icon, outlined, color='grey', @click='refresh')
|
||||
v-icon mdi-refresh
|
||||
v-btn.animated.fadeInDown(color='success', depressed, @click='save', large)
|
||||
v-icon(left) mdi-check
|
||||
@@ -30,15 +32,6 @@
|
||||
v-list-item-avatar
|
||||
v-icon(v-if='$vuetify.theme.dark', :color='config.mode === `TREE` ? `teal lighten-3` : `grey darken-2`') mdi-check-circle
|
||||
v-icon(v-else, :color='config.mode === `TREE` ? `teal` : `grey lighten-3`') mdi-check-circle
|
||||
v-list-item(value='MIXED')
|
||||
v-list-item-avatar
|
||||
img(src='/_assets/svg/icon-user-menu-male-dotted.svg', alt='Custom Navigation')
|
||||
v-list-item-content
|
||||
v-list-item-title {{$t('admin:navigation.modeCustom.title')}}
|
||||
v-list-item-subtitle {{$t('admin:navigation.modeCustom.description')}}
|
||||
v-list-item-avatar
|
||||
v-icon(v-if='$vuetify.theme.dark', :color='config.mode === `MIXED` ? `teal lighten-3` : `grey darken-2`') mdi-check-circle
|
||||
v-icon(v-else, :color='config.mode === `MIXED` ? `teal` : `grey lighten-3`') mdi-check-circle
|
||||
v-list-item(value='STATIC')
|
||||
v-list-item-avatar
|
||||
img(src='/_assets/svg/icon-features-list.svg', alt='Static Navigation')
|
||||
@@ -48,6 +41,15 @@
|
||||
v-list-item-avatar
|
||||
v-icon(v-if='$vuetify.theme.dark', :color='config.mode === `STATIC` ? `teal lighten-3` : `grey darken-2`') mdi-check-circle
|
||||
v-icon(v-else, :color='config.mode === `STATIC` ? `teal` : `grey lighten-3`') mdi-check-circle
|
||||
v-list-item(value='MIXED')
|
||||
v-list-item-avatar
|
||||
img(src='/_assets/svg/icon-user-menu-male-dotted.svg', alt='Custom Navigation')
|
||||
v-list-item-content
|
||||
v-list-item-title {{$t('admin:navigation.modeCustom.title')}}
|
||||
v-list-item-subtitle {{$t('admin:navigation.modeCustom.description')}}
|
||||
v-list-item-avatar
|
||||
v-icon(v-if='$vuetify.theme.dark', :color='config.mode === `MIXED` ? `teal lighten-3` : `grey darken-2`') mdi-check-circle
|
||||
v-icon(v-else, :color='config.mode === `MIXED` ? `teal` : `grey lighten-3`') mdi-check-circle
|
||||
v-list-item(value='NONE')
|
||||
v-list-item-avatar
|
||||
img(src='/_assets/svg/icon-cancel-dotted.svg', alt='None')
|
||||
@@ -421,7 +423,7 @@ export default {
|
||||
icon: 'check'
|
||||
})
|
||||
} else {
|
||||
throw new Error(_.get(resp, 'data.navigation.updateTree.responseResult.message', 'An unexpected error occured.'))
|
||||
throw new Error(_.get(resp, 'data.navigation.updateTree.responseResult.message', 'An unexpected error occurred.'))
|
||||
}
|
||||
} catch (err) {
|
||||
this.$store.commit('pushGraphError', err)
|
||||
|
||||
@@ -85,18 +85,12 @@
|
||||
hide-details
|
||||
inset
|
||||
)
|
||||
v-card-text.py-2.pl-4
|
||||
.body-2.pt-3 {{currentRenderer.description}}
|
||||
.body-2.pt-1.pb-5: a(href='https://docs.requarks.io/en/rendering', target='_blank') Documentation
|
||||
i18next.body-2(path='admin:auth.strategyState', tag='div', v-if='currentRenderer.isEnabled')
|
||||
v-chip(color='green', small, dark, label, place='state') {{$t('admin:auth.strategyStateActive')}}
|
||||
span(v-if='selectedCore === `local`', place='locked') {{$t('admin:auth.strategyStateLocked')}}
|
||||
span(v-else, place='locked', v-text='')
|
||||
i18next.body-2(path='admin:auth.strategyState', tag='div', v-else)
|
||||
v-chip(color='red', small, dark, label, place='state') {{$t('admin:auth.strategyStateInactive')}}
|
||||
v-divider.mt-3
|
||||
v-card-text.pb-4.pt-2.pl-4
|
||||
.overline.my-5 Rendering Module Configuration
|
||||
v-card-info(color='blue')
|
||||
div
|
||||
div {{currentRenderer.description}}
|
||||
span.caption: a(href='https://docs.requarks.io/en/rendering', target='_blank') Documentation
|
||||
v-card-text.pb-4.pl-4
|
||||
.overline.mb-5 Rendering Module Configuration
|
||||
.body-2.ml-3(v-if='!currentRenderer.config || currentRenderer.config.length < 1'): em This rendering module has no configuration options you can modify.
|
||||
template(v-else, v-for='(cfg, idx) in currentRenderer.config')
|
||||
v-select(
|
||||
|
||||
@@ -41,13 +41,15 @@
|
||||
v-card.animated.fadeInUp.wait-p2s
|
||||
v-toolbar(color='primary', dense, flat, dark)
|
||||
.subtitle-1 {{engine.title}}
|
||||
v-card-text
|
||||
.enginelogo
|
||||
v-card-info(color='blue')
|
||||
div
|
||||
div {{engine.description}}
|
||||
span.caption: a(:href='engine.website') {{engine.website}}
|
||||
v-spacer
|
||||
.admin-providerlogo
|
||||
img(:src='engine.logo', :alt='engine.title')
|
||||
.caption.pt-3 {{engine.description}}
|
||||
.caption.pb-3: a(:href='engine.website') {{engine.website}}
|
||||
v-divider.mt-3
|
||||
.overline.my-5 {{$t('admin:search.engineConfig')}}
|
||||
v-card-text
|
||||
.overline.mb-5 {{$t('admin:search.engineConfig')}}
|
||||
.body-2.ml-3(v-if='!engine.config || engine.config.length < 1'): em {{$t('admin:search.engineNoConfig')}}
|
||||
template(v-else, v-for='cfg in engine.config')
|
||||
v-select(
|
||||
|
||||
@@ -92,12 +92,15 @@
|
||||
hide-details
|
||||
inset
|
||||
)
|
||||
v-card-info(color='blue')
|
||||
div
|
||||
div {{target.description}}
|
||||
span.caption: a(:href='target.website') {{target.website}}
|
||||
v-spacer
|
||||
.admin-providerlogo
|
||||
img(:src='target.logo', :alt='target.title')
|
||||
v-card-text
|
||||
v-form
|
||||
.targetlogo
|
||||
img(:src='target.logo', :alt='target.title')
|
||||
.body-2.pt-3 {{target.description}}
|
||||
.body-2.pt-3.pb-5: a(:href='target.website') {{target.website}}
|
||||
i18next.body-2(path='admin:storage.targetState', tag='div', v-if='target.isEnabled')
|
||||
v-chip(color='green', small, dark, label, place='state') {{$t('admin:storage.targetStateActive')}}
|
||||
i18next.body-2(path='admin:storage.targetState', tag='div', v-else)
|
||||
|
||||
@@ -153,7 +153,7 @@ export default {
|
||||
})
|
||||
this.refresh()
|
||||
} else {
|
||||
throw new Error(_.get(resp, 'data.pages.deleteTag.responseResult.message', 'An unexpected error occured.'))
|
||||
throw new Error(_.get(resp, 'data.pages.deleteTag.responseResult.message', 'An unexpected error occurred.'))
|
||||
}
|
||||
} catch (err) {
|
||||
this.$store.commit('pushGraphError', err)
|
||||
@@ -193,7 +193,7 @@ export default {
|
||||
})
|
||||
this.current.updatedAt = new Date()
|
||||
} else {
|
||||
throw new Error(_.get(resp, 'data.pages.updateTag.responseResult.message', 'An unexpected error occured.'))
|
||||
throw new Error(_.get(resp, 'data.pages.updateTag.responseResult.message', 'An unexpected error occurred.'))
|
||||
}
|
||||
} catch (err) {
|
||||
this.$store.commit('pushGraphError', err)
|
||||
|
||||
@@ -212,7 +212,7 @@ export default {
|
||||
} else {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: _.get(resp, 'data.users.create.responseResult.message', 'An unexpected error occured.'),
|
||||
message: _.get(resp, 'data.users.create.responseResult.message', 'An unexpected error occurred.'),
|
||||
icon: 'alert'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -174,7 +174,8 @@
|
||||
v-icon mdi-two-factor-authentication
|
||||
v-list-item-content
|
||||
v-list-item-title {{$t('admin:users.tfa')}}
|
||||
v-list-item-subtitle.red--text Inactive
|
||||
v-list-item-subtitle.green--text(v-if='user.tfaIsActive') Active
|
||||
v-list-item-subtitle.red--text(v-else) Inactive
|
||||
v-list-item-action
|
||||
v-tooltip(top)
|
||||
template(v-slot:activator='{ on }')
|
||||
@@ -709,7 +710,7 @@ export default {
|
||||
} else {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: _.get(resp, 'data.users.activate.responseResult.message', 'An unexpected error occured.'),
|
||||
message: _.get(resp, 'data.users.activate.responseResult.message', 'An unexpected error occurred.'),
|
||||
icon: 'warning'
|
||||
})
|
||||
}
|
||||
@@ -749,7 +750,7 @@ export default {
|
||||
} else {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: _.get(resp, 'data.users.deactivate.responseResult.message', 'An unexpected error occured.'),
|
||||
message: _.get(resp, 'data.users.deactivate.responseResult.message', 'An unexpected error occurred.'),
|
||||
icon: 'warning'
|
||||
})
|
||||
}
|
||||
@@ -798,7 +799,7 @@ export default {
|
||||
} else {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: _.get(resp, 'data.users.delete.responseResult.message', 'An unexpected error occured.'),
|
||||
message: _.get(resp, 'data.users.delete.responseResult.message', 'An unexpected error occurred.'),
|
||||
icon: 'warning'
|
||||
})
|
||||
}
|
||||
@@ -864,7 +865,7 @@ export default {
|
||||
} else {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: _.get(resp, 'data.users.update.responseResult.message', 'An unexpected error occured.'),
|
||||
message: _.get(resp, 'data.users.update.responseResult.message', 'An unexpected error occurred.'),
|
||||
icon: 'warning'
|
||||
})
|
||||
}
|
||||
@@ -935,7 +936,7 @@ export default {
|
||||
} else {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: _.get(resp, 'data.users.verify.responseResult.message', 'An unexpected error occured.'),
|
||||
message: _.get(resp, 'data.users.verify.responseResult.message', 'An unexpected error occurred.'),
|
||||
icon: 'warning'
|
||||
})
|
||||
}
|
||||
@@ -962,6 +963,7 @@ export default {
|
||||
createdAt
|
||||
updatedAt
|
||||
lastLoginAt
|
||||
tfaIsActive
|
||||
groups {
|
||||
id
|
||||
name
|
||||
|
||||
@@ -345,7 +345,7 @@ export default {
|
||||
})
|
||||
const respObj = _.get(resp, 'data.system.importUsersFromV1', {})
|
||||
if (!_.get(respObj, 'responseResult.succeeded', false)) {
|
||||
throw new Error(_.get(respObj, 'responseResult.message', 'An unexpected error occured'))
|
||||
throw new Error(_.get(respObj, 'responseResult.message', 'An unexpected error occurred'))
|
||||
}
|
||||
this.successUsers = _.get(respObj, 'usersCount', 0)
|
||||
this.successGroups = _.get(respObj, 'groupsCount', 0)
|
||||
@@ -429,7 +429,7 @@ export default {
|
||||
})
|
||||
const respObj = _.get(respSv, 'data.storage.updateTargets', {})
|
||||
if (!_.get(respObj, 'responseResult.succeeded', false)) {
|
||||
throw new Error(_.get(respObj, 'responseResult.message', 'An unexpected error occured'))
|
||||
throw new Error(_.get(respObj, 'responseResult.message', 'An unexpected error occurred'))
|
||||
}
|
||||
|
||||
this.progress += 10
|
||||
@@ -480,7 +480,7 @@ export default {
|
||||
|
||||
const respImportObj = _.get(respImport, 'data.storage.executeAction', {})
|
||||
if (!_.get(respImportObj, 'responseResult.succeeded', false)) {
|
||||
throw new Error(_.get(respImportObj, 'responseResult.message', 'An unexpected error occured'))
|
||||
throw new Error(_.get(respImportObj, 'responseResult.message', 'An unexpected error occurred'))
|
||||
}
|
||||
|
||||
this.progress += 15
|
||||
|
||||
@@ -314,7 +314,7 @@ export default {
|
||||
this.$vuetify.goTo(`#comment-post-id-${_.get(resp, 'data.comments.create.id', 0)}`, this.scrollOpts)
|
||||
})
|
||||
} else {
|
||||
throw new Error(_.get(resp, 'data.comments.create.responseResult.message', 'An unexpected error occured.'))
|
||||
throw new Error(_.get(resp, 'data.comments.create.responseResult.message', 'An unexpected error occurred.'))
|
||||
}
|
||||
} catch (err) {
|
||||
this.$store.commit('showNotification', {
|
||||
@@ -420,7 +420,7 @@ export default {
|
||||
|
||||
this.editCommentCancel()
|
||||
} else {
|
||||
throw new Error(_.get(resp, 'data.comments.delete.responseResult.message', 'An unexpected error occured.'))
|
||||
throw new Error(_.get(resp, 'data.comments.delete.responseResult.message', 'An unexpected error occurred.'))
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(err)
|
||||
@@ -482,7 +482,7 @@ export default {
|
||||
|
||||
this.comments = _.reject(this.comments, ['id', this.commentToDelete.id])
|
||||
} else {
|
||||
throw new Error(_.get(resp, 'data.comments.delete.responseResult.message', 'An unexpected error occured.'))
|
||||
throw new Error(_.get(resp, 'data.comments.delete.responseResult.message', 'An unexpected error occurred.'))
|
||||
}
|
||||
} catch (err) {
|
||||
this.$store.commit('showNotification', {
|
||||
|
||||
@@ -172,6 +172,19 @@
|
||||
span {{$t('common:header.newPage')}}
|
||||
v-divider(vertical)
|
||||
|
||||
//- ADMIN
|
||||
|
||||
template(v-if='isAuthenticated && isAdmin')
|
||||
v-tooltip(bottom, v-if='mode !== `admin`')
|
||||
template(v-slot:activator='{ on }')
|
||||
v-btn(icon, tile, height='64', v-on='on', href='/a', :aria-label='$t(`common:header.admin`)')
|
||||
v-icon(color='grey') mdi-cog
|
||||
span {{$t('common:header.admin')}}
|
||||
v-btn(v-else, text, tile, height='64', href='/', :aria-label='$t(`common:actions.exit`)')
|
||||
v-icon(left, color='grey') mdi-exit-to-app
|
||||
span {{$t('common:actions.exit')}}
|
||||
v-divider(vertical)
|
||||
|
||||
//- ACCOUNT
|
||||
|
||||
v-menu(v-if='isAuthenticated', offset-y, bottom, min-width='300', transition='slide-y-transition', left)
|
||||
@@ -210,9 +223,6 @@
|
||||
v-list-item-action: v-icon(color='blue-grey') mdi-face-profile
|
||||
v-list-item-content
|
||||
v-list-item-title(:class='$vuetify.theme.dark ? `blue-grey--text text--lighten-3` : `blue-grey--text`') {{$t('common:header.profile')}}
|
||||
v-list-item(href='/a', v-if='isAuthenticated && isAdmin')
|
||||
v-list-item-action.btn-animate-rotate: v-icon(:color='$vuetify.theme.dark ? `blue-grey lighten-3` : `blue-grey`') mdi-cog
|
||||
v-list-item-title(:class='$vuetify.theme.dark ? `blue-grey--text text--lighten-3` : `blue-grey--text`') {{$t('common:header.admin')}}
|
||||
v-list-item(@click='logout')
|
||||
v-list-item-action: v-icon(color='red') mdi-logout
|
||||
v-list-item-title.red--text {{$t('common:header.logout')}}
|
||||
|
||||
@@ -418,7 +418,7 @@ export default {
|
||||
window.location.assign(`/${this.locale}/${this.path}`)
|
||||
}, 1000)
|
||||
} else {
|
||||
throw new Error(_.get(resp, 'data.pages.restore.responseResult.message', 'An unexpected error occured'))
|
||||
throw new Error(_.get(resp, 'data.pages.restore.responseResult.message', 'An unexpected error occurred'))
|
||||
}
|
||||
} catch (err) {
|
||||
this.$store.commit('showNotification', {
|
||||
|
||||
+157
-82
@@ -2,17 +2,27 @@
|
||||
v-app
|
||||
.login(:style='`background-image: url(` + bgUrl + `);`')
|
||||
.login-sd
|
||||
.d-flex
|
||||
.d-flex.mb-5
|
||||
.login-logo
|
||||
v-avatar(tile, size='34')
|
||||
v-img(:src='logoUrl')
|
||||
.login-title
|
||||
.text-h6 {{ siteTitle }}
|
||||
v-alert.mb-0(
|
||||
v-model='errorShown'
|
||||
transition='slide-y-reverse-transition'
|
||||
color='red darken-2'
|
||||
tile
|
||||
dark
|
||||
dense
|
||||
icon='mdi-alert'
|
||||
)
|
||||
.body-2 {{errorMessage}}
|
||||
//-------------------------------------------------
|
||||
//- PROVIDERS LIST
|
||||
//-------------------------------------------------
|
||||
template(v-if='screen === `login` && strategies.length > 1')
|
||||
.login-subtitle.mt-5
|
||||
.login-subtitle
|
||||
.text-subtitle-1 Select Authentication Provider
|
||||
.login-list
|
||||
v-list.elevation-1.radius-7(nav)
|
||||
@@ -176,19 +186,51 @@
|
||||
v-model='securityCode'
|
||||
:placeholder='$t("auth:tfa.placeholder")'
|
||||
autocomplete='one-time-code'
|
||||
@keyup.enter='verifySecurityCode'
|
||||
@keyup.enter='verifySecurityCode(false)'
|
||||
)
|
||||
v-btn.mt-2.text-none(
|
||||
width='100%'
|
||||
large
|
||||
color='primary'
|
||||
dark
|
||||
@click='verifySecurityCode'
|
||||
@click='verifySecurityCode(false)'
|
||||
:loading='isLoading'
|
||||
) {{ $t('auth:tfa.verifyToken') }}
|
||||
|
||||
//-------------------------------------------------
|
||||
//- SETUP TFA FORM
|
||||
//-------------------------------------------------
|
||||
v-dialog(v-model='isTFASetupShown', max-width='600', persistent)
|
||||
v-card
|
||||
.login-tfa.text-center.pa-5
|
||||
.subtitle-1.primary--text Your administrator has required Two-Factor Authentication (2FA) to be enabled on your account.
|
||||
v-divider.my-5
|
||||
.subtitle-2 1) Scan the QR code below from your mobile 2FA application:
|
||||
.caption (e.g. #[a(href='https://authy.com/', target='_blank', noopener) Authy], #[a(href='https://support.google.com/accounts/answer/1066447', target='_blank', noopener) Google Authenticator], #[a(href='https://www.microsoft.com/en-us/account/authenticator', target='_blank', noopener) Microsoft Authenticator], etc.)
|
||||
.login-tfa-qr.mt-5(v-if='isTFASetupShown', v-html='tfaQRImage')
|
||||
.subtitle-2.mt-5 2) Enter the security code generated from your trusted device:
|
||||
v-text-field.login-tfa-field.mt-2(
|
||||
solo
|
||||
flat
|
||||
background-color='white'
|
||||
hide-details
|
||||
ref='iptTFASetup'
|
||||
v-model='securityCode'
|
||||
:placeholder='$t("auth:tfa.placeholder")'
|
||||
autocomplete='one-time-code'
|
||||
@keyup.enter='verifySecurityCode(true)'
|
||||
)
|
||||
v-btn.mt-2.text-none(
|
||||
width='100%'
|
||||
large
|
||||
color='primary'
|
||||
dark
|
||||
@click='verifySecurityCode(true)'
|
||||
:loading='isLoading'
|
||||
) {{ $t('auth:tfa.verifyToken') }}
|
||||
|
||||
loader(v-model='isLoading', :color='loaderColor', :title='loaderTitle', :subtitle='$t(`auth:pleaseWait`)')
|
||||
notify
|
||||
notify(style='padding-top: 64px;')
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -231,7 +273,11 @@ export default {
|
||||
isShown: false,
|
||||
newPassword: '',
|
||||
newPasswordVerify: '',
|
||||
isTFAShown: false
|
||||
isTFAShown: false,
|
||||
isTFASetupShown: false,
|
||||
tfaQRImage: '',
|
||||
errorShown: false,
|
||||
errorMessage: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -282,26 +328,21 @@ export default {
|
||||
* LOGIN
|
||||
*/
|
||||
async login () {
|
||||
this.errorShown = false
|
||||
if (this.username.length < 2) {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: this.$t('auth:invalidEmailUsername'),
|
||||
icon: 'alert'
|
||||
})
|
||||
this.errorMessage = this.$t('auth:invalidEmailUsername')
|
||||
this.errorShown = true
|
||||
this.$refs.iptEmail.focus()
|
||||
} else if (this.password.length < 2) {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: this.$t('auth:invalidPassword'),
|
||||
icon: 'alert'
|
||||
})
|
||||
this.errorMessage = this.$t('auth:invalidPassword')
|
||||
this.errorShown = true
|
||||
this.$refs.iptPassword.focus()
|
||||
} else {
|
||||
this.loaderColor = 'grey darken-4'
|
||||
this.loaderTitle = this.$t('auth:signingIn')
|
||||
this.isLoading = true
|
||||
try {
|
||||
let resp = await this.$apollo.mutate({
|
||||
const resp = await this.$apollo.mutate({
|
||||
mutation: gql`
|
||||
mutation($username: String!, $password: String!, $strategy: String!) {
|
||||
authentication {
|
||||
@@ -315,8 +356,10 @@ export default {
|
||||
jwt
|
||||
mustChangePwd
|
||||
mustProvideTFA
|
||||
mustSetupTFA
|
||||
continuationToken
|
||||
redirect
|
||||
tfaQRImage
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -328,38 +371,9 @@ export default {
|
||||
}
|
||||
})
|
||||
if (_.has(resp, 'data.authentication.login')) {
|
||||
let respObj = _.get(resp, 'data.authentication.login', {})
|
||||
const respObj = _.get(resp, 'data.authentication.login', {})
|
||||
if (respObj.responseResult.succeeded === true) {
|
||||
this.continuationToken = respObj.continuationToken
|
||||
if (respObj.mustChangePwd === true) {
|
||||
this.screen = 'changePwd'
|
||||
this.$nextTick(() => {
|
||||
this.$refs.iptNewPassword.focus()
|
||||
})
|
||||
this.isLoading = false
|
||||
} else if (respObj.mustProvideTFA === true) {
|
||||
this.screen = 'tfa'
|
||||
this.securityCode = ''
|
||||
this.$nextTick(() => {
|
||||
this.$refs.iptTFA.focus()
|
||||
})
|
||||
this.isLoading = false
|
||||
} else {
|
||||
this.loaderColor = 'green darken-1'
|
||||
this.loaderTitle = this.$t('auth:loginSuccess')
|
||||
Cookies.set('jwt', respObj.jwt, { expires: 365 })
|
||||
_.delay(() => {
|
||||
const loginRedirect = Cookies.get('loginRedirect')
|
||||
if (loginRedirect) {
|
||||
Cookies.remove('loginRedirect')
|
||||
window.location.replace(loginRedirect)
|
||||
} else if (respObj.redirect) {
|
||||
window.location.replace(respObj.redirect)
|
||||
} else {
|
||||
window.location.replace('/')
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
this.handleLoginResponse(respObj)
|
||||
} else {
|
||||
throw new Error(respObj.responseResult.message)
|
||||
}
|
||||
@@ -380,58 +394,70 @@ export default {
|
||||
/**
|
||||
* VERIFY TFA CODE
|
||||
*/
|
||||
verifySecurityCode () {
|
||||
async verifySecurityCode (setup = false) {
|
||||
if (this.securityCode.length !== 6) {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: 'Enter a valid security code.',
|
||||
icon: 'warning'
|
||||
icon: 'alert'
|
||||
})
|
||||
this.$refs.iptTFA.focus()
|
||||
if (setup) {
|
||||
this.$refs.iptTFASetup.focus()
|
||||
} else {
|
||||
this.$refs.iptTFA.focus()
|
||||
}
|
||||
} else {
|
||||
this.loaderColor = 'grey darken-4'
|
||||
this.loaderTitle = this.$t('auth:signingIn')
|
||||
this.isLoading = true
|
||||
this.$apollo.mutate({
|
||||
mutation: gql`
|
||||
{
|
||||
authentication {
|
||||
activeStrategies {
|
||||
key
|
||||
try {
|
||||
const resp = await this.$apollo.mutate({
|
||||
mutation: gql`
|
||||
mutation(
|
||||
$continuationToken: String!
|
||||
$securityCode: String!
|
||||
$setup: Boolean
|
||||
) {
|
||||
authentication {
|
||||
loginTFA(
|
||||
continuationToken: $continuationToken
|
||||
securityCode: $securityCode
|
||||
setup: $setup
|
||||
) {
|
||||
responseResult {
|
||||
succeeded
|
||||
errorCode
|
||||
slug
|
||||
message
|
||||
}
|
||||
jwt
|
||||
mustChangePwd
|
||||
continuationToken
|
||||
redirect
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
continuationToken: this.continuationToken,
|
||||
securityCode: this.securityCode,
|
||||
setup
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
continuationToken: this.continuationToken,
|
||||
securityCode: this.securityCode
|
||||
}
|
||||
}).then(resp => {
|
||||
})
|
||||
if (_.has(resp, 'data.authentication.loginTFA')) {
|
||||
let respObj = _.get(resp, 'data.authentication.loginTFA', {})
|
||||
if (respObj.responseResult.succeeded === true) {
|
||||
this.$store.commit('showNotification', {
|
||||
message: 'Login successful!',
|
||||
style: 'success',
|
||||
icon: 'check'
|
||||
})
|
||||
_.delay(() => {
|
||||
const loginRedirect = Cookies.get('loginRedirect')
|
||||
if (loginRedirect) {
|
||||
Cookies.remove('loginRedirect')
|
||||
window.location.replace(loginRedirect)
|
||||
} else if (respObj.redirect) {
|
||||
window.location.replace(respObj.redirect)
|
||||
} else {
|
||||
window.location.replace('/')
|
||||
}
|
||||
}, 1000)
|
||||
this.isLoading = false
|
||||
this.handleLoginResponse(respObj)
|
||||
} else {
|
||||
if (!setup) {
|
||||
this.isTFAShown = false
|
||||
}
|
||||
throw new Error(respObj.responseResult.message)
|
||||
}
|
||||
} else {
|
||||
throw new Error(this.$t('auth:genericError'))
|
||||
}
|
||||
}).catch(err => {
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
@@ -439,7 +465,7 @@ export default {
|
||||
icon: 'alert'
|
||||
})
|
||||
this.isLoading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
@@ -498,6 +524,46 @@ export default {
|
||||
message: 'Coming soon!',
|
||||
icon: 'ferry'
|
||||
})
|
||||
},
|
||||
handleLoginResponse (respObj) {
|
||||
this.continuationToken = respObj.continuationToken
|
||||
if (respObj.mustChangePwd === true) {
|
||||
this.screen = 'changePwd'
|
||||
this.$nextTick(() => {
|
||||
this.$refs.iptNewPassword.focus()
|
||||
})
|
||||
this.isLoading = false
|
||||
} else if (respObj.mustProvideTFA === true) {
|
||||
this.securityCode = ''
|
||||
this.isTFAShown = true
|
||||
setTimeout(() => {
|
||||
this.$refs.iptTFA.focus()
|
||||
}, 500)
|
||||
this.isLoading = false
|
||||
} else if (respObj.mustSetupTFA === true) {
|
||||
this.securityCode = ''
|
||||
this.isTFASetupShown = true
|
||||
this.tfaQRImage = respObj.tfaQRImage
|
||||
setTimeout(() => {
|
||||
this.$refs.iptTFASetup.focus()
|
||||
}, 500)
|
||||
this.isLoading = false
|
||||
} else {
|
||||
this.loaderColor = 'green darken-1'
|
||||
this.loaderTitle = this.$t('auth:loginSuccess')
|
||||
Cookies.set('jwt', respObj.jwt, { expires: 365 })
|
||||
_.delay(() => {
|
||||
const loginRedirect = Cookies.get('loginRedirect')
|
||||
if (loginRedirect) {
|
||||
Cookies.remove('loginRedirect')
|
||||
window.location.replace(loginRedirect)
|
||||
} else if (respObj.redirect) {
|
||||
window.location.replace(respObj.redirect)
|
||||
} else {
|
||||
window.location.replace('/')
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
},
|
||||
apollo: {
|
||||
@@ -619,6 +685,15 @@ export default {
|
||||
&-field input {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&-qr {
|
||||
background-color: #FFF;
|
||||
padding: 5px;
|
||||
border-radius: 5px;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -33,7 +33,7 @@
|
||||
v-text-field.md2.mt-2(
|
||||
solo
|
||||
flat
|
||||
prepend-icon='mdi-textbox-password'
|
||||
prepend-icon='mdi-form-textbox-password'
|
||||
:background-color='$vuetify.theme.dark ? `grey darken-3` : `grey lighten-4`'
|
||||
ref='iptPassword'
|
||||
v-model='password'
|
||||
@@ -49,7 +49,7 @@
|
||||
v-text-field.md2.mt-2(
|
||||
solo
|
||||
flat
|
||||
prepend-icon='mdi-textbox-password'
|
||||
prepend-icon='mdi-form-textbox-password'
|
||||
:background-color='$vuetify.theme.dark ? `grey darken-3` : `grey lighten-4`'
|
||||
hide-details
|
||||
ref='iptVerifyPassword'
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
v-card.elevation-20.radius-7.animated.fadeInUp
|
||||
v-alert(v-if='isDevMode', tile, dark, color='red darken-3', icon='mdi-alert', prominent)
|
||||
.body-2 You are running an unstable, unreleased development version. This code base is #[strong NOT] for production use!
|
||||
.body-2.mt-3 Cloning the master branch directly from GitHub is #[strong NOT] the proper way to install Wiki.js!
|
||||
.body-2.mt-3 Cloning the dev branch directly from GitHub is #[strong NOT] the proper way to install Wiki.js!
|
||||
.body-2 Read the #[a(href='https://docs.requarks.io/install', style='color: #FFF;') documentation] on correctly installing the latest stable version.
|
||||
.text-center
|
||||
img.setup-logo.animated.fadeInUp.wait-p2s(src='/_assets/svg/logo-wikijs-full.svg', alt='Wiki.js Logo')
|
||||
@@ -249,7 +249,7 @@ export default {
|
||||
height: 100vh;
|
||||
z-index: 0;
|
||||
background-color: transparent;
|
||||
background-image: url(/_assets/svg/motif-grid.svg) !important;
|
||||
background-image: url(../static/svg/motif-grid.svg) !important;
|
||||
background-size: 100px;
|
||||
background-repeat: repeat;
|
||||
animation: bg-anim 100s linear infinite;
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,3 +1,4 @@
|
||||
require('./scss/legacy.scss')
|
||||
require('./scss/fonts/default.scss')
|
||||
|
||||
window.WIKI = null
|
||||
@@ -1,39 +1,39 @@
|
||||
@font-face {
|
||||
font-family: 'Tajawal';
|
||||
src: url('/_assets/fonts/arabic/Tajawal-Bold.woff2') format('woff2'),
|
||||
url('/_assets/fonts/arabic/Tajawal-Bold.woff') format('woff');
|
||||
src: url('../../fonts/arabic/Tajawal-Bold.woff2') format('woff2'),
|
||||
url('../../fonts/arabic/Tajawal-Bold.woff') format('woff');
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Tajawal';
|
||||
src: url('/_assets/fonts/arabic/Tajawal-Regular.woff2') format('woff2'),
|
||||
url('/_assets/fonts/arabic/Tajawal-Regular.woff') format('woff');
|
||||
src: url('../../fonts/arabic/Tajawal-Regular.woff2') format('woff2'),
|
||||
url('../../fonts/arabic/Tajawal-Regular.woff') format('woff');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Tajawal';
|
||||
src: url('/_assets/fonts/arabic/Tajawal-Medium.woff2') format('woff2'),
|
||||
url('/_assets/fonts/arabic/Tajawal-Medium.woff') format('woff');
|
||||
src: url('../../fonts/arabic/Tajawal-Medium.woff2') format('woff2'),
|
||||
url('../../fonts/arabic/Tajawal-Medium.woff') format('woff');
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'BalooBhaijaan';
|
||||
src: url('/_assets/fonts/arabic/BalooBhaijaan-Regular.woff2') format('woff2'),
|
||||
url('/_assets/fonts/arabic/BalooBhaijaan-Regular.woff') format('woff');
|
||||
src: url('../../fonts/arabic/BalooBhaijaan-Regular.woff2') format('woff2'),
|
||||
url('../../fonts/arabic/BalooBhaijaan-Regular.woff') format('woff');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto Mono';
|
||||
src: url('/_assets/fonts/default/RobotoMono-Regular.woff2') format('woff2'),
|
||||
url('/_assets/fonts/default/RobotoMono-Regular.woff') format('woff');
|
||||
src: url('../../fonts/default/RobotoMono-Regular.woff2') format('woff2'),
|
||||
url('../../fonts/default/RobotoMono-Regular.woff') format('woff');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@@ -1,55 +1,55 @@
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: url('/_assets/fonts/default/Roboto-MediumItalic.woff2') format('woff2'),
|
||||
url('/_assets/fonts/default/Roboto-MediumItalic.woff') format('woff');
|
||||
src: url('../../fonts/default/Roboto-MediumItalic.woff2') format('woff2'),
|
||||
url('../../fonts/default/Roboto-MediumItalic.woff') format('woff');
|
||||
font-weight: 500;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: url('/_assets/fonts/default/Roboto-Italic.woff2') format('woff2'),
|
||||
url('/_assets/fonts/default/Roboto-Italic.woff') format('woff');
|
||||
src: url('../../fonts/default/Roboto-Italic.woff2') format('woff2'),
|
||||
url('../../fonts/default/Roboto-Italic.woff') format('woff');
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: url('/_assets/fonts/default/Roboto-Bold.woff2') format('woff2'),
|
||||
url('/_assets/fonts/default/Roboto-Bold.woff') format('woff');
|
||||
src: url('../../fonts/default/Roboto-Bold.woff2') format('woff2'),
|
||||
url('../../fonts/default/Roboto-Bold.woff') format('woff');
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: url('/_assets/fonts/default/Roboto-Regular.woff2') format('woff2'),
|
||||
url('/_assets/fonts/default/Roboto-Regular.woff') format('woff');
|
||||
src: url('../../fonts/default/Roboto-Regular.woff2') format('woff2'),
|
||||
url('../../fonts/default/Roboto-Regular.woff') format('woff');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: url('/_assets/fonts/default/Roboto-BoldItalic.woff2') format('woff2'),
|
||||
url('/_assets/fonts/default/Roboto-BoldItalic.woff') format('woff');
|
||||
src: url('../../fonts/default/Roboto-BoldItalic.woff2') format('woff2'),
|
||||
url('../../fonts/default/Roboto-BoldItalic.woff') format('woff');
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: url('/_assets/fonts/default/Roboto-Medium.woff2') format('woff2'),
|
||||
url('/_assets/fonts/default/Roboto-Medium.woff') format('woff');
|
||||
src: url('../../fonts/default/Roboto-Medium.woff2') format('woff2'),
|
||||
url('../../fonts/default/Roboto-Medium.woff') format('woff');
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto Mono';
|
||||
src: url('/_assets/fonts/default/RobotoMono-Regular.woff2') format('woff2'),
|
||||
url('/_assets/fonts/default/RobotoMono-Regular.woff') format('woff');
|
||||
src: url('../../fonts/default/RobotoMono-Regular.woff2') format('woff2'),
|
||||
url('../../fonts/default/RobotoMono-Regular.woff') format('woff');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
@import "global";
|
||||
|
||||
@import "./base/icons.scss";
|
||||
@import "./fonts/default.scss";
|
||||
@import '~katex/dist/katex.min.css';
|
||||
@import '~@mdi/font/css/materialdesignicons.css';
|
||||
|
||||
|
||||
Reference in new issue
Block a user