diff --git a/frontend/src/routes/user/ConnectedServices.svelte b/frontend/src/routes/user/ConnectedServices.svelte
index 82a5786..b585d68 100644
--- a/frontend/src/routes/user/ConnectedServices.svelte
+++ b/frontend/src/routes/user/ConnectedServices.svelte
@@ -5,7 +5,7 @@
let connections = $state([]);
- onMount(async () => {
+ async function loadConnections(){
let url = `${location.protocol}//${location.host.replace('5173','8080')}/api/user/oidc/connected`;
let resp = await fetch(url,{credentials:'include'});
@@ -16,7 +16,23 @@
console.log(entry);
}
}
- });
+ }
+
+ onMount(loadConnections);
+
+ async function unlink(connection){
+ const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/user/oidc/connected`;
+ const resp = fetch(url,{
+ method: 'DELETE',
+ credentials: 'include',
+ body: JSON.stringify(connection)
+ });
+ if (resp.ok){
+ alert('succeeded');
+ } else {
+ alert('failed');
+ }
+ }
{#if connections.length>0}
@@ -36,7 +52,7 @@
{connection.service_id} |
{connection.foreign_id} |
-
+
|
{/each}
diff --git a/user/src/main/java/de/srsoftware/umbrella/user/UserModule.java b/user/src/main/java/de/srsoftware/umbrella/user/UserModule.java
index 2922124..ad87a62 100644
--- a/user/src/main/java/de/srsoftware/umbrella/user/UserModule.java
+++ b/user/src/main/java/de/srsoftware/umbrella/user/UserModule.java
@@ -20,6 +20,7 @@ import static java.net.HttpURLConnection.*;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.text.MessageFormat.format;
import static java.time.temporal.ChronoUnit.DAYS;
+import static javax.security.auth.callback.ConfirmationCallback.OK;
import com.sun.net.httpserver.HttpExchange;
import de.srsoftware.tools.Path;
@@ -81,11 +82,59 @@ public class UserModule extends PathHandler {
headers.add("Access-Control-Allow-Origin", url);
headers.add("Access-Control-Allow-Headers", "Content-Type");
headers.add("Access-Control-Allow-Credentials", "true");
- headers.add("Access-Control-Allow-Methods","GET, POST, PATCH");
+ headers.add("Access-Control-Allow-Methods","DELETE, GET, POST, PATCH");
}
return ex;
}
+ private boolean deleteOIDC(HttpExchange ex, UmbrellaUser user, Path path) throws IOException {
+ var head = path.pop();
+ return switch (head){
+ case CONNECTED -> deleteServiceConnection(ex,user);
+ case null, default -> super.doGet(path,ex);
+ };
+ }
+
+ private boolean deleteServiceConnection(HttpExchange ex, UmbrellaUser user) throws IOException {
+ if (user == null) return sendContent(ex,HTTP_SERVER_ERROR,"Expected user object to be of type DbUser");
+ JSONObject json;
+ try {
+ json = json(ex);
+ } catch (Exception e){
+ LOG.log(WARNING,"Request does not contain valid JSON",e);
+ return sendContent(ex,HTTP_FAILED_DEPENDENCY,"Request does not contain valid JSON");
+ }
+ if (!(json.has(FOREIGN_ID) && json.get(FOREIGN_ID) instanceof String foreignId && !foreignId.isBlank())) return sendContent(ex,HTTP_UNPROCESSABLE,format(ERROR_MISSING_FIELD,FOREIGN_ID));
+ if (!(json.has(SERVICE_ID) && json.get(SERVICE_ID) instanceof String serviceId && !serviceId.isBlank())) return sendContent(ex,HTTP_UNPROCESSABLE,format(ERROR_MISSING_FIELD,SERVICE_ID));
+
+
+ try {
+ logins.unlink(ForeignLogin.of(serviceId,foreignId,user.id()));
+ return sendEmptyResponse(OK,ex);
+ } catch (UmbrellaException e) {
+ return send(ex,e);
+ }
+
+ }
+
+ @Override
+ public boolean doDelete(Path path, HttpExchange ex) throws IOException {
+ UmbrellaUser user = null;
+ var sessionToken = SessionToken.from(ex).map(Token::of);
+ if (sessionToken.isPresent()) try {
+ user = users.load(users.load(sessionToken.get()));
+ } catch (UmbrellaException e) {
+ LOG.log(WARNING,e);
+ }
+ addCors(ex);
+ var head = path.pop();
+ switch (head) {
+ case OIDC: return deleteOIDC(ex,user,path);
+
+ };
+ return super.doDelete(path, ex);
+ }
+
@Override
public boolean doGet(Path path, HttpExchange ex) throws IOException {
UmbrellaUser user = null;