updated library de.srsoftware.tools.http
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
@@ -6,7 +6,7 @@ plugins {
|
|||||||
|
|
||||||
dependencies{
|
dependencies{
|
||||||
implementation("org.json:json:20240303")
|
implementation("org.json:json:20240303")
|
||||||
implementation("de.srsoftware:tools.http:1.3.0")
|
implementation("de.srsoftware:tools.http:1.5.4")
|
||||||
implementation("de.srsoftware:tools.logging:1.2.0")
|
implementation("de.srsoftware:tools.logging:1.2.0")
|
||||||
implementation("de.srsoftware:tools.optionals:1.0.0")
|
implementation("de.srsoftware:tools.optionals:1.0.0")
|
||||||
implementation("de.srsoftware:tools.util:1.3.1")
|
implementation("de.srsoftware:tools.util:1.3.1")
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ description = "SRSoftware OIDC: backend"
|
|||||||
|
|
||||||
dependencies{
|
dependencies{
|
||||||
implementation("com.sun.mail:jakarta.mail:2.0.1")
|
implementation("com.sun.mail:jakarta.mail:2.0.1")
|
||||||
implementation("de.srsoftware:tools.http:1.3.0")
|
implementation("de.srsoftware:tools.http:1.5.4")
|
||||||
implementation("de.srsoftware:tools.optionals:1.0.0")
|
implementation("de.srsoftware:tools.optionals:1.0.0")
|
||||||
implementation("de.srsoftware:tools.result:1.0.0")
|
implementation("de.srsoftware:tools.result:1.0.0")
|
||||||
implementation("de.srsoftware:tools.util:1.3.1")
|
implementation("de.srsoftware:tools.util:1.3.1")
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import de.srsoftware.oidc.api.data.Client;
|
|||||||
import de.srsoftware.oidc.api.data.Session;
|
import de.srsoftware.oidc.api.data.Session;
|
||||||
import de.srsoftware.oidc.api.data.User;
|
import de.srsoftware.oidc.api.data.User;
|
||||||
import de.srsoftware.tools.Optionals;
|
import de.srsoftware.tools.Optionals;
|
||||||
|
import de.srsoftware.tools.Path;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@@ -124,7 +125,7 @@ public class ClientController extends Controller {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doDelete(String path, HttpExchange ex) throws IOException {
|
public boolean doDelete(Path path, HttpExchange ex) throws IOException {
|
||||||
var optSession = getSession(ex);
|
var optSession = getSession(ex);
|
||||||
if (optSession.isEmpty()) return sendEmptyResponse(HTTP_UNAUTHORIZED, ex);
|
if (optSession.isEmpty()) return sendEmptyResponse(HTTP_UNAUTHORIZED, ex);
|
||||||
|
|
||||||
@@ -135,15 +136,12 @@ public class ClientController extends Controller {
|
|||||||
var user = optUser.get();
|
var user = optUser.get();
|
||||||
sessions.extend(session, user);
|
sessions.extend(session, user);
|
||||||
|
|
||||||
switch (path) {
|
if (path.isEmpty()) return deleteClient(ex, session);
|
||||||
case "/":
|
|
||||||
return deleteClient(ex, session);
|
|
||||||
}
|
|
||||||
return notFound(ex);
|
return notFound(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doGet(String path, HttpExchange ex) throws IOException {
|
public boolean doGet(Path path, HttpExchange ex) throws IOException {
|
||||||
var optSession = getSession(ex);
|
var optSession = getSession(ex);
|
||||||
if (optSession.isEmpty()) return sendContent(ex, HTTP_UNAUTHORIZED, "No authorized!");
|
if (optSession.isEmpty()) return sendContent(ex, HTTP_UNAUTHORIZED, "No authorized!");
|
||||||
|
|
||||||
@@ -154,10 +152,10 @@ public class ClientController extends Controller {
|
|||||||
var user = optUser.get();
|
var user = optUser.get();
|
||||||
sessions.extend(session, user);
|
sessions.extend(session, user);
|
||||||
|
|
||||||
switch (path) {
|
switch (path.pop()) {
|
||||||
case "/dash":
|
case "dash":
|
||||||
return dashboard(ex, user);
|
return dashboard(ex, user);
|
||||||
case "/list":
|
case "list":
|
||||||
return list(ex, session);
|
return list(ex, session);
|
||||||
}
|
}
|
||||||
return notFound(ex);
|
return notFound(ex);
|
||||||
@@ -177,7 +175,7 @@ public class ClientController extends Controller {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doPost(String path, HttpExchange ex) throws IOException {
|
public boolean doPost(Path path, HttpExchange ex) throws IOException {
|
||||||
var optSession = getSession(ex);
|
var optSession = getSession(ex);
|
||||||
if (optSession.isEmpty()) return sendContent(ex, HTTP_UNAUTHORIZED, "No authorized!");
|
if (optSession.isEmpty()) return sendContent(ex, HTTP_UNAUTHORIZED, "No authorized!");
|
||||||
|
|
||||||
@@ -188,12 +186,11 @@ public class ClientController extends Controller {
|
|||||||
var user = optUser.get();
|
var user = optUser.get();
|
||||||
sessions.extend(session, user);
|
sessions.extend(session, user);
|
||||||
|
|
||||||
switch (path) {
|
if (path.isEmpty()) return load(ex,session);
|
||||||
case "/":
|
switch (path.pop()) {
|
||||||
return load(ex, session);
|
case "add", "update":
|
||||||
case "/add", "/update":
|
|
||||||
return save(ex, session);
|
return save(ex, session);
|
||||||
case "/authorize":
|
case "authorize":
|
||||||
return authorize(ex, session);
|
return authorize(ex, session);
|
||||||
}
|
}
|
||||||
return notFound(ex);
|
return notFound(ex);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public abstract class Controller extends PathHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Optional<Session> getSession(HttpExchange ex) {
|
protected Optional<Session> getSession(HttpExchange ex) {
|
||||||
return SessionToken.from(ex).map(SessionToken::sessionId).flatMap(sessionId -> sessions.retrieve(sessionId));
|
return SessionToken.from(ex).map(SessionToken::sessionId).flatMap(sessions::retrieve);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean invalidSessionUser(HttpExchange ex) throws IOException {
|
protected boolean invalidSessionUser(HttpExchange ex) throws IOException {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import de.srsoftware.oidc.api.MailConfig;
|
|||||||
import de.srsoftware.oidc.api.SessionService;
|
import de.srsoftware.oidc.api.SessionService;
|
||||||
import de.srsoftware.oidc.api.UserService;
|
import de.srsoftware.oidc.api.UserService;
|
||||||
import de.srsoftware.oidc.api.data.Session;
|
import de.srsoftware.oidc.api.data.Session;
|
||||||
|
import de.srsoftware.tools.Path;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class EmailController extends Controller {
|
public class EmailController extends Controller {
|
||||||
@@ -24,7 +25,7 @@ public class EmailController extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doGet(String path, HttpExchange ex) throws IOException {
|
public boolean doGet(Path path, HttpExchange ex) throws IOException {
|
||||||
var optSession = getSession(ex);
|
var optSession = getSession(ex);
|
||||||
if (optSession.isEmpty()) return sendEmptyResponse(HTTP_UNAUTHORIZED, ex);
|
if (optSession.isEmpty()) return sendEmptyResponse(HTTP_UNAUTHORIZED, ex);
|
||||||
var session = optSession.get();
|
var session = optSession.get();
|
||||||
@@ -33,15 +34,15 @@ public class EmailController extends Controller {
|
|||||||
var user = optUser.get();
|
var user = optUser.get();
|
||||||
sessions.extend(session, user);
|
sessions.extend(session, user);
|
||||||
|
|
||||||
switch (path) {
|
switch (path.pop()) {
|
||||||
case "/settings":
|
case "settings":
|
||||||
return provideSettings(ex, session);
|
return provideSettings(ex, session);
|
||||||
}
|
}
|
||||||
return notFound(ex);
|
return notFound(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doPost(String path, HttpExchange ex) throws IOException {
|
public boolean doPost(Path path, HttpExchange ex) throws IOException {
|
||||||
var optSession = getSession(ex);
|
var optSession = getSession(ex);
|
||||||
if (optSession.isEmpty()) return sendEmptyResponse(HTTP_UNAUTHORIZED, ex);
|
if (optSession.isEmpty()) return sendEmptyResponse(HTTP_UNAUTHORIZED, ex);
|
||||||
var session = optSession.get();
|
var session = optSession.get();
|
||||||
@@ -50,8 +51,8 @@ public class EmailController extends Controller {
|
|||||||
var user = optUser.get();
|
var user = optUser.get();
|
||||||
sessions.extend(session, user);
|
sessions.extend(session, user);
|
||||||
|
|
||||||
switch (path) {
|
switch (path.pop()) {
|
||||||
case "/settings":
|
case "settings":
|
||||||
return saveSettings(ex, session);
|
return saveSettings(ex, session);
|
||||||
}
|
}
|
||||||
return notFound(ex);
|
return notFound(ex);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package de.srsoftware.oidc.backend;
|
|||||||
|
|
||||||
import com.sun.net.httpserver.HttpExchange;
|
import com.sun.net.httpserver.HttpExchange;
|
||||||
import de.srsoftware.oidc.api.KeyStorage;
|
import de.srsoftware.oidc.api.KeyStorage;
|
||||||
|
import de.srsoftware.tools.Path;
|
||||||
import de.srsoftware.tools.PathHandler;
|
import de.srsoftware.tools.PathHandler;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import org.jose4j.jwk.JsonWebKey;
|
import org.jose4j.jwk.JsonWebKey;
|
||||||
@@ -18,11 +19,8 @@ public class KeyStoreController extends PathHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doGet(String path, HttpExchange ex) throws IOException {
|
public boolean doGet(Path path, HttpExchange ex) throws IOException {
|
||||||
switch (path) {
|
if (path.isEmpty()) return jwksJson(ex);
|
||||||
case "/":
|
|
||||||
return jwksJson(ex);
|
|
||||||
}
|
|
||||||
return notFound(ex);
|
return notFound(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import de.srsoftware.oidc.api.*;
|
|||||||
import de.srsoftware.oidc.api.data.AccessToken;
|
import de.srsoftware.oidc.api.data.AccessToken;
|
||||||
import de.srsoftware.oidc.api.data.Client;
|
import de.srsoftware.oidc.api.data.Client;
|
||||||
import de.srsoftware.oidc.api.data.User;
|
import de.srsoftware.oidc.api.data.User;
|
||||||
|
import de.srsoftware.tools.Path;
|
||||||
import de.srsoftware.tools.PathHandler;
|
import de.srsoftware.tools.PathHandler;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
@@ -56,12 +57,9 @@ public class TokenController extends PathHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doPost(String path, HttpExchange ex) throws IOException {
|
public boolean doPost(Path path, HttpExchange ex) throws IOException {
|
||||||
// pre-login paths
|
// pre-login paths
|
||||||
switch (path) {
|
if (path.isEmpty()) return provideToken(ex);
|
||||||
case "/":
|
|
||||||
return provideToken(ex);
|
|
||||||
}
|
|
||||||
return notFound(ex);
|
return notFound(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import de.srsoftware.oidc.api.*;
|
|||||||
import de.srsoftware.oidc.api.data.Permission;
|
import de.srsoftware.oidc.api.data.Permission;
|
||||||
import de.srsoftware.oidc.api.data.Session;
|
import de.srsoftware.oidc.api.data.Session;
|
||||||
import de.srsoftware.oidc.api.data.User;
|
import de.srsoftware.oidc.api.data.User;
|
||||||
|
import de.srsoftware.tools.Path;
|
||||||
import de.srsoftware.tools.SessionToken;
|
import de.srsoftware.tools.SessionToken;
|
||||||
import de.srsoftware.tools.result.*;
|
import de.srsoftware.tools.result.*;
|
||||||
import jakarta.mail.*;
|
import jakarta.mail.*;
|
||||||
@@ -49,7 +50,7 @@ public class UserController extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doDelete(String path, HttpExchange ex) throws IOException {
|
public boolean doDelete(Path path, HttpExchange ex) throws IOException {
|
||||||
var optSession = getSession(ex);
|
var optSession = getSession(ex);
|
||||||
if (optSession.isEmpty()) return sendEmptyResponse(HTTP_UNAUTHORIZED, ex);
|
if (optSession.isEmpty()) return sendEmptyResponse(HTTP_UNAUTHORIZED, ex);
|
||||||
var session = optSession.get();
|
var session = optSession.get();
|
||||||
@@ -58,10 +59,10 @@ public class UserController extends Controller {
|
|||||||
var user = optUser.get();
|
var user = optUser.get();
|
||||||
sessions.extend(session, user);
|
sessions.extend(session, user);
|
||||||
|
|
||||||
switch (path) {
|
switch (path.pop()) {
|
||||||
case "/delete":
|
case "delete":
|
||||||
return deleteUser(ex, user);
|
return deleteUser(ex, user);
|
||||||
case "/permission":
|
case "permission":
|
||||||
return editPermission(ex, user, true);
|
return editPermission(ex, user, true);
|
||||||
}
|
}
|
||||||
return badRequest(ex, "%s not found".formatted(path));
|
return badRequest(ex, "%s not found".formatted(path));
|
||||||
@@ -82,11 +83,12 @@ public class UserController extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doGet(String path, HttpExchange ex) throws IOException {
|
public boolean doGet(Path path, HttpExchange ex) throws IOException {
|
||||||
switch (path) {
|
var part = path.pop();
|
||||||
case "/info":
|
switch (part) {
|
||||||
|
case "info":
|
||||||
return userInfo(ex);
|
return userInfo(ex);
|
||||||
case "/reset":
|
case "reset":
|
||||||
return generateResetLink(ex);
|
return generateResetLink(ex);
|
||||||
}
|
}
|
||||||
var optSession = getSession(ex);
|
var optSession = getSession(ex);
|
||||||
@@ -97,8 +99,8 @@ public class UserController extends Controller {
|
|||||||
var user = optUser.get();
|
var user = optUser.get();
|
||||||
sessions.extend(session, user);
|
sessions.extend(session, user);
|
||||||
|
|
||||||
switch (path) {
|
switch (part) {
|
||||||
case "/logout":
|
case "logout":
|
||||||
return logout(ex, session);
|
return logout(ex, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,11 +109,12 @@ public class UserController extends Controller {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doPost(String path, HttpExchange ex) throws IOException {
|
public boolean doPost(Path pathstack, HttpExchange ex) throws IOException {
|
||||||
|
var path = pathstack.toString();
|
||||||
switch (path) {
|
switch (path) {
|
||||||
case "/login":
|
case "login":
|
||||||
return login(ex);
|
return login(ex);
|
||||||
case "/reset":
|
case "reset":
|
||||||
return resetPassword(ex);
|
return resetPassword(ex);
|
||||||
}
|
}
|
||||||
var optSession = getSession(ex);
|
var optSession = getSession(ex);
|
||||||
@@ -123,17 +126,17 @@ public class UserController extends Controller {
|
|||||||
sessions.extend(session, user);
|
sessions.extend(session, user);
|
||||||
|
|
||||||
switch (path) {
|
switch (path) {
|
||||||
case "/":
|
case "":
|
||||||
return sendUserAndCookie(ex, session, user);
|
return sendUserAndCookie(ex, session, user);
|
||||||
case "/add":
|
case "add":
|
||||||
return addUser(ex, user);
|
return addUser(ex, user);
|
||||||
case "/list":
|
case "list":
|
||||||
return list(ex, user);
|
return list(ex, user);
|
||||||
case "/password":
|
case "password":
|
||||||
return updatePassword(ex, user);
|
return updatePassword(ex, user);
|
||||||
case "/permission":
|
case "permission":
|
||||||
return editPermission(ex, user, false);
|
return editPermission(ex, user, false);
|
||||||
case "/update":
|
case "update":
|
||||||
return updateUser(ex, user);
|
return updateUser(ex, user);
|
||||||
}
|
}
|
||||||
return notFound(ex);
|
return notFound(ex);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package de.srsoftware.oidc.backend;
|
|||||||
|
|
||||||
|
|
||||||
import com.sun.net.httpserver.HttpExchange;
|
import com.sun.net.httpserver.HttpExchange;
|
||||||
|
import de.srsoftware.tools.Path;
|
||||||
import de.srsoftware.tools.PathHandler;
|
import de.srsoftware.tools.PathHandler;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -10,9 +11,9 @@ import java.util.Map;
|
|||||||
|
|
||||||
public class WellKnownController extends PathHandler {
|
public class WellKnownController extends PathHandler {
|
||||||
@Override
|
@Override
|
||||||
public boolean doGet(String path, HttpExchange ex) throws IOException {
|
public boolean doGet(Path path, HttpExchange ex) throws IOException {
|
||||||
switch (path) {
|
switch (path.pop()) {
|
||||||
case "/openid-configuration":
|
case "openid-configuration":
|
||||||
return openidConfig(ex);
|
return openidConfig(ex);
|
||||||
}
|
}
|
||||||
return notFound(ex);
|
return notFound(ex);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
description = "SRSoftware OIDC: web module"
|
description = "SRSoftware OIDC: web module"
|
||||||
|
|
||||||
dependencies{
|
dependencies{
|
||||||
implementation("de.srsoftware:tools.http:1.3.0")
|
implementation("de.srsoftware:tools.http:1.5.4")
|
||||||
implementation(project(":de.srsoftware.oidc.api"))
|
implementation(project(":de.srsoftware.oidc.api"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ package de.srsoftware.oidc.web;
|
|||||||
import static java.lang.System.Logger.Level.INFO;
|
import static java.lang.System.Logger.Level.INFO;
|
||||||
|
|
||||||
import com.sun.net.httpserver.HttpExchange;
|
import com.sun.net.httpserver.HttpExchange;
|
||||||
|
import de.srsoftware.tools.Path;
|
||||||
import de.srsoftware.tools.PathHandler;
|
import de.srsoftware.tools.PathHandler;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@@ -16,7 +17,7 @@ public class Forward extends PathHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doGet(String path, HttpExchange ex) throws IOException {
|
public boolean doGet(Path path, HttpExchange ex) throws IOException {
|
||||||
LOG.log(INFO, "Forwarding ({0}}) {1} to {2}…", CODE, path, toPath);
|
LOG.log(INFO, "Forwarding ({0}}) {1} to {2}…", CODE, path, toPath);
|
||||||
return sendRedirect(ex, toPath);
|
return sendRedirect(ex, toPath);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,22 +26,20 @@ public class StaticPages extends PathHandler implements ResourceLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static final String INDEX = "en/index.html";
|
private static final String INDEX = "index.html";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doGet(String relativePath, HttpExchange ex) throws IOException {
|
public boolean doGet(de.srsoftware.tools.Path relativePath, HttpExchange ex) throws IOException {
|
||||||
|
var relPath = relativePath.toString();
|
||||||
String lang = language(ex);
|
String lang = language(ex);
|
||||||
if (relativePath.startsWith("/")) relativePath = relativePath.substring(1);
|
if (relPath.isBlank()) relPath = ex.getRequestURI().toString().endsWith(FAVICON) ? FAVICON : INDEX;
|
||||||
if (relativePath.isBlank()) {
|
|
||||||
relativePath = ex.getRequestURI().toString().endsWith(FAVICON) ? FAVICON : INDEX;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
Resource resource = loadFile(lang, relativePath).orElseThrow(() -> new FileNotFoundException());
|
Resource resource = loadFile(lang, relPath).orElseThrow(() -> new FileNotFoundException());
|
||||||
ex.getResponseHeaders().add(CONTENT_TYPE, resource.contentType());
|
ex.getResponseHeaders().add(CONTENT_TYPE, resource.contentType());
|
||||||
LOG.log(DEBUG, "Loaded {0} for language {1}…success.", relativePath, lang);
|
LOG.log(DEBUG, "Loaded {0} for language {1}…success.", relPath, lang);
|
||||||
return sendContent(ex, resource.content());
|
return sendContent(ex, resource.content());
|
||||||
} catch (FileNotFoundException fnf) {
|
} catch (FileNotFoundException fnf) {
|
||||||
LOG.log(WARNING, "Loaded {0} for language {1}…failed.", relativePath, lang);
|
LOG.log(WARNING, "Loaded {0} for language {1}…failed.", relPath, lang);
|
||||||
return notFound(ex);
|
return notFound(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
<span class="hidden" id="message">Really remove client "{}"?</span>
|
<span class="hidden" id="message">Benutzer "{}" wirklich löschen?</span>
|
||||||
<span class="error" style="display: none" id="missing_user_id">Server did not receive a valid user_id for removal!</span>
|
<span class="error" style="display: none" id="missing_user_id">Server did not receive a valid user_id for removal!</span>
|
||||||
<span class="error" style="display: none" id="missing_confirmation">Server did not receive confirmation for this request!</span>
|
<span class="error" style="display: none" id="missing_confirmation">Server did not receive confirmation for this request!</span>
|
||||||
<span class="error" style="display: none" id="unknown_user">The backend does not know this user!</span>
|
<span class="error" style="display: none" id="unknown_user">The backend does not know this user!</span>
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
<span class="hidden" id="message">Really remove client "{}"?</span>
|
<span class="hidden" id="message">Really remove user "{}"?</span>
|
||||||
<span class="error" style="display: none" id="missing_user_id">Server did not receive a valid user_id for removal!</span>
|
<span class="error" style="display: none" id="missing_user_id">Server did not receive a valid user_id for removal!</span>
|
||||||
<span class="error" style="display: none" id="missing_confirmation">Server did not receive confirmation for this request!</span>
|
<span class="error" style="display: none" id="missing_confirmation">Server did not receive confirmation for this request!</span>
|
||||||
<span class="error" style="display: none" id="unknown_user">The backend does not know this user!</span>
|
<span class="error" style="display: none" id="unknown_user">The backend does not know this user!</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user