re-implemented user update
- only for text fields - password and theme need to be re-implemented, too
This commit is contained in:
@@ -13,7 +13,9 @@
|
|||||||
function check_key(evt){
|
function check_key(evt){
|
||||||
if (evt.key === 'Enter'){
|
if (evt.key === 'Enter'){
|
||||||
input = false;
|
input = false;
|
||||||
onUpdate({key:key,value:value});
|
let obj = {};
|
||||||
|
obj[key] = value;
|
||||||
|
onUpdate(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -26,12 +26,12 @@
|
|||||||
<td>{user.id}</td>
|
<td>{user.id}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<EditableField key='user.name' value={user.name} onUpdate={patch} />
|
<EditableField key='user.name' value={user.name} onUpdate={patch} />
|
||||||
<EditableField key='user.login' value={user.login} />
|
|
||||||
<EditableField key='user.email' value={user.email} />
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>{t('user.language')}</th>
|
<th>{t('user.login')}</th>
|
||||||
<td>{user.language}</td>
|
<td>{user.login}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<EditableField key='user.email' value={user.email} onUpdate={patch} />
|
||||||
|
<EditableField key='user.language' value={user.language} onUpdate={patch} />
|
||||||
<tr>
|
<tr>
|
||||||
<th>{t('user.theme')}</th>
|
<th>{t('user.theme')}</th>
|
||||||
<td>{user.theme}</td>
|
<td>{user.theme}</td>
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
/* © SRSoftware 2025 */
|
/* © SRSoftware 2025 */
|
||||||
package de.srsoftware.umbrella.user;
|
package de.srsoftware.umbrella.user;
|
||||||
|
|
||||||
import static de.srsoftware.tools.Optionals.nullable;
|
import static de.srsoftware.tools.Optionals.*;
|
||||||
import static de.srsoftware.umbrella.core.Constants.PASSWORD;
|
import static de.srsoftware.umbrella.core.Constants.*;
|
||||||
import static de.srsoftware.umbrella.core.Paths.LOGOUT;
|
import static de.srsoftware.umbrella.core.Paths.LOGOUT;
|
||||||
import static de.srsoftware.umbrella.core.ResponseCode.*;
|
import static de.srsoftware.umbrella.core.ResponseCode.*;
|
||||||
import static de.srsoftware.umbrella.user.Constants.*;
|
import static de.srsoftware.umbrella.user.Constants.*;
|
||||||
import static de.srsoftware.umbrella.user.Paths.LOGIN;
|
import static de.srsoftware.umbrella.user.Paths.LOGIN;
|
||||||
import static de.srsoftware.umbrella.user.Paths.WHOAMI;
|
import static de.srsoftware.umbrella.user.Paths.WHOAMI;
|
||||||
|
import static java.lang.System.Logger.Level.WARNING;
|
||||||
import static java.time.temporal.ChronoUnit.DAYS;
|
import static java.time.temporal.ChronoUnit.DAYS;
|
||||||
|
|
||||||
import com.sun.net.httpserver.HttpExchange;
|
import com.sun.net.httpserver.HttpExchange;
|
||||||
@@ -16,14 +17,13 @@ import de.srsoftware.tools.PathHandler;
|
|||||||
import de.srsoftware.tools.SessionToken;
|
import de.srsoftware.tools.SessionToken;
|
||||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||||
import de.srsoftware.umbrella.user.api.UserDb;
|
import de.srsoftware.umbrella.user.api.UserDb;
|
||||||
import de.srsoftware.umbrella.user.model.Password;
|
import de.srsoftware.umbrella.user.model.*;
|
||||||
import de.srsoftware.umbrella.user.model.Session;
|
|
||||||
import de.srsoftware.umbrella.user.model.Token;
|
|
||||||
import de.srsoftware.umbrella.user.model.UmbrellaUser;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
|
||||||
public class UserModule extends PathHandler {
|
public class UserModule extends PathHandler {
|
||||||
@@ -75,18 +75,24 @@ public class UserModule extends PathHandler {
|
|||||||
|
|
||||||
public boolean doPatch(Path path, HttpExchange ex) throws IOException {
|
public boolean doPatch(Path path, HttpExchange ex) throws IOException {
|
||||||
addCors(ex);
|
addCors(ex);
|
||||||
|
JSONObject json;
|
||||||
|
try {
|
||||||
|
json = json(ex);
|
||||||
|
} catch (Exception e){
|
||||||
|
LOG.log(WARNING,"Request does not contain valid JSON",e);
|
||||||
|
return sendContent(ex,BAD_REQUEST,"Body contains no JSON data");
|
||||||
|
}
|
||||||
var head = path.pop();
|
var head = path.pop();
|
||||||
try {
|
try {
|
||||||
if (head == null || head.isBlank()) return sendContent(ex,UNPROCESSABLE,"User id missing!");
|
if (head == null || head.isBlank()) return sendContent(ex,UNPROCESSABLE,"User id missing!");
|
||||||
long userId = Long.parseLong(head);
|
long userId = Long.parseLong(head);
|
||||||
var user = users.load(userId);
|
var user = (DbUser) users.load(userId);
|
||||||
// TODO: update user, then return user data
|
return update(ex, user,json);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
return sendContent(ex,UNPROCESSABLE,"Invalid user id: "+head);
|
return sendContent(ex,UNPROCESSABLE,"Invalid user id: "+head);
|
||||||
} catch (UmbrellaException e) {
|
} catch (UmbrellaException e) {
|
||||||
return sendContent(ex,e.statusCode(),e.getMessage());
|
return sendContent(ex,e.statusCode(),e.getMessage());
|
||||||
}
|
}
|
||||||
return super.doPatch(path,ex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -144,4 +150,15 @@ public class UserModule extends PathHandler {
|
|||||||
return sendContent(ex,ue.statusCode(),ue.getMessage());
|
return sendContent(ex,ue.statusCode(),ue.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean update(HttpExchange ex, DbUser user, JSONObject json) throws UmbrellaException, IOException {
|
||||||
|
var id = user.id();
|
||||||
|
var name = json.has("user.name") && json.get("user.name") instanceof String s && !s.isBlank() ? s : user.name();
|
||||||
|
var email = json.has("user.email") && json.get("user.email") instanceof String e && !e.isBlank() ? e : user.email();
|
||||||
|
var pass = json.has("user.password") && json.get("user.password") instanceof String p && !p.isBlank() ? Password.of(BAD_HASHER.hash(p,null)) : user.hashedPassword();
|
||||||
|
var theme = json.has("user.theme") && json.get("user.theme") instanceof String t && !t.isBlank() ? t : user.theme();
|
||||||
|
var lang = json.has("user.language") && json.get("user.language") instanceof String l && !l.isBlank() ? l : user.language();
|
||||||
|
var saved = users.save(new DbUser(id,name,email,pass,theme,lang, Set.of(),null));
|
||||||
|
return sendContent(ex,OK,saved);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ CREATE TABLE IF NOT EXISTS {0} (
|
|||||||
PRIMARY KEY({1})
|
PRIMARY KEY({1})
|
||||||
)""";
|
)""";
|
||||||
try {
|
try {
|
||||||
var stmt = db.prepareStatement(format(createTable,TABLE_USERS, ID, LOGIN, PASSWORD, THEME, EMAIL, MESSAGE_DELIVERY, LAST_LOGOFF, SETTINGS));
|
var stmt = db.prepareStatement(format(createTable,TABLE_USERS, ID, LOGIN, PASS, THEME, EMAIL, MESSAGE_DELIVERY, LAST_LOGOFF, SETTINGS));
|
||||||
stmt.execute();
|
stmt.execute();
|
||||||
stmt.close();
|
stmt.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
@@ -435,7 +435,7 @@ CREATE TABLE IF NOT EXISTS {0} (
|
|||||||
try {
|
try {
|
||||||
Long id = user.id();
|
Long id = user.id();
|
||||||
if (id<1) id = null;
|
if (id<1) id = null;
|
||||||
replaceInto(TABLE_USERS, ID, LOGIN, PASSWORD, THEME, EMAIL, LAST_LOGOFF)
|
replaceInto(TABLE_USERS, ID, LOGIN, PASS, THEME, EMAIL, LAST_LOGOFF)
|
||||||
.values(id,user.name(),user.hashedPassword(),user.theme(),user.email(),user.lastLogoff())
|
.values(id,user.name(),user.hashedPassword(),user.theme(),user.email(),user.lastLogoff())
|
||||||
.execute(db)
|
.execute(db)
|
||||||
.close();
|
.close();
|
||||||
|
|||||||
Reference in New Issue
Block a user