feat(webui): password change from user settings screen

closes #503
This commit is contained in:
Gauthier Roebroeck 2021-06-28 11:43:07 +08:00
parent 30303a6df3
commit 668331eb00
6 changed files with 45 additions and 25 deletions

View file

@ -36,6 +36,17 @@
</v-tooltip>
</v-list-item-action>
<v-list-item-action>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn icon @click="changeUserPassword(u)" v-on="on">
<v-icon>mdi-lock-reset</v-icon>
</v-btn>
</template>
<span>{{ $t('settings_user.change_password') }}</span>
</v-tooltip>
</v-list-item-action>
<v-list-item-action>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
@ -73,6 +84,10 @@
:user="userToEditSharedLibraries"
/>
<password-change-dialog v-model="modalChangePassword"
:user="userToChangePassword"
/>
<user-edit-dialog v-model="modalEditUser"
:user="userToEdit"
/>
@ -91,10 +106,11 @@ import UserEditDialog from '@/components/dialogs/UserEditDialog.vue'
import UserSharedLibrariesEditDialog from '@/components/dialogs/UserSharedLibrariesEditDialog.vue'
import {UserRoles} from '@/types/enum-users'
import Vue from 'vue'
import PasswordChangeDialog from "@/components/dialogs/PasswordChangeDialog.vue"
export default Vue.extend({
name: 'UsersList',
components: {UserSharedLibrariesEditDialog, UserDeleteDialog, UserEditDialog},
components: {UserSharedLibrariesEditDialog, UserDeleteDialog, UserEditDialog, PasswordChangeDialog},
data: () => ({
UserRoles,
modalAddUser: false,
@ -104,6 +120,8 @@ export default Vue.extend({
userToEditSharedLibraries: {} as UserWithSharedLibrariesDto,
modalEditUser: false,
userToEdit: {} as UserDto,
modalChangePassword: false,
userToChangePassword: {} as UserDto,
}),
computed: {
users(): UserWithSharedLibrariesDto[] {
@ -129,6 +147,10 @@ export default Vue.extend({
this.userToEdit = user
this.modalEditUser = true
},
changeUserPassword(user: UserDto) {
this.userToChangePassword = user
this.modalChangePassword = true
},
},
})
</script>

View file

@ -152,7 +152,7 @@ export default Vue.extend({
},
async updatePassword () {
try {
await this.$store.dispatch('updateMyPassword', { password: this.form.newPassword })
await this.$komgaUsers.patchUserPassword(this.user, { password: this.form.newPassword } as PasswordUpdateDto)
} catch (e) {
this.showSnack(e.message)
}

View file

@ -580,6 +580,7 @@
"server_settings": "Server Settings"
},
"settings_user": {
"change_password": "Change password",
"edit_shared_libraries": "Edit shared libraries",
"edit_user": "Edit user",
"role_administrator": "Administrator",

View file

@ -1,8 +1,8 @@
import KomgaUsersService from '@/services/komga-users.service'
import { UserRoles } from '@/types/enum-users'
import { AxiosInstance } from 'axios'
import {UserRoles} from '@/types/enum-users'
import {AxiosInstance} from 'axios'
import _Vue from 'vue'
import { Module } from 'vuex/types'
import {Module} from 'vuex/types'
let service: KomgaUsersService
@ -39,9 +39,6 @@ const vuexModule: Module<any, any> = {
async getMe ({ commit }) {
commit('setMe', await service.getMe())
},
async updateMyPassword (_, newPassword: PasswordUpdateDto) {
await service.patchMePassword(newPassword)
},
async getAllUsers ({ commit }) {
commit('setAllUsers', await service.getAll())
},

View file

@ -7,11 +7,11 @@ const API_USERS = '/api/v1/users'
export default class KomgaUsersService {
private http: AxiosInstance
constructor (http: AxiosInstance) {
constructor(http: AxiosInstance) {
this.http = http
}
async getMeWithAuth (login: string, password: string): Promise<UserDto> {
async getMeWithAuth(login: string, password: string): Promise<UserDto> {
try {
return (await this.http.get(
`${API_USERS}/me`,
@ -36,7 +36,7 @@ export default class KomgaUsersService {
}
}
async getMe (): Promise<UserDto> {
async getMe(): Promise<UserDto> {
try {
return (await this.http.get(`${API_USERS}/me`)).data
} catch (e) {
@ -48,7 +48,7 @@ export default class KomgaUsersService {
}
}
async getAll (): Promise<UserWithSharedLibrariesDto[]> {
async getAll(): Promise<UserWithSharedLibrariesDto[]> {
try {
return (await this.http.get(`${API_USERS}`)).data
} catch (e) {
@ -60,7 +60,7 @@ export default class KomgaUsersService {
}
}
async postUser (user: UserCreationDto): Promise<UserDto> {
async postUser(user: UserCreationDto): Promise<UserDto> {
try {
return (await this.http.post(API_USERS, user)).data
} catch (e) {
@ -72,7 +72,7 @@ export default class KomgaUsersService {
}
}
async patchUserRoles (userId: string, roles: RolesUpdateDto): Promise<UserDto> {
async patchUserRoles(userId: string, roles: RolesUpdateDto): Promise<UserDto> {
try {
return (await this.http.patch(`${API_USERS}/${userId}`, roles)).data
} catch (e) {
@ -84,7 +84,7 @@ export default class KomgaUsersService {
}
}
async deleteUser (user: UserDto) {
async deleteUser(user: UserDto) {
try {
await this.http.delete(`${API_USERS}/${user.id}`)
} catch (e) {
@ -96,11 +96,11 @@ export default class KomgaUsersService {
}
}
async patchMePassword (newPassword: PasswordUpdateDto) {
async patchUserPassword(user: UserDto, newPassword: PasswordUpdateDto) {
try {
return (await this.http.patch(`${API_USERS}/me/password`, newPassword)).data
return (await this.http.patch(`${API_USERS}/${user.id}/password`, newPassword)).data
} catch (e) {
let msg = `An error occurred while trying to update password for current user`
let msg = `An error occurred while trying to update password for user ${user.email}`
if (e.response.data.message) {
msg += `: ${e.response.data.message}`
}
@ -108,7 +108,7 @@ export default class KomgaUsersService {
}
}
async patchUserSharedLibraries (user: UserDto, sharedLibrariesUpdateDto: SharedLibrariesUpdateDto) {
async patchUserSharedLibraries(user: UserDto, sharedLibrariesUpdateDto: SharedLibrariesUpdateDto) {
try {
return (await this.http.patch(`${API_USERS}/${user.id}/shared-libraries`, sharedLibrariesUpdateDto)).data
} catch (e) {
@ -120,7 +120,7 @@ export default class KomgaUsersService {
}
}
async logout () {
async logout() {
try {
await this.http.post(`${API_USERS}/logout`)
} catch (e) {
@ -132,11 +132,11 @@ export default class KomgaUsersService {
}
}
async getMyAuthenticationActivity (pageRequest?: PageRequest): Promise<Page<AuthenticationActivityDto>> {
async getMyAuthenticationActivity(pageRequest?: PageRequest): Promise<Page<AuthenticationActivityDto>> {
try {
return (await this.http.get(`${API_USERS}/me/authentication-activity`, {
params: pageRequest,
paramsSerializer: params => qs.stringify(params, { indices: false }),
paramsSerializer: params => qs.stringify(params, {indices: false}),
})).data
} catch (e) {
let msg = 'An error occurred while trying to retrieve authentication activity'
@ -147,11 +147,11 @@ export default class KomgaUsersService {
}
}
async getAuthenticationActivity (pageRequest?: PageRequest): Promise<Page<AuthenticationActivityDto>> {
async getAuthenticationActivity(pageRequest?: PageRequest): Promise<Page<AuthenticationActivityDto>> {
try {
return (await this.http.get(`${API_USERS}/authentication-activity`, {
params: pageRequest,
paramsSerializer: params => qs.stringify(params, { indices: false }),
paramsSerializer: params => qs.stringify(params, {indices: false}),
})).data
} catch (e) {
let msg = 'An error occurred while trying to retrieve authentication activity'

View file

@ -4,7 +4,7 @@
<v-col class="text-h5">{{ $t('users.users') }}</v-col>
</v-row>
<v-row>
<v-col cols="12" md="8" lg="6" xl="4">
<v-col cols="12" md="10" lg="8" xl="4">
<users-list/>
</v-col>
</v-row>