Added logging to the websocket connections
This commit is contained in:
parent
f6d81e3c05
commit
b571b08660
@ -1,53 +1,129 @@
|
|||||||
package org.asamk.signal.manager.config;
|
package org.asamk.signal.manager.config;
|
||||||
|
|
||||||
import org.asamk.signal.manager.api.ServiceEnvironment;
|
|
||||||
import org.signal.libsignal.protocol.util.Medium;
|
|
||||||
import org.whispersystems.signalservice.api.account.AccountAttributes;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import okhttp3.Interceptor;
|
import okhttp3.Interceptor;
|
||||||
|
import org.asamk.signal.manager.api.ServiceEnvironment;
|
||||||
|
import org.signal.libsignal.protocol.util.Medium;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.whispersystems.signalservice.api.account.AccountAttributes;
|
||||||
|
|
||||||
public class ServiceConfig {
|
public class ServiceConfig {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(
|
||||||
|
ServiceConfig.class
|
||||||
|
);
|
||||||
|
|
||||||
public static final int PREKEY_MINIMUM_COUNT = 10;
|
public static final int PREKEY_MINIMUM_COUNT = 10;
|
||||||
public static final int PREKEY_BATCH_SIZE = 100;
|
public static final int PREKEY_BATCH_SIZE = 100;
|
||||||
public static final int PREKEY_MAXIMUM_ID = Medium.MAX_VALUE;
|
public static final int PREKEY_MAXIMUM_ID = Medium.MAX_VALUE;
|
||||||
public static final long PREKEY_ARCHIVE_AGE = TimeUnit.DAYS.toMillis(30);
|
public static final long PREKEY_ARCHIVE_AGE = TimeUnit.DAYS.toMillis(30);
|
||||||
public static final long PREKEY_STALE_AGE = TimeUnit.DAYS.toMillis(90);
|
public static final long PREKEY_STALE_AGE = TimeUnit.DAYS.toMillis(90);
|
||||||
public static final long SIGNED_PREKEY_ROTATE_AGE = TimeUnit.DAYS.toMillis(2);
|
public static final long SIGNED_PREKEY_ROTATE_AGE = TimeUnit.DAYS.toMillis(
|
||||||
|
2
|
||||||
|
);
|
||||||
|
|
||||||
public static final int MAX_ATTACHMENT_SIZE = 150 * 1024 * 1024;
|
public static final int MAX_ATTACHMENT_SIZE = 150 * 1024 * 1024;
|
||||||
public static final long MAX_ENVELOPE_SIZE = 0;
|
public static final long MAX_ENVELOPE_SIZE = 0;
|
||||||
public static final int MAX_MESSAGE_SIZE_BYTES = 2000;
|
public static final int MAX_MESSAGE_SIZE_BYTES = 2000;
|
||||||
public static final long AVATAR_DOWNLOAD_FAILSAFE_MAX_SIZE = 10 * 1024 * 1024;
|
public static final long AVATAR_DOWNLOAD_FAILSAFE_MAX_SIZE =
|
||||||
|
10 * 1024 * 1024;
|
||||||
public static final boolean AUTOMATIC_NETWORK_RETRY = true;
|
public static final boolean AUTOMATIC_NETWORK_RETRY = true;
|
||||||
public static final int GROUP_MAX_SIZE = 1001;
|
public static final int GROUP_MAX_SIZE = 1001;
|
||||||
public static final int MAXIMUM_ONE_OFF_REQUEST_SIZE = 3;
|
public static final int MAXIMUM_ONE_OFF_REQUEST_SIZE = 3;
|
||||||
public static final long UNREGISTERED_LIFESPAN = TimeUnit.DAYS.toMillis(30);
|
public static final long UNREGISTERED_LIFESPAN = TimeUnit.DAYS.toMillis(30);
|
||||||
|
|
||||||
public static AccountAttributes.Capabilities getCapabilities(boolean isPrimaryDevice) {
|
public static AccountAttributes.Capabilities getCapabilities(
|
||||||
|
boolean isPrimaryDevice
|
||||||
|
) {
|
||||||
final var deleteSync = !isPrimaryDevice;
|
final var deleteSync = !isPrimaryDevice;
|
||||||
final var storageEncryptionV2 = !isPrimaryDevice;
|
final var storageEncryptionV2 = !isPrimaryDevice;
|
||||||
final var attachmentBackfill = !isPrimaryDevice;
|
final var attachmentBackfill = !isPrimaryDevice;
|
||||||
return new AccountAttributes.Capabilities(true, deleteSync, true, storageEncryptionV2, attachmentBackfill);
|
return new AccountAttributes.Capabilities(
|
||||||
|
true,
|
||||||
|
deleteSync,
|
||||||
|
true,
|
||||||
|
storageEncryptionV2,
|
||||||
|
attachmentBackfill
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ServiceEnvironmentConfig getServiceEnvironmentConfig(
|
public static ServiceEnvironmentConfig getServiceEnvironmentConfig(
|
||||||
ServiceEnvironment serviceEnvironment,
|
ServiceEnvironment serviceEnvironment,
|
||||||
String userAgent
|
String userAgent
|
||||||
) {
|
) {
|
||||||
final Interceptor userAgentInterceptor = chain -> chain.proceed(chain.request()
|
final Interceptor userAgentInterceptor = chain ->
|
||||||
.newBuilder()
|
chain.proceed(
|
||||||
.header("User-Agent", userAgent)
|
chain
|
||||||
.build());
|
.request()
|
||||||
|
.newBuilder()
|
||||||
|
.header("User-Agent", userAgent)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
|
||||||
final var interceptors = List.of(userAgentInterceptor);
|
final Interceptor webSocketLoggingInterceptor = chain -> {
|
||||||
|
var request = chain.request();
|
||||||
|
var response = chain.proceed(request);
|
||||||
|
|
||||||
|
// Check if this is a WebSocket connection attempt by URL pattern or headers
|
||||||
|
String url = request.url().toString();
|
||||||
|
boolean isWebSocketRequest =
|
||||||
|
url.contains("/v1/websocket") ||
|
||||||
|
"websocket".equalsIgnoreCase(request.header("Upgrade")) ||
|
||||||
|
"Upgrade".equalsIgnoreCase(request.header("Connection"));
|
||||||
|
|
||||||
|
if (isWebSocketRequest) {
|
||||||
|
logger.info(
|
||||||
|
"=== WebSocket Connection HTTP Response ===\nURL: {}\nMethod: {}\nStatus: {} {}\nRequest Headers: {}\nResponse Headers: {}",
|
||||||
|
request.url(),
|
||||||
|
request.method(),
|
||||||
|
response.code(),
|
||||||
|
response.message(),
|
||||||
|
request.headers(),
|
||||||
|
response.headers()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Log specific WebSocket-related headers
|
||||||
|
var upgradeHeader = response.header("Upgrade");
|
||||||
|
var connectionHeader = response.header("Connection");
|
||||||
|
var acceptHeader = response.header("Sec-WebSocket-Accept");
|
||||||
|
var protocolHeader = response.header("Sec-WebSocket-Protocol");
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
"WebSocket Upgrade Details:\n Upgrade: {}\n Connection: {}\n Sec-WebSocket-Accept: {}\n Sec-WebSocket-Protocol: {}",
|
||||||
|
upgradeHeader,
|
||||||
|
connectionHeader,
|
||||||
|
acceptHeader,
|
||||||
|
protocolHeader
|
||||||
|
);
|
||||||
|
|
||||||
|
// Log success or failure
|
||||||
|
if (response.code() == 101) {
|
||||||
|
logger.info("✅ WebSocket upgrade successful!");
|
||||||
|
} else {
|
||||||
|
logger.warn(
|
||||||
|
"❌ WebSocket upgrade failed with status: {} {}",
|
||||||
|
response.code(),
|
||||||
|
response.message()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
logger.info("=== End WebSocket Connection Log ===");
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
};
|
||||||
|
|
||||||
|
final var interceptors = List.of(
|
||||||
|
userAgentInterceptor,
|
||||||
|
webSocketLoggingInterceptor
|
||||||
|
);
|
||||||
|
|
||||||
return switch (serviceEnvironment) {
|
return switch (serviceEnvironment) {
|
||||||
case LIVE -> LiveConfig.getServiceEnvironmentConfig(interceptors);
|
case LIVE -> LiveConfig.getServiceEnvironmentConfig(interceptors);
|
||||||
case STAGING -> StagingConfig.getServiceEnvironmentConfig(interceptors);
|
case STAGING -> StagingConfig.getServiceEnvironmentConfig(
|
||||||
|
interceptors
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,13 @@
|
|||||||
package org.asamk.signal.manager.internal;
|
package org.asamk.signal.manager.internal;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Proxy;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Supplier;
|
||||||
import org.asamk.signal.manager.config.ServiceConfig;
|
import org.asamk.signal.manager.config.ServiceConfig;
|
||||||
import org.asamk.signal.manager.config.ServiceEnvironmentConfig;
|
import org.asamk.signal.manager.config.ServiceEnvironmentConfig;
|
||||||
import org.asamk.signal.manager.util.Utils;
|
import org.asamk.signal.manager.util.Utils;
|
||||||
@ -41,18 +49,11 @@ import org.whispersystems.signalservice.api.websocket.SignalWebSocket;
|
|||||||
import org.whispersystems.signalservice.internal.push.PushServiceSocket;
|
import org.whispersystems.signalservice.internal.push.PushServiceSocket;
|
||||||
import org.whispersystems.signalservice.internal.websocket.OkHttpWebSocketConnection;
|
import org.whispersystems.signalservice.internal.websocket.OkHttpWebSocketConnection;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.Proxy;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
public class SignalDependencies {
|
public class SignalDependencies {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(SignalDependencies.class);
|
private static final Logger logger = LoggerFactory.getLogger(
|
||||||
|
SignalDependencies.class
|
||||||
|
);
|
||||||
|
|
||||||
private final Object LOCK = new Object();
|
private final Object LOCK = new Object();
|
||||||
|
|
||||||
@ -93,12 +94,12 @@ public class SignalDependencies {
|
|||||||
private ProfileApi profileApi;
|
private ProfileApi profileApi;
|
||||||
|
|
||||||
SignalDependencies(
|
SignalDependencies(
|
||||||
final ServiceEnvironmentConfig serviceEnvironmentConfig,
|
final ServiceEnvironmentConfig serviceEnvironmentConfig,
|
||||||
final String userAgent,
|
final String userAgent,
|
||||||
final CredentialsProvider credentialsProvider,
|
final CredentialsProvider credentialsProvider,
|
||||||
final SignalServiceDataStore dataStore,
|
final SignalServiceDataStore dataStore,
|
||||||
final ExecutorService executor,
|
final ExecutorService executor,
|
||||||
final SignalSessionLock sessionLock
|
final SignalSessionLock sessionLock
|
||||||
) {
|
) {
|
||||||
this.serviceEnvironmentConfig = serviceEnvironmentConfig;
|
this.serviceEnvironmentConfig = serviceEnvironmentConfig;
|
||||||
this.userAgent = userAgent;
|
this.userAgent = userAgent;
|
||||||
@ -144,36 +145,58 @@ public class SignalDependencies {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public PushServiceSocket getPushServiceSocket() {
|
public PushServiceSocket getPushServiceSocket() {
|
||||||
return getOrCreate(() -> pushServiceSocket,
|
return getOrCreate(
|
||||||
() -> pushServiceSocket = new PushServiceSocket(serviceEnvironmentConfig.signalServiceConfiguration(),
|
() -> pushServiceSocket,
|
||||||
credentialsProvider,
|
() ->
|
||||||
userAgent,
|
pushServiceSocket = new PushServiceSocket(
|
||||||
ServiceConfig.AUTOMATIC_NETWORK_RETRY));
|
serviceEnvironmentConfig.signalServiceConfiguration(),
|
||||||
|
credentialsProvider,
|
||||||
|
userAgent,
|
||||||
|
ServiceConfig.AUTOMATIC_NETWORK_RETRY
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Network getLibSignalNetwork() {
|
public Network getLibSignalNetwork() {
|
||||||
return getOrCreate(() -> libSignalNetwork, () -> {
|
return getOrCreate(
|
||||||
libSignalNetwork = new Network(serviceEnvironmentConfig.netEnvironment(), userAgent);
|
() -> libSignalNetwork,
|
||||||
setSignalNetworkProxy(libSignalNetwork);
|
() -> {
|
||||||
});
|
libSignalNetwork = new Network(
|
||||||
|
serviceEnvironmentConfig.netEnvironment(),
|
||||||
|
userAgent
|
||||||
|
);
|
||||||
|
setSignalNetworkProxy(libSignalNetwork);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setSignalNetworkProxy(Network libSignalNetwork) {
|
private void setSignalNetworkProxy(Network libSignalNetwork) {
|
||||||
final var proxy = Utils.getHttpsProxy();
|
final var proxy = Utils.getHttpsProxy();
|
||||||
if (proxy.address() instanceof InetSocketAddress addr) {
|
if (proxy.address() instanceof InetSocketAddress addr) {
|
||||||
switch (proxy.type()) {
|
switch (proxy.type()) {
|
||||||
case Proxy.Type.DIRECT -> {
|
case Proxy.Type.DIRECT -> {}
|
||||||
}
|
|
||||||
case Proxy.Type.HTTP -> {
|
case Proxy.Type.HTTP -> {
|
||||||
try {
|
try {
|
||||||
libSignalNetwork.setProxy("http", addr.getHostName(), addr.getPort(), null, null);
|
libSignalNetwork.setProxy(
|
||||||
|
"http",
|
||||||
|
addr.getHostName(),
|
||||||
|
addr.getPort(),
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("Failed to set http proxy", e);
|
logger.warn("Failed to set http proxy", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case Proxy.Type.SOCKS -> {
|
case Proxy.Type.SOCKS -> {
|
||||||
try {
|
try {
|
||||||
libSignalNetwork.setProxy("socks", addr.getHostName(), addr.getPort(), null, null);
|
libSignalNetwork.setProxy(
|
||||||
|
"socks",
|
||||||
|
addr.getHostName(),
|
||||||
|
addr.getPort(),
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("Failed to set socks proxy", e);
|
logger.warn("Failed to set socks proxy", e);
|
||||||
}
|
}
|
||||||
@ -183,59 +206,102 @@ public class SignalDependencies {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SignalServiceAccountManager getAccountManager() {
|
public SignalServiceAccountManager getAccountManager() {
|
||||||
return getOrCreate(() -> accountManager,
|
return getOrCreate(
|
||||||
() -> accountManager = new SignalServiceAccountManager(getAuthenticatedSignalWebSocket(),
|
() -> accountManager,
|
||||||
getAccountApi(),
|
() ->
|
||||||
getPushServiceSocket(),
|
accountManager = new SignalServiceAccountManager(
|
||||||
getGroupsV2Operations()));
|
getAuthenticatedSignalWebSocket(),
|
||||||
|
getAccountApi(),
|
||||||
|
getPushServiceSocket(),
|
||||||
|
getGroupsV2Operations()
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SignalServiceAccountManager createUnauthenticatedAccountManager(String number, String password) {
|
public SignalServiceAccountManager createUnauthenticatedAccountManager(
|
||||||
return SignalServiceAccountManager.createWithStaticCredentials(getServiceEnvironmentConfig().signalServiceConfiguration(),
|
String number,
|
||||||
null,
|
String password
|
||||||
null,
|
) {
|
||||||
number,
|
return SignalServiceAccountManager.createWithStaticCredentials(
|
||||||
SignalServiceAddress.DEFAULT_DEVICE_ID,
|
getServiceEnvironmentConfig().signalServiceConfiguration(),
|
||||||
password,
|
null,
|
||||||
userAgent,
|
null,
|
||||||
ServiceConfig.AUTOMATIC_NETWORK_RETRY,
|
number,
|
||||||
ServiceConfig.GROUP_MAX_SIZE);
|
SignalServiceAddress.DEFAULT_DEVICE_ID,
|
||||||
|
password,
|
||||||
|
userAgent,
|
||||||
|
ServiceConfig.AUTOMATIC_NETWORK_RETRY,
|
||||||
|
ServiceConfig.GROUP_MAX_SIZE
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AccountApi getAccountApi() {
|
public AccountApi getAccountApi() {
|
||||||
return getOrCreate(() -> accountApi, () -> accountApi = new AccountApi(getAuthenticatedSignalWebSocket()));
|
return getOrCreate(
|
||||||
|
() -> accountApi,
|
||||||
|
() -> accountApi = new AccountApi(getAuthenticatedSignalWebSocket())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RateLimitChallengeApi getRateLimitChallengeApi() {
|
public RateLimitChallengeApi getRateLimitChallengeApi() {
|
||||||
return getOrCreate(() -> rateLimitChallengeApi,
|
return getOrCreate(
|
||||||
() -> rateLimitChallengeApi = new RateLimitChallengeApi(getAuthenticatedSignalWebSocket()));
|
() -> rateLimitChallengeApi,
|
||||||
|
() ->
|
||||||
|
rateLimitChallengeApi = new RateLimitChallengeApi(
|
||||||
|
getAuthenticatedSignalWebSocket()
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CdsApi getCdsApi() {
|
public CdsApi getCdsApi() {
|
||||||
return getOrCreate(() -> cdsApi, () -> cdsApi = new CdsApi(getAuthenticatedSignalWebSocket()));
|
return getOrCreate(
|
||||||
|
() -> cdsApi,
|
||||||
|
() -> cdsApi = new CdsApi(getAuthenticatedSignalWebSocket())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UsernameApi getUsernameApi() {
|
public UsernameApi getUsernameApi() {
|
||||||
return getOrCreate(() -> usernameApi, () -> usernameApi = new UsernameApi(getUnauthenticatedSignalWebSocket()));
|
return getOrCreate(
|
||||||
|
() -> usernameApi,
|
||||||
|
() ->
|
||||||
|
usernameApi = new UsernameApi(
|
||||||
|
getUnauthenticatedSignalWebSocket()
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GroupsV2Api getGroupsV2Api() {
|
public GroupsV2Api getGroupsV2Api() {
|
||||||
return getOrCreate(() -> groupsV2Api, () -> groupsV2Api = getAccountManager().getGroupsV2Api());
|
return getOrCreate(
|
||||||
|
() -> groupsV2Api,
|
||||||
|
() -> groupsV2Api = getAccountManager().getGroupsV2Api()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegistrationApi getRegistrationApi() {
|
public RegistrationApi getRegistrationApi() {
|
||||||
return getOrCreate(() -> registrationApi, () -> registrationApi = getAccountManager().getRegistrationApi());
|
return getOrCreate(
|
||||||
|
() -> registrationApi,
|
||||||
|
() -> registrationApi = getAccountManager().getRegistrationApi()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LinkDeviceApi getLinkDeviceApi() {
|
public LinkDeviceApi getLinkDeviceApi() {
|
||||||
return getOrCreate(() -> linkDeviceApi,
|
return getOrCreate(
|
||||||
() -> linkDeviceApi = new LinkDeviceApi(getAuthenticatedSignalWebSocket()));
|
() -> linkDeviceApi,
|
||||||
|
() ->
|
||||||
|
linkDeviceApi = new LinkDeviceApi(
|
||||||
|
getAuthenticatedSignalWebSocket()
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private StorageServiceApi getStorageServiceApi() {
|
private StorageServiceApi getStorageServiceApi() {
|
||||||
return getOrCreate(() -> storageServiceApi,
|
return getOrCreate(
|
||||||
() -> storageServiceApi = new StorageServiceApi(getAuthenticatedSignalWebSocket(),
|
() -> storageServiceApi,
|
||||||
getPushServiceSocket()));
|
() ->
|
||||||
|
storageServiceApi = new StorageServiceApi(
|
||||||
|
getAuthenticatedSignalWebSocket(),
|
||||||
|
getPushServiceSocket()
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StorageServiceRepository getStorageServiceRepository() {
|
public StorageServiceRepository getStorageServiceRepository() {
|
||||||
@ -243,35 +309,69 @@ public class SignalDependencies {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CertificateApi getCertificateApi() {
|
public CertificateApi getCertificateApi() {
|
||||||
return getOrCreate(() -> certificateApi,
|
return getOrCreate(
|
||||||
() -> certificateApi = new CertificateApi(getAuthenticatedSignalWebSocket()));
|
() -> certificateApi,
|
||||||
|
() ->
|
||||||
|
certificateApi = new CertificateApi(
|
||||||
|
getAuthenticatedSignalWebSocket()
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AttachmentApi getAttachmentApi() {
|
public AttachmentApi getAttachmentApi() {
|
||||||
return getOrCreate(() -> attachmentApi,
|
return getOrCreate(
|
||||||
() -> attachmentApi = new AttachmentApi(getAuthenticatedSignalWebSocket(), getPushServiceSocket()));
|
() -> attachmentApi,
|
||||||
|
() ->
|
||||||
|
attachmentApi = new AttachmentApi(
|
||||||
|
getAuthenticatedSignalWebSocket(),
|
||||||
|
getPushServiceSocket()
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MessageApi getMessageApi() {
|
public MessageApi getMessageApi() {
|
||||||
return getOrCreate(() -> messageApi,
|
return getOrCreate(
|
||||||
() -> messageApi = new MessageApi(getAuthenticatedSignalWebSocket(),
|
() -> messageApi,
|
||||||
getUnauthenticatedSignalWebSocket()));
|
() ->
|
||||||
|
messageApi = new MessageApi(
|
||||||
|
getAuthenticatedSignalWebSocket(),
|
||||||
|
getUnauthenticatedSignalWebSocket()
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeysApi getKeysApi() {
|
public KeysApi getKeysApi() {
|
||||||
return getOrCreate(() -> keysApi,
|
return getOrCreate(
|
||||||
() -> keysApi = new KeysApi(getAuthenticatedSignalWebSocket(), getUnauthenticatedSignalWebSocket()));
|
() -> keysApi,
|
||||||
|
() ->
|
||||||
|
keysApi = new KeysApi(
|
||||||
|
getAuthenticatedSignalWebSocket(),
|
||||||
|
getUnauthenticatedSignalWebSocket()
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GroupsV2Operations getGroupsV2Operations() {
|
public GroupsV2Operations getGroupsV2Operations() {
|
||||||
return getOrCreate(() -> groupsV2Operations,
|
return getOrCreate(
|
||||||
() -> groupsV2Operations = new GroupsV2Operations(ClientZkOperations.create(serviceEnvironmentConfig.signalServiceConfiguration()),
|
() -> groupsV2Operations,
|
||||||
ServiceConfig.GROUP_MAX_SIZE));
|
() ->
|
||||||
|
groupsV2Operations = new GroupsV2Operations(
|
||||||
|
ClientZkOperations.create(
|
||||||
|
serviceEnvironmentConfig.signalServiceConfiguration()
|
||||||
|
),
|
||||||
|
ServiceConfig.GROUP_MAX_SIZE
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClientZkOperations getClientZkOperations() {
|
private ClientZkOperations getClientZkOperations() {
|
||||||
return getOrCreate(() -> clientZkOperations,
|
return getOrCreate(
|
||||||
() -> clientZkOperations = ClientZkOperations.create(serviceEnvironmentConfig.signalServiceConfiguration()));
|
() -> clientZkOperations,
|
||||||
|
() ->
|
||||||
|
clientZkOperations = ClientZkOperations.create(
|
||||||
|
serviceEnvironmentConfig.signalServiceConfiguration()
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClientZkProfileOperations getClientZkProfileOperations() {
|
private ClientZkProfileOperations getClientZkProfileOperations() {
|
||||||
@ -280,89 +380,178 @@ public class SignalDependencies {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SignalWebSocket.AuthenticatedWebSocket getAuthenticatedSignalWebSocket() {
|
public SignalWebSocket.AuthenticatedWebSocket getAuthenticatedSignalWebSocket() {
|
||||||
return getOrCreate(() -> authenticatedSignalWebSocket, () -> {
|
return getOrCreate(
|
||||||
final var timer = new UptimeSleepTimer();
|
() -> authenticatedSignalWebSocket,
|
||||||
final var healthMonitor = new SignalWebSocketHealthMonitor(timer);
|
() -> {
|
||||||
|
logger.info(
|
||||||
|
"Creating new authenticated WebSocket connection to Signal server..."
|
||||||
|
);
|
||||||
|
final var timer = new UptimeSleepTimer();
|
||||||
|
final var healthMonitor = new SignalWebSocketHealthMonitor(
|
||||||
|
timer
|
||||||
|
);
|
||||||
|
|
||||||
authenticatedSignalWebSocket = new SignalWebSocket.AuthenticatedWebSocket(() -> new OkHttpWebSocketConnection(
|
authenticatedSignalWebSocket =
|
||||||
"normal",
|
new SignalWebSocket.AuthenticatedWebSocket(
|
||||||
serviceEnvironmentConfig.signalServiceConfiguration(),
|
() -> {
|
||||||
Optional.of(credentialsProvider),
|
logger.info(
|
||||||
userAgent,
|
"Establishing authenticated WebSocket connection - URL: {}",
|
||||||
healthMonitor,
|
serviceEnvironmentConfig
|
||||||
allowStories), () -> true, timer, TimeUnit.SECONDS.toMillis(10));
|
.signalServiceConfiguration()
|
||||||
healthMonitor.monitor(authenticatedSignalWebSocket);
|
.getSignalServiceUrls()[0].getUrl()
|
||||||
});
|
);
|
||||||
|
return new OkHttpWebSocketConnection(
|
||||||
|
"normal",
|
||||||
|
serviceEnvironmentConfig.signalServiceConfiguration(),
|
||||||
|
Optional.of(credentialsProvider),
|
||||||
|
userAgent,
|
||||||
|
healthMonitor,
|
||||||
|
allowStories
|
||||||
|
);
|
||||||
|
},
|
||||||
|
() -> true,
|
||||||
|
timer,
|
||||||
|
TimeUnit.SECONDS.toMillis(10)
|
||||||
|
);
|
||||||
|
healthMonitor.monitor(authenticatedSignalWebSocket);
|
||||||
|
logger.info(
|
||||||
|
"Authenticated WebSocket connection created and health monitoring started"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SignalWebSocket.UnauthenticatedWebSocket getUnauthenticatedSignalWebSocket() {
|
public SignalWebSocket.UnauthenticatedWebSocket getUnauthenticatedSignalWebSocket() {
|
||||||
return getOrCreate(() -> unauthenticatedSignalWebSocket, () -> {
|
return getOrCreate(
|
||||||
final var timer = new UptimeSleepTimer();
|
() -> unauthenticatedSignalWebSocket,
|
||||||
final var healthMonitor = new SignalWebSocketHealthMonitor(timer);
|
() -> {
|
||||||
|
logger.info(
|
||||||
|
"Creating new unauthenticated WebSocket connection to Signal server..."
|
||||||
|
);
|
||||||
|
final var timer = new UptimeSleepTimer();
|
||||||
|
final var healthMonitor = new SignalWebSocketHealthMonitor(
|
||||||
|
timer
|
||||||
|
);
|
||||||
|
|
||||||
unauthenticatedSignalWebSocket = new SignalWebSocket.UnauthenticatedWebSocket(() -> new OkHttpWebSocketConnection(
|
unauthenticatedSignalWebSocket =
|
||||||
"unidentified",
|
new SignalWebSocket.UnauthenticatedWebSocket(
|
||||||
serviceEnvironmentConfig.signalServiceConfiguration(),
|
() -> {
|
||||||
Optional.empty(),
|
logger.info(
|
||||||
userAgent,
|
"Establishing unauthenticated WebSocket connection - URL: {}",
|
||||||
healthMonitor,
|
serviceEnvironmentConfig
|
||||||
allowStories), () -> true, timer, TimeUnit.SECONDS.toMillis(10));
|
.signalServiceConfiguration()
|
||||||
healthMonitor.monitor(unauthenticatedSignalWebSocket);
|
.getSignalServiceUrls()[0].getUrl()
|
||||||
});
|
);
|
||||||
|
return new OkHttpWebSocketConnection(
|
||||||
|
"unidentified",
|
||||||
|
serviceEnvironmentConfig.signalServiceConfiguration(),
|
||||||
|
Optional.empty(),
|
||||||
|
userAgent,
|
||||||
|
healthMonitor,
|
||||||
|
allowStories
|
||||||
|
);
|
||||||
|
},
|
||||||
|
() -> true,
|
||||||
|
timer,
|
||||||
|
TimeUnit.SECONDS.toMillis(10)
|
||||||
|
);
|
||||||
|
healthMonitor.monitor(unauthenticatedSignalWebSocket);
|
||||||
|
logger.info(
|
||||||
|
"Unauthenticated WebSocket connection created and health monitoring started"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SignalServiceMessageReceiver getMessageReceiver() {
|
public SignalServiceMessageReceiver getMessageReceiver() {
|
||||||
return getOrCreate(() -> messageReceiver,
|
return getOrCreate(
|
||||||
() -> messageReceiver = new SignalServiceMessageReceiver(getPushServiceSocket()));
|
() -> messageReceiver,
|
||||||
|
() ->
|
||||||
|
messageReceiver = new SignalServiceMessageReceiver(
|
||||||
|
getPushServiceSocket()
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SignalServiceMessageSender getMessageSender() {
|
public SignalServiceMessageSender getMessageSender() {
|
||||||
return getOrCreate(() -> messageSender,
|
return getOrCreate(
|
||||||
() -> messageSender = new SignalServiceMessageSender(getPushServiceSocket(),
|
() -> messageSender,
|
||||||
dataStore,
|
() ->
|
||||||
sessionLock,
|
messageSender = new SignalServiceMessageSender(
|
||||||
getAttachmentApi(),
|
getPushServiceSocket(),
|
||||||
getMessageApi(),
|
dataStore,
|
||||||
getKeysApi(),
|
sessionLock,
|
||||||
Optional.empty(),
|
getAttachmentApi(),
|
||||||
executor,
|
getMessageApi(),
|
||||||
ServiceConfig.MAX_ENVELOPE_SIZE,
|
getKeysApi(),
|
||||||
() -> true,
|
Optional.empty(),
|
||||||
UsePqRatchet.NO));
|
executor,
|
||||||
|
ServiceConfig.MAX_ENVELOPE_SIZE,
|
||||||
|
() -> true,
|
||||||
|
UsePqRatchet.NO
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SecureValueRecovery> getSecureValueRecovery() {
|
public List<SecureValueRecovery> getSecureValueRecovery() {
|
||||||
return getOrCreate(() -> secureValueRecovery,
|
return getOrCreate(
|
||||||
() -> secureValueRecovery = serviceEnvironmentConfig.svr2Mrenclaves()
|
() -> secureValueRecovery,
|
||||||
.stream()
|
() ->
|
||||||
.map(mr -> (SecureValueRecovery) getAccountManager().getSecureValueRecoveryV2(mr))
|
secureValueRecovery = serviceEnvironmentConfig
|
||||||
.toList());
|
.svr2Mrenclaves()
|
||||||
|
.stream()
|
||||||
|
.map(mr ->
|
||||||
|
(SecureValueRecovery) getAccountManager().getSecureValueRecoveryV2(
|
||||||
|
mr
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.toList()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileApi getProfileApi() {
|
public ProfileApi getProfileApi() {
|
||||||
return getOrCreate(() -> profileApi,
|
return getOrCreate(
|
||||||
() -> profileApi = new ProfileApi(getAuthenticatedSignalWebSocket(),
|
() -> profileApi,
|
||||||
getUnauthenticatedSignalWebSocket(),
|
() ->
|
||||||
getPushServiceSocket(),
|
profileApi = new ProfileApi(
|
||||||
getClientZkProfileOperations()));
|
getAuthenticatedSignalWebSocket(),
|
||||||
|
getUnauthenticatedSignalWebSocket(),
|
||||||
|
getPushServiceSocket(),
|
||||||
|
getClientZkProfileOperations()
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileService getProfileService() {
|
public ProfileService getProfileService() {
|
||||||
return getOrCreate(() -> profileService,
|
return getOrCreate(
|
||||||
() -> profileService = new ProfileService(getClientZkProfileOperations(),
|
() -> profileService,
|
||||||
getAuthenticatedSignalWebSocket(),
|
() ->
|
||||||
getUnauthenticatedSignalWebSocket()));
|
profileService = new ProfileService(
|
||||||
|
getClientZkProfileOperations(),
|
||||||
|
getAuthenticatedSignalWebSocket(),
|
||||||
|
getUnauthenticatedSignalWebSocket()
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SignalServiceCipher getCipher(ServiceIdType serviceIdType) {
|
public SignalServiceCipher getCipher(ServiceIdType serviceIdType) {
|
||||||
final var certificateValidator = new CertificateValidator(serviceEnvironmentConfig.unidentifiedSenderTrustRoot());
|
final var certificateValidator = new CertificateValidator(
|
||||||
final var address = new SignalServiceAddress(credentialsProvider.getAci(), credentialsProvider.getE164());
|
serviceEnvironmentConfig.unidentifiedSenderTrustRoot()
|
||||||
|
);
|
||||||
|
final var address = new SignalServiceAddress(
|
||||||
|
credentialsProvider.getAci(),
|
||||||
|
credentialsProvider.getE164()
|
||||||
|
);
|
||||||
final var deviceId = credentialsProvider.getDeviceId();
|
final var deviceId = credentialsProvider.getDeviceId();
|
||||||
return new SignalServiceCipher(address,
|
return new SignalServiceCipher(
|
||||||
deviceId,
|
address,
|
||||||
serviceIdType == ServiceIdType.ACI ? dataStore.aci() : dataStore.pni(),
|
deviceId,
|
||||||
sessionLock,
|
serviceIdType == ServiceIdType.ACI
|
||||||
certificateValidator);
|
? dataStore.aci()
|
||||||
|
: dataStore.pni(),
|
||||||
|
sessionLock,
|
||||||
|
certificateValidator
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T getOrCreate(Supplier<T> supplier, Callable creator) {
|
private <T> T getOrCreate(Supplier<T> supplier, Callable creator) {
|
||||||
@ -382,7 +571,6 @@ public class SignalDependencies {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private interface Callable {
|
private interface Callable {
|
||||||
|
|
||||||
void call();
|
void call();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user