diff --git a/lib/src/main/java/org/asamk/signal/manager/SignalAccountFiles.java b/lib/src/main/java/org/asamk/signal/manager/SignalAccountFiles.java index 82b73495..9ce9e313 100644 --- a/lib/src/main/java/org/asamk/signal/manager/SignalAccountFiles.java +++ b/lib/src/main/java/org/asamk/signal/manager/SignalAccountFiles.java @@ -5,6 +5,7 @@ import org.asamk.signal.manager.api.NotRegisteredException; import org.asamk.signal.manager.api.Pair; import org.asamk.signal.manager.api.ServiceEnvironment; import org.asamk.signal.manager.config.ServiceConfig; +import org.signal.core.models.ServiceId.ACI; import org.asamk.signal.manager.config.ServiceEnvironmentConfig; import org.asamk.signal.manager.internal.AccountFileUpdaterImpl; import org.asamk.signal.manager.internal.ManagerImpl; @@ -95,6 +96,30 @@ public class SignalAccountFiles { return this.initManager(number, accountPath); } + public String getAccountNumberByAci(final String aciStr) throws IOException { + final var accounts = accountsStore.getAllAccounts(); + final var account = accounts.stream() + .filter(a -> aciStr.equals(a.uuid())) + .findFirst() + .orElse(null); + if (account == null || account.number() == null) { + return null; + } + return account.number(); + } + + public Manager initManagerByAci(String aciStr) throws IOException, NotRegisteredException, AccountCheckException { + final var phoneNumber = getAccountNumberByAci(aciStr); + if (phoneNumber == null) { + throw new NotRegisteredException(); + } + final var accountPath = accountsStore.getPathByNumber(phoneNumber); + if (accountPath == null) { + throw new NotRegisteredException(); + } + return this.initManager(phoneNumber, accountPath); + } + private Manager initManager( String number, String accountPath diff --git a/lib/src/main/java/org/asamk/signal/manager/internal/MultiAccountManagerImpl.java b/lib/src/main/java/org/asamk/signal/manager/internal/MultiAccountManagerImpl.java index 24ecae61..3adefbef 100644 --- a/lib/src/main/java/org/asamk/signal/manager/internal/MultiAccountManagerImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/internal/MultiAccountManagerImpl.java @@ -8,6 +8,7 @@ import org.asamk.signal.manager.SignalAccountFiles; import org.asamk.signal.manager.api.AccountCheckException; import org.asamk.signal.manager.api.NotRegisteredException; import org.slf4j.Logger; +import org.signal.core.util.UuidUtil; import org.slf4j.LoggerFactory; import java.io.IOException; @@ -95,23 +96,54 @@ public class MultiAccountManagerImpl implements MultiAccountManager { } @Override - public Manager getManager(final String number) { + public Manager getManager(final String identifier) { synchronized (managers) { - final var manager = managers.stream() - .filter(m -> m.getSelfNumber().equals(number)) - .findFirst() - .orElse(null); - if (manager != null) { - return manager; - } - try { - final var newManager = signalAccountFiles.initManager(number); - managers.add(newManager); - return newManager; - } catch (IOException | NotRegisteredException | AccountCheckException e) { - logger.warn("Failed to load new manager", e); - return null; + if (UuidUtil.INSTANCE.isUuid(identifier)) { + // Check if UUID corresponds to an already-loaded manager + try { + final var phoneNumber = signalAccountFiles.getAccountNumberByAci(identifier); + if (phoneNumber != null) { + final var existing = managers.stream() + .filter(m -> m.getSelfNumber().equals(phoneNumber)) + .findFirst() + .orElse(null); + if (existing != null) { + logger.debug("Found already loaded manager for ACI: {}", identifier); + return existing; + } + } + } catch (IOException e) { + logger.warn("Failed to lookup ACI in accounts: {}", identifier, e); + } + // Load by ACI + try { + final var newManager = signalAccountFiles.initManagerByAci(identifier); + managers.add(newManager); + return newManager; + } catch (NotRegisteredException e) { + logger.debug("Manager not found by ACI: {}", identifier); + } catch (IOException | IllegalArgumentException | AccountCheckException e) { + logger.warn("Failed to load new manager by ACI: {}", identifier, e); + } + } else { + // Phone number — check already loaded managers + var existing = managers.stream() + .filter(m -> m.getSelfNumber().equals(identifier)) + .findFirst() + .orElse(null); + if (existing != null) { + return existing; + } + // Load by phone number + try { + final var newManager = signalAccountFiles.initManager(identifier); + managers.add(newManager); + return newManager; + } catch (NotRegisteredException | IOException | IllegalArgumentException | AccountCheckException e) { + logger.warn("Failed to load manager by number: {}", identifier, e); + } } + return null; } } diff --git a/src/main/java/org/asamk/signal/http/HttpServerHandler.java b/src/main/java/org/asamk/signal/http/HttpServerHandler.java index a6fc9f9e..c797e22a 100644 --- a/src/main/java/org/asamk/signal/http/HttpServerHandler.java +++ b/src/main/java/org/asamk/signal/http/HttpServerHandler.java @@ -262,6 +262,9 @@ public class HttpServerHandler implements AutoCloseable { } else { final var manager = c.getManager(account); if (manager == null) { + // Account not found by the given identifier (number or ACI/UUID) + // Log the available accounts to help debug + logger.warn("Account not found for identifier: {}", account); return null; } return List.of(manager); diff --git a/src/main/java/org/asamk/signal/util/Util.java b/src/main/java/org/asamk/signal/util/Util.java index 585c5690..76e41fa7 100644 --- a/src/main/java/org/asamk/signal/util/Util.java +++ b/src/main/java/org/asamk/signal/util/Util.java @@ -79,7 +79,7 @@ public class Util { for (var param : params) { final var paramParts = param.split("=", 2); var name = URLDecoder.decode(paramParts[0], StandardCharsets.UTF_8); - var value = paramParts.length == 1 ? null : URLDecoder.decode(paramParts[1], StandardCharsets.UTF_8); + var value = paramParts.length == 1 ? null : URLDecoder.decode(paramParts[1].replace("+", "%2B"), StandardCharsets.UTF_8); map.put(name, value); } return map;