feat: enable password update
All checks were successful
Deploy Miniplan / build (push) Successful in 2m21s

This commit is contained in:
Jonas Gerg 2025-03-22 07:56:51 +01:00
parent e4de1c62f8
commit 9eecde7a80
4 changed files with 93 additions and 4 deletions

View File

@ -34,6 +34,7 @@ data class AuthenticationResult(
@Serializable @Serializable
data class AuthenticationUpdateRequest( data class AuthenticationUpdateRequest(
val username: String?,
val newPassword: String val newPassword: String
) )
@ -70,7 +71,11 @@ fun Route.configureAuthenticationRoutes() {
val principal = call.principal<JWTPrincipal>()!! val principal = call.principal<JWTPrincipal>()!!
val request = call.receive<AuthenticationUpdateRequest>() val request = call.receive<AuthenticationUpdateRequest>()
Security.setPassword(principal.payload.username(), request.newPassword) val username = if(request.username != null && principal.payload.username() == "admin") {
request.username
} else principal.payload.username()
Security.setPassword(username, request.newPassword)
call.respond(hashMapOf("success" to true)) call.respond(hashMapOf("success" to true))
} }
@ -92,8 +97,6 @@ fun Route.configureAuthenticationRoutes() {
call.respond(hashMapOf("password" to newPassword)) call.respond(hashMapOf("password" to newPassword))
} }
} }
} }

View File

@ -7,6 +7,7 @@ import {ref, toRaw} from "vue";
import {onKeyPress} from "@/composables/enter"; import {onKeyPress} from "@/composables/enter";
import {API} from "@/services/api"; import {API} from "@/services/api";
import {Dialogs} from "@/services/DialogService"; import {Dialogs} from "@/services/DialogService";
import UpdatePasswordDialog from "@/components/dialog/UpdatePasswordDialog.vue";
interface CreateMinistrantDialogProps extends DialogControls { interface CreateMinistrantDialogProps extends DialogControls {
onCreate: (any) => (Promise<any> | undefined), onCreate: (any) => (Promise<any> | undefined),
onDelete: (id) => (Promise<any> | undefined), onDelete: (id) => (Promise<any> | undefined),
@ -62,6 +63,23 @@ async function resetPassword(username: string) {
console.log(result) console.log(result)
} }
async function updatePassword(username: string) {
Dialogs.createDialog(
UpdatePasswordDialog,
{
onDismiss(){},
onNegative(){},
onPositive(){},
},
{
async onUpdated(newPassword: string){
await API.updatePassword(username, newPassword)
},
username
}
)
}
</script> </script>
<template> <template>
@ -75,7 +93,9 @@ async function resetPassword(username: string) {
<Input class="input" v-model:value="ministrant.privileges" label="Privilegien"/> <Input class="input" v-model:value="ministrant.privileges" label="Privilegien"/>
<div class="actions" v-if="ministrant.id != -1"> <div class="actions" v-if="ministrant.id != -1">
<button @click="resetPassword(ministrant.username)"><i>lock_reset</i>Passwort zurücksetzen <!-- <button @click="resetPassword(ministrant.username)"><i>lock_reset</i>Passwort zurücksetzen-->
<!-- </button>-->
<button @click="updatePassword(ministrant.username)"><i>lock_reset</i>Passwort ändern
</button> </button>
<button class="red" @click="deleteMinistrant()"><i>delete</i>Entfernen</button> <button class="red" @click="deleteMinistrant()"><i>delete</i>Entfernen</button>
</div> </div>

View File

@ -0,0 +1,61 @@
<script setup lang="ts">
import type {DialogControls} from "@/components/dialog/dialog";
import Dialog from "@/components/dialog/Dialog.vue";
import Input from "@/components/Input.vue";
import {ref} from "vue";
interface UpdatePasswordDialogProps extends DialogControls {
username: string,
onUpdated: (newPassword: string) => (Promise<any> | undefined)
}
const props = defineProps<UpdatePasswordDialogProps>()
const newPassword = ref("")
const newPasswordCheck = ref("")
function updatePassword() {
if(newPassword.value !== newPasswordCheck.value) {
alert("Beide Passwörter müssen gleich sein!")
return
}
props.onUpdated(newPassword.value)
props.onPositive()
}
</script>
<template>
<Dialog class="dialog">
<h3>Passwort zurücksetzen</h3>
<Input class="input" v-model:value="newPassword" type="password" label="Neues Passwort"/>
<Input class="input" v-model:value="newPasswordCheck" type="password" label="Wiederholen"/>
<div class="buttons" style="display: flex; justify-content: end; margin-top: 20px;">
<button @click="onDismiss">Abbrechen</button>
<button @click="updatePassword">Passwort speichern</button>
</div>
</Dialog>
</template>
<style scoped lang="less">
.dialog {
display: flex;
flex-direction: column;
width: 500px;
h3{
margin-bottom: 30px;
}
.input {
margin-bottom: 16px;
}
}
</style>

View File

@ -134,6 +134,11 @@ export namespace API {
.then(res => res.json()) .then(res => res.json())
} }
export async function updatePassword(username: String, newPassword: string): Promise<any> {
return api("/auth/update", "PUT", { username, newPassword })
.then(res => res.json())
}
} }