feat: mandatory password change on login + UI fixes
This commit is contained in:
@@ -66,7 +66,7 @@
|
||||
v-tab-item(:transition='false', :reverse-transition='false')
|
||||
.body-1.pa-3 {{ $t('admin:contribute.tshirts') }}
|
||||
v-card-actions.ml-2
|
||||
v-btn(outline, :color='darkMode ? `blue lighten-1` : `primary`', href='https://wikijs.threadless.com', large)
|
||||
v-btn(outlined, :color='darkMode ? `blue lighten-1` : `primary`', href='https://wikijs.threadless.com', large)
|
||||
v-icon(left) mdi-tshirt-crew
|
||||
span {{ $t('admin:contribute.shop') }}
|
||||
v-divider.mt-3
|
||||
|
@@ -13,7 +13,7 @@
|
||||
span {{$t('common:actions.apply')}}
|
||||
|
||||
v-card.mt-3.white.grey--text.text--darken-3
|
||||
v-alert(color='red', value='true', icon='mdi-alert', dark, prominent)
|
||||
v-alert(color='red', :value='true', icon='mdi-alert', dark, prominent)
|
||||
span Do NOT enable these flags unless you know what you're doing!
|
||||
.caption Doing so may result in data loss or broken installation!
|
||||
v-card-text
|
||||
|
@@ -92,14 +92,14 @@
|
||||
|
||||
v-flex(lg6 xs12)
|
||||
v-card.animated.fadeInUp.wait-p4s
|
||||
v-toolbar(color='primary', dark, dense, flat)
|
||||
v-toolbar(color='indigo', dark, dense, flat)
|
||||
v-toolbar-title.subtitle-1 Features
|
||||
v-spacer
|
||||
v-chip(label, color='white', small).primary--text coming soon
|
||||
v-chip(label, color='white', small).indigo--text coming soon
|
||||
v-card-text
|
||||
v-switch(
|
||||
label='Asset Image Optimization'
|
||||
color='primary'
|
||||
color='indigo'
|
||||
v-model='config.featureTinyPNG'
|
||||
persistent-hint
|
||||
hint='Image optimization tool to reduce filesize and bandwidth costs.'
|
||||
@@ -119,7 +119,7 @@
|
||||
v-divider.mt-3
|
||||
v-switch(
|
||||
label='Page Ratings'
|
||||
color='primary'
|
||||
color='indigo'
|
||||
v-model='config.featurePageRatings'
|
||||
persistent-hint
|
||||
hint='Allow users to rate pages.'
|
||||
@@ -129,7 +129,7 @@
|
||||
v-divider.mt-3
|
||||
v-switch(
|
||||
label='Page Comments'
|
||||
color='primary'
|
||||
color='indigo'
|
||||
v-model='config.featurePageComments'
|
||||
persistent-hint
|
||||
hint='Allow users to leave comments on pages.'
|
||||
@@ -139,13 +139,75 @@
|
||||
v-divider.mt-3
|
||||
v-switch(
|
||||
label='Personal Wikis'
|
||||
color='primary'
|
||||
color='indigo'
|
||||
v-model='config.featurePersonalWikis'
|
||||
persistent-hint
|
||||
hint='Allow users to have their own personal wiki.'
|
||||
disabled
|
||||
)
|
||||
|
||||
v-card.mt-5.animated.fadeInUp.wait-p5s
|
||||
v-toolbar(color='red darken-2', dark, dense, flat)
|
||||
v-toolbar-title.subtitle-1 Security
|
||||
v-card-text
|
||||
v-alert(outlined, color='red darken-2', icon='mdi-information-outline').body-2 Make sure to understand the implications before turning on / off a security feature.
|
||||
v-switch.mt-3(
|
||||
label='Block IFrame Embedding'
|
||||
color='red darken-2'
|
||||
v-model='config.securityIframe'
|
||||
persistent-hint
|
||||
hint='Prevents other websites from embedding your wiki in an iframe. This provides clickjacking protection.'
|
||||
)
|
||||
v-divider.mt-3
|
||||
v-switch(
|
||||
label='Same Origin Referrer Policy'
|
||||
color='red darken-2'
|
||||
v-model='config.securityReferrerPolicy'
|
||||
persistent-hint
|
||||
hint='Limits the referrer header to same origin.'
|
||||
)
|
||||
|
||||
v-divider.mt-3
|
||||
v-switch(
|
||||
label='Enforce HSTS'
|
||||
color='red darken-2'
|
||||
v-model='config.securityHSTS'
|
||||
persistent-hint
|
||||
hint='This ensures the connection cannot be established through an insecure HTTP connection.'
|
||||
)
|
||||
v-select.mt-5(
|
||||
outlined
|
||||
label='HSTS Max Age'
|
||||
:items='hstsDurations'
|
||||
v-model='config.securityHSTSDuration'
|
||||
prepend-icon='mdi-subdirectory-arrow-right'
|
||||
:disabled='!config.securityHSTS'
|
||||
hide-details
|
||||
style='max-width: 450px;'
|
||||
)
|
||||
.pl-11.mt-3
|
||||
.caption Defines the duration for which the server should only deliver content through HTTPS.
|
||||
.caption It's a good idea to start with small values and make sure that nothing breaks on your wiki before moving to longer values.
|
||||
|
||||
v-divider.mt-3
|
||||
v-switch(
|
||||
label='Enforce CSP'
|
||||
color='red darken-2'
|
||||
v-model='config.securityCSP'
|
||||
persistent-hint
|
||||
hint='Restricts scripts to pre-approved content sources.'
|
||||
disabled
|
||||
)
|
||||
v-textarea.mt-5(
|
||||
label='CSP Directives'
|
||||
outlined
|
||||
v-model='config.securityCSPDirectives'
|
||||
prepend-icon='mdi-subdirectory-arrow-right'
|
||||
persistent-hint
|
||||
hint='One directive per line.'
|
||||
disabled
|
||||
)
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -163,12 +225,6 @@ export default {
|
||||
{ text: 'Google Analytics', value: 'ga' },
|
||||
{ text: 'Google Tag Manager', value: 'gtm' }
|
||||
],
|
||||
metaRobots: [
|
||||
{ text: 'Index', value: 'index' },
|
||||
{ text: 'Follow', value: 'follow' },
|
||||
{ text: 'No Index', value: 'noindex' },
|
||||
{ text: 'No Follow', value: 'nofollow' }
|
||||
],
|
||||
config: {
|
||||
host: '',
|
||||
title: '',
|
||||
@@ -183,8 +239,28 @@ export default {
|
||||
featurePageRatings: false,
|
||||
featurePageComments: false,
|
||||
featurePersonalWikis: false,
|
||||
featureTinyPNG: false
|
||||
}
|
||||
featureTinyPNG: false,
|
||||
securityIframe: true,
|
||||
securityReferrerPolicy: true,
|
||||
securityHSTS: false,
|
||||
securityHSTSDuration: 0,
|
||||
securityCSP: false,
|
||||
securityCSPDirectives: ''
|
||||
},
|
||||
hstsDurations: [
|
||||
{ value: 300, text: '5 minutes' },
|
||||
{ value: 86400, text: '1 day' },
|
||||
{ value: 604800, text: '1 week' },
|
||||
{ value: 2592000, text: '1 month' },
|
||||
{ value: 31536000, text: '1 year' },
|
||||
{ value: 63072000, text: '2 years' }
|
||||
],
|
||||
metaRobots: [
|
||||
{ text: 'Index', value: 'index' },
|
||||
{ text: 'Follow', value: 'follow' },
|
||||
{ text: 'No Index', value: 'noindex' },
|
||||
{ text: 'No Follow', value: 'nofollow' }
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -198,18 +274,24 @@ export default {
|
||||
await this.$apollo.mutate({
|
||||
mutation: siteUpdateConfigMutation,
|
||||
variables: {
|
||||
host: this.config.host || '',
|
||||
title: this.config.title || '',
|
||||
description: this.config.description || '',
|
||||
robots: this.config.robots || [],
|
||||
analyticsService: this.config.analyticsService || '',
|
||||
analyticsId: this.config.analyticsId || '',
|
||||
company: this.config.company || '',
|
||||
hasLogo: this.config.hasLogo || false,
|
||||
logoIsSquare: this.config.logoIsSquare || false,
|
||||
featurePageRatings: this.config.featurePageRatings || false,
|
||||
featurePageComments: this.config.featurePageComments || false,
|
||||
featurePersonalWikis: this.config.featurePersonalWikis || false
|
||||
host: _.get(this.config, 'host', ''),
|
||||
title: _.get(this.config, 'title', ''),
|
||||
description: _.get(this.config, 'description', ''),
|
||||
robots: _.get(this.config, 'robots', []),
|
||||
analyticsService: _.get(this.config, 'analyticsService', ''),
|
||||
analyticsId: _.get(this.config, 'analyticsId', ''),
|
||||
company: _.get(this.config, 'company', ''),
|
||||
hasLogo: _.get(this.config, 'hasLogo', false),
|
||||
logoIsSquare: _.get(this.config, 'logoIsSquare', false),
|
||||
featurePageRatings: _.get(this.config, 'featurePageRatings', false),
|
||||
featurePageComments: _.get(this.config, 'featurePageComments', false),
|
||||
featurePersonalWikis: _.get(this.config, 'featurePersonalWikis', false),
|
||||
securityIframe: _.get(this.config, 'securityIframe', false),
|
||||
securityReferrerPolicy: _.get(this.config, 'securityReferrerPolicy', false),
|
||||
securityHSTS: _.get(this.config, 'securityHSTS', false),
|
||||
securityHSTSDuration: _.get(this.config, 'securityHSTSDuration', 0),
|
||||
securityCSP: _.get(this.config, 'securityCSP', false),
|
||||
securityCSPDirectives: _.get(this.config, 'securityCSPDirectives', '')
|
||||
},
|
||||
watchLoading (isLoading) {
|
||||
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-site-update')
|
||||
|
@@ -23,26 +23,21 @@
|
||||
must-sort,
|
||||
hide-default-footer
|
||||
)
|
||||
template(slot='item', slot-scope='props')
|
||||
tr(:active='props.selected')
|
||||
td.text-xs-right {{ props.item.id }}
|
||||
td {{ props.item.name }}
|
||||
td {{ props.item.email }}
|
||||
td
|
||||
v-menu(bottom, right, min-width='200')
|
||||
template(v-slot:activator='{ on }')
|
||||
v-btn(icon, v-on='on', small)
|
||||
v-icon.grey--text.text--darken-1 mdi-dots-horizontal
|
||||
v-list(dense, nav)
|
||||
v-list-item(:to='`/users/` + props.item.id')
|
||||
v-list-item-action: v-icon(color='primary') mdi-account-outline
|
||||
v-list-item-content
|
||||
v-list-item-title View User Profile
|
||||
template(v-if='props.item.id !== 2')
|
||||
v-list-item(@click='unassignUser(props.item.id)')
|
||||
v-list-item-action: v-icon(color='orange') mdi-account-remove-outline
|
||||
v-list-item-content
|
||||
v-list-item-title Unassign
|
||||
template(v-slot:item.actions='{ item }')
|
||||
v-menu(bottom, right, min-width='200')
|
||||
template(v-slot:activator='{ on }')
|
||||
v-btn(icon, v-on='on', small)
|
||||
v-icon.grey--text.text--darken-1 mdi-dots-horizontal
|
||||
v-list(dense, nav)
|
||||
v-list-item(:to='`/users/` + item.id')
|
||||
v-list-item-action: v-icon(color='primary') mdi-account-outline
|
||||
v-list-item-content
|
||||
v-list-item-title View User Profile
|
||||
template(v-if='item.id !== 2')
|
||||
v-list-item(@click='unassignUser(item.id)')
|
||||
v-list-item-action: v-icon(color='orange') mdi-account-remove-outline
|
||||
v-list-item-content
|
||||
v-list-item-title Unassign
|
||||
template(slot='no-data')
|
||||
v-alert.ma-3(icon='warning', outlined) No users to display.
|
||||
.text-center.py-2(v-if='group.users.length > 15')
|
||||
@@ -70,10 +65,10 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
headers: [
|
||||
{ text: 'ID', value: 'id', width: 50, align: 'right' },
|
||||
{ text: 'ID', value: 'id', width: 50 },
|
||||
{ text: 'Name', value: 'name' },
|
||||
{ text: 'Email', value: 'email' },
|
||||
{ text: '', value: 'actions', sortable: false, width: 50 }
|
||||
{ text: 'Actions', value: 'actions', sortable: false, width: 50 }
|
||||
],
|
||||
searchUserDialog: false,
|
||||
pagination: 1,
|
||||
|
@@ -17,7 +17,7 @@
|
||||
span New Group
|
||||
v-card
|
||||
.dialog-header.is-short New Group
|
||||
v-card-text
|
||||
v-card-text.pt-5
|
||||
v-text-field.md2(
|
||||
outlined
|
||||
prepend-icon='mdi-account-group'
|
||||
|
@@ -30,11 +30,11 @@
|
||||
template(v-slot:activator='{ on }')
|
||||
v-btn.mx-1.animated.fadeInDown.wait-p1s(color='red', large, outlined, v-on='on')
|
||||
v-icon(color='red') mdi-trash-can-outline
|
||||
v-card.wiki-form
|
||||
v-card
|
||||
.dialog-header.is-short.is-red
|
||||
v-icon.mr-2(color='white') mdi-file-document-box-remove-outline
|
||||
span {{$t('common:page.delete')}}
|
||||
v-card-text
|
||||
v-card-text.pt-5
|
||||
i18next.body-2(path='common:page.deleteTitle', tag='div')
|
||||
span.red--text.text--darken-2(place='title') {{page.title}}
|
||||
.caption {{$t('common:page.deleteSubtitle')}}
|
||||
@@ -44,7 +44,7 @@
|
||||
span.red--text.text--darken-2 /{{page.path}}
|
||||
v-card-chin
|
||||
v-spacer
|
||||
v-btn(flat, @click='deletePageDialog = false', :disabled='loading') {{$t('common:actions.cancel')}}
|
||||
v-btn(text, @click='deletePageDialog = false', :disabled='loading') {{$t('common:actions.cancel')}}
|
||||
v-btn(color='red darken-2', @click='deletePage', :loading='loading').white--text {{$t('common:actions.delete')}}
|
||||
v-btn.ml-1.animated.fadeInDown(color='teal', large, outlined, @click='rerenderPage')
|
||||
v-icon(left) mdi-cube-scan
|
||||
|
@@ -64,7 +64,7 @@
|
||||
td {{ props.item.createdAt | moment('calendar') }}
|
||||
td {{ props.item.updatedAt | moment('calendar') }}
|
||||
template(slot='no-data')
|
||||
v-alert.ma-3(icon='warning', :value='true', outline) No pages to display.
|
||||
v-alert.ma-3(icon='mdi-alert', :value='true', outlined) No pages to display.
|
||||
.text-xs-center.py-2.animated.fadeInDown(v-if='this.pageTotal > 1')
|
||||
v-pagination(v-model='pagination', :length='pageTotal')
|
||||
</template>
|
||||
|
@@ -26,8 +26,8 @@
|
||||
v-list-item(:key='eng.key', @click='selectedEngine = eng.key', :disabled='!eng.isAvailable')
|
||||
v-list-item-avatar(size='24')
|
||||
v-icon(color='grey', v-if='!eng.isAvailable') mdi-minus-box-outline
|
||||
v-icon(color='primary', v-else-if='eng.key === selectedEngine') mdi-checkbox-marked-outline
|
||||
v-icon(color='grey', v-else) mdi-checkbox-blank-outline
|
||||
v-icon(color='primary', v-else-if='eng.key === selectedEngine') mdi-checkbox-marked-circle-outline
|
||||
v-icon(color='grey', v-else) mdi-checkbox-blank-circle-outline
|
||||
v-list-item-content
|
||||
v-list-item-title.body-2(:class='!eng.isAvailable ? `grey--text` : (selectedEngine === eng.key ? `primary--text` : ``)') {{ eng.title }}
|
||||
v-list-item-subtitle: .caption(:class='!eng.isAvailable ? `grey--text text--lighten-1` : (selectedEngine === eng.key ? `blue--text ` : ``)') {{ eng.description }}
|
||||
|
@@ -49,7 +49,7 @@
|
||||
v-icon(color='white') mdi-clock-outline
|
||||
v-list-item-content
|
||||
v-list-item-title.body-2 {{tgt.title}}
|
||||
v-list-item-sub-title.purple--text.caption {{tgt.status}}
|
||||
v-list-item-subtitle.purple--text.caption {{tgt.status}}
|
||||
v-list-item-action
|
||||
v-progress-circular(indeterminate, :size='20', :width='2', color='purple')
|
||||
template(v-else-if='tgt.status === `operational`')
|
||||
@@ -57,13 +57,13 @@
|
||||
v-icon(color='white') mdi-check-circle
|
||||
v-list-item-content
|
||||
v-list-item-title.body-2 {{tgt.title}}
|
||||
v-list-item-sub-title.green--text.caption {{$t('admin:storage.lastSync', { time: $options.filters.moment(tgt.lastAttempt, 'from') })}}
|
||||
v-list-item-subtitle.green--text.caption {{$t('admin:storage.lastSync', { time: $options.filters.moment(tgt.lastAttempt, 'from') })}}
|
||||
template(v-else)
|
||||
v-list-item-avatar(color='red')
|
||||
v-icon(color='white') mdi-close-circle-outline
|
||||
v-list-item-content
|
||||
v-list-item-title.body-2 {{tgt.title}}
|
||||
v-list-item-sub-title.red--text.caption {{$t('admin:storage.lastSyncAttempt', { time: $options.filters.moment(tgt.lastAttempt, 'from') })}}
|
||||
v-list-item-subtitle.red--text.caption {{$t('admin:storage.lastSyncAttempt', { time: $options.filters.moment(tgt.lastAttempt, 'from') })}}
|
||||
v-list-item-action
|
||||
v-menu
|
||||
v-btn(slot='activator', icon)
|
||||
@@ -86,6 +86,10 @@
|
||||
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)
|
||||
v-chip(color='red', small, dark, label, place='state') {{$t('admin:storage.targetStateInactive')}}
|
||||
v-divider.mt-3
|
||||
.overline.my-5 {{$t('admin:storage.targetConfig')}}
|
||||
.body-2.ml-3(v-if='!target.config || target.config.length < 1'): em {{$t('admin:storage.noConfigOption')}}
|
||||
@@ -179,6 +183,8 @@
|
||||
template(v-if='target.actions && target.actions.length > 0')
|
||||
v-divider.mt-3
|
||||
.overline.my-5 {{$t('admin:storage.actions')}}
|
||||
v-alert(outlined, :value='!target.isEnabled', color='red', icon='mdi-alert')
|
||||
.body-2 {{$t('admin:storage.actionsInactiveWarn')}}
|
||||
v-container.pt-0(grid-list-xl, fluid)
|
||||
v-layout(row, wrap, fill-height)
|
||||
v-flex(xs12, lg6, xl4, v-for='act of target.actions', :key='act.handler')
|
||||
@@ -190,7 +196,7 @@
|
||||
@click='executeAction(target.key, act.handler)'
|
||||
outlined
|
||||
:color='$vuetify.theme.dark ? `blue` : `primary`'
|
||||
:disabled='runningAction'
|
||||
:disabled='runningAction || !target.isEnabled'
|
||||
:loading='runningActionHandler === act.handler'
|
||||
) {{$t('admin:storage.actionRun')}}
|
||||
|
||||
|
@@ -13,13 +13,13 @@
|
||||
v-btn.animated.fadeInLeft.wait-p2s.btn-animate-rotate(fab, absolute, :right='!$vuetify.rtl', :left='$vuetify.rtl', top, small, light, @click='refresh'): v-icon(color='grey') mdi-refresh
|
||||
v-subheader Wiki.js
|
||||
v-list(two-line, dense)
|
||||
v-list-item(avatar)
|
||||
v-list-item
|
||||
v-list-item-avatar
|
||||
v-icon.blue.white--text mdi-application-export
|
||||
v-list-item-content
|
||||
v-list-item-title {{ $t('admin:system.currentVersion') }}
|
||||
v-list-item-subtitle {{ info.currentVersion }}
|
||||
v-list-item(avatar)
|
||||
v-list-item
|
||||
v-list-item-avatar
|
||||
v-icon.blue.white--text mdi-inbox-arrow-up
|
||||
v-list-item-content
|
||||
@@ -31,38 +31,38 @@
|
||||
v-divider.mt-3
|
||||
v-subheader {{ $t('admin:system.hostInfo') }}
|
||||
v-list(two-line, dense)
|
||||
v-list-item(avatar)
|
||||
v-list-item
|
||||
v-list-item-avatar
|
||||
v-avatar.blue-grey(size='40')
|
||||
v-icon(color='white') {{platformLogo}}
|
||||
v-list-item-content
|
||||
v-list-item-title {{ $t('admin:system.os') }}
|
||||
v-list-item-subtitle {{ (info.platform === 'docker') ? 'Docker Container (Linux)' : info.operatingSystem }}
|
||||
v-list-item(avatar)
|
||||
v-list-item
|
||||
v-list-item-avatar
|
||||
v-icon.blue-grey.white--text mdi-desktop-classic
|
||||
v-list-item-content
|
||||
v-list-item-title {{ $t('admin:system.hostname') }}
|
||||
v-list-item-subtitle {{ info.hostname }}
|
||||
v-list-item(avatar)
|
||||
v-list-item
|
||||
v-list-item-avatar
|
||||
v-icon.blue-grey.white--text mdi-cpu-64-bit
|
||||
v-list-item-content
|
||||
v-list-item-title {{ $t('admin:system.cpuCores') }}
|
||||
v-list-item-subtitle {{ info.cpuCores }}
|
||||
v-list-item(avatar)
|
||||
v-list-item
|
||||
v-list-item-avatar
|
||||
v-icon.blue-grey.white--text mdi-memory
|
||||
v-list-item-content
|
||||
v-list-item-title {{ $t('admin:system.totalRAM') }}
|
||||
v-list-item-subtitle {{ info.ramTotal }}
|
||||
v-list-item(avatar)
|
||||
v-list-item
|
||||
v-list-item-avatar
|
||||
v-icon.blue-grey.white--text mdi-iframe-outline
|
||||
v-list-item-content
|
||||
v-list-item-title {{ $t('admin:system.workingDirectory') }}
|
||||
v-list-item-subtitle {{ info.workingDirectory }}
|
||||
v-list-item(avatar)
|
||||
v-list-item
|
||||
v-list-item-avatar
|
||||
v-icon.blue-grey.white--text mdi-card-bulleted-settings-outline
|
||||
v-list-item-content
|
||||
@@ -73,7 +73,7 @@
|
||||
v-card.pb-3.animated.fadeInUp.wait-p4s
|
||||
v-subheader Node.js
|
||||
v-list(dense)
|
||||
v-list-item(avatar)
|
||||
v-list-item
|
||||
v-list-item-avatar
|
||||
v-avatar.light-green(size='40')
|
||||
v-icon(color='white') mdi-nodejs
|
||||
@@ -83,7 +83,7 @@
|
||||
v-divider.mt-3
|
||||
v-subheader {{ info.dbType }}
|
||||
v-list(dense)
|
||||
v-list-item(avatar)
|
||||
v-list-item
|
||||
v-list-item-avatar
|
||||
v-avatar.indigo.darken-1(size='40')
|
||||
v-icon(color='white') mdi-database
|
||||
|
@@ -8,7 +8,7 @@
|
||||
v-btn.mx-0(color='white', outlined, disabled, dark)
|
||||
v-icon(left) mdi-database-import
|
||||
span Bulk Import
|
||||
v-card-text
|
||||
v-card-text.pt-5
|
||||
v-select(
|
||||
:items='providers'
|
||||
item-text='title'
|
||||
@@ -89,6 +89,7 @@
|
||||
label='Send a welcome email'
|
||||
hide-details
|
||||
v-model='sendWelcomeEmail'
|
||||
disabled
|
||||
)
|
||||
v-card-chin
|
||||
v-spacer
|
||||
|
@@ -3,12 +3,26 @@
|
||||
v-layout(row, wrap)
|
||||
v-flex(xs12)
|
||||
.admin-header
|
||||
img.animated.fadeInUp(src='/svg/icon-male-user.svg', alt='Edit User', style='width: 80px;')
|
||||
img.animated.fadeInUp(src='/svg/icon-male-user.svg', :alt='$t(`admin:users.edit`)', style='width: 80px;')
|
||||
.admin-header-title
|
||||
.headline.blue--text.text--darken-2.animated.fadeInLeft Edit User
|
||||
.headline.blue--text.text--darken-2.animated.fadeInLeft {{$t('admin:users.edit')}}
|
||||
.subtitle-1.grey--text.animated.fadeInLeft.wait-p2s {{user.name}}
|
||||
v-spacer
|
||||
.caption.grey--text.animated.fadeInRight.wait-p5s ID #[strong {{user.id}}]
|
||||
template(v-if='user.isActive')
|
||||
status-indicator.mr-3(positive, pulse)
|
||||
.caption.green--text {{$t('admin:users.active')}}
|
||||
template(v-else)
|
||||
status-indicator.mr-3(negative, pulse)
|
||||
.caption.red--text {{$t('admin:users.inactive')}}
|
||||
template(v-if='user.isVerified')
|
||||
status-indicator.mr-3.ml-4(active, pulse)
|
||||
.caption.blue--text {{$t('admin:users.verified')}}
|
||||
template(v-else)
|
||||
status-indicator.mr-3.ml-4(intermediary, pulse)
|
||||
.caption.deep-orange--text {{$t('admin:users.unverified')}}
|
||||
v-spacer
|
||||
i18next.caption.grey--text.animated.fadeInRight.wait-p5s(path='admin:users.id', tag='div')
|
||||
strong(place='id') {{user.id}}
|
||||
v-divider.animated.fadeInRight.wait-p3s.ml-3(vertical)
|
||||
v-btn.ml-3.animated.fadeInDown.wait-p2s(color='grey', large, outlined, to='/users')
|
||||
v-icon mdi-arrow-left
|
||||
@@ -30,15 +44,15 @@
|
||||
v-card.animated.fadeInUp
|
||||
v-toolbar(color='primary', dense, dark, flat)
|
||||
v-icon.mr-2 mdi-information-variant
|
||||
span Basic Info
|
||||
span {{$t('admin:users.basicInfo')}}
|
||||
v-list.py-0(two-line, dense)
|
||||
v-list-item
|
||||
v-list-item-avatar(size='32')
|
||||
v-icon mdi-email-variant
|
||||
v-list-item-content
|
||||
v-list-item-title Email
|
||||
v-list-item-title {{$t('admin:users.email')}}
|
||||
v-list-item-subtitle {{ user.email }}
|
||||
v-list-item-action(v-if='!user.isSystem')
|
||||
v-list-item-action(v-if='!user.isSystem && user.providerKey === `local`')
|
||||
v-menu(
|
||||
v-model='editPop.email'
|
||||
:close-on-content-click='false'
|
||||
@@ -52,7 +66,7 @@
|
||||
v-text-field(
|
||||
ref='iptEmail'
|
||||
v-model='user.email'
|
||||
label='Email'
|
||||
:label='$t(`admin:users.email`)'
|
||||
solo
|
||||
hide-details
|
||||
append-icon='mdi-check'
|
||||
@@ -66,7 +80,7 @@
|
||||
v-list-item-avatar(size='32')
|
||||
v-icon mdi-account
|
||||
v-list-item-content
|
||||
v-list-item-title Display Name
|
||||
v-list-item-title {{$t('admin:users.displayName')}}
|
||||
v-list-item-subtitle {{ user.name }}
|
||||
v-list-item-action
|
||||
v-menu(
|
||||
@@ -82,7 +96,7 @@
|
||||
v-text-field(
|
||||
ref='iptDisplayName'
|
||||
v-model='user.name'
|
||||
label='Display Name'
|
||||
:label='$t(`admin:users.displayName`)'
|
||||
solo
|
||||
hide-details
|
||||
append-icon='mdi-check'
|
||||
@@ -94,13 +108,13 @@
|
||||
v-card.mt-3.animated.fadeInUp.wait-p2s(v-if='!user.isSystem')
|
||||
v-toolbar(color='primary', dense, dark, flat)
|
||||
v-icon.mr-2 mdi-lock-outline
|
||||
span Authentication
|
||||
span {{$t('admin:users.authentication')}}
|
||||
v-list.py-0(two-line, dense)
|
||||
v-list-item
|
||||
v-list-item-avatar(size='32')
|
||||
v-icon mdi-domain
|
||||
v-list-item-content
|
||||
v-list-item-title Provider
|
||||
v-list-item-title {{$t('admin:users.authProvider')}}
|
||||
v-list-item-subtitle {{ user.providerKey }}
|
||||
//- v-list-item-action
|
||||
//- v-img(src='https://static.requarks.io/logo/wikijs.svg', alt='', contain, max-height='32', position='center right')
|
||||
@@ -110,7 +124,7 @@
|
||||
v-list-item-avatar(size='32')
|
||||
v-icon mdi-textbox-password
|
||||
v-list-item-content
|
||||
v-list-item-title Password
|
||||
v-list-item-title {{$t('admin:users.password')}}
|
||||
v-list-item-subtitle ••••••••
|
||||
v-list-item-action
|
||||
v-menu(
|
||||
@@ -124,12 +138,12 @@
|
||||
template(v-slot:activator='{ on: tooltip }')
|
||||
v-btn(icon, color='grey', x-small, v-on='{ ...menu, ...tooltip }', @click='focusField(`iptNewPassword`)')
|
||||
v-icon mdi-cached
|
||||
span Change Password
|
||||
span {{$t('admin:users.changePassword')}}
|
||||
v-card
|
||||
v-text-field(
|
||||
ref='iptNewPassword'
|
||||
v-model='newPassword'
|
||||
label='New Password'
|
||||
:label='$t(`admin:users.newPassword`)'
|
||||
solo
|
||||
hide-details
|
||||
append-icon='mdi-check'
|
||||
@@ -149,26 +163,26 @@
|
||||
v-list-item-avatar(size='32')
|
||||
v-icon mdi-two-factor-authentication
|
||||
v-list-item-content
|
||||
v-list-item-title Two Factor Authentication (2FA)
|
||||
v-list-item-title {{$t('admin:users.tfa')}}
|
||||
v-list-item-subtitle.red--text Inactive
|
||||
v-list-item-action
|
||||
v-tooltip(top)
|
||||
template(v-slot:activator='{ on }')
|
||||
v-btn(icon, color='grey', x-small, v-on='on', disabled)
|
||||
v-icon mdi-power
|
||||
span Toggle 2FA
|
||||
template(v-if='user.providerId')
|
||||
v-divider
|
||||
v-list-item
|
||||
v-list-item-avatar(size='32')
|
||||
v-icon mdi-account
|
||||
v-list-item-content
|
||||
v-list-item-title Provider Id
|
||||
v-list-item-subtitle {{ user.providerId }}
|
||||
span {{$t('admin:users.toggle2FA')}}
|
||||
template(v-if='user.providerId')
|
||||
v-divider
|
||||
v-list-item
|
||||
v-list-item-avatar(size='32')
|
||||
v-icon mdi-music-accidental-sharp
|
||||
v-list-item-content
|
||||
v-list-item-title {{$t('admin:users.authProviderId')}}
|
||||
v-list-item-subtitle {{ user.providerId }}
|
||||
v-card.mt-3.animated.fadeInUp.wait-p4s
|
||||
v-toolbar(color='primary', dense, dark, flat)
|
||||
v-icon.mr-2 mdi-account-group
|
||||
span User Groups
|
||||
span {{$t('admin:users.groups')}}
|
||||
v-list(dense)
|
||||
template(v-for='(group, idx) in user.groups')
|
||||
v-list-item(:key='`group-` + group.id')
|
||||
@@ -181,14 +195,14 @@
|
||||
v-icon mdi-close
|
||||
v-divider(v-if='idx < user.groups.length - 1')
|
||||
v-alert.mx-3(v-if='user.groups.length < 1', outlined, color='grey darken-1', icon='mdi-alert')
|
||||
.caption This user is not assigned to any group yet. You must assign at least 1 group to a user.
|
||||
.caption {{$t('admin:users.noGroupAssigned')}}
|
||||
v-card-chin(v-if='!user.isSystem')
|
||||
v-spacer
|
||||
v-select(
|
||||
ref='iptAssignGroup'
|
||||
:items='groups'
|
||||
v-model='newGroup'
|
||||
label='Select Group...'
|
||||
:label='$t(`admin:users.selectGroup`)'
|
||||
item-value='id'
|
||||
item-text='name'
|
||||
item-disabled='isSystem'
|
||||
@@ -201,18 +215,18 @@
|
||||
)
|
||||
v-btn.ml-2.px-4(depressed, color='primary', height='48', @click='assignGroup', :disabled='newGroup === 0')
|
||||
v-icon(left) mdi-clipboard-account-outline
|
||||
span Assign
|
||||
span {{$t('admin:users.groupAssign')}}
|
||||
v-flex(xs6)
|
||||
v-card.animated.fadeInUp.wait-p2s
|
||||
v-toolbar(color='primary', dense, dark, flat)
|
||||
v-icon.mr-2 mdi-account-badge-outline
|
||||
span Extended Metadata
|
||||
span {{$t('admin:users.extendedMetadata')}}
|
||||
v-list.py-0(two-line, dense)
|
||||
v-list-item
|
||||
v-list-item-avatar(size='32')
|
||||
v-icon mdi-map-marker
|
||||
v-list-item-content
|
||||
v-list-item-title Location
|
||||
v-list-item-title {{$t('admin:users.location')}}
|
||||
v-list-item-subtitle {{ user.location }}
|
||||
v-list-item-action
|
||||
v-menu(
|
||||
@@ -228,7 +242,7 @@
|
||||
v-text-field(
|
||||
ref='iptLocation'
|
||||
v-model='user.location'
|
||||
label='Location'
|
||||
:label='$t(`admin:users.location`)'
|
||||
solo
|
||||
hide-details
|
||||
append-icon='mdi-check'
|
||||
@@ -241,7 +255,7 @@
|
||||
v-list-item-avatar(size='32')
|
||||
v-icon mdi-account-badge-horizontal-outline
|
||||
v-list-item-content
|
||||
v-list-item-title Job Title
|
||||
v-list-item-title {{$t('admin:users.jobTitle')}}
|
||||
v-list-item-subtitle {{ user.jobTitle }}
|
||||
v-list-item-action
|
||||
v-menu(
|
||||
@@ -257,7 +271,7 @@
|
||||
v-text-field(
|
||||
ref='iptJobTitle'
|
||||
v-model='user.jobTitle'
|
||||
label='Job Title'
|
||||
:label='$t(`admin:users.jobTitle`)'
|
||||
solo
|
||||
hide-details
|
||||
append-icon='mdi-check'
|
||||
@@ -270,7 +284,7 @@
|
||||
v-list-item-avatar(size='32')
|
||||
v-icon mdi-map-clock-outline
|
||||
v-list-item-content
|
||||
v-list-item-title Timezone
|
||||
v-list-item-title {{$t('admin:users.timezone')}}
|
||||
v-list-item-subtitle {{ user.timezone }}
|
||||
v-list-item-action
|
||||
v-menu(
|
||||
@@ -287,7 +301,7 @@
|
||||
ref='iptTimezone'
|
||||
:items='timezones'
|
||||
v-model='user.timezone'
|
||||
label='Timezone'
|
||||
:label='$t(`admin:users.timezone`)'
|
||||
solo
|
||||
dense
|
||||
hide-details
|
||||
@@ -308,11 +322,16 @@
|
||||
import _ from 'lodash'
|
||||
import { get } from 'vuex-pathify'
|
||||
|
||||
import { StatusIndicator } from 'vue-status-indicator'
|
||||
|
||||
import userQuery from 'gql/admin/users/users-query-single.gql'
|
||||
import groupsQuery from 'gql/admin/users/users-query-groups.gql'
|
||||
import updateUserMutation from 'gql/admin/users/users-mutation-update.gql'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
StatusIndicator
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
deleteUserDialog: false,
|
||||
@@ -334,7 +353,9 @@ export default {
|
||||
location: '',
|
||||
jobTitle: '',
|
||||
timezone: '',
|
||||
groups: []
|
||||
groups: [],
|
||||
isActive: false,
|
||||
isVerified: false
|
||||
},
|
||||
timezones: [
|
||||
{ text: '(GMT-11:00) Niue', value: 'Pacific/Niue' },
|
||||
@@ -613,7 +634,7 @@ export default {
|
||||
if (_.get(resp, 'data.users.update.responseResult.succeeded', false)) {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'success',
|
||||
message: 'User updated successfully.',
|
||||
message: this.$t('admin:users.userUpdateSuccess'),
|
||||
icon: 'check'
|
||||
})
|
||||
this.$router.push('/users')
|
||||
@@ -636,7 +657,7 @@ export default {
|
||||
assignGroup() {
|
||||
if (_.some(this.user.groups, ['id', this.newGroup])) {
|
||||
this.$store.commit('showNotification', {
|
||||
message: 'User is already assigned to this group!',
|
||||
message: this.$t('admin:users.userAlreadyAssignedToGroup'),
|
||||
style: 'error',
|
||||
icon: 'alert'
|
||||
})
|
||||
|
@@ -4,7 +4,7 @@
|
||||
.dialog-header.is-short.is-red
|
||||
v-icon.mr-2(color='white') mdi-file-document-box-remove-outline
|
||||
span {{$t('common:page.delete')}}
|
||||
v-card-text
|
||||
v-card-text.pt-5
|
||||
i18next.body-1(path='common:page.deleteTitle', tag='div')
|
||||
span.red--text.text--darken-2(place='title') {{pageTitle}}
|
||||
.caption {{$t('common:page.deleteSubtitle')}}
|
||||
|
@@ -3,7 +3,7 @@
|
||||
v-model='dialogOpen'
|
||||
max-width='650'
|
||||
)
|
||||
v-card.wiki-form
|
||||
v-card
|
||||
.dialog-header
|
||||
span {{$t('common:user.search')}}
|
||||
v-spacer
|
||||
@@ -14,7 +14,7 @@
|
||||
:width='2'
|
||||
v-show='searchLoading'
|
||||
)
|
||||
v-card-text
|
||||
v-card-text.pt-5
|
||||
v-text-field(
|
||||
outlined
|
||||
:label='$t(`common:user.searchPlaceholder`)'
|
||||
@@ -56,7 +56,7 @@ import searchUsersQuery from 'gql/common/common-users-query-search.gql'
|
||||
export default {
|
||||
filters: {
|
||||
initials(val) {
|
||||
return val.split(' ').map(v => v.substring(0, 1)).join()
|
||||
return val.split(' ').map(v => v.substring(0, 1)).join('')
|
||||
}
|
||||
},
|
||||
props: {
|
||||
|
@@ -11,17 +11,18 @@
|
||||
offset-xl4, xl4
|
||||
)
|
||||
transition(name='fadeUp')
|
||||
v-card.elevation-5.md2(v-show='isShown')
|
||||
v-card.elevation-5(v-show='isShown')
|
||||
v-toolbar(color='primary', flat, dense, dark)
|
||||
v-spacer
|
||||
.subheading(v-if='screen === "tfa"') {{ $t('auth:tfa.subtitle') }}
|
||||
.subheading(v-if='screen === "changePwd"') {{ $t('auth:changePwd.subtitle') }}
|
||||
.subheading(v-else-if='selectedStrategy.key !== "local"') {{ $t('auth:loginUsingStrategy', { strategy: selectedStrategy.title, interpolation: { escapeValue: false } }) }}
|
||||
.subheading(v-else) {{ $t('auth:loginRequired') }}
|
||||
v-spacer
|
||||
v-card-text.text-center
|
||||
h1.display-1.primary--text.py-2 {{ siteTitle }}
|
||||
template(v-if='screen === "login"')
|
||||
v-text-field.md2.mt-3(
|
||||
v-text-field.mt-3(
|
||||
solo
|
||||
flat
|
||||
prepend-icon='mdi-clipboard-account'
|
||||
@@ -31,7 +32,7 @@
|
||||
v-model='username'
|
||||
:placeholder='$t("auth:fields.emailUser")'
|
||||
)
|
||||
v-text-field.md2.mt-2(
|
||||
v-text-field.mt-2(
|
||||
solo
|
||||
flat
|
||||
prepend-icon='mdi-textbox-password'
|
||||
@@ -47,7 +48,7 @@
|
||||
)
|
||||
template(v-else-if='screen === "tfa"')
|
||||
.body-2 Enter the security code generated from your trusted device:
|
||||
v-text-field.md2.centered.mt-2(
|
||||
v-text-field.centered.mt-2(
|
||||
solo
|
||||
flat
|
||||
background-color='grey lighten-4'
|
||||
@@ -57,12 +58,34 @@
|
||||
:placeholder='$t("auth:tfa.placeholder")'
|
||||
@keyup.enter='verifySecurityCode'
|
||||
)
|
||||
template(v-else-if='screen === "forgot"')
|
||||
.body-2 {{ $t('auth:forgotPasswordSubtitle') }}
|
||||
v-text-field.md2.mt-3(
|
||||
template(v-else-if='screen === "changePwd"')
|
||||
.body-2 {{$t('auth:changePwd.instructions')}}
|
||||
v-text-field.mt-2(
|
||||
type='password'
|
||||
solo
|
||||
flat
|
||||
prepend-icon='email'
|
||||
background-color='grey lighten-4'
|
||||
hide-details
|
||||
ref='iptNewPassword'
|
||||
v-model='newPassword'
|
||||
:placeholder='$t(`auth:changePwd.newPasswordPlaceholder`)'
|
||||
)
|
||||
v-text-field.mt-2(
|
||||
type='password'
|
||||
solo
|
||||
flat
|
||||
background-color='grey lighten-4'
|
||||
hide-details
|
||||
v-model='newPasswordVerify'
|
||||
:placeholder='$t(`auth:changePwd.newPasswordVerifyPlaceholder`)'
|
||||
@keyup.enter='changePassword'
|
||||
)
|
||||
template(v-else-if='screen === "forgot"')
|
||||
.body-2 {{ $t('auth:forgotPasswordSubtitle') }}
|
||||
v-text-field.mt-3(
|
||||
solo
|
||||
flat
|
||||
prepend-icon='mdi-email'
|
||||
background-color='grey lighten-4'
|
||||
hide-details
|
||||
ref='iptEmailForgot'
|
||||
@@ -71,31 +94,48 @@
|
||||
)
|
||||
v-card-actions.pb-4
|
||||
v-spacer
|
||||
v-btn.md2(
|
||||
v-btn(
|
||||
width='100%'
|
||||
max-width='250px'
|
||||
v-if='screen === "login"'
|
||||
block
|
||||
large
|
||||
color='primary'
|
||||
color='teal'
|
||||
dark
|
||||
@click='login'
|
||||
round
|
||||
rounded
|
||||
:loading='isLoading'
|
||||
) {{ $t('auth:actions.login') }}
|
||||
v-btn.md2(
|
||||
v-btn(
|
||||
width='100%'
|
||||
max-width='250px'
|
||||
v-else-if='screen === "tfa"'
|
||||
block
|
||||
large
|
||||
color='primary'
|
||||
color='teal'
|
||||
dark
|
||||
@click='verifySecurityCode'
|
||||
round
|
||||
rounded
|
||||
:loading='isLoading'
|
||||
) {{ $t('auth:tfa.verifyToken') }}
|
||||
v-btn.md2(
|
||||
v-else-if='screen === "forgot"'
|
||||
block
|
||||
v-btn(
|
||||
width='100%'
|
||||
max-width='250px'
|
||||
v-else-if='screen === "changePwd"'
|
||||
large
|
||||
color='primary'
|
||||
color='teal'
|
||||
dark
|
||||
@click='changePassword'
|
||||
rounded
|
||||
:loading='isLoading'
|
||||
) {{ $t('auth:changePwd.proceed') }}
|
||||
v-btn(
|
||||
width='100%'
|
||||
max-width='250px'
|
||||
v-else-if='screen === "forgot"'
|
||||
large
|
||||
color='teal'
|
||||
dark
|
||||
@click='forgotPasswordSubmit'
|
||||
round
|
||||
rounded
|
||||
:loading='isLoading'
|
||||
) {{ $t('auth:sendResetPassword') }}
|
||||
v-spacer
|
||||
@@ -111,15 +151,16 @@
|
||||
v-divider
|
||||
v-card-text.grey.lighten-4.text-center
|
||||
.pb-2.body-2.text-xs-center.grey--text.text--darken-2 {{ $t('auth:orLoginUsingStrategy') }}
|
||||
v-tooltip(top, v-for='strategy in strategies', :key='strategy.key')
|
||||
.social-login-btn.mr-2(
|
||||
slot='activator'
|
||||
v-ripple
|
||||
v-html='strategy.icon'
|
||||
:class='strategy.color + " elevation-" + (strategy.key === selectedStrategy.key ? "0" : "4")'
|
||||
@click='selectStrategy(strategy)'
|
||||
)
|
||||
span {{ strategy.title }}
|
||||
v-btn.mx-1.social-login-btn(
|
||||
v-for='strategy in strategies', :key='strategy.key'
|
||||
large
|
||||
@click='selectStrategy(strategy)'
|
||||
dark
|
||||
:color='strategy.color'
|
||||
:depressed='strategy.key === selectedStrategy.key'
|
||||
)
|
||||
v-avatar.mr-3(tile, :class='strategy.color', size='24', v-html='strategy.icon')
|
||||
span(style='text-transform: none;') {{ strategy.title }}
|
||||
template(v-if='screen === "login" && selectedStrategy.selfRegistration')
|
||||
v-divider
|
||||
v-card-actions.py-3(:class='isSocialShown ? "" : "grey lighten-4"')
|
||||
@@ -142,6 +183,7 @@ import Cookies from 'js-cookie'
|
||||
import strategiesQuery from 'gql/login/login-query-strategies.gql'
|
||||
import loginMutation from 'gql/login/login-mutation-login.gql'
|
||||
import tfaMutation from 'gql/login/login-mutation-tfa.gql'
|
||||
import changePasswordMutation from 'gql/login/login-mutation-changepassword.gql'
|
||||
|
||||
export default {
|
||||
i18nOptions: { namespaces: 'auth' },
|
||||
@@ -155,11 +197,13 @@ export default {
|
||||
password: '',
|
||||
hidePassword: true,
|
||||
securityCode: '',
|
||||
loginToken: '',
|
||||
continuationToken: '',
|
||||
isLoading: false,
|
||||
loaderColor: 'grey darken-4',
|
||||
loaderTitle: 'Working...',
|
||||
isShown: false
|
||||
isShown: false,
|
||||
newPassword: '',
|
||||
newPasswordVerify: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -205,14 +249,14 @@ export default {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: this.$t('auth:invalidEmailUsername'),
|
||||
icon: 'warning'
|
||||
icon: 'alert'
|
||||
})
|
||||
this.$refs.iptEmail.focus()
|
||||
} else if (this.password.length < 2) {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: this.$t('auth:invalidPassword'),
|
||||
icon: 'warning'
|
||||
icon: 'alert'
|
||||
})
|
||||
this.$refs.iptPassword.focus()
|
||||
} else {
|
||||
@@ -231,10 +275,16 @@ export default {
|
||||
if (_.has(resp, 'data.authentication.login')) {
|
||||
let respObj = _.get(resp, 'data.authentication.login', {})
|
||||
if (respObj.responseResult.succeeded === true) {
|
||||
if (respObj.tfaRequired === 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.loginToken = respObj.tfaLoginToken
|
||||
this.$nextTick(() => {
|
||||
this.$refs.iptTFA.focus()
|
||||
})
|
||||
@@ -258,7 +308,7 @@ export default {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: err.message,
|
||||
icon: 'warning'
|
||||
icon: 'alert'
|
||||
})
|
||||
this.isLoading = false
|
||||
}
|
||||
@@ -280,7 +330,7 @@ export default {
|
||||
this.$apollo.mutate({
|
||||
mutation: tfaMutation,
|
||||
variables: {
|
||||
loginToken: this.loginToken,
|
||||
continuationToken: this.continuationToken,
|
||||
securityCode: this.securityCode
|
||||
}
|
||||
}).then(resp => {
|
||||
@@ -307,23 +357,59 @@ export default {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: err.message,
|
||||
icon: 'warning'
|
||||
icon: 'alert'
|
||||
})
|
||||
this.isLoading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
forgotPassword() {
|
||||
/**
|
||||
* CHANGE PASSWORD
|
||||
*/
|
||||
async changePassword () {
|
||||
this.loaderColor = 'grey darken-4'
|
||||
this.loaderTitle = this.$t('auth:changePwd.loading')
|
||||
this.isLoading = true
|
||||
const resp = await this.$apollo.mutate({
|
||||
mutation: changePasswordMutation,
|
||||
variables: {
|
||||
continuationToken: this.continuationToken,
|
||||
newPassword: this.newPassword
|
||||
}
|
||||
})
|
||||
if (_.get(resp, 'data.authentication.loginChangePassword.responseResult.succeeded', false) === true) {
|
||||
this.loaderColor = 'green darken-1'
|
||||
this.loaderTitle = this.$t('auth:loginSuccess')
|
||||
Cookies.set('jwt', _.get(resp, 'data.authentication.loginChangePassword.jwt', ''), { expires: 365 })
|
||||
_.delay(() => {
|
||||
window.location.replace('/') // TEMPORARY - USE RETURNURL
|
||||
}, 1000)
|
||||
} else {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: _.get(resp, 'data.authentication.loginChangePassword.responseResult.message', false),
|
||||
icon: 'alert'
|
||||
})
|
||||
this.isLoading = false
|
||||
}
|
||||
},
|
||||
/**
|
||||
* SWITCH TO FORGOT PASSWORD SCREEN
|
||||
*/
|
||||
forgotPassword () {
|
||||
this.screen = 'forgot'
|
||||
this.$nextTick(() => {
|
||||
this.$refs.iptEmailForgot.focus()
|
||||
})
|
||||
},
|
||||
async forgotPasswordSubmit() {
|
||||
/**
|
||||
* FORGOT PASSWORD SUBMIT
|
||||
*/
|
||||
async forgotPasswordSubmit () {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'pink',
|
||||
message: 'Coming soon!',
|
||||
icon: 'free_breakfast'
|
||||
icon: 'ferry'
|
||||
})
|
||||
}
|
||||
},
|
||||
@@ -378,18 +464,12 @@ export default {
|
||||
}
|
||||
|
||||
.social-login-btn {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 50%;
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
cursor: pointer;
|
||||
transition: opacity .2s ease;
|
||||
&:hover {
|
||||
opacity: .8;
|
||||
}
|
||||
margin: .5rem 0;
|
||||
margin: .25rem 0;
|
||||
svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
|
Reference in New Issue
Block a user