feat: update user
This commit is contained in:
parent
379d58d069
commit
823ff1bc61
@ -14,7 +14,7 @@
|
|||||||
v-icon mdi-arrow-left
|
v-icon mdi-arrow-left
|
||||||
v-dialog(v-model='deleteGroupDialog', max-width='500', v-if='!group.isSystem')
|
v-dialog(v-model='deleteGroupDialog', max-width='500', v-if='!group.isSystem')
|
||||||
template(v-slot:activator='{ on }')
|
template(v-slot:activator='{ on }')
|
||||||
v-btn(color='red', large, outlined, v-on='{ on }')
|
v-btn.ml-2(color='red', large, outlined, v-on='{ on }')
|
||||||
v-icon(color='red') mdi-trash-can-outline
|
v-icon(color='red') mdi-trash-can-outline
|
||||||
v-card
|
v-card
|
||||||
.dialog-header.is-red Delete Group?
|
.dialog-header.is-red Delete Group?
|
||||||
|
@ -120,7 +120,7 @@
|
|||||||
v-btn(v-else-if='item.isInstalled && item.installDate < item.updatedAt', icon, small, @click='download(item)')
|
v-btn(v-else-if='item.isInstalled && item.installDate < item.updatedAt', icon, small, @click='download(item)')
|
||||||
v-icon.blue--text mdi-cached
|
v-icon.blue--text mdi-cached
|
||||||
v-btn(v-else-if='item.isInstalled', icon, small, @click='download(item)')
|
v-btn(v-else-if='item.isInstalled', icon, small, @click='download(item)')
|
||||||
v-icon.green--text mdi-check
|
v-icon.green--text mdi-check-bold
|
||||||
v-btn(v-else, icon, small, @click='download(item)')
|
v-btn(v-else, icon, small, @click='download(item)')
|
||||||
v-icon.grey--text mdi-cloud-download
|
v-icon.grey--text mdi-cloud-download
|
||||||
v-card.wiki-form.mt-3.animated.fadeInUp.wait-p5s
|
v-card.wiki-form.mt-3.animated.fadeInUp.wait-p5s
|
||||||
|
@ -114,7 +114,7 @@
|
|||||||
item-key='value',
|
item-key='value',
|
||||||
:items-per-page='1000'
|
:items-per-page='1000'
|
||||||
)
|
)
|
||||||
template(v-slot:items='thm')
|
template(v-slot:item='thm')
|
||||||
td
|
td
|
||||||
strong {{thm.item.text}}
|
strong {{thm.item.text}}
|
||||||
td
|
td
|
||||||
@ -124,7 +124,7 @@
|
|||||||
v-btn(v-else-if='thm.item.isInstalled && thm.item.installDate < thm.item.updatedAt', icon)
|
v-btn(v-else-if='thm.item.isInstalled && thm.item.installDate < thm.item.updatedAt', icon)
|
||||||
v-icon.blue--text mdi-cached
|
v-icon.blue--text mdi-cached
|
||||||
v-btn(v-else-if='thm.item.isInstalled', icon)
|
v-btn(v-else-if='thm.item.isInstalled', icon)
|
||||||
v-icon.green--text mdi-check
|
v-icon.green--text mdi-check-bold
|
||||||
v-btn(v-else, icon)
|
v-btn(v-else, icon)
|
||||||
v-icon.grey--text mdi-cloud-download
|
v-icon.grey--text mdi-cloud-download
|
||||||
</template>
|
</template>
|
||||||
|
@ -67,10 +67,12 @@
|
|||||||
:items='groups'
|
:items='groups'
|
||||||
item-text='name'
|
item-text='name'
|
||||||
item-value='id'
|
item-value='id'
|
||||||
|
item-disabled='isSystem'
|
||||||
outlined
|
outlined
|
||||||
prepend-icon='mdi-account-group'
|
prepend-icon='mdi-account-group'
|
||||||
v-model='group'
|
v-model='group'
|
||||||
label='Assign to Group(s)...'
|
label='Assign to Group(s)...'
|
||||||
|
dense
|
||||||
clearable
|
clearable
|
||||||
multiple
|
multiple
|
||||||
)
|
)
|
||||||
@ -104,7 +106,7 @@ import _ from 'lodash'
|
|||||||
|
|
||||||
import createUserMutation from 'gql/admin/users/users-mutation-create.gql'
|
import createUserMutation from 'gql/admin/users/users-mutation-create.gql'
|
||||||
import providersQuery from 'gql/admin/users/users-query-strategies.gql'
|
import providersQuery from 'gql/admin/users/users-query-strategies.gql'
|
||||||
import groupsQuery from 'gql/admin/auth/auth-query-groups.gql'
|
import groupsQuery from 'gql/admin/users/users-query-groups.gql'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
v-icon mdi-arrow-left
|
v-icon mdi-arrow-left
|
||||||
v-dialog(v-model='deleteUserDialog', max-width='500', v-if='user.id !== currentUserId && !user.isSystem')
|
v-dialog(v-model='deleteUserDialog', max-width='500', v-if='user.id !== currentUserId && !user.isSystem')
|
||||||
template(v-slot:activator='{ on }')
|
template(v-slot:activator='{ on }')
|
||||||
v-btn.ml-3.animated.fadeInDown.wait-p1s(color='red', large, outlined, v-on='on')
|
v-btn.ml-3.animated.fadeInDown.wait-p1s(color='red', large, outlined, v-on='on', disabled)
|
||||||
v-icon(color='red') mdi-trash-can-outline
|
v-icon(color='red') mdi-trash-can-outline
|
||||||
v-card
|
v-card
|
||||||
.dialog-header.is-red Delete User?
|
.dialog-header.is-red Delete User?
|
||||||
@ -113,15 +113,35 @@
|
|||||||
v-list-item-title Password
|
v-list-item-title Password
|
||||||
v-list-item-subtitle ••••••••
|
v-list-item-subtitle ••••••••
|
||||||
v-list-item-action
|
v-list-item-action
|
||||||
v-tooltip(top)
|
v-menu(
|
||||||
template(v-slot:activator='{ on }')
|
v-model='editPop.newPassword'
|
||||||
v-btn(icon, color='grey', x-small, v-on='on')
|
:close-on-content-click='false'
|
||||||
v-icon mdi-cached
|
min-width='350'
|
||||||
span Change Password
|
left
|
||||||
|
)
|
||||||
|
template(v-slot:activator='{ on: menu }')
|
||||||
|
v-tooltip(top)
|
||||||
|
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
|
||||||
|
v-card
|
||||||
|
v-text-field(
|
||||||
|
ref='iptNewPassword'
|
||||||
|
v-model='newPassword'
|
||||||
|
label='New Password'
|
||||||
|
solo
|
||||||
|
hide-details
|
||||||
|
append-icon='mdi-check'
|
||||||
|
type='password'
|
||||||
|
@click:append='editPop.newPassword = false'
|
||||||
|
@keydown.enter='editPop.newPassword = false'
|
||||||
|
@keydown.esc='editPop.newPassword = false'
|
||||||
|
)
|
||||||
v-list-item-action
|
v-list-item-action
|
||||||
v-tooltip(top)
|
v-tooltip(top)
|
||||||
template(v-slot:activator='{ on }')
|
template(v-slot:activator='{ on }')
|
||||||
v-btn(icon, color='grey', x-small, v-on='on')
|
v-btn(icon, color='grey', x-small, v-on='on', disabled)
|
||||||
v-icon mdi-email
|
v-icon mdi-email
|
||||||
span Send Password Reset Email
|
span Send Password Reset Email
|
||||||
v-divider
|
v-divider
|
||||||
@ -151,22 +171,37 @@
|
|||||||
span User Groups
|
span User Groups
|
||||||
v-list(dense)
|
v-list(dense)
|
||||||
template(v-for='(group, idx) in user.groups')
|
template(v-for='(group, idx) in user.groups')
|
||||||
v-list-item
|
v-list-item(:key='`group-` + group.id')
|
||||||
v-list-item-avatar(size='32')
|
v-list-item-avatar(size='32')
|
||||||
v-icon mdi-account-group-outline
|
v-icon mdi-account-group-outline
|
||||||
v-list-item-content
|
v-list-item-content
|
||||||
v-list-item-title {{group.name}}
|
v-list-item-title {{group.name}}
|
||||||
v-list-item-action(v-if='!user.isSystem')
|
v-list-item-action(v-if='!user.isSystem')
|
||||||
v-btn(icon, color='red', x-small)
|
v-btn(icon, color='red', x-small, @click='unassignGroup(group.id)')
|
||||||
v-icon mdi-close
|
v-icon mdi-close
|
||||||
v-divider(v-if='idx < user.groups.length - 1')
|
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')
|
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 This user is not assigned to any group yet. You must assign at least 1 group to a user.
|
||||||
v-card-chin(v-if='!user.isSystem')
|
v-card-chin(v-if='!user.isSystem')
|
||||||
v-spacer
|
v-spacer
|
||||||
v-btn(color='primary', text)
|
v-select(
|
||||||
v-icon(left) mdi-clipboard-account
|
ref='iptAssignGroup'
|
||||||
span Assign to group
|
:items='groups'
|
||||||
|
v-model='newGroup'
|
||||||
|
label='Select Group...'
|
||||||
|
item-value='id'
|
||||||
|
item-text='name'
|
||||||
|
item-disabled='isSystem'
|
||||||
|
solo
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
hide-details
|
||||||
|
@keydown.esc='editPop.assignGroup = false'
|
||||||
|
style='max-width: 300px;'
|
||||||
|
)
|
||||||
|
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
|
||||||
v-flex(xs6)
|
v-flex(xs6)
|
||||||
v-card.animated.fadeInUp.wait-p2s
|
v-card.animated.fadeInUp.wait-p2s
|
||||||
v-toolbar(color='primary', dense, dark, flat)
|
v-toolbar(color='primary', dense, dark, flat)
|
||||||
@ -274,6 +309,8 @@ import _ from 'lodash'
|
|||||||
import { get } from 'vuex-pathify'
|
import { get } from 'vuex-pathify'
|
||||||
|
|
||||||
import userQuery from 'gql/admin/users/users-query-single.gql'
|
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 {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
@ -285,10 +322,18 @@ export default {
|
|||||||
pwd: false,
|
pwd: false,
|
||||||
location: false,
|
location: false,
|
||||||
jobTitle: false,
|
jobTitle: false,
|
||||||
timezone: false
|
timezone: false,
|
||||||
|
newPassword: false,
|
||||||
|
assignGroup: false
|
||||||
},
|
},
|
||||||
|
newGroup: 0,
|
||||||
|
newPassword: '',
|
||||||
user: {
|
user: {
|
||||||
|
email: '',
|
||||||
name: '',
|
name: '',
|
||||||
|
location: '',
|
||||||
|
jobTitle: '',
|
||||||
|
timezone: '',
|
||||||
groups: []
|
groups: []
|
||||||
},
|
},
|
||||||
timezones: [
|
timezones: [
|
||||||
@ -550,13 +595,58 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
deleteUser() {},
|
deleteUser() {},
|
||||||
updateUser() {},
|
async updateUser() {
|
||||||
|
this.$store.commit(`loadingStart`, 'admin-users-update')
|
||||||
|
const resp = await this.$apollo.mutate({
|
||||||
|
mutation: updateUserMutation,
|
||||||
|
variables: {
|
||||||
|
id: this.user.id,
|
||||||
|
email: this.user.email,
|
||||||
|
name: this.user.name,
|
||||||
|
newPassword: this.newPassword,
|
||||||
|
groups: _.map(this.user.groups, 'id'),
|
||||||
|
location: this.user.location,
|
||||||
|
jobTitle: this.user.jobTitle,
|
||||||
|
timezone: this.user.timezone
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (_.get(resp, 'data.users.update.responseResult.succeeded', false)) {
|
||||||
|
this.$store.commit('showNotification', {
|
||||||
|
style: 'success',
|
||||||
|
message: 'User updated successfully.',
|
||||||
|
icon: 'check'
|
||||||
|
})
|
||||||
|
this.$router.push('/users')
|
||||||
|
} else {
|
||||||
|
this.$store.commit('showNotification', {
|
||||||
|
style: 'red',
|
||||||
|
message: _.get(resp, 'data.users.update.responseResult.message', 'An unexpected error occured.'),
|
||||||
|
icon: 'warning'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.$store.commit(`loadingStop`, 'admin-users-update')
|
||||||
|
},
|
||||||
focusField (ipt) {
|
focusField (ipt) {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
_.delay(() => {
|
_.delay(() => {
|
||||||
this.$refs[ipt].focus()
|
this.$refs[ipt].focus()
|
||||||
}, 200)
|
}, 200)
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
assignGroup() {
|
||||||
|
if (_.some(this.user.groups, ['id', this.newGroup])) {
|
||||||
|
this.$store.commit('showNotification', {
|
||||||
|
message: 'User is already assigned to this group!',
|
||||||
|
style: 'error',
|
||||||
|
icon: 'alert'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.user.groups.push(_.find(this.groups, ['id', this.newGroup]))
|
||||||
|
this.newGroup = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
unassignGroup(gid) {
|
||||||
|
this.user.groups = _.reject(this.user.groups, ['id', gid])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
apollo: {
|
apollo: {
|
||||||
@ -572,6 +662,14 @@ export default {
|
|||||||
watchLoading (isLoading) {
|
watchLoading (isLoading) {
|
||||||
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-users-refresh')
|
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-users-refresh')
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
groups: {
|
||||||
|
query: groupsQuery,
|
||||||
|
fetchPolicy: 'network-only',
|
||||||
|
update: (data) => data.groups.list,
|
||||||
|
watchLoading (isLoading) {
|
||||||
|
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-groups-refresh')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,8 +40,8 @@
|
|||||||
v-list-item-avatar(size='24'): v-icon(color='indigo') mdi-file-document-edit-outline
|
v-list-item-avatar(size='24'): v-icon(color='indigo') mdi-file-document-edit-outline
|
||||||
v-list-item-title.body-2 {{$t('common:header.edit')}}
|
v-list-item-title.body-2 {{$t('common:header.edit')}}
|
||||||
v-list-item.pl-4(@click='pageHistory', v-if='mode !== `history`')
|
v-list-item.pl-4(@click='pageHistory', v-if='mode !== `history`')
|
||||||
v-list-item-avatar(size='24'): v-icon(color='indigo') mdi-history
|
v-list-item-avatar(size='24'): v-icon(color='grey lighten-2') mdi-history
|
||||||
v-list-item-title.body-2 {{$t('common:header.history')}}
|
v-list-item-title.body-2.grey--text.text--ligten-2 {{$t('common:header.history')}}
|
||||||
v-list-item.pl-4(@click='pageSource', v-if='mode !== `source`')
|
v-list-item.pl-4(@click='pageSource', v-if='mode !== `source`')
|
||||||
v-list-item-avatar(size='24'): v-icon(color='indigo') mdi-code-tags
|
v-list-item-avatar(size='24'): v-icon(color='indigo') mdi-code-tags
|
||||||
v-list-item-title.body-2 {{$t('common:header.viewSource')}}
|
v-list-item-title.body-2 {{$t('common:header.viewSource')}}
|
||||||
@ -309,7 +309,12 @@ export default {
|
|||||||
window.location.assign(`/e/${this.locale}/${this.path}`)
|
window.location.assign(`/e/${this.locale}/${this.path}`)
|
||||||
},
|
},
|
||||||
pageHistory () {
|
pageHistory () {
|
||||||
window.location.assign(`/h/${this.locale}/${this.path}`)
|
this.$store.commit('showNotification', {
|
||||||
|
style: 'indigo',
|
||||||
|
message: `Coming soon...`,
|
||||||
|
icon: 'ferry'
|
||||||
|
})
|
||||||
|
// window.location.assign(`/h/${this.locale}/${this.path}`)
|
||||||
},
|
},
|
||||||
pageSource () {
|
pageSource () {
|
||||||
window.location.assign(`/s/${this.locale}/${this.path}`)
|
window.location.assign(`/s/${this.locale}/${this.path}`)
|
||||||
|
12
client/graph/admin/users/users-mutation-update.gql
Normal file
12
client/graph/admin/users/users-mutation-update.gql
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
mutation ($id: Int!, $email: String, $name: String, $newPassword: String, $groups: [Int], $location: String, $jobTitle: String, $timezone: String) {
|
||||||
|
users {
|
||||||
|
update(id: $id, email: $email, name: $name, newPassword: $newPassword, groups: $groups, location: $location, jobTitle: $jobTitle, timezone: $timezone) {
|
||||||
|
responseResult {
|
||||||
|
succeeded
|
||||||
|
errorCode
|
||||||
|
slug
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
client/graph/admin/users/users-query-groups.gql
Normal file
9
client/graph/admin/users/users-query-groups.gql
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
query {
|
||||||
|
groups {
|
||||||
|
list {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
isSystem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -47,15 +47,15 @@
|
|||||||
.caption.red--text {{$t('common:page.unpublished')}}
|
.caption.red--text {{$t('common:page.unpublished')}}
|
||||||
status-indicator.ml-3(negative, pulse)
|
status-indicator.ml-3(negative, pulse)
|
||||||
v-divider
|
v-divider
|
||||||
v-toolbar.px-2(:color='darkMode ? `grey darken-4-l3` : `grey lighten-4`', flat, :height='90')
|
v-container.grey.pa-0(fluid, :class='darkMode ? `darken-4-l3` : `lighten-4`')
|
||||||
div(style='padding-left: 376px;')
|
v-row(no-gutters, align-content='center', style='height: 90px;')
|
||||||
.headline.grey--text(:class='darkMode ? `text--lighten-2` : `text--darken-3`') {{title}}
|
v-col.pl-4(offset-xl='2', offset-lg='3')
|
||||||
.caption.grey--text.text--darken-1 {{description}}
|
.headline.grey--text(:class='darkMode ? `text--lighten-2` : `text--darken-3`') {{title}}
|
||||||
v-spacer
|
.caption.grey--text.text--darken-1 {{description}}
|
||||||
v-divider
|
v-divider
|
||||||
v-container.pl-5.pt-2(fill-height, fluid, grid-list-xl)
|
v-container.pl-5.pt-4(fluid, grid-list-xl)
|
||||||
v-layout(row)
|
v-layout(row)
|
||||||
v-flex.page-col-sd(lg3, xl2, fill-height, v-if='$vuetify.breakpoint.lgAndUp', style='margin-top: -90px;')
|
v-flex.page-col-sd(lg3, xl2, v-if='$vuetify.breakpoint.lgAndUp', style='margin-top: -90px;')
|
||||||
v-card(v-if='toc.length')
|
v-card(v-if='toc.length')
|
||||||
.overline.pa-5.pb-0(:class='darkMode ? `blue--text text--lighten-2` : `primary--text`') {{$t('common:page.toc')}}
|
.overline.pa-5.pb-0(:class='darkMode ? `blue--text text--lighten-2` : `primary--text`') {{$t('common:page.toc')}}
|
||||||
v-list.pb-3(dense, nav, :class='darkMode ? `darken-3-d3` : ``')
|
v-list.pb-3(dense, nav, :class='darkMode ? `darken-3-d3` : ``')
|
||||||
|
@ -25,6 +25,16 @@
|
|||||||
h1, h2, h3, h4, h5, h6 {
|
h1, h2, h3, h4, h5, h6 {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
display: block;
|
||||||
|
content: " ";
|
||||||
|
width: 1px;
|
||||||
|
margin-top: -75px;
|
||||||
|
height: 75px;
|
||||||
|
visibility: hidden;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
&:first-child {
|
&:first-child {
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
}
|
}
|
||||||
@ -84,7 +94,6 @@
|
|||||||
}
|
}
|
||||||
h2 {
|
h2 {
|
||||||
margin: 1rem 0 0 0;
|
margin: 1rem 0 0 0;
|
||||||
padding: 8px 0 0 0;
|
|
||||||
color: mc('grey', '800');
|
color: mc('grey', '800');
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
@ -114,8 +123,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
h3 {
|
h3 {
|
||||||
margin: 0;
|
margin: 8px 0 0 0;
|
||||||
padding: 8px 0 0 0;
|
|
||||||
color: mc('grey', '700');
|
color: mc('grey', '700');
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
@ -135,8 +143,7 @@
|
|||||||
}
|
}
|
||||||
h4, h5, h6 {
|
h4, h5, h6 {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
margin: 0;
|
margin: 8px 0 0 0;
|
||||||
padding: 8px 0 0 0;
|
|
||||||
color: mc('grey', '700');
|
color: mc('grey', '700');
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
@ -165,19 +172,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// scroll offset fix
|
|
||||||
|
|
||||||
h1:before, h2:before, h3:before, h4:before, h5:before, h6:before {
|
|
||||||
display: block;
|
|
||||||
content: " ";
|
|
||||||
width: 1px;
|
|
||||||
height: 1px;
|
|
||||||
margin-top: -75px;
|
|
||||||
height: 75px;
|
|
||||||
visibility: hidden;
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------
|
// ---------------------------------
|
||||||
// PARAGRAPHS
|
// PARAGRAPHS
|
||||||
// ---------------------------------
|
// ---------------------------------
|
||||||
|
@ -43,19 +43,19 @@ module.exports = {
|
|||||||
delete(obj, args) {
|
delete(obj, args) {
|
||||||
return WIKI.models.users.query().deleteById(args.id)
|
return WIKI.models.users.query().deleteById(args.id)
|
||||||
},
|
},
|
||||||
update(obj, args) {
|
async update(obj, args) {
|
||||||
return WIKI.models.users.query().patch({
|
try {
|
||||||
email: args.email,
|
await WIKI.models.users.updateUser(args)
|
||||||
name: args.name,
|
|
||||||
provider: args.provider,
|
return {
|
||||||
providerId: args.providerId
|
responseResult: graphHelper.generateSuccess('User created successfully')
|
||||||
}).where('id', args.id)
|
}
|
||||||
|
} catch (err) {
|
||||||
|
return graphHelper.generateError(err)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
resetPassword(obj, args) {
|
resetPassword(obj, args) {
|
||||||
return false
|
return false
|
||||||
},
|
|
||||||
setPassword(obj, args) {
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
User: {
|
User: {
|
||||||
|
@ -48,9 +48,12 @@ type UserMutation {
|
|||||||
id: Int!
|
id: Int!
|
||||||
email: String
|
email: String
|
||||||
name: String
|
name: String
|
||||||
providerKey: String
|
newPassword: String
|
||||||
providerId: String
|
groups: [Int]
|
||||||
): UserResponse @auth(requires: ["manage:users", "manage:system"])
|
location: String
|
||||||
|
jobTitle: String
|
||||||
|
timezone: String
|
||||||
|
): DefaultResponse @auth(requires: ["manage:users", "manage:system"])
|
||||||
|
|
||||||
delete(
|
delete(
|
||||||
id: Int!
|
id: Int!
|
||||||
@ -59,11 +62,6 @@ type UserMutation {
|
|||||||
resetPassword(
|
resetPassword(
|
||||||
id: Int!
|
id: Int!
|
||||||
): DefaultResponse
|
): DefaultResponse
|
||||||
|
|
||||||
setPassword(
|
|
||||||
id: Int!
|
|
||||||
passwordRaw: String!
|
|
||||||
): DefaultResponse
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# -----------------------------------------------
|
# -----------------------------------------------
|
||||||
|
@ -140,5 +140,9 @@ module.exports = {
|
|||||||
UserCreationFailed: CustomError('UserCreationFailed', {
|
UserCreationFailed: CustomError('UserCreationFailed', {
|
||||||
message: 'An unexpected error occured during user creation.',
|
message: 'An unexpected error occured during user creation.',
|
||||||
code: 1009
|
code: 1009
|
||||||
|
}),
|
||||||
|
UserNotFound: CustomError('UserNotFound', {
|
||||||
|
message: 'This user does not exist.',
|
||||||
|
code: 1016
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -374,6 +374,11 @@ module.exports = class User extends Model {
|
|||||||
throw new WIKI.Error.AuthTFAInvalid()
|
throw new WIKI.Error.AuthTFAInvalid()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new user
|
||||||
|
*
|
||||||
|
* @param {Object} param0 User Fields
|
||||||
|
*/
|
||||||
static async createNewUser ({ providerKey, email, passwordRaw, name, groups, mustChangePassword, sendWelcomeEmail }) {
|
static async createNewUser ({ providerKey, email, passwordRaw, name, groups, mustChangePassword, sendWelcomeEmail }) {
|
||||||
// Input sanitization
|
// Input sanitization
|
||||||
email = _.toLower(email)
|
email = _.toLower(email)
|
||||||
@ -487,6 +492,69 @@ module.exports = class User extends Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update an existing user
|
||||||
|
*
|
||||||
|
* @param {Object} param0 User ID and fields to update
|
||||||
|
*/
|
||||||
|
static async updateUser ({ id, email, name, newPassword, groups, location, jobTitle, timezone }) {
|
||||||
|
const usr = await WIKI.models.users.query().findById(id)
|
||||||
|
if (usr) {
|
||||||
|
let usrData = {}
|
||||||
|
if (!_.isEmpty(email) && email !== usr.email) {
|
||||||
|
const dupUsr = await WIKI.models.users.query().select('id').where({
|
||||||
|
email,
|
||||||
|
providerKey: usr.providerKey
|
||||||
|
})
|
||||||
|
if (dupUsr) {
|
||||||
|
throw new WIKI.Error.AuthAccountAlreadyExists()
|
||||||
|
}
|
||||||
|
usrData.email = email
|
||||||
|
}
|
||||||
|
if (!_.isEmpty(name) && name !== usr.name) {
|
||||||
|
usrData.name = _.trim(name)
|
||||||
|
}
|
||||||
|
if (!_.isEmpty(newPassword)) {
|
||||||
|
if (newPassword.length < 6) {
|
||||||
|
throw new WIKI.Error.InputInvalid('Password must be at least 6 characters!')
|
||||||
|
}
|
||||||
|
usrData.password = newPassword
|
||||||
|
}
|
||||||
|
if (!_.isEmpty(groups)) {
|
||||||
|
const usrGroupsRaw = await usr.$relatedQuery('groups')
|
||||||
|
const usrGroups = _.map(usrGroupsRaw, 'id')
|
||||||
|
// Relate added groups
|
||||||
|
const addUsrGroups = _.difference(groups, usrGroups)
|
||||||
|
for (const grp of addUsrGroups) {
|
||||||
|
await usr.$relatedQuery('groups').relate(grp)
|
||||||
|
}
|
||||||
|
// Unrelate removed groups
|
||||||
|
const remUsrGroups = _.difference(usrGroups, groups)
|
||||||
|
for (const grp of remUsrGroups) {
|
||||||
|
await usr.$relatedQuery('groups').unrelate().where('groupId', grp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!_.isEmpty(location) && location !== usr.location) {
|
||||||
|
usrData.location = _.trim(location)
|
||||||
|
}
|
||||||
|
if (!_.isEmpty(jobTitle) && jobTitle !== usr.jobTitle) {
|
||||||
|
usrData.jobTitle = _.trim(jobTitle)
|
||||||
|
}
|
||||||
|
if (!_.isEmpty(timezone) && timezone !== usr.timezone) {
|
||||||
|
usrData.timezone = timezone
|
||||||
|
}
|
||||||
|
await WIKI.models.users.query().patch(usrData).findById(id)
|
||||||
|
} else {
|
||||||
|
throw new WIKI.Error.UserNotFound()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a new user (client-side registration)
|
||||||
|
*
|
||||||
|
* @param {Object} param0 User fields
|
||||||
|
* @param {Object} context GraphQL Context
|
||||||
|
*/
|
||||||
static async register ({ email, password, name, verify = false, bypassChecks = false }, context) {
|
static async register ({ email, password, name, verify = false, bypassChecks = false }, context) {
|
||||||
const localStrg = await WIKI.models.authentication.getStrategy('local')
|
const localStrg = await WIKI.models.authentication.getStrategy('local')
|
||||||
// Check if self-registration is enabled
|
// Check if self-registration is enabled
|
||||||
|
Loading…
Reference in New Issue
Block a user