From f72530bf8410c876249405a28d1cb3b1217de77f Mon Sep 17 00:00:00 2001 From: NGPixel Date: Sat, 22 Aug 2020 19:37:49 -0400 Subject: [PATCH] refactor: deps update + 2FA setup + verify --- client/client-app.js | 2 +- client/components/admin.vue | 15 + client/components/admin/admin-analytics.vue | 32 +- client/components/admin/admin-api-create.vue | 2 +- client/components/admin/admin-api.vue | 4 +- client/components/admin/admin-auth.vue | 21 +- client/components/admin/admin-comments.vue | 30 +- client/components/admin/admin-mail.vue | 2 +- client/components/admin/admin-navigation.vue | 24 +- client/components/admin/admin-rendering.vue | 18 +- client/components/admin/admin-search.vue | 14 +- client/components/admin/admin-storage.vue | 11 +- client/components/admin/admin-tags.vue | 4 +- .../components/admin/admin-users-create.vue | 2 +- client/components/admin/admin-users-edit.vue | 14 +- .../admin/admin-utilities-importv1.vue | 6 +- client/components/comments.vue | 6 +- client/components/common/nav-header.vue | 16 +- client/components/history.vue | 2 +- client/components/login.vue | 239 +- client/components/register.vue | 4 +- client/components/setup.vue | 4 +- .../fonts/arabic/BalooBhaijaan-Regular.woff | Bin .../fonts/arabic/BalooBhaijaan-Regular.woff2 | Bin .../fonts/arabic/Tajawal-Bold.woff | Bin .../fonts/arabic/Tajawal-Bold.woff2 | Bin .../fonts/arabic/Tajawal-Medium.woff | Bin .../fonts/arabic/Tajawal-Medium.woff2 | Bin .../fonts/arabic/Tajawal-Regular.woff | Bin .../fonts/arabic/Tajawal-Regular.woff2 | Bin .../fonts/default/Roboto-Bold.woff | Bin .../fonts/default/Roboto-Bold.woff2 | Bin .../fonts/default/Roboto-BoldItalic.woff | Bin .../fonts/default/Roboto-BoldItalic.woff2 | Bin .../fonts/default/Roboto-Italic.woff | Bin .../fonts/default/Roboto-Italic.woff2 | Bin .../fonts/default/Roboto-Medium.woff | Bin .../fonts/default/Roboto-Medium.woff2 | Bin .../fonts/default/Roboto-MediumItalic.woff | Bin .../fonts/default/Roboto-MediumItalic.woff2 | Bin .../fonts/default/Roboto-Regular.woff | Bin .../fonts/default/Roboto-Regular.woff2 | Bin .../fonts/default/RobotoMono-Regular.woff | Bin .../fonts/default/RobotoMono-Regular.woff2 | Bin client/index-legacy.js | 1 + client/scss/fonts/arabic.scss | 20 +- client/scss/fonts/default.scss | 28 +- client/scss/legacy.scss | 1 - dev/webpack/webpack.dev.js | 5 +- dev/webpack/webpack.prod.js | 5 +- package.json | 132 +- server/graph/schemas/authentication.graphql | 3 + server/graph/schemas/user.graphql | 1 + server/models/assets.js | 2 +- server/models/userKeys.js | 22 +- server/models/users.js | 178 +- server/setup.js | 2 +- yarn.lock | 3740 ++++++++--------- 58 files changed, 2148 insertions(+), 2464 deletions(-) rename client/{static => }/fonts/arabic/BalooBhaijaan-Regular.woff (100%) rename client/{static => }/fonts/arabic/BalooBhaijaan-Regular.woff2 (100%) rename client/{static => }/fonts/arabic/Tajawal-Bold.woff (100%) rename client/{static => }/fonts/arabic/Tajawal-Bold.woff2 (100%) rename client/{static => }/fonts/arabic/Tajawal-Medium.woff (100%) rename client/{static => }/fonts/arabic/Tajawal-Medium.woff2 (100%) rename client/{static => }/fonts/arabic/Tajawal-Regular.woff (100%) rename client/{static => }/fonts/arabic/Tajawal-Regular.woff2 (100%) rename client/{static => }/fonts/default/Roboto-Bold.woff (100%) rename client/{static => }/fonts/default/Roboto-Bold.woff2 (100%) rename client/{static => }/fonts/default/Roboto-BoldItalic.woff (100%) rename client/{static => }/fonts/default/Roboto-BoldItalic.woff2 (100%) rename client/{static => }/fonts/default/Roboto-Italic.woff (100%) rename client/{static => }/fonts/default/Roboto-Italic.woff2 (100%) rename client/{static => }/fonts/default/Roboto-Medium.woff (100%) rename client/{static => }/fonts/default/Roboto-Medium.woff2 (100%) rename client/{static => }/fonts/default/Roboto-MediumItalic.woff (100%) rename client/{static => }/fonts/default/Roboto-MediumItalic.woff2 (100%) rename client/{static => }/fonts/default/Roboto-Regular.woff (100%) rename client/{static => }/fonts/default/Roboto-Regular.woff2 (100%) rename client/{static => }/fonts/default/RobotoMono-Regular.woff (100%) rename client/{static => }/fonts/default/RobotoMono-Regular.woff2 (100%) diff --git a/client/client-app.js b/client/client-app.js index 5161e926..40f4cc60 100644 --- a/client/client-app.js +++ b/client/client-app.js @@ -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' }) } diff --git a/client/components/admin.vue b/client/components/admin.vue index 97cea971..f6e3722a 100644 --- a/client/components/admin.vue +++ b/client/components/admin.vue @@ -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; diff --git a/client/components/admin/admin-analytics.vue b/client/components/admin/admin-analytics.vue index 25543d67..dd760502 100644 --- a/client/components/admin/admin-analytics.vue +++ b/client/components/admin/admin-analytics.vue @@ -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 { } } - - diff --git a/client/components/admin/admin-api-create.vue b/client/components/admin/admin-api-create.vue index c7218dff..22712bf1 100644 --- a/client/components/admin/admin-api-create.vue +++ b/client/components/admin/admin-api-create.vue @@ -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' }) } diff --git a/client/components/admin/admin-api.vue b/client/components/admin/admin-api.vue index a8a9ebbb..3e1f94f2 100644 --- a/client/components/admin/admin-api.vue +++ b/client/components/admin/admin-api.vue @@ -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' }) } diff --git a/client/components/admin/admin-auth.vue b/client/components/admin/admin-auth.vue index 26134235..df8212b6 100644 --- a/client/components/admin/admin-auth.vue +++ b/client/components/admin/admin-auth.vue @@ -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 { } } - - diff --git a/client/components/admin/admin-comments.vue b/client/components/admin/admin-comments.vue index d2dad8c7..af960eb8 100644 --- a/client/components/admin/admin-comments.vue +++ b/client/components/admin/admin-comments.vue @@ -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 { } } - - diff --git a/client/components/admin/admin-mail.vue b/client/components/admin/admin-mail.vue index e9fdd385..660660f9 100644 --- a/client/components/admin/admin-mail.vue +++ b/client/components/admin/admin-mail.vue @@ -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 = '' diff --git a/client/components/admin/admin-navigation.vue b/client/components/admin/admin-navigation.vue index ba112418..e4796c2f 100644 --- a/client/components/admin/admin-navigation.vue +++ b/client/components/admin/admin-navigation.vue @@ -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) diff --git a/client/components/admin/admin-rendering.vue b/client/components/admin/admin-rendering.vue index 5ef1b24a..5a77cd3c 100644 --- a/client/components/admin/admin-rendering.vue +++ b/client/components/admin/admin-rendering.vue @@ -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( diff --git a/client/components/admin/admin-search.vue b/client/components/admin/admin-search.vue index b721b71d..cf58b5db 100644 --- a/client/components/admin/admin-search.vue +++ b/client/components/admin/admin-search.vue @@ -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( diff --git a/client/components/admin/admin-storage.vue b/client/components/admin/admin-storage.vue index e860a31a..fae1d2bd 100644 --- a/client/components/admin/admin-storage.vue +++ b/client/components/admin/admin-storage.vue @@ -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) diff --git a/client/components/admin/admin-tags.vue b/client/components/admin/admin-tags.vue index 6d862c4b..0bd000e8 100644 --- a/client/components/admin/admin-tags.vue +++ b/client/components/admin/admin-tags.vue @@ -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) diff --git a/client/components/admin/admin-users-create.vue b/client/components/admin/admin-users-create.vue index 7c4222ce..7128149e 100644 --- a/client/components/admin/admin-users-create.vue +++ b/client/components/admin/admin-users-create.vue @@ -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' }) } diff --git a/client/components/admin/admin-users-edit.vue b/client/components/admin/admin-users-edit.vue index fea3bf52..965bd760 100644 --- a/client/components/admin/admin-users-edit.vue +++ b/client/components/admin/admin-users-edit.vue @@ -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 diff --git a/client/components/admin/admin-utilities-importv1.vue b/client/components/admin/admin-utilities-importv1.vue index c8ac1c44..78dd3a54 100644 --- a/client/components/admin/admin-utilities-importv1.vue +++ b/client/components/admin/admin-utilities-importv1.vue @@ -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 diff --git a/client/components/comments.vue b/client/components/comments.vue index fd2f1ccc..c3c79d68 100644 --- a/client/components/comments.vue +++ b/client/components/comments.vue @@ -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', { diff --git a/client/components/common/nav-header.vue b/client/components/common/nav-header.vue index 0c608ae1..de23014d 100644 --- a/client/components/common/nav-header.vue +++ b/client/components/common/nav-header.vue @@ -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')}} diff --git a/client/components/history.vue b/client/components/history.vue index 0fb8fbd3..985310ca 100644 --- a/client/components/history.vue +++ b/client/components/history.vue @@ -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', { diff --git a/client/components/login.vue b/client/components/login.vue index e2ebcc29..340134cc 100644 --- a/client/components/login.vue +++ b/client/components/login.vue @@ -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(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' + @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;')