improved display of password reset overlay, added security checks on password edit
Build Docker Image / Docker-Build (push) Successful in 1m19s
Build Docker Image / Clean-Registry (push) Successful in 5s

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2026-11-10 23:37:12 +01:00
parent 3746149aa4
commit 320a0cde1e
5 changed files with 23 additions and 14 deletions
+9 -4
View File
@@ -1,6 +1,7 @@
<script>
import { api } from '../../urls.svelte.js';
import { t } from '../../translations.svelte.js';
import { error } from '../../warn.svelte';
let { editPassword = $bindable() } = $props();
@@ -17,6 +18,10 @@
editPassword = false;
}
function oninput(ev){
caption = t('update');
}
async function submit(){
caption = t('data_sent');
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/user/password`;
@@ -33,7 +38,7 @@
if (resp.ok){
caption = t('saved');
} else {
caption = t('failed');
caption = await resp.text();
}
}
</script>
@@ -47,19 +52,19 @@
<fieldset class="overlay">
<legend>{t('edit_password')}</legend>
<label>
<input type="password" bind:value={oldPass} /> {t('old_password')}
<input type="password" bind:value={oldPass} {oninput} /> {t('old_password')}
{#if oldEmpty}
<span class="error">{t('must_not_be_empty')}</span>
{/if}
</label>
<label>
<input type="password" bind:value={newPass} /> {t('new_password')}
<input type="password" bind:value={newPass} {oninput} /> {t('new_password')}
{#if newEmpty}
<span class="error">{t('must_not_be_empty')}</span>
{/if}
</label>
<label>
<input type="password" bind:value={repeat} /> {t('repeat_new_password')}
<input type="password" bind:value={repeat} {oninput} /> {t('repeat_new_password')}
{#if mismatch}
<span class="error">{t('mismatch')}</span>
{/if}
+2 -7
View File
@@ -2,7 +2,7 @@
import { useTinyRouter } from 'svelte-tiny-router';
import { onMount } from 'svelte';
import { api } from '../../urls.svelte'
import { api, patch } from '../../urls.svelte'
import { error, yikes } from '../../warn.svelte';
import { checkUser } from '../../user.svelte';
import { t } from '../../translations.svelte';
@@ -45,7 +45,6 @@
ev.preventDefault();
sent = true;
caption = t('data_sent');
let method = 'PATCH';
let url = null;
if (user_id) {
url = api(`user/${user_id}`);
@@ -53,11 +52,7 @@
url = api('user/create');
method = 'POST';
}
let resp = await fetch(url,{
method : method,
credentials : 'include',
body : JSON.stringify(editUser)
});
let resp = await patch(url,editUser);
if (resp.ok){
caption = t('saved');
checkUser();
@@ -600,7 +600,14 @@ public class UserModule extends BaseHandler implements UserService {
var id = user.id();
var name = json.has(NAME) && json.get(NAME) instanceof String s && !s.isBlank() ? s : user.name();
var email = json.has(EMAIL) && json.get(EMAIL) instanceof String e && !e.isBlank() ? new EmailAddress(e) : user.email();
var pass = json.has(PASSWORD) && json.get(PASSWORD) instanceof String p && !p.isBlank() ? Password.of(BAD_HASHER.hash(p,null)) : user.hashedPassword();
var pass = user.hashedPassword();
if (json.has(PASSWORD) && json.get(PASSWORD) instanceof String p && !p.isBlank()){
if (user.permissions().contains(UPDATE_USERS)) {
pass = Password.of(BAD_HASHER.hash(p,null));
} else {
throw forbidden("You are not allowed to set a password without presenting the old one!");
}
}
var theme = json.has(THEME) && json.get(THEME) instanceof String t && !t.isBlank() ? t : user.theme();
var lang = json.has(LANGUAGE) && json.get(LANGUAGE) instanceof String l && !l.isBlank() ? l : user.language();
var saved = users.save(new DbUser(id,name,email,pass,theme,lang, user.permissions(),null));
@@ -201,7 +201,10 @@ code,
color: black;
}
.overlay{
background: rgba(0,0,0,0.9);
color: orange;
}
/** priority colors **/
@@ -201,7 +201,6 @@ td, tr{
right: 0;
left: 0;
padding: 40px 10px 10px;
background: rgba(0,0,0,0.9);
z-index: 50;
}