X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/b7005884fdcfa8d95f54e557ddbf2fe4201962f8..80befec5893fcd75131b7ef65196bb86c2e836b5:/src/main/java/org/asamk/signal/jsonrpc/SignalJsonRpcDispatcherHandler.java diff --git a/src/main/java/org/asamk/signal/jsonrpc/SignalJsonRpcDispatcherHandler.java b/src/main/java/org/asamk/signal/jsonrpc/SignalJsonRpcDispatcherHandler.java index c4e9775a..8d13ad28 100644 --- a/src/main/java/org/asamk/signal/jsonrpc/SignalJsonRpcDispatcherHandler.java +++ b/src/main/java/org/asamk/signal/jsonrpc/SignalJsonRpcDispatcherHandler.java @@ -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,14 +17,17 @@ 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; import java.io.IOException; +import java.nio.channels.OverlappingFileLockException; import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -64,6 +65,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 +79,9 @@ public class SignalJsonRpcDispatcherHandler { subscribeReceive(m); } + final var currentThread = Thread.currentThread(); + m.addClosedListener(currentThread::interrupt); + handleConnection(); } @@ -177,6 +183,9 @@ public class SignalJsonRpcDispatcherHandler { final var registrationManager = c.getNewRegistrationManager(params.get("account").asText()); ((ObjectNode) params).remove("account"); return registrationManager; + } catch (OverlappingFileLockException e) { + logger.warn("Account is already in use"); + return null; } catch (IOException | IllegalStateException e) { logger.warn("Failed to load registration manager", e); return null; @@ -264,22 +273,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 void parseParamsAndRunCommand( final ObjectMapper objectMapper, final TreeNode params,