mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-25 04:48:04 +01:00
Device provisioning fixes.
// FREEBIE
This commit is contained in:
@@ -31,6 +31,7 @@ import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.Device;
|
||||
import org.whispersystems.textsecuregcm.storage.PendingDevicesManager;
|
||||
import org.whispersystems.textsecuregcm.util.Util;
|
||||
import org.whispersystems.textsecuregcm.util.VerificationCode;
|
||||
|
||||
import javax.validation.Valid;
|
||||
@@ -119,6 +120,7 @@ public class DeviceController {
|
||||
device.setSignalingKey(accountAttributes.getSignalingKey());
|
||||
device.setFetchesMessages(accountAttributes.getFetchesMessages());
|
||||
device.setId(account.get().getNextDeviceId());
|
||||
device.setLastSeen(Util.todayInMillis());
|
||||
|
||||
account.get().addDevice(device);
|
||||
accounts.update(account.get());
|
||||
|
||||
@@ -18,7 +18,7 @@ import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import io.dropwizard.auth.Auth;
|
||||
import static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal;
|
||||
@@ -74,8 +74,8 @@ public class ReceiptController {
|
||||
private void sendDirectReceipt(Account source, String destination, long messageId)
|
||||
throws NotPushRegisteredException, TransientPushFailureException, NoSuchUserException
|
||||
{
|
||||
Account destinationAccount = getDestinationAccount(destination);
|
||||
List<Device> destinationDevices = destinationAccount.getDevices();
|
||||
Account destinationAccount = getDestinationAccount(destination);
|
||||
Set<Device> destinationDevices = destinationAccount.getDevices();
|
||||
|
||||
OutgoingMessageSignal.Builder message =
|
||||
OutgoingMessageSignal.newBuilder()
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package org.whispersystems.textsecuregcm.entities;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
@@ -42,7 +43,19 @@ public class PreKeyResponseV2 {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public List<PreKeyResponseItemV2> getDevices() {
|
||||
return devices;
|
||||
@JsonIgnore
|
||||
public PreKeyResponseItemV2 getDevice(int deviceId) {
|
||||
for (PreKeyResponseItemV2 device : devices) {
|
||||
if (device.getDeviceId() == deviceId) return device;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@JsonIgnore
|
||||
public int getDevicesCount() {
|
||||
return devices.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,6 +40,6 @@ public class NonLimitedAccount extends Account {
|
||||
|
||||
@Override
|
||||
public Optional<Device> getAuthenticatedDevice() {
|
||||
return Optional.of(new Device(deviceId, null, null, null, null, null, false, 0, null));
|
||||
return Optional.of(new Device(deviceId, null, null, null, null, null, false, 0, null, System.currentTimeMillis()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class Account {
|
||||
|
||||
@@ -36,7 +36,7 @@ public class Account {
|
||||
private boolean supportsSms;
|
||||
|
||||
@JsonProperty
|
||||
private List<Device> devices = new LinkedList<>();
|
||||
private Set<Device> devices = new HashSet<>();
|
||||
|
||||
@JsonProperty
|
||||
private String identityKey;
|
||||
@@ -47,7 +47,7 @@ public class Account {
|
||||
public Account() {}
|
||||
|
||||
@VisibleForTesting
|
||||
public Account(String number, boolean supportsSms, List<Device> devices) {
|
||||
public Account(String number, boolean supportsSms, Set<Device> devices) {
|
||||
this.number = number;
|
||||
this.supportsSms = supportsSms;
|
||||
this.devices = devices;
|
||||
@@ -78,14 +78,11 @@ public class Account {
|
||||
}
|
||||
|
||||
public void addDevice(Device device) {
|
||||
this.devices.remove(device);
|
||||
this.devices.add(device);
|
||||
}
|
||||
|
||||
public void setDevices(List<Device> devices) {
|
||||
this.devices = devices;
|
||||
}
|
||||
|
||||
public List<Device> getDevices() {
|
||||
public Set<Device> getDevices() {
|
||||
return devices;
|
||||
}
|
||||
|
||||
@@ -113,7 +110,9 @@ public class Account {
|
||||
long highestDevice = Device.MASTER_ID;
|
||||
|
||||
for (Device device : devices) {
|
||||
if (device.getId() > highestDevice) {
|
||||
if (!device.isActive()) {
|
||||
return device.getId();
|
||||
} else if (device.getId() > highestDevice) {
|
||||
highestDevice = device.getId();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ import org.whispersystems.textsecuregcm.auth.AuthenticationCredentials;
|
||||
import org.whispersystems.textsecuregcm.entities.SignedPreKey;
|
||||
import org.whispersystems.textsecuregcm.util.Util;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class Device {
|
||||
|
||||
public static final long MASTER_ID = 1;
|
||||
@@ -56,12 +58,15 @@ public class Device {
|
||||
@JsonProperty
|
||||
private SignedPreKey signedPreKey;
|
||||
|
||||
@JsonProperty
|
||||
private long lastSeen;
|
||||
|
||||
public Device() {}
|
||||
|
||||
public Device(long id, String authToken, String salt,
|
||||
String signalingKey, String gcmId, String apnId,
|
||||
boolean fetchesMessages, int registrationId,
|
||||
SignedPreKey signedPreKey)
|
||||
SignedPreKey signedPreKey, long lastSeen)
|
||||
{
|
||||
this.id = id;
|
||||
this.authToken = authToken;
|
||||
@@ -72,6 +77,7 @@ public class Device {
|
||||
this.fetchesMessages = fetchesMessages;
|
||||
this.registrationId = registrationId;
|
||||
this.signedPreKey = signedPreKey;
|
||||
this.lastSeen = lastSeen;
|
||||
}
|
||||
|
||||
public String getApnId() {
|
||||
@@ -86,6 +92,14 @@ public class Device {
|
||||
}
|
||||
}
|
||||
|
||||
public void setLastSeen(long lastSeen) {
|
||||
this.lastSeen = lastSeen;
|
||||
}
|
||||
|
||||
public long getLastSeen() {
|
||||
return lastSeen;
|
||||
}
|
||||
|
||||
public String getGcmId() {
|
||||
return gcmId;
|
||||
}
|
||||
@@ -124,7 +138,10 @@ public class Device {
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return fetchesMessages || !Util.isEmpty(getApnId()) || !Util.isEmpty(getGcmId());
|
||||
boolean hasChannel = fetchesMessages || !Util.isEmpty(getApnId()) || !Util.isEmpty(getGcmId());
|
||||
|
||||
return (id == MASTER_ID && hasChannel) ||
|
||||
(id != MASTER_ID && hasChannel && signedPreKey != null && lastSeen > (System.currentTimeMillis() - TimeUnit.DAYS.toMillis(30)));
|
||||
}
|
||||
|
||||
public boolean getFetchesMessages() {
|
||||
@@ -158,4 +175,17 @@ public class Device {
|
||||
public long getPushTimestamp() {
|
||||
return pushTimestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == null || !(other instanceof Device)) return false;
|
||||
|
||||
Device that = (Device)other;
|
||||
return this.id == that.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (int)this.id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.net.URLEncoder;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class Util {
|
||||
|
||||
@@ -119,4 +120,8 @@ public class Util {
|
||||
Thread.sleep(i);
|
||||
} catch (InterruptedException ie) {}
|
||||
}
|
||||
|
||||
public static long todayInMillis() {
|
||||
return TimeUnit.DAYS.toMillis(TimeUnit.MILLISECONDS.toDays(System.currentTimeMillis()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.Device;
|
||||
import org.whispersystems.textsecuregcm.storage.PubSubManager;
|
||||
import org.whispersystems.textsecuregcm.storage.StoredMessages;
|
||||
import org.whispersystems.textsecuregcm.util.Util;
|
||||
import org.whispersystems.websocket.session.WebSocketSessionContext;
|
||||
import org.whispersystems.websocket.setup.WebSocketConnectListener;
|
||||
|
||||
@@ -48,6 +49,11 @@ public class AuthenticatedConnectListener implements WebSocketConnectListener {
|
||||
return;
|
||||
}
|
||||
|
||||
if (device.get().getLastSeen() != Util.todayInMillis()) {
|
||||
device.get().setLastSeen(Util.todayInMillis());
|
||||
accountsManager.update(account.get());
|
||||
}
|
||||
|
||||
final WebSocketConnection connection = new WebSocketConnection(accountsManager, pushSender,
|
||||
storedMessages, pubSubManager,
|
||||
account.get(), device.get(),
|
||||
|
||||
Reference in New Issue
Block a user