]> nmode's Git Repositories - signal-cli/blobdiff - src/main/java/org/asamk/signal/jsonrpc/SignalJsonRpcDispatcherHandler.java
Cache group credentials in memory
[signal-cli] / src / main / java / org / asamk / signal / jsonrpc / SignalJsonRpcDispatcherHandler.java
index c4e9775aefb52f273e378286d830427a15fbf8c0..23c89f26ef810c596a7bf8bbb595b204675b1e1f 100644 (file)
@@ -8,8 +8,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ContainerNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 
-import org.asamk.signal.JsonReceiveMessageHandler;
-import org.asamk.signal.JsonWriter;
 import org.asamk.signal.commands.Command;
 import org.asamk.signal.commands.Commands;
 import org.asamk.signal.commands.JsonRpcMultiCommand;
@@ -19,9 +17,11 @@ import org.asamk.signal.commands.exceptions.CommandException;
 import org.asamk.signal.commands.exceptions.IOErrorException;
 import org.asamk.signal.commands.exceptions.UntrustedKeyErrorException;
 import org.asamk.signal.commands.exceptions.UserErrorException;
+import org.asamk.signal.json.JsonReceiveMessageHandler;
 import org.asamk.signal.manager.Manager;
 import org.asamk.signal.manager.MultiAccountManager;
 import org.asamk.signal.manager.RegistrationManager;
+import org.asamk.signal.output.JsonWriter;
 import org.asamk.signal.util.Util;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -64,6 +64,8 @@ public class SignalJsonRpcDispatcherHandler {
 
         if (!noReceiveOnStart) {
             c.getAccountNumbers().stream().map(c::getManager).filter(Objects::nonNull).forEach(this::subscribeReceive);
+            c.addOnManagerAddedHandler(this::subscribeReceive);
+            c.addOnManagerRemovedHandler(this::unsubscribeReceive);
         }
 
         handleConnection();
@@ -76,6 +78,9 @@ public class SignalJsonRpcDispatcherHandler {
             subscribeReceive(m);
         }
 
+        final var currentThread = Thread.currentThread();
+        m.addClosedListener(currentThread::interrupt);
+
         handleConnection();
     }
 
@@ -264,22 +269,35 @@ public class SignalJsonRpcDispatcherHandler {
                     e.getMessage(),
                     null));
         } catch (UserErrorException e) {
-            throw new JsonRpcException(new JsonRpcResponse.Error(USER_ERROR, e.getMessage(), null));
+            throw new JsonRpcException(new JsonRpcResponse.Error(USER_ERROR,
+                    e.getMessage(),
+                    getErrorDataNode(objectMapper, result)));
         } catch (IOErrorException e) {
-            throw new JsonRpcException(new JsonRpcResponse.Error(IO_ERROR, e.getMessage(), null));
+            throw new JsonRpcException(new JsonRpcResponse.Error(IO_ERROR,
+                    e.getMessage(),
+                    getErrorDataNode(objectMapper, result)));
         } catch (UntrustedKeyErrorException e) {
-            throw new JsonRpcException(new JsonRpcResponse.Error(UNTRUSTED_KEY_ERROR, e.getMessage(), null));
+            throw new JsonRpcException(new JsonRpcResponse.Error(UNTRUSTED_KEY_ERROR,
+                    e.getMessage(),
+                    getErrorDataNode(objectMapper, result)));
         } catch (Throwable e) {
             logger.error("Command execution failed", e);
             throw new JsonRpcException(new JsonRpcResponse.Error(JsonRpcResponse.Error.INTERNAL_ERROR,
                     e.getMessage(),
-                    null));
+                    getErrorDataNode(objectMapper, result)));
         }
 
         Object output = result[0] == null ? Map.of() : result[0];
         return objectMapper.valueToTree(output);
     }
 
+    private JsonNode getErrorDataNode(final ObjectMapper objectMapper, final Object[] result) {
+        if (result[0] == null) {
+            return null;
+        }
+        return objectMapper.valueToTree(Map.of("response", result[0]));
+    }
+
     private <T> void parseParamsAndRunCommand(
             final ObjectMapper objectMapper,
             final TreeNode params,